First post for me and I have only little experience in coding. I have an Arduino Uno that I am trying to control a motor with an encoder so that it spins a definitive amount then spins the opposite direction the exact same amount to the starting point and then do it over and over again when activated with a push button or foot pad.
Specifically, I have a ServoCity HD Premium Planetary Gear motor with encoder 612 RPM, Cytron MD10C R3 motor controller along with the Arduino Uno. I have three resistors and LEDs in a breadboard indicate status of program. This is a Halloween application where there is a spider attached to a string and the string is on a pulley attached to the motor. The foot pad is stepped on and activates the code, the spider drops fast and then it has to return slowly to its original position. It then waits for the next foot pad activation. It has to this over many cycles, so I want it to be super accurate. I don't want to mess with repositioning the pulley during the haunt.
Currently, it is close to being accurate, but it doesn't seem to get to the intended target drop distance and get back to the origin every time. Over many cycles it can make a big difference on the accuracy. I can see the position data in serial monitor but I would like to see it in the serial plotter but I can't seem to figure out the syntax for the plotter. There are other posts on this subject but they seem to give conflicting syntax info. Currently in the code, I just want to plot two variables: "target" and "position". These are the only variables that I have not commented out. Once I am able to use serial plot I want to add additional variables to the plot to help diagnose the problem. Thanks in advance.
#include <util/atomic.h> // For the ATOMIC_BLOCK macro
#include "CytronMotorDriver.h"
#define ENCA 2 // YELLOW Encoder Wire Goes to pin 2 of Arduino
#define ENCB 3 // BROWN Encoder Wire Goes to pin 3 of Arduino
CytronMD motor(PWM_DIR, 10, 12); //PWM = Pin 10 of Arduino to PWR of Cytron, DIR = Pin 12 of Arduino to DIR of Cytron Motor Controller.
https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
volatile int posi = 0; //specify posi as volatile:
int switchState1; //switchState1 for footpad or push button indication
int switchState2; //switchState2 for when the Spider is dropping
int switchState3; //switchState3 for when the Spider is lifting
int pos = 0; //Initial Position is set to zero
int target = 750; // set target position
int origin = 0;
void setup() { //put your setup code here, to run once:
Serial.begin(9600);
pinMode(5, INPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(ENCA, INPUT);
pinMode(ENCB, INPUT);
attachInterrupt(digitalPinToInterrupt(ENCA), readEncoder, RISING);
}
void loop() { //put your main code here, to run repeatedly:
//The If Statement below is for occasions when someone continually steps on footpad or steps on footpad before the spider is back up.
//switchState3 is 1 when the spider is lifting and the program will ignore someone stepping on footpad
if (switchState3 == 0) {
switchState1 = digitalRead(5); //Push Button or Foot Pad is Connected to Pin 5 Arduino
}
//switchState1 == 1 activates dropping of Spider, switchState 2 keeps the spider dropping and ensures if statement runs till spider is at bottom position
if ((switchState1 == 1 || switchState2 == 1) && switchState3 == 0) { //Spider Drops
switchState2 = 1;
digitalWrite(6, HIGH); //LED Indicator turns ON and shows that switchState2 is High and Spider is Dropping
// Read the position in an atomic block to avoid a potential misread if the interrupt coincides with this code running
// see: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
pos = posi;
}
int e = -pos + target; // error - how far away the spider is from the target position
int u = e; //u is used for motor speed variable (could use e)
Serial.print("target:");
Serial.print(target);
//Serial.print(" ");
Serial.print(",position:");
Serial.print(pos);
//Serial.print(" ");
//Serial.print(",posi:");
//Serial.print(posi);
//Serial.print(" ");
//Serial.print(",error: ");
//Serial.print(e);
//Serial.print(" ");
//Serial.println();
// motor power (speed)
if (u > 255) {
motor.setSpeed(255);
} else if (u >= 20 && u <= 255) {
motor.setSpeed(u);
} else if (u < 20 && u > 0) {
motor.setSpeed(13);
} else if (u < 0) {
motor.setSpeed(-13);
} else if (fabs(u) < 1.0) {
digitalWrite(6, LOW); //LED Indicator turns OFF and shows that switchState2 is LOW and Spider is NOT Dropping
motor.setSpeed(0);
//switchState1 & switchState2 are set to 0 & 1 so that program falls out of If Statement for Dropping
switchState2 = 0;
switchState3 = 1;
delay(3000); //Let the Spider linger at bottom position
}
} //End of If Statement for Spider Drop
//switchState3 is 1 when the spider is lifting and the program will ignore someone stepping on footpad
if (switchState2 == 0 && switchState3 == 1) { //Spider is at bottom and will start lifting
digitalWrite(7, HIGH); //LED Indicator turns ON and shows that switchState3 is HIGH and Spider will begin lifting
// Read the position in an atomic block to avoid a potential
// misread if the interrupt coincides with this code running
// see: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
pos = posi;
}
int e = pos + origin; // error - how far away the spider is from the target position
int u = e; //u is used for motor speed variable (could use e)
/*
Serial.print("origin: ");
Serial.print(origin);
Serial.print("\t");
Serial.print("position: ");
Serial.print(pos);
Serial.print("\t");
Serial.print("position i: ");
Serial.print(posi);
Serial.print("\t");
Serial.print("error: ");
Serial.print(e);
Serial.print("\t");
Serial.println();
*/
// motor power (speed)
if (u > 255) {
motor.setSpeed(-50);
} else if (u >= 35 && u <= 255) {
motor.setSpeed(-35);
} else if (u < 35 && u > 0) {
motor.setSpeed(-20);
} else if (u < 0) {
motor.setSpeed(13);
} else if (fabs(u) < 1.0) {
digitalWrite(7, LOW); //LED Indicator turns OFF and shows that switchState2 is LOW and Spider is NOT Lifting
switchState3 = 0; //switchState3 is set to zero and Spider is at top and ready to scare the next kid
motor.setSpeed(0);
}
} //End of If Statement for Spider Lift
} //End of Void Loop
//Function for reading of motor encoder
void readEncoder() {
int b = digitalRead(ENCB);
if (b > 0) {
posi++;
} else {
posi--;
}
}