Last active
February 26, 2020 18:16
-
-
Save Will-Firgelli/89978da2585a747ef5ff988b2fa53904 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Written by Firgelli Automations | |
* Limited or no support: we do not have the resources for Arduino code support | |
* This code exists in the public domain | |
* | |
* Program requires two (or more) of our supported linear actuators: | |
* FA-OS-35-12-XX | |
* FA-OS-240-12-XX | |
* FA-OS-400-12-XX | |
* Products available for purchase at https://www.firgelliauto.com/collections/linear-actuators/products/optical-sensor-actuators | |
*/ | |
#include <elapsedMillis.h> | |
elapsedMillis timeElapsed; | |
#define numberOfActuators 2 | |
int RPWM[numberOfActuators]={6, 11}; //PWM signal right side | |
int LPWM[numberOfActuators]={5,10}; | |
int opticalPins[numberOfActuators]={2,3}; //connect optical pins to interrupt pins on Arduino. More information: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ | |
volatile long lastDebounceTime_0=0; //timer for when interrupt was triggered | |
volatile long lastDebounceTime_1=0; | |
int Speed = 255; //choose any speed in the range [0, 255] | |
#define falsepulseDelay 20 //noise pulse time, if too high, ISR will miss pulses. | |
volatile int counter[numberOfActuators]={}; | |
volatile int prevCounter[numberOfActuators]={}; | |
int Direction; //-1 = retracting | |
// 0 = stopped | |
// 1 = extending | |
int extensionCount[numberOfActuators] = {}; | |
int retractionCount[numberOfActuators] = {}; | |
int pulseTotal[numberOfActuators]={}; //stores number of pulses in one full extension/actuation | |
void setup(){ | |
for(int i=0; i<numberOfActuators; i++){ | |
pinMode(RPWM[i],OUTPUT); | |
pinMode(LPWM[i], OUTPUT); | |
pinMode(opticalPins[i], INPUT_PULLUP); | |
counter[i]=0; //initialize variables as array of zeros | |
prevCounter[i]=0; | |
extensionCount[i] = 0; | |
retractionCount[i] = 0; | |
pulseTotal[i] = 0; | |
} | |
attachInterrupt(digitalPinToInterrupt(opticalPins[0]), count_0, RISING); | |
attachInterrupt(digitalPinToInterrupt(opticalPins[1]), count_1, RISING); | |
Serial.begin(9600); | |
Serial.println("Initializing calibration"); | |
Serial.println("Actuator retracting..."); | |
Direction = -1; | |
moveTillLimit(Direction, 255); | |
Serial.println("Actuator fully retracted"); | |
delay(1000); | |
for(int i=0; i<numberOfActuators; i++){ | |
Serial.print("\t\t\t\tActuator "); | |
Serial.print(i); | |
} | |
Direction = 1; | |
moveTillLimit(Direction, 255); //extend fully and count pulses | |
Serial.print("\nExtension Count:"); | |
for(int i=0; i<numberOfActuators; i++){ | |
extensionCount[i]=counter[i]; | |
Serial.print("\t\t"); | |
Serial.print(extensionCount[i]); | |
Serial.print("\t\t\t"); | |
} | |
delay(1000); | |
Direction = -1; | |
moveTillLimit(Direction, 255); //retract fully and count pulses | |
Serial.print("\nRetraction Count:"); | |
for(int i=0; i<numberOfActuators; i++){ | |
retractionCount[i]=counter[i]; | |
Serial.print("\t\t"); | |
Serial.print(abs(retractionCount[i])); | |
Serial.print("\t\t\t"); | |
} | |
Serial.print("\n"); | |
for(int i=0; i<numberOfActuators; i++){ | |
Serial.print("\nActuator "); | |
Serial.print(i); | |
Serial.print(" average pulses: "); | |
pulseTotal[i]=(extensionCount[i]+abs(retractionCount[i]))/2; //takes the average of measurements | |
Serial.print(pulseTotal[i]); | |
} | |
Serial.println("\n\nEnter these values in the synchronous control progam."); | |
} | |
void loop() { | |
} | |
void moveTillLimit(int Direction, int Speed){ | |
//this function moves the actuator to one of its limits | |
for(int i = 0; i < numberOfActuators; i++){ | |
counter[i] = 0; //reset counter variables | |
prevCounter[i] = 0; | |
} | |
do { | |
for(int i = 0; i < numberOfActuators; i++) { | |
prevCounter[i] = counter[i]; | |
} | |
timeElapsed = 0; | |
while(timeElapsed < 200){ //keep moving until counter remains the same for a short duration of time | |
for(int i = 0; i < numberOfActuators; i++) { | |
driveActuator(i, Direction, Speed); | |
} | |
} | |
} while(compareCounter(prevCounter, counter)); //loop until all counts remain the same | |
} | |
bool compareCounter(volatile int prevCounter[], volatile int counter[]){ | |
//compares two arrays and returns false when every element of one array is the same as its corresponding indexed element in the other array | |
bool areUnequal = true; | |
for(int i = 0; i < numberOfActuators; i++){ | |
if(prevCounter[i] == counter[i]){ | |
areUnequal = false; | |
} | |
else{ //if even one pair of elements are unequal the entire function returns true | |
areUnequal = true; | |
break; | |
} | |
} | |
return areUnequal; | |
} | |
void driveActuator(int Actuator, int Direction, int Speed){ | |
int rightPWM=RPWM[Actuator]; | |
int leftPWM=LPWM[Actuator]; | |
switch(Direction){ | |
case 1: //extension | |
analogWrite(rightPWM, Speed); | |
analogWrite(leftPWM, 0); | |
break; | |
case 0: //stopping | |
analogWrite(rightPWM, 0); | |
analogWrite(leftPWM, 0); | |
break; | |
case -1: //retraction | |
analogWrite(rightPWM, 0); | |
analogWrite(leftPWM, Speed); | |
break; | |
} | |
} | |
void count_0(){ | |
//This interrupt function increments a counter corresponding to changes in the optical pin status | |
if ((millis() - lastDebounceTime_0) > falsepulseDelay) { //reduce noise by debouncing IR signal | |
lastDebounceTime_0 = millis(); | |
if(Direction==1){ | |
counter[0]++; | |
} | |
if(Direction==-1){ | |
counter[0]--; | |
} | |
} | |
} | |
void count_1(){ | |
if ((millis() - lastDebounceTime_1) > falsepulseDelay) { | |
lastDebounceTime_1 = millis(); | |
if(Direction==1){ | |
counter[1]++; | |
} | |
if(Direction==-1){ | |
counter[1]--; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment