Versions Compared

Key

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

...

The mobility of this system can be represented using Gruebler's Equation: M = 3(6-1) - 2*7 = 1 DOF. 

Kinematic Analysis and Synthesis

The following graphs show the position, velocity, and acceleration for the linkages in this system with the 

Image Removed 

Image Removed

Image Removed

Image Removed

Kinematic Plots of Slider

Image Removed

Image Removed

Image Removed

Kinematic Plots of Linkage 5

Image Removed

Image Removed

Image Removed

Kinematic Plots of Linkage 4

Image Removed

Image Removed

Image Removed

Kinematic Plots of Linkage 3

The following animation is provided to show simulated movement 

View file
namePMKS_Web - Internet Explorer 2021-05-09 13-48-25.mp4
height250

Manufacturing and Assembly

The linkages are 3D printed and were initially constrained using #8-32 1/4" standoffs with washers. The standoffs were too long resulting in unwanted translation of the mechanism. 

Image Removed

Early Version of Prototype. Motor is constrained with zip-ties and linkages are constrained by #8-32 bolts.

To improve the mechanism, I used M3 bolts with locknuts to eliminate any translation within the linkage system. In addition, I used a 3D printed part with T-nuts to slide the aluminum extrusion along. This piece is shown below

Image Removed

Stationary portion of slider joint.

Image Removed

Rev2 of the Assembly with Slider constrained by T-Nut

This assembly did not have smooth frictionless motion as the 3D printed part kept binding against the aluminum extrusion. I added bearing wheels to the assembly to fix this issue. The final assembly is shown below. 

Electronics and Software

To better control the speed of the input crank, I used a potentiometer to quickly adjust the speed of the mechanism. I connected the potentiometer, a motor, and H-Bridge to the Arduino. My setup is shown below

Image Removed

Electronics Setup

The software for this setup is located in the Appendix. 

Final Prototype

Conclusions and Future Work

Appendix 

...

// Actuator Pins
#define MOTOR_FWD_PIN 8
#define MOTOR_BWD_PIN 9
#define MOTOR_ENA_PIN 10

typedef struct ActuatorOut {
uint8_t fwd_pin;
uint8_t bwd_pin;
uint8_t ena_pin;
} AcuatorOut;

const ActuatorOut MOTOR_PINS = {MOTOR_FWD_PIN, MOTOR_BWD_PIN, MOTOR_ENA_PIN};

#define POTENTIOMETER_PIN A5
//------------ActuatorInit-----------
// Function to initialize the direction and enable pins of an actuator.
// Inputs: actuator struct representing actuator configuration
// Outputs: none
void ActuatorInit(const ActuatorOut *actuator) {
pinMode((*actuator).fwd_pin, OUTPUT);
pinMode((*actuator).bwd_pin, OUTPUT);
pinMode((*actuator).ena_pin, OUTPUT);
}

//------------ClipValue-----------
// Function to bound values between two limits. If value is higher/lower than a limit, it is set to that limit.
// Inputs: *val pointer to current value
// upper_lim upper limit for value
// lower_lim lower limit for value
// Outputs: none
void ClipValue(int16_t *val, int16_t lower_lim, int16_t upper_lim) {
(*val) = (*val > upper_lim) ? upper_lim : *val;
(*val) = (*val < lower_lim) ? lower_lim : *val;
}

//------------SetActuator-----------
// Function to set the direction and magnitude of an actuator. Negative magnitude implies
// Counter-Clockwise rotation for a motor and opposing polarity for an electromagnet
// Inputs: mag magnitude of actuator effort between -255 and 255
// actuator struct representing actuator configuration
// Outputs: none
void SetActuator(int16_t mag, const ActuatorOut *actuator) {
// Clip to 8-bit value
ClipValue(&mag, -255, 255);

if (mag > 0) { // Forward Direction
digitalWrite((*actuator).bwd_pin, LOW);
digitalWrite((*actuator).fwd_pin, HIGH);
}
else if (mag < 0) { // Backward Direction
digitalWrite((*actuator).fwd_pin, LOW);
digitalWrite((*actuator).bwd_pin, HIGH);
}
else { // Zero Magnitude
digitalWrite((*actuator).fwd_pin, LOW);
digitalWrite((*actuator).bwd_pin, LOW);
}

// Send actuator command
analogWrite((*actuator).ena_pin, abs(mag));
}

...

void loop() {
SetActuator((analogRead(POTENTIOMETER_PIN) - 512)/2, &MOTOR_PINS);

}