So I am building a lamination table that will laminate 4x8 sheets of material. The design incorporates a pushbutton interface with controls for momentary advance, momentary reverse, laminate, and reset table (if the material needs to be sprayed with adhesive again). In essence, when laminate (spray() and driveTable()) is called, two roller tables begin to motivate (move the material forward) and a sprayer begins to sweep back and forth on a gantry assembly (spraying side to side as material passes underneath). If tableHome is called, the table moves the material back to the starting position so "laminate" (spray() and driveTable()) can be called again.
I have written firmware that has been working really well, but every time a function is called other than manual advance and manual reverse, the program gets hung up and does not return to loop. This means that every time these functions are called, I have to press the reset button on the Arduino. I would prefer to never have to press the reset button, but I am not sure how to accomplish this, despite many troubleshooting efforts. Guidance is much appreciated.
#include <AccelStepper.h>
#include <LiquidCrystal.h>
#include <StateMachine.h>
//LCD Screen Setup
const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
unsigned int lcdStatus;
bool advanceHasRun = false;
int reverseHasRun = false;
int idleingHasRun = false;
//motor decleration
AccelStepper sprayer(1, 35, 33); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5 . ////37 now 33, 39 now 35
AccelStepper table1(1, 43, 41); // 1, pulse pin, direction pin
AccelStepper table2(1, 47, 45); // 1, pulse pin, direction pin
//const int motorEnable = 10;
/////////////////////////start button
int button1 = 52;
int button1state = 0;
/////////////////////////boolean switches
bool sprayerOff = true;
bool tableOff = true;
bool tableHomeOff = true;
bool sprayHomeOff = true;
/////////////////////////table1 manual control
//forwardButton = t1f = 49
//reverseButton = t1r = 51
int forwardButton = 49;
int reverseButton = 51;
//t1fstate = forwardButtonStatus = 0
//t1rstate = reverseButtonStatus = 0
int forwardButtonStatus = 0;
int reverseButtonStatus = 0;
/////////////////////////reset buttons
// this is becoming home buttons, and has been renamed. old variable names are slashed out
//t2f = sprayerResetButton = 50
//t2r = tableResetButton = 53
int sprayerResetButton = 50;
int tableResetButton = 53;
//t2fState = sprayerResetStatus = 0
//t2rState = tableResetStatus = 0
int sprayerResetStatus = 0;
int tableResetStatus = 0;
//////////////////////////table tuning
int tableSpeed = 10000; //table overall speed // previously set to 900
int tableAccel = 5000; //changed from 1000 to 2000 to get more table speed
int spraySpeed = 10000; //sprayer overall speed
int sprayAccel = 2000; //accelleration rate . //previously set to 10000
//////////////////////////Time based longs and ints
long previousMillis = 0;
long sprayHomeTime = 1000;
long tableHomeTime = 80000;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// SETUP ///////////////////////////////////////////////////////////////
void setup() {
//Initalize LCD screen
//first set the LCD's number of colums and rows:
lcd.begin(16, 2);
Serial.begin(9600);
startUpScreen();
//////////////////////////////////////INITALIZE STEPPERS////////////////////////////////////
sprayer.setAcceleration(sprayAccel);
sprayer.setMaxSpeed(spraySpeed);
sprayer.moveTo(1800); //sets limit on reverse distance
table1.setMaxSpeed(tableSpeed);
table1.setAcceleration(tableAccel);
// table1.moveTo(25000); /// changed from 50000 to 70000 to see if table will advance
//
table2.setMaxSpeed(tableSpeed);
table2.setAcceleration(tableAccel);
// table2.moveTo(45000);
pinMode (button1, INPUT);
pinMode (forwardButton, INPUT);
pinMode (reverseButton, INPUT);
pinMode (sprayerResetButton, INPUT);
pinMode (tableResetButton, INPUT);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// LOOP ///////////////////////////////////////////////////////////////
void loop() {
/////////////////////////// MANUAL CONTROL ////////////////////////////
//check status of forward button, if high, advance
forwardButtonStatus = digitalRead(forwardButton);
if (forwardButtonStatus == HIGH) {
table1Advance();
table2Advance();
if (advanceHasRun == false){
advanceScreen();
}
}
//check status of reverse button, if high, reverse
reverseButtonStatus = digitalRead(reverseButton);
if (reverseButtonStatus == HIGH) {
table1Reverse();
table2Reverse();
if (reverseHasRun == false){
reverseScreen();
}
//idleScreen();
}
/////////////////////////////// RESET ////////////////////////////////
tableResetStatus = digitalRead(tableResetButton);
if (tableResetStatus == HIGH) {
tableHomeOff = !tableHomeOff;
resetScreen();
}
while (tableHomeOff == false){
tableHome();
}
///send the sprayer to the starting position if right set left button is pressed
// sprayerResetStatus = digitalRead(sprayerResetButton);
// if (sprayerResetStatus == HIGH) {
// sprayHomeOff = !sprayHomeOff;
// }
// while (sprayHomeOff == false) {
// sprayHome();
// }
//////////////////////// START SEQUENCE /////////////////////////////////
button1state = digitalRead(button1);
if (button1state == HIGH) {
// tableOff = !tableOff;
// sprayerOff = !sprayerOff;
tableOff = false;
sprayerOff = false;
laminationScreen();
}
while (sprayerOff == false & tableOff == false) {
spray();
driveTable();
}
if (forwardButtonStatus == LOW & reverseButtonStatus == LOW & button1state == LOW & tableResetStatus == LOW){
idleScreen();
}
}
//
// When the two directional buttons are pressed, both tables advance and reverse in sync with eachother
//
//STATUS: Complete and working properly, but slow due to motor load.
//advance function, table one
void table1Advance() {
table1.setSpeed(10000);
table1.run();
}
//reverse function, table one
void table1Reverse() {
table1.setSpeed(-10000);
table1.run();
}
//advance function, table two
void table2Advance() {
table2.setSpeed(10000);
table2.run();
}
//reverse function, table two
void table2Reverse() {
table2.setSpeed(-10000);
table2.run();
}
//
//
// When the start button is pressed, the table drive function and the spray function are called.
// The sprayer is set with a delay, so that the material advances to the sprayers before the sprayers begin spraying.
// Sprayer begin code will be written once the spray guns are mounted.
//
// changed spray delay
//
long sprayTime = 43900; // changed from 45000 to 30000 to see if table movement distance is affected, it shortened the overall movement by roughly three feet, readjusted to 43000, very close, again to 53900
long tableTime = 80000; // change from 90000 to 80000 did not affect distance of table movement
long sprayDelay = 7000; //delay sprayer until table has correctly positioned materials // CHANGED TO 6000 from 7000
/////////////////build out idle state ()
int idleSpeed = 0;
int idleAccel = 0;
int idleDistance = 0;
//function that controls sprayer in "start" state
void spray() {
unsigned long currentSprayMillis = millis();
if (currentSprayMillis - previousMillis > sprayDelay) {
sprayer.setMaxSpeed(spraySpeed);
sprayer.setAcceleration(sprayAccel);
sprayer.run();
//Serial.println("sprayer is running"); //program responded here, motors slowed down immediately
if (sprayer.distanceToGo() == 0){
sprayer.moveTo(-sprayer.currentPosition());
sprayer.run();
Serial.println("sprayer is running"); //program responded here, did not slow motors
}
if (currentSprayMillis - previousMillis > sprayTime + sprayDelay) { //deleted "+ spray delay) from end of perentheses
sprayerOff = true;
Serial.println("sprayer is off");
previousMillis = currentSprayMillis;
}
}
}
//function that controls table in "start" state
void driveTable() {
unsigned long currentTableMillis = millis();
table1.setMaxSpeed(tableSpeed);
table1.setAcceleration(tableAccel);
//table1.moveTo(33000); // driver set to 4 microsteps
table1.moveTo(20000); // driver set to 8 microsteps //previously set to 16500
table2.setMaxSpeed(tableSpeed);
table2.setAcceleration(tableAccel);
//table2.moveTo(48000); // driver set to 4 microsteps
table2.moveTo(24000); //driverr set to 8 microsteps // previously 24700
table1.run();
table2.run();
if (table1.distanceToGo() == 0 & table2.distanceToGo() == 0){
idleScreen();
}
}
// if (currentTableMillis - previousMillis > tableTime) {
// Serial.println("tableDrive is off");
// tableOff = true;
// sprayerOff = true;
// idleScreen();
// previousMillis = currentTableMillis;
// }
void idleState() {
sprayer.setMaxSpeed(idleSpeed);
sprayer.setAcceleration(idleAccel);
sprayer.moveTo(idleDistance);
table1.setMaxSpeed(idleSpeed);
table1.setAcceleration(idleAccel);
table1.moveTo(idleDistance);
table2.setMaxSpeed(idleSpeed);
table2.setAcceleration(idleAccel);
table2.moveTo(idleDistance);
Serial.println("idling");
}
//
//
//sends everything back to starting position, aka RESET
//
//
// homing functions
//spray home runs on pin 50
//table home runs on pin 53
int t2RewindDistance = -24700;
int t1RewindDistance = -28000; ////////-25900;
void tableHome() {
unsigned long currentTableResetTime = millis();
table1.setMaxSpeed(tableSpeed);
table2.setMaxSpeed(tableSpeed);
table1.setAcceleration(tableAccel);
table2.setAcceleration(tableAccel);
table1.moveTo(t2RewindDistance); //driver set to 8 microsteps // previously set to -24500
table2.moveTo(t1RewindDistance); //driverr set to 8 microsteps
table1.run();
table2.run();
if (table1.distanceToGo() == 0){
idleScreen();
}
}
void idleScreen(){
lcd.print("Status:");
lcd.setCursor(0, 2);
lcd.print("Ready to proceed");
//Serial.println("idling, ready to proceed");
}
void startUpScreen(){
lcd.print("SPRAY TABLE V2.0");
lcd.setCursor(0, 2);
lcd.print("INITALIZING...");
Serial.println("Startup complete");
delay(500);
idleScreen();
}
//unsigned long advanceCount;
//int previousAdvanceCount = 0;
void advanceScreen(){
lcd.print("STATUS: ");
lcd.setCursor(0, 2);
lcd.print("Advancing ");
advanceHasRun = true;
reverseHasRun = false;
Serial.println("advancing");
}
void reverseScreen(){
lcd.clear();
lcd.print("STATUS: ");
lcd.setCursor(0, 2);
lcd.print("Reversing ");
reverseHasRun = true;
advanceHasRun = false;
Serial.println("reversing");
}
void laminationScreen(){
lcd.print("Status:");
lcd.setCursor(0,2);
lcd.print("Laminating ");
if (tableOff == true & sprayerOff == true){
idleScreen();
}
}
void resetScreen(){
lcd.clear();
lcd.print(F("Status:"));
lcd.setCursor(0, 2);
lcd.print(F("Table Resetting"));
}