1

I have a project where I need to state from leds turning on and off to another one that will have all the leds turned on and send data and I was wondering how should I do that, this the code I have:

#include <CapacitiveSensor.h>
CapacitiveSensor cs_11_10 = CapacitiveSensor(11,10);
int state_s1 = 0;
int state_s2 = 0;
int state_s3 = 0;
int state_s4 = 0;
int state_prev_s1 =0;
int pin_s1 = 12;
int val_s1 = 0;
const unsigned int ledPins[]={2,3,4,5,6,7,8,9};
const unsigned int lenledPins=9; 
unsigned long t_s1 = 0;
unsigned long t_0_s1 = 0;
unsigned long t_s3 = 0;
unsigned long t_0_s3 = 0;
unsigned long t_0_s4 = 0;
unsigned long t_s4 = 0;
unsigned long t_s2_4 = 0;
unsigned long tiempo = 250;
unsigned long bounce_delay_s1 = 5;
long total = 0;
void setup() 
{
 pinMode(pin_s1, INPUT_PULLUP);
 Serial.begin(9600);
 for(int i=0; i<(9); i++)
 {
 pinMode(ledPins[i], OUTPUT); 
 }
 cs_11_10.set_CS_AutocaL_Millis(0xFFFFFFFF);
 Serial.begin(9600);
}
void loop()
{
 MBoton(); //MAQUINA DE ESTADO
 MaquinaGeneral();
 if(state_s2 == 1)
 {
 led(); 
 }
 if(state_s1 != state_prev_s1)
 {
 Serial.print("state =");
 Serial.println(state_s3);
 }
 if(state_s4 == 6)
 {
 for(int i=0; i<lenledPins; i++)
 {
 digitalWrite(ledPins[i],HIGH); 
 }
 }
 Serial.print("");
}
void MaquinaGeneral()
{
 switch(state_s2)
 {
 case 0:
 if(state_s1 == 4)
 { 
 state_s2 = 1;
 } 
 break;
 case 1:
 break;
 }
} 
void MBoton()
{
 state_prev_s1 = state_s1;
 switch(state_s1)
 {
 case 0: //RESET
 state_s1 = 1;
 break;
 case 1: //START
 val_s1 = digitalRead(pin_s1);
 if(val_s1 == LOW)
 {
 state_s1 = 2;
 }
 break;
 case 2: // GO!
 t_0_s1 = millis();
 state_s1 = 3;
 break;
 case 3: //WAIT
 t_s1 = millis();
 if(t_s1 - t_0_s1 >= bounce_delay_s1)
 {
 state_s1 = 5;
 }
 break;
 case 5: //ARMED
 val_s1 = digitalRead(pin_s1);
 if(val_s1 == HIGH)
 {
 state_s1 = 4;
 }
 break;
 case 4: //TRIGGERED
 state_s1 = 0;
 break;
 }
}
void led()
{
 switch(state_s3)
 { 
 case 0: //OFF
 for(int i=0; i<lenledPins; i=i+2)
 {
 digitalWrite(ledPins[i],LOW);
 }
 for(int i=1; i<lenledPins; i=i+2)
 {
 digitalWrite(ledPins[i],HIGH);
 } 
 t_0_s3 = millis();
 state_s3 = 1;
 break;
 case 1: //WAIT
 t_s3 = millis();
 if(t_s3 - t_0_s3 >= tiempo)
 {
 state_s3 = 2;
 }
 break;
 case 2: // ON
 for(int i=0; i<lenledPins; i=i+2)
 {
 digitalWrite(ledPins[i],HIGH);
 }
 for(int i=1; i<lenledPins; i=i+2)
 {
 digitalWrite(ledPins[i],LOW);
 }
 t_0_s3 = millis();
 state_s3 = 3;
 break;
 case 3: //WAIT 
 t_s3 = millis();
 if(t_s3 - t_0_s3 >= tiempo) 
 {
 state_s3 = 0;
 }
 break;
 }
 }
void Capacitor()
 {
 switch(state_s4)
 {
 case 0: //RESET
 state_s4 = 1;
 break;
 case 1: //START
 total = cs_11_10.capacitiveSensor(10);
 if(total >= 1000)
 {
 state_s4 = 2;
 }
 break;
 case 2: // GO!
 t_0_s4 = millis();
 state_s4 = 3;
 break;
 case 3: //WAIT
 total = cs_11_10.capacitiveSensor(10);
 if(total < 1000)
 {
 state_s4 = 0;
 }
 t_s4 = millis();
 if(t_s4 - t_0_s4 >= 2000)
 {
 state_s4 = 5;
 }
 break;
 case 5: //ARMED & WAIT
 t_s2_4 = millis();
 total = cs_11_10.capacitiveSensor(10);
 if(total < 1000)
 {
 state_s4 = 4;
 }
 if(t_s2_4-t_s4 >= 1000)
 { 
 state_s4= 6;
 }
 break;
 case 4: //TRIGGERED
 state_s4 = 0;
 break;
 case 6: // ARMED 2 
 Serial.println("Entro al estado 6");
 total = cs_11_10.capacitiveSensor(10);
 break;
}
}
asked Jun 14, 2019 at 2:37
4
  • 2
    A quick scan of your code would suggest you have too much going on. That or not enough comments to explain your decision to use multiple state machines. I would start over with only 1 state machine and stick with only 1 state machine. Commented Jun 14, 2019 at 3:37
  • I don't quite understand, what your problem is with doing so. You have written all these state machines. So you can just add states for exactly what you want (a state that would leave the LEDs on and would send data). Though I think st2000 is right in that you should check thoroughly if using only 1 state machine would be sufficient. That would be way easier to code. Commented Jun 14, 2019 at 7:31
  • 1
    Also use an enumeration type for the states, instead of 'magic numbers' 1, 2, 3 etc. Commented Jun 14, 2019 at 8:30
  • I highly recommend you design state machines with a state-diagram showing events, transitions, and actions. They are a whole lot easier to read & understand than any state-machine code I've ever seen or written. When you have a diagram you believe does what you want, then start coding it. Remember to check your state-machine code against the diagram, to be confident your code does what the diagram says it should. The state-diagram should be your working reference. When you debug, debug/fix it on the diagram first, then use that to fix the code. You'll get a working state machine much sooner. Commented Jul 14, 2019 at 12:39

2 Answers 2

1

If you think you need two finite state machines, where only one of them is running at any given time, then it is trivial to combine them together: draw them side by side, and add the required transitions between them. The set of states of the combined FSM will be the union of the states of the initial FSMs. For example, if you have:

  • FSM 1 states: STATE_A, STATE_B, STATE_C
  • FSM 2 stages: STATE_D, STATE_E
  • global states: FSM_1_RUNNING, FSM_2_RUNNING

Then the combined FSM will have the states STATE_A, STATE_B, STATE_C, STATE_D and STATE_E, and all the transitions of both initial FSMs.

answered Jun 14, 2019 at 7:33
0

Similar to what others have commented, this is not the best implementation of a Finite State Machine (FSM). You should establish clear states and define what happens during all transitions of your system.

Follow Edgar's advice on using enumerators for your states.

Nick Gammon's guide will surely be of great help: https://www.gammon.com.au/statemachine

answered Sep 19, 2021 at 12:09

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.