All and all my code seems to be working pretty well except as time goes on and the stepper moves back and forth it seems to be slowly loosing its starting position, I have a Nema 23 motor running on a TB6600 driver set to 1/4 micro stepping @ 24V with an UNO. After about 5 minutes the stepper is almost a full rotation away from its starting position. I tried slowing the stepper down but it didn't seem to help. The web seems to think these motors can spin at 400rpm and its moving much slower than that anyway so i don't feel like its loosing steps. Any insight would be greatly appreciated..
#include <Adafruit_DS3502.h>
Adafruit_DS3502 ds3502 = Adafruit_DS3502();
byte directionPin = 2; //New Stepper control
byte stepPin = 3;
byte stepstop = 4;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenStepsup = 1; // milliseconds
unsigned long millisBetweenStepsdown = 2; // milliseconds
#include "MultiMap.h" //Multimap
int mappedValue; //
int in[] = {0 , 31, 63, 95, 127}; //
int out[] = {0, 95, 115, 125, 127}; //
#define magnetDetected HIGH
#define noMagnet LOW
#define weAreTiming true
#define weAreNotTiming false
#define notfull false
#define full true
#define resetting true
#define tensioning false
#define brakeon true
#define brakeoff false
#define clutchon true
#define clutchoff false
const byte BRAKE_IN_PIN = A0;
const byte CLUTCH_IN_PIN =A3;
const byte PRESSURE = A1; // Pot on Analog Pin 1
const byte POTH = A2; // Pot on Analog Pin 2
bool timerRunningFlag = weAreNotTiming;
bool fullthrottle = notfull;
bool resetflag = tensioning;
bool brakeflag = brakeoff;
bool clutchflag = clutchoff;
const byte sensor = 6;
const byte heartbeatLED = 13;
int reset = 7;
byte lastWheelState = noMagnet;
int digitalPot ;
int brake_value = 0;
int clutch_value = 0;
int clutch_temp = 0;
int lowspeed = 0; // Low speed set
int highspeed = 0; // High Speed set
int lowrpm = 0; // Low RPM kick in
int highrpm = 0; // High RPM kick in
int highValue = 0;
int stepsLeft = 0;
int force = 0;
int stepmath = 0;
int tension = 0;
int stepstaken = 0;
int fullsqueeze = 0;
int totaltension =2500;
const int lowValue = 800; //low speed setting
const int highLow = 600; //reading 0
const int highHigh = 200; //reading 1023
//timing stuff
unsigned long startTime;
unsigned long endTime;
unsigned long duration;
unsigned long timerMillis;
unsigned long heartbeatMillis;
unsigned long wheelMillis;
//*********************************************************************
void setup()
{
analogReference(A0);
ds3502.setWiper(0);
pinMode (sensor, INPUT_PULLUP);
pinMode (heartbeatLED, OUTPUT);
Serial.begin(115200);
while (!Serial)
{
delay(1);
}
Serial.println("Adafruit DS3502 Test");
if (!ds3502.begin()) // <-----<<<<<
{ // <-----<<<<<
Serial.println("Couldn't find DS3502 chip"); // <-----<<<<<
while (1); // <-----<<<<<
} // <-----<<<<<
Serial.println("Found DS3502 chip");
pinMode(reset, INPUT_PULLUP);
pinMode(directionPin, OUTPUT); //New stepper
pinMode(stepPin, OUTPUT);
pinMode(stepstop, OUTPUT);
fullthrottle = notfull;
}
//*********************************************************************
void loop()
{
digitalRead(reset);
while (digitalRead(reset) == LOW)
{
stepstaken = 0;
tension = 0;
digitalWrite(stepstop, HIGH);
if (resetflag == tensioning) {
Serial.println("reset");
resetflag = resetting;
}
digitalRead(reset);
}
digitalWrite(stepstop, LOW); // reengage stepmotor
resetflag = tensioning;
if(millis() - heartbeatMillis >= 500)
{ heartbeatMillis = millis();
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//***********************
//time to check the wheel sensor ?
if (millis() - wheelMillis >= 10)
{
//restart the TIMER
wheelMillis = millis();
checkWheelSensor();
}
if (timerRunningFlag == weAreTiming && millis() - timerMillis >= lowValue) //timeout
{
timerRunningFlag = weAreNotTiming;
duration = lowValue;
printDigitalPot();
//timerRunningFlag = weAreTiming; //testing
//start this TIMER
// startTime = millis();
//start this TIMER
// timerMillis = millis(); //too here
}
//***********************
//Other non-blocking code goes here
//***********************
brake_value = analogRead(BRAKE_IN_PIN);
clutch_value = analogRead(CLUTCH_IN_PIN);
digitalRead(reset);
curMillis = millis();
if (tension > stepstaken && curMillis - prevStepMillis >= millisBetweenStepsup) {
digitalWrite(directionPin, HIGH);
prevStepMillis = curMillis;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
stepstaken = stepstaken+1;
}
if (tension < stepstaken && curMillis - prevStepMillis >= millisBetweenStepsdown) {
digitalWrite(directionPin, LOW);
prevStepMillis = curMillis;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
stepstaken = stepstaken-1;
}
while (brake_value < 500) { // used to be 920
ds3502.setWiper(127);
if (brakeflag == brakeoff) {
Serial.print("Brake on ");
Serial.println(brake_value);
brakeflag = brakeon;
}
curMillis = millis();
if (stepstaken > 0 && curMillis - prevStepMillis >= millisBetweenStepsup) {
digitalWrite(directionPin, LOW);
prevStepMillis = curMillis;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
stepstaken = stepstaken-1;
}
brake_value = analogRead(BRAKE_IN_PIN);
}
brakeflag = brakeoff;
while (clutch_value < 900 && brake_value > 920) {
clutch_temp = map(clutch_value, 800, 80, digitalPot, 127);
clutch_temp = constrain(clutch_temp, 0, 127);
ds3502.setWiper(clutch_temp);
if (clutchflag == clutchoff) {
Serial.print("Clutch on ");
Serial.print(clutch_value);
Serial.print(" Digitalpot value: ");
Serial.println(clutch_temp);
clutchflag = clutchon;
}
curMillis = millis();
if (stepstaken > 0 && curMillis - prevStepMillis >= millisBetweenStepsdown) {
digitalWrite(directionPin, LOW);
prevStepMillis = curMillis;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
stepstaken = stepstaken-1;
}
brake_value = analogRead(BRAKE_IN_PIN);
clutch_value = analogRead(CLUTCH_IN_PIN);
}
clutchflag = clutchoff;
} //END of loop()
//*********************************************************************
void checkWheelSensor()
{
byte thisState = digitalRead(sensor);
//***********************
//was there a change in state ?
if (lastWheelState != thisState)
{
//update to the new state
lastWheelState = thisState;
//***********************
//if we are 'not' timing has the sensor detected the magnet ?
if (timerRunningFlag == weAreNotTiming && thisState == magnetDetected)
{
//enable timing
timerRunningFlag = weAreTiming;
//start this TIMER
startTime = millis();
//start this TIMER
timerMillis = millis();
}
//***********************
if (timerRunningFlag == weAreTiming && thisState == noMagnet)
{
//disable the timing
timerRunningFlag = weAreNotTiming;
endTime = millis();
duration = endTime - startTime;
printDigitalPot();
}
} //END of if(lastWheelState != thisState)
} //END of checkWheelSensor()
//*********************************************************************
void printDigitalPot()
{
highspeed = analogRead(POTH); //0 to 1023
highValue = map(highspeed, 0, 1000, highLow, highHigh);
int temp = map( duration, highValue, lowValue, 0, 127);
temp = constrain(temp, 0, 127); //stay within the 0-127 range
digitalPot=multiMap(temp, in, out, 5);
ds3502.setWiper(digitalPot);
force = analogRead(PRESSURE);
force = map(force,0,1023,0,totaltension);
stepmath = map(temp,0,127,force,0); //temp might become "digitalPot" again
if (temp > 0) //less than full throttle
{
fullthrottle = notfull;
tension = stepmath;
}
if (fullthrottle == full)
{
fullsqueeze = 10; //stepmath/300; //300 may need to change depending on required full throttle pressure
tension = tension+fullsqueeze;
}
if (fullthrottle == notfull && temp == 0)
{fullthrottle = full;
tension = stepmath;
}
Serial.print("B: ");
Serial.print(brake_value);
Serial.print("C: ");
Serial.print(clutch_value);
Serial.print(" ");
Serial.print(lowValue);
Serial.print(" ");
Serial.print("Timer spread ");
Serial.print(highValue);
Serial.print (" Time in millis = ");
Serial.print (duration);
Serial.print(" ");
Serial.print(temp);
Serial.print(" Digital pot set to: ");
Serial.print(digitalPot);
Serial.print("\t");
Serial.print("Savage level: ");
Serial.print(force);
Serial.print(" ");
Serial.print(stepmath);
Serial.print(" -Stepmath Stepstaken- ");
Serial.print(stepstaken);
Serial.print(" Needed tension: ");
Serial.println(tension);
Serial.println("");
} //END of printDigitalPot()