Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Design

Cam Profile Design

...

Just like for out initial prototype, we utilized a graphing calculator to visualize the profile of the cams before manufacturing. An additional step we took this time around, however, was the use of Norton's Dynacam program to calculate pitch angles for the entire cam to determine if we had an appropriate prime radius. This program can be found in the CD of the "Design of Machinery" textbook. The connection between each of the dwells on the cams was chosen to be a modified sine curve, in order to achieve smooth continuity across displacement, velocity and acceleration.

Figure: screenshot of graphing calculator program to visualize cam profiles.

Live demo of graphing calculator program used: https://www.desmos.com/calculator/lsqv4ouwov

Figure: screenshot of Dynacam program used to compute pitch angles.

Once we had a method of making arbitrary cam profile designs, we set out to design the images that our tiles would output. Since we only had a 5x5 display, our image options were limited. We ended up designing the following images to display, where a color of white corresponds to an output height displacement of 0", and a color of black represents and output height displacement of 0.5". Gray colors are intermediate values between 0" and 0.5". For our final prototype, we only displayed the following four images: blank, one, checker, and spiral.

Figure: Potential image outputs for our 3D display (5x5 pixel grid).


Structure Design

For our structure, we ended up designing the entire assembly in SolidWorks, and then exporting those files to PDF drawings that were used by the laser cutter. All connections and contact surfaces between planes, rods, and shafts were toleranced to be either snug fits or loose fits, depending on their function.

 

Figure: Structure assemblies designed in SolidWorks.

In order to couple and drive all 5 camshafts together with a single motor input, we decided to design a drive train similar to that in train wheels. The drive train consisted of a series of parallelogram linkage mechanisms that rotated at the same speed.

Figure: Underside of assembly showing internal cams.

Video: 2015-12-03 09.17.14.mov

 

Materials

The large majority of our materials were 1/4" birch wood and 1/8" acrylic sheets that were used for making the various components in the laser cutter. Other materials used were 3/8" diameter Delrin rods for the camshafts, 1/4" diameter wooden dowels used to couple the revolute joints in the drive train, and hot glue for putting things together.

...

Camshafts: 3/8" black Delrin rods

Figure: Laser cut materials used in our final design.


Mechatronics

For our mechatronics, we used an Arduino board with a motor controller, and a AC to DC power supply. Our Arduino code was written to read the motor encoder position and rotate by 90 degrees with each press of the reseat button. This had the effect of switching between images whenever the button was pressed once. In addition, the display could be run in "continuous" mode by unplugging the encoder signal wires, since that way the motor would never find it's target position and keep turning.

Figure: Motor connected to the center shaft of 3D display. It is controlled via an Arduino motor controller.

Code Block
languagecpp
titleArduino Code
linenumberstrue
// current code
#include "DualMC33926MotorShield.h"
enum PinAssignments {
  encoderPinA = 2,
  encoderPinB = 3,
  clearButton = 8
};
enum Positions {
  one = 1633,
  two = 3267,
  three = 4900,
  four = 6533
};
volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1;
boolean A_set = false;
boolean B_set = false;
DualMC33926MotorShield md;
void stopIfFault()
{
  if (md.getFault())
  {
    Serial.println("fault");
    while(1);
  }
}
void setup()
{
  
  pinMode(encoderPinA, INPUT); 
  pinMode(encoderPinB, INPUT); 
  pinMode(clearButton, INPUT);
  digitalWrite(encoderPinA, HIGH);  // turn on pullup resistor
  digitalWrite(encoderPinB, HIGH);  // turn on pullup resistor
  digitalWrite(clearButton, HIGH);
// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);
  
  Serial.begin(115200);
  Serial.println("Dual MC33926 Motor Shield");
  md.init();
}
boolean turn = false;
int target = -1633;
void loop()
{
  if (lastReportedPos != encoderPos) {
    Serial.print("Index:");
    Serial.print(encoderPos);
    Serial.println();
    lastReportedPos = encoderPos;
  }
  if (digitalRead(clearButton) == LOW)  {
    encoderPos = 0;
  }
  
  
  int i = encoderPos;
  
  if(i < (target-15)) {
    md.setM1Speed(-100);
    stopIfFault(); 
  } else if(i > ((target))) {
    md.setM1Speed(100);
    stopIfFault(); 
  } else {
    md.setM1Speed(0);
    stopIfFault();
  }
}
// Interrupt on A changing state
void doEncoderA(){
  // Test transition
  A_set = digitalRead(encoderPinA) == HIGH;
  // and adjust counter + if A leads B
  encoderPos += (A_set != B_set) ? +1 : -1;
}
// Interrupt on B changing state
void doEncoderB(){
  // Test transition
  B_set = digitalRead(encoderPinB) == HIGH;
  // and adjust counter + if B follows A
  encoderPos += (A_set == B_set) ? +1 : -1;
}

...