Lot going on here, but the code is here
#include <AccelStepper.h>
#include <Wire.h>
#include "Adafruit_MCP23X17.h"
#include "PinChangeInterrupt.h"
#include <avr/wdt.h>
#define NUM_STEPS 200
#define STEPS_PER_VALUE 4.5454545
#define ENX 41
#define RST 39
// Instance of MCP23017 library
Adafruit_MCP23X17 mcp;
uint8_t values[15] = {};
uint8_t addressesExpected[5][3] = {
{0,0,1},
{0,1,1},
{1,0,1},
{1,1,1},
{1,1,0}
};
uint8_t reelAddresses[5][3] = {};
bool pendingAddressCheckSuccess = false;
const byte numReels = 5;
const byte sensorPins[5] = {69,68,67,66,65};
int stepperPins[5]={5,57,58,59,2};
int dirPins[5]={60,54,55,56,61};
AccelStepper stepper1(AccelStepper::DRIVER, stepperPins[0], dirPins[0]);
AccelStepper stepper2(AccelStepper::DRIVER, stepperPins[1], dirPins[1]);
AccelStepper stepper3(AccelStepper::DRIVER, stepperPins[2], dirPins[2]);
AccelStepper stepper4(AccelStepper::DRIVER, stepperPins[3], dirPins[3]);
AccelStepper stepper5(AccelStepper::DRIVER, stepperPins[4], dirPins[4]);//AccelStepper stepperY(AccelStepper::DRIVER, stepperPin2, dirPin2);
AccelStepper steppers[5] = {stepper1,stepper2,stepper3,stepper4,stepper5};
int maxSpeed = 250;//250
int maxAccel = 500;//500
int cmdSpecifics = 0; /*<cmdSpecifics, reelStop1, reelStop2, reelStop3, reelStop4, reelStop5>*/
bool reelHomed[5]={1,1,1,1,1};
bool newData = false;
const byte numChars = 21;
char receivedChars[numChars];
char tempChars[numChars];
bool cmdValid = false;
bool spinValidated = true;
bool cmdSent = false;
bool cmdWaiting=false;
int targetValues[5] = {};
unsigned long timeOfLastHigh;
unsigned long timeOfFirstHigh;
unsigned long lengthOfHigh;
volatile int optosCounts[5]={};
volatile bool optosStatus[5]={};
bool isHigh = false;
int index=0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); Serial3.begin(9600);
Serial.println(__FILE__ __DATE__);
wdt_disable();
mcp.begin_I2C();
pinMode(ENX, OUTPUT);
digitalWrite(ENX, LOW);
digitalWrite(RST, HIGH);
for(int i=0;i<numReels;i++){
pinMode(sensorPins[i], INPUT_PULLUP);
//attachPCINT(digitalPinToPCINT(i), countOptos, RISING);
}
attachPCINT(digitalPinToPCINT(69), countOptos1, RISING);
attachPCINT(digitalPinToPCINT(68), countOptos2, RISING);
attachPCINT(digitalPinToPCINT(67), countOptos3, RISING);
attachPCINT(digitalPinToPCINT(66), countOptos4, RISING);
attachPCINT(digitalPinToPCINT(65), countOptos5, RISING);
if(pendingAddressCheckSuccess == false){
parseAddresses();
delay(100);
verifyAddresses();
delay(100);
Serial.println(pendingAddressCheckSuccess);
}
for(int i=0;i<numReels;i++){//need 2 here
//pinMode(sensorPins[i], INPUT);
steppers[i].setMaxSpeed(maxSpeed);
steppers[i].setMinPulseWidth(20);
steppers[i].setAcceleration(maxAccel);
CalibrateReel(i);
}
}
void countOptos1(void){
optosCounts[0] = (optosCounts[0] + 1) % 24;
}
void countOptos2(void){
optosCounts[1] = (optosCounts[1] + 1) % 24;
}
void countOptos3(void){
optosCounts[2] = (optosCounts[2] + 1) % 24;
}
void countOptos4(void){
optosCounts[3] = (optosCounts[3] + 1) % 24;
}
void countOptos5(void){
optosCounts[4] = (optosCounts[4] + 1) % 24;
}
void loop() {
//probe for serial input
//receive command
checkForData();
if(cmdWaiting==true or spinValidated==false){
cueMotors();
}
}
void cueMotors(){
bool allHomed = checkReelState();
digitalWrite(ENX, LOW);
// Sending 9 re-calibrates the reel
if(cmdSpecifics == 9 or allHomed == false){
wdt_reset();
reset();
}
if(cmdWaiting == true){
sendCommand();
}//EndIf
steppers[index].run();//should be index, not 0
index++;
if(index==numReels){
index=0;
}
if(isSpinFinished()==true){
//Serial.println("spin is finished");
if(spinValidated == false){
validateSpin();//needs a lot of work
}
}
}
void parseAddresses(){
int pinIndex = 0;
for(int i = 0; i < 5; i++){
for (int x = 0; x < 3; x++){
char val = mcp.digitalRead(pinIndex);
reelAddresses[i][x] = val;
pinIndex++;
}
}
}
void verifyAddresses(){
for(int i = 0; i < 5; i++){
for (int x = 0; x < 3; x++){
(reelAddresses[i][x]==addressesExpected[i][x])?pendingAddressCheckSuccess=true:pendingAddressCheckSuccess=false;
}
}
}
void checkForData(){
recvWithStartEndMarkers();
//assign values to appropriate variables
if(newData==true){
strcpy(tempChars, receivedChars);
parseData();
newData=false;
Serial.flush();
if(cmdValid==true){
Serial.println(200);
cmdWaiting=true;
}
else{
Serial.println(404);
cmdWaiting=false;
}
}
}
void reset(){
wdt_enable(WDTO_8S);
while(1);
}
bool checkReelState(){
bool allHomed = false;
for(int i = 0; i < numReels; i++){
if(reelHomed[i]==0){
allHomed=false;
return allHomed;
}
else(allHomed = true);
}
return allHomed;
}
bool isSpinFinished(){
if(steppers[0].distanceToGo()==0 and steppers[1].distanceToGo()==0 and steppers[2].distanceToGo()==0 and steppers[3].distanceToGo()==0 and steppers[4].distanceToGo()==0){// and steppers[1].distanceToGo()==0 and steppers[2].distanceToGo()==0 and steppers[3].distanceToGo()==0 and steppers[4].distanceToGo()==0
return true;
}else{
return false;
}
}
void validateSpin(){
long thisRotation;
long thisTarget;
for(int i=0; i<numReels; i++) {
int fullRotations = i+1;
thisRotation = fullRotations*NUM_STEPS;
thisTarget = targetValues[i]*STEPS_PER_VALUE;
if(steppers[i].currentPosition() == (thisRotation+thisTarget)){
spinValidated=true;
steppers[i].setCurrentPosition((thisRotation-thisTarget)*-1);
}//EndIf
else{
spinValidated=false;
}//EndElse
}//EndFor
}
void sendCommand(){
for(int i=0; i<numReels; i++) {
int fullRotations = i+1;
// Set *relative* position for each target
steppers[i].moveTo((fullRotations*NUM_STEPS)+(targetValues[i]*STEPS_PER_VALUE));//was moveTo
}//EndFor
cmdWaiting = false;
spinValidated = false;
}
void CalibrateReel(int stepperNum){
reelHomed[stepperNum] = false;
// Set the stepper to a slow speed
steppers[stepperNum].setMaxSpeed(100);
// Make at most one complete rotation from the current position
steppers[stepperNum].move(NUM_STEPS);
while(steppers[stepperNum].distanceToGo() != 0){
steppers[stepperNum].run();
}
steppers[stepperNum].stop();
steppers[stepperNum].move(NUM_STEPS*4);
timeTheOptos(stepperNum);
// Stop the motor and declare this the zero position
steppers[stepperNum].stop();
steppers[stepperNum].setCurrentPosition(0);
// Now that calibration is complete, send to default position
steppers[stepperNum].move(19*STEPS_PER_VALUE);
while(steppers[stepperNum].distanceToGo() != 0){
steppers[stepperNum].run();
}
steppers[stepperNum].setMaxSpeed(maxSpeed);
steppers[stepperNum].setCurrentPosition(0);
optosCounts[stepperNum]=0;
}
void timeTheOptos(int stepperNum){
while(reelHomed[stepperNum] == false){
steppers[stepperNum].run();
int detectState=digitalRead(sensorPins[stepperNum]);
if(detectState==1){
if(isHigh==false){
timeOfFirstHigh = millis();
isHigh=true;
}
}
else if(detectState==0){
if(isHigh==true){
timeOfLastHigh=millis();
lengthOfHigh=timeOfLastHigh-timeOfFirstHigh;
isHigh=false;
if(lengthOfHigh<=20UL){//20UL
reelHomed[stepperNum]=true;
}
}
}
}
}
void recvWithStartEndMarkers(){
static boolean recvInProgress=false;
static byte ndx=0;
char startMarker = '<';
char endMarker = '>';
char rc;
while(Serial.available()>0 && newData==false){
rc=Serial.read();
if(recvInProgress==true){
if(rc!=endMarker){
receivedChars[ndx]=rc;
ndx++;
if(ndx>=numChars){
ndx=numChars-1;
}
}
else{
receivedChars[ndx]='\0';//terminate the string
recvInProgress=false;
ndx=0;
newData=true;
}
}
else if(rc==startMarker){
recvInProgress=true;
}
}
Serial.flush();
}
void parseData(){
int numParams = 6; //<x,x,x,x,x,x> (SEE ABOVE)
Serial.println("parseData");
char * strtokIndx;
for(int i=0;i<numParams;i++){
if(i==0){
strtokIndx=strtok(tempChars,",");
}else{
strtokIndx=strtok(NULL,",");
}
cmdValid = validateChar(atoi(strtokIndx),i);
if(cmdValid==false){
memset(targetValues,0,sizeof(targetValues));
return;
}
}
}
bool validateChar(int convertedChar, int index){
bool results = true;
if(index == 0){
if(convertedChar == 0 or convertedChar == 1 or convertedChar == 9){
Serial.print("convertedChar inside if = ");
Serial.println(convertedChar);
cmdSpecifics = convertedChar;
}else results=false;
}else{
if(convertedChar >=0 and convertedChar<44){
targetValues[index-1]=convertedChar;
}else results=false;
}
return results;
}
Not sure if will help with problem or not, and sorry i'm not the cleanest coder.