Howdy folks,
Sorry to be posting another generically labeled question likely with a very simple answer. I have tried searching around the internet for a solution, but I am not finding one.
This is my first program using finite state machine logic, and I'm a bit lost. I also got overly confident and wrote it all out without trying to compile and test as I went. I know, I know. Shame on me.
This is for a machine that laminates two pieces of 4x8 material together using two roller tables and a spray nozzle that sweeps back and forth over the moving material. It is running three NEMA 23 stepper motors that control two roller tables and one spray gantry assembly. I was able to get everything running smoothly using functions and the loop, and then suddenly the sprayer motor quit on me. I think it is somehow related to the fake TB6006 drivers I got on amazon. Replacing with gecko G203V drivers asap (a separate issue for a different section of this forum).
The code you see below is the first tab, the other tabs that have not been posted contain the functions that the state machine will call upon. I switched over to a state machine because I felt that it would be less expensive to run the code in that way. That, and the LCD commands were far too expensive to be looping over and over again to the degree that they were slowing down the speed of the steppers. I want the state machine to return to an idle state after each task is executed. Idle would reset the stepper values and display a message reading "idling" displays on the LCD screen.
When I try to compile I get this error message:
cleanSlateOS:8:31: error: 'state0' was not declared in this scope
State* S0 = machine.addState(&state0); // startup
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:8:31: note: suggested alternative: 'State'
State* S0 = machine.addState(&state0); // startup
^~~~~~
State
cleanSlateOS:9:31: error: 'state1' was not declared in this scope
State* S1 = machine.addState(&state1); // idle
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:9:31: note: suggested alternative: 'State'
State* S1 = machine.addState(&state1); // idle
^~~~~~
State
cleanSlateOS:10:31: error: 'state2' was not declared in this scope
State* S2 = machine.addState(&state2); // forward
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:10:31: note: suggested alternative: 'State'
State* S2 = machine.addState(&state2); // forward
^~~~~~
State
cleanSlateOS:11:31: error: 'state3' was not declared in this scope
State* S3 = machine.addState(&state3); // reverse
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:11:31: note: suggested alternative: 'State'
State* S3 = machine.addState(&state3); // reverse
^~~~~~
State
cleanSlateOS:12:31: error: 'state4' was not declared in this scope
State* S4 = machine.addState(&state4); // laminate
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:12:31: note: suggested alternative: 'State'
State* S4 = machine.addState(&state4); // laminate
^~~~~~
State
cleanSlateOS:13:31: error: 'state5' was not declared in this scope
State* S5 = machine.addState(&state5); // reset
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:13:31: note: suggested alternative: 'State'
State* S5 = machine.addState(&state5); // reset
^~~~~~
State
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino: In function 'void transitionS0S1()':
cleanSlateOS:126:7: error: 'bootUp' was not declared in this scope
if (bootUp == true){
^~~~~~
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino:126:7: note: suggested alternative: 'loop'
if (bootUp == true){
^~~~~~
loop
/Users/lewisdenver/Desktop/cleanSlateOS/cleanSlateOS.ino: At global scope:
cleanSlateOS:199:3: error: 'machine' does not name a type
machine.executeOnce(startUpScreen());
^~~~~~~
cleanSlateOS:200:1: error: expected declaration before '}' token
}
^
exit status 1
'state0' was not declared in this scope
So am I missing something simple? Do I need to declare these states somewhere else? I was under the assumption that replicating the example code in the library would work without declaring ints.
#include <AccelStepper.h>
#include <LiquidCrystal.h>
#include <YA_FSM.h>
#include <StateMachine.h>
StateMachine machine = StateMachine();
State* S0 = machine.addState(&state0); // startup
State* S1 = machine.addState(&state1); // idle
State* S2 = machine.addState(&state2); // forward
State* S3 = machine.addState(&state3); // reverse
State* S4 = machine.addState(&state4); // laminate
State* S5 = machine.addState(&state5); // reset
/////////////// 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);
//state machine for LCD
YA_FSM screenMachine;
/////////////// MOTOR SETUP & VARIABLES //////////////
AccelStepper sprayer(1, 35, 33); // 1, pulse pin, direction pin
AccelStepper table1(1, 43, 41); // 1, pulse pin, direction pin
AccelStepper table2(1, 47, 45); // 1, pulse pin, direction pin
int tableSpeed = 10000;
int tableAccel = 5000;
int spraySpeed = 10000;
int sprayAccel = 2000;
////////////// BUTTONS & STATUS //////////////
//start
int startButton = 52;
int startButtonStatus = 0;
//manual advance
int forwardButton = 49;
int forwardButtonStatus = 0;
//manual reverse
int reverseButton = 51;
int reverseButtonStatus = 0;
//table reset
int tableResetButton = 53;
int tableResetStatus = 0;
//sprayer reset
int sprayerResetButton = 50;
int sprayerResetStatus = 0;
////////////// MILLIS VARIABLES //////////////
long previousMillis = 0;
long sprayHomeTime = 1000;
long tableHomeTime = 80000;
////////////// BOOLEANS ///////////////
bool sprayerOff = true;
bool tableOff = true;
bool tableHomeOff = true;
bool sprayHomeOff = true;
///////////////////////////////////////////////////////
//////////////////// SETUP //////////////////////
///////////////////////////////////////////////////////
void setup() {
//initalize LCD screen
lcd.begin(16, 2);
//initalize stepper motors
sprayer.setAcceleration(sprayAccel);
sprayer.setMaxSpeed(spraySpeed);
sprayer.moveTo(1800); //sets limits sprayer sweep distance
table1.setMaxSpeed(tableSpeed);
table1.setAcceleration(tableAccel);
table2.setMaxSpeed(tableSpeed);
table2.setAcceleration(tableAccel);
//declare buttons as inputs
pinMode (startButton, INPUT);
pinMode (forwardButton, INPUT);
pinMode (reverseButton, INPUT);
pinMode (sprayerResetButton, INPUT);
pinMode (tableResetButton, INPUT);
S0->addTransition(&transitionS0S1,S1); //startup to idle
S1->addTransition(&transitionS1S2,S2); //idle to fwd
S2->addTransition(&transitionS2S1,S1); //fwd to idle
S1->addTransition(&transitionS1S3,S3); //idle to reverse
S3->addTransition(&transitionS3S1,S1); //reverse to idle
S1->addTransition(&transitionS1S4,S4); //idle to laminate
S4->addTransition(&transitionS4S1,S1); //laminate to idle
S1->addTransition(&transitionS1S5,S5); //idle to reset
S5->addTransition(&transitionS5S1,S1); //reset to idle
//add flipper state???
}
////////////////////////////////////////////////////
/////////////////// LOOP /////////////////
////////////////////////////////////////////////////
void loop () {
machine.run();
}
///////////////////////////////////////////////////////
///////////// TRANSITIONS //////////////
///////////////////////////////////////////////////////
//startup to idle
void transitionS0S1(){
if (bootUp == true){
return true;
}
}
//idle to forward
void transitionS1S2(){
forwardButtonStatus = digitalRead(forwardButton);
if (forwardButtonStatus == HIGH) {
return true;
}
}
//forward to idle
void transitionS2S1(){
reverseButtonStatus = digitalRead(reverseButton);
if (reverseButtonStatus == HIGH) {
return true;
}
}
//idle to reverse
void transitionS1S3(){
reverseButtonStatus = digitalRead(reverseButton);
if (reverseButtonStatus == HIGH) {
return true;
}
}
//reverse to idle
void transitionS3S1(){
forwardButtonStatus = digitalRead(forwardButton);
if (forwardButtonStatus == LOW) {
return true;
}
}
//idle to laminate
void transitionS1S4(){
startButtonStatus = digitalRead(startButton);
if (startButtonStatus == HIGH) {
return true;
}
}
//laminate to idle
void transitionS4S1(){
if (sprayerOff == true & tableOff == true){
return true;
}
}
//idle to reset
void transitionS1S5(){
tableResetStatus = digitalRead(tableResetButton);
if (tableResetStatus == HIGH) {
return true;
}
}
//reset to idle
void transitionS5S1(){
if (tableHomeOff == true){
return true;
}
}
///////////////////////////////////////////////////////
//////////////// STATES /////////////////
///////////////////////////////////////////////////////
//startup sequence\\
void state0(){
machine.executeOnce(startUpScreen());
}
//idle state\\
void state1(){
machine.executeOnce(IdleState());
machine.executeOnce(idleScreen());
}
//advance state\\
void state2(){
table1Advance();
table2Advance();
machine.executeOnce(advanceScreen());
}
//reverse state\\
void state3(){
table1Reverse();
table2Reverse();
machine.executeOnce(reverseScreen());
}
//lamination state\\
void state4(){
driveTable();
spray();
machine.executeOnce(laminationScreen());
}
//resetState\\
void state5(){
tableHome();
machine.executeOnce(resetScreen());
}
I apologize again for the mess I have brought to this forum, and thank you in advance for any guidance you can give.