Components and supplies
1
12VDC Motor
1
Aluminum Extrusion 30 Series
1
12VDC Power Supply
1
Arduino Nano R3
1
Dual H-Bridge motor drivers L298
1
24VDC Power Supply
1
Smart Vision Lights Backlight (DLP-300x300)
Tools and machines
1
Laser cutter (generic)
1
3D Printer (generic)
1
Saw
Project description
Code
Main Code
arduino
1/* 2 Author: Harrison McIntyre 3 Youtube Channel: https://www.youtube.com/c/HarrisonMcIntyre 4 Last Updated: 6.25.2021 5 6 Credit for the "MillisDelay" library code here: https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html 7 8*/ 9 10#include <millisDelay.h> 11 12// L298N Control Pins 13#define directionPin1 9 14#define directionPin2 10 15#define speedPin 11 16 17// Encoder Pin 18#define encoderPin 2 19 20// Light Triggering Pin 21#define npnLine 8 22 23// External Control Pins 24#define switchPin1 3 25#define switchPin2 4 26 27// Various Timers for Checking External Controls 28millisDelay switchDelay; 29millisDelay potDelay; 30millisDelay checkSpeedDelay; 31 32// Some sort of delay after the light is triggered (I honestly don't remember what it does) 33unsigned long pulseTimer = 0; 34 35// The light's current state 36int lightState = 0; 37// The light's previous state 38int prevLightState = 1; 39// Wheter or not to strobe the light (turn it on then back off again quickly) 40boolean strobe = false; 41// Total recorded light pulses 42unsigned long totalPulses = 0; 43 44// The gear ratio for the motor 45double gearRatio = 62.4; 46// Number of encoder pulses per revolution of the motor 47double ppr = 11; 48 49// External switch state 50int switchState = 1; 51// External dial val 52double dialVal = 0.0; 53// Previous external dial val 54double prevDialVal = 0.0; 55 56// Adjustment delay for drift compensation on the animation 57int adjustmentVal = 0; 58// Number of total frames 59double framesPerRev = 20.0; 60 61// Used to calculate the RPM of the motor 62unsigned long rpmTime = 1; 63// The current rotations per minute of the motor 64double rpm = 0.0; 65// The Desired rotations per minute of the motor 66double setRpm = 0.0; 67 68// Variables used in closed loop control of the motor's RPM 69double difference = 0.0; 70double gain = 0.05; 71 72// Used for debugging purposes 73unsigned long debugVal = 0; 74 75// Used to calculate when to strobe the light next 76unsigned long rawStrobeTime = 0; 77 78void setup() { 79 // Initialize the necessary pins 80 pinMode(directionPin1, OUTPUT); 81 pinMode(directionPin2, OUTPUT); 82 pinMode(speedPin, OUTPUT); 83 pinMode(npnLine, OUTPUT); 84 85 pinMode(switchPin1, INPUT_PULLUP); 86 pinMode(switchPin2, INPUT_PULLUP); 87 88 // Start the timers that we use to check various controls and machine states 89 switchDelay.start(500); 90 potDelay.start(700); 91 checkSpeedDelay.start(1); 92 93 // Attach an interrupt to the encoder pin 94 attachInterrupt(digitalPinToInterrupt(encoderPin), increment, FALLING); 95 96 // Start serial communication 97 //Serial.begin(9600); 98 99 // Wait (because why not) 100 delay(1000); 101 102 // Set some initial states for the L298N control pins 103 digitalWrite(directionPin1, HIGH); 104 digitalWrite(directionPin2, LOW); 105 analogWrite(speedPin, 240); 106} 107 108 109// Function for pulsing the overhead light 110void pulseLight(unsigned long val) { 111 // If commanded to strobe, do 112 if (strobe) { 113 // Only strobe once 114 strobe = false; 115 // Turn the light on 116 lightState = 1; 117 // Store the current time in microseconds 118 pulseTimer = micros(); 119 } 120 // If the desired time has elapsed turn the light off 121 if (micros() - pulseTimer >= val) { 122 lightState = 0; 123 } 124 // Change the light state only if it has changed 125 if (lightState != prevLightState) { 126 digitalWrite(npnLine, lightState); 127 prevLightState = lightState; 128 } 129} 130 131// Function for checking the external switch 132void checkSwitch() { 133 // If it's time to check the switch, do 134 if (switchDelay.justFinished()) { 135 // Reset the timer 136 switchDelay.repeat(); 137 // Read the switch state 138 if (!digitalRead(switchPin1)) { 139 switchState = -1; 140 }else if (!digitalRead(switchPin2)) { 141 switchState = 0; 142 }else { 143 switchState = 1; 144 } 145 } 146 // Update the motor speed 147 analogWrite(speedPin, dialVal); 148} 149 150// Function for checking the external dial 151void checkDial() { 152 // If it's time to check the dial, do 153 if (potDelay.justFinished()) { 154 // Reset the timer 155 potDelay.repeat(); 156 // Read the dial 157 adjustmentVal = (analogRead(A3) / 1024.0 * 400) - 200; 158 if (adjustmentVal >= -5 && adjustmentVal <= 5) { 159 adjustmentVal = 0; 160 } 161 } 162} 163 164// Function for closed loop control of the motor speed 165void checkSpeed() { 166 // If it's time to check the motor speed, do 167 if (checkSpeedDelay.justFinished()) { 168 // Restart the timer 169 checkSpeedDelay.repeat(); 170 // Check the motor speed and make necessary adjustments to motor output 171 difference = (setRpm - rpm) / 5; 172 difference = constrain(difference, -1, 1); 173 dialVal = dialVal + difference*gain; 174 } 175} 176 177void loop() { 178 // Pulse the light for 1000 microseconds (1 millisecond) 179 pulseLight(1000); 180 181 // Check the various external controls and motor speed 182 checkSwitch(); 183 checkDial(); 184 checkSpeed(); 185 186 // Calculate the motor RPM 187 rpm = 1000000/(debugVal*ppr*gearRatio)*60; 188 189 // Various display modes based upon external switch input 190 if (switchState == 1) { 191 totalPulses = 0; 192 setRpm = 84; 193 194 // If it's time to strobe the light, do 195 if (micros() - rawStrobeTime >= 35755 + adjustmentVal) { 196 strobe = true; 197 rawStrobeTime = micros(); 198 } 199 200 }else if (switchState == 0) { 201 totalPulses = 0; 202 setRpm = 90; 203 204 // If it's time to strobe the light, do 205 if (micros() - rawStrobeTime >= 33270 + adjustmentVal) { 206 strobe = true; 207 rawStrobeTime = micros(); 208 } 209 }else if (switchState == -1) { 210 totalPulses = 0; 211 dialVal = 150; 212 213 // Turn the light off 214 digitalWrite(npnLine, LOW); 215 } 216} 217 218// Function to increment totalPulses every time the encoder pulses 219void increment() { 220 debugVal = (micros() - rpmTime); 221 rpmTime = micros(); 222 totalPulses++; 223} 224
Comments
Only logged in users can leave comments