...
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
Kinematic Plots of Slider
Kinematic Plots of Linkage 5
Kinematic Plots of Linkage 4
Kinematic Plots of Linkage 3
The following animation is provided to show simulated movement
View file | ||||
---|---|---|---|---|
|
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.
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
Stationary portion of slider joint.
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
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);
}