Top: Laser beam working prior to condensation obscuring the acrylic.

Bottom: Condensation on top panel hides the laser beam

Analysis:

Due to the technical limitation of fog condensing on the inside of our acrylic and preventing the laser’s path from being seen, our first presentation failed to invoke any moments of delight in the visitors. However, we did observe some interesting interactions despite our exhibits broken state. For instance, we observed that a lot of people assumed that our exhibit somehow controlled the larger “Lake Light” kinetic sculpture next to us. Often the visitors would turn the knob while looking at “Lake Light” instead of our project. This was mostly due to the fact that “Lake Light” was much bigger than ours and incorporated motion, sounds, and lights which drew in visitors. Because of this for our next iteration we plan to have completed our planned musical aspect and have the actuators fully operational to have a motion aspect to further draw in visitors. Previously we had thought that the light of the lasers would be enough to draw visitors in but after our observations at the museum we are planning to add additional LED to go with the musical element and help draw people in better.

Revision Plan:

Currently, in order to rectify the condensation limitation we have ordered anti-fog spray which should help prevent liquids from condensing on our viewing surfaces and obscuring the laser-show.

Overall the experience needs to be made more engaging so we will be increasing its size and number of actuators to allow the users to interact with it more. Additionally, we observed that the experience needs to generate some kind of effect beyond just the laser movement so we will be integrating music that is affected by the actuators in the second design to address this.

All new items which must be purchased are prepared on this form: Purchase Form

New Timeline

Code

/* Basic Code Base for Verifying All Core Functionality on a
 * Proof-of-Concept Box */

#include <Encoder.h>
#include <CheapStepper.h>

#define ENC_STEPS_PER_REV 80.0
Encoder EncO(3,4); // Output Encoder

const float MOT_STEPS_PER_REV = 4075.7728 * 43.0 / 11.0;
CheapStepper stepper(8,9,10,11);
bool movingClockwise = true;
unsigned long moveStartTime = 0; // this will save the time (millis()) when we started each new move

// Returns the Output Angle of the Encoder in Degrees
float outputAng(){
  return 360 * EncO.read() / ENC_STEPS_PER_REV;
} // #outputAng

struct CurrentMoveType{
  float start; // Starting Angle of Move [deg]
  float e; // Ending Angle of Move [deg]
  int stepLen; // Number of Steps in Move
} CurrentMove;

void goTo(float ang){
  static float commAng = 0.0; // Last Commanded Angle
  float Da = ang - commAng;
  CurrentMove.start = commAng;
  CurrentMove.e = ang;
  CurrentMove.stepLen = abs(Da) * MOT_STEPS_PER_REV / 360.0;

  movingClockwise = Da < 0;
  moveStartTime = millis();
  stepper.newMove(movingClockwise, CurrentMove.stepLen);
  commAng = ang;
} // #goTo

// Return the Current Commanded Motor Angle using Step Interpolation across 
// the Bounds of the Current Move
float getCommAng(){
  return CurrentMove.start + ((float)(CurrentMove.stepLen - abs(stepper.getStepsLeft()))) * (CurrentMove.e-CurrentMove.start) / ((float)CurrentMove.stepLen);
} // #getCommPos
void setup(){
  Serial.begin(9600);
  stepper.set4076StepMode();
  stepper.setRpm(36);
  goTo(180.0);
} // #setup

char dir = 1;
unsigned long last_update = -10000;
void loop(){
  stepper.run();
  if(millis() - last_update > 100){
    Serial.print(getCommAng());
    Serial.print(", ");
    Serial.println(outputAng());
    last_update = millis(); // Call at e of printing to have event e-start spacing
  }
  if(stepper.getStepsLeft() == 0){
    dir = !dir;
    goTo((dir ? 1 : -1) * 180.0);
  }
} // #loop

CAD

Series Elastic Actuator

Test Box