Using Millis with switch state cases

So I could do without the default section and it would still do the same? it does compile without it.

This is what I'm saying about 'not seeing the woods for the trees'

Iv'e muddled my way theough umpteen examples to get to this point and I'm not actually knowledgeable enough to realise.

I've made another error in case 1 at the top. it should be-
1st
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 0
dial_pin_four = 1

2nd
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 1
dial_pin_four = 0

3rd
magnet_pin_one = 0
magnet_pin_two = 0 or start again after 2nd
dial_pin_three = 0
dial_pin_four = 0

Try this:

// Define the pins being used for the states on the LN298N

#define magnet_pin_one      7     //int1 L298N Motor Control Magnet pins from Arduino D8
#define magnet_pin_two      8
#define dial_pin_three      9     //int3 L298N Motor Control pilot dial pins Arduino from D9          
#define dial_pin_four       10    //int4 L298N Motor Control pilot dial pins from Arduino D10         
#define hallpin             2     //Hall sensor output to Arduino D2

const byte heartbeatLED   = 13;

byte FSMstate             = 0;
byte lastHallSwitchState  = 0;

unsigned long heartbeatMillis;
unsigned long hallSensorMillis;

//**********************************************************
void setup()
{
  pinMode(heartbeatLED, OUTPUT);

  //Set the pin directions
  pinMode(hallpin, INPUT);
  pinMode(magnet_pin_one, OUTPUT);
  pinMode(magnet_pin_two, OUTPUT);
  pinMode(dial_pin_three, OUTPUT);
  pinMode(dial_pin_four, OUTPUT);

  digitalWrite(magnet_pin_one, LOW);
  digitalWrite(magnet_pin_two, LOW);
  digitalWrite(dial_pin_three, HIGH);
  digitalWrite(dial_pin_four, LOW);

}

//**********************************************************
void loop()
{
  //*****************************
  //flash the heartbeat LED every 250ms
  if (millis() - heartbeatMillis >= 250)
  {
    //retart the TIMER
    heartbeatMillis = millis();
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //*****************************
  //check the hall sensor every 10 milliseconds
  if (millis() - hallSensorMillis > 10)
  {
    //restart the TIMER
    hallSensorMillis = hallSensorMillis + 10;

    checkHallSensor();
  }

  //*****************************
  //check the FSM (finite state machine)
  checkFSM();

} //END of loop()


//**********************************************************
void checkFSM()
{
  switch (FSMstate)
  {
    //*************
    case 0:
      digitalWrite(magnet_pin_one, HIGH);
      digitalWrite(magnet_pin_two, LOW);
      digitalWrite(dial_pin_three, LOW);
      digitalWrite(dial_pin_four, HIGH);

      break;

    //*************
    case 1:

      digitalWrite(magnet_pin_one, HIGH);
      digitalWrite(magnet_pin_two, LOW);
      digitalWrite(dial_pin_three, HIGH);
      digitalWrite(dial_pin_four, LOW);

      break;
  } //END of switch/case

} //END of checkFSM()

//**********************************************************
void checkHallSensor()
{
  byte hallSwitchState;

  //**************
  //change state detected ?
  hallSwitchState = digitalRead(hallpin);

  if (lastHallSwitchState != hallSwitchState)
  {
    //update to the new state
    lastHallSwitchState = hallSwitchState;

    if (hallSwitchState == LOW) //use LOW or HIGH as you need
    {
      //next state in FSM
      FSMstate++;

      if (FSMstate >= 2)
      {
        FSMstate = 0;
      }
    }
    
  }

} //END of checkHallSensor()


1 Like

1st
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 0
dial_pin_four = 1

2nd
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 1
dial_pin_four = 0

3rd
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 0
dial_pin_four = 1

4th
magnet_pin_one = 1
magnet_pin_two = 0
dial_pin_three = 1
dial_pin_four = 0

etc.


So magnet_pin_one will always be HIGH ?
AND
magnet_pin_two will always be LOW



See offering in post #23

Yes that's correct. The electro magnet to drive the pendulum is't alternating polarity. I realise that my circuit could accout for this by putting a permanant 0v to it.

I for one prefer that over the original code. All that state = old + 1 was confusing me.

But, I think the original question was "how can I add a 500ms delay before case 1?". So perhaps the state machine should be more like:

  1. set initial pin states
  2. poll hall sensor until it triggers
  3. do nothing for 500ms
  4. set 2nd pin states
  5. presumably there would need to be another pause here before looping state 0.

You mean the LN298N? :wink:

I like the 'heartbeat' great idea.
The first test run using this code doesn't seem to be running right.
in the first case I'm not getting anything (not on for 500ms then off)
and the second it's not alternating.
I realise that i'm most likely miles behind you right now but I'll work through it bit by bit.

oh that old thing, new for me :rofl:

Dd you try post #23 ?

Thanks everyone. stavs and all Im not sure if I made the correct request clear or not with timers and delay.

digitalWrite(magnet_pin_one, HIGH); 
     //timer of approx 500ms or so, here so (magnet_pin_one) goes low.
     digitalWrite(magnet_pin_two, LOW);  
     digitalWrite(dial_pin_three, LOW);  
     digitalWrite(dial_pin_four, HIGH);  
     old = state;
     break;

We need a better Story Board showing the exact sequence you want to happen.

Add delays as needed.

Example:

Power up:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, LOW);
digitalWrite(dial_pin_four, HIGH);

Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

Sense magnet:
Add the next sequences and add delays required.

magnet_pin_one** will be HIGH / 50ms Low

Still not following.

Please explain more and add this to the story board above.

Power up:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
#magnet_pin_one to go low after 500ms here then carry on.#
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, LOW);
digitalWrite(dial_pin_four, HIGH);

Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
#magnet_pin_one to go low after 500ms here then carry on.#
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

repeat

#magnet_pin_one to go low after 500ms here then carry on.#
this output is driving the pendulum drive magnet. I require this to go HIGH then after 500ms or so go low within each case.

So you want this ?

Power up:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);


1st
Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, LOW);
digitalWrite(dial_pin_four, HIGH);

After 500ms:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, LOW);
digitalWrite(dial_pin_four, HIGH);

2nd
Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

After 500ms:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

Repeat . . . . . . . . . .

Thanks LarryD. Yes if thats the same has:

1st
Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
After 500ms:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, LOW);
digitalWrite(dial_pin_four, HIGH);

2nd
Sense magnet:
digitalWrite(magnet_pin_one, HIGH);
After 500ms:
digitalWrite(magnet_pin_one, LOW);
digitalWrite(magnet_pin_two, LOW);
digitalWrite(dial_pin_three, HIGH);
digitalWrite(dial_pin_four, LOW);

Repeat . . . . . . . . . . :blush: :blush:

Should be close:

//Forum URL   https://forum.arduino.cc/t/using-millis-with-switch-state-cases/865187/39?u=larryd

//Version  YY/MM/DD     Description 
//  1.00   21/01/22     Working sketch

// Define the pins being used for the states on the LN298N

#define magnet_pin_one      7     //int1 L298N Motor Control Magnet pins from Arduino D8
#define magnet_pin_two      8
#define dial_pin_three      9     //int3 L298N Motor Control pilot dial pins Arduino from D9          
#define dial_pin_four       10    //int4 L298N Motor Control pilot dial pins from Arduino D10         
#define hallpin             2     //Hall sensor output to Arduino D2

const byte heartbeatLED   = 13;

int FSMstate              = -1;
byte lastHallSwitchState  = 0;

unsigned long heartbeatMillis;
unsigned long hallSensorMillis;
unsigned long commonMillis;



//                     s e t u p ( )
//**********************************************************
void setup()
{
  pinMode(heartbeatLED, OUTPUT);

  //Set the pin directions
  pinMode(hallpin, INPUT);
  
  pinMode(magnet_pin_one, OUTPUT);
  pinMode(magnet_pin_two, OUTPUT);
  pinMode(dial_pin_three, OUTPUT);
  pinMode(dial_pin_four, OUTPUT);

  //initial conditions
  digitalWrite(magnet_pin_one, LOW);
  digitalWrite(magnet_pin_two, LOW);
  digitalWrite(dial_pin_three, HIGH);
  digitalWrite(dial_pin_four, LOW);

}


//                      l o o p ( )
//**********************************************************
void loop()
{
  //*****************************
  //flash the heartbeat LED every 250ms
  if (millis() - heartbeatMillis >= 250)
  {
    //retart the TIMER
    heartbeatMillis = millis();
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //*****************************
  //check the hall sensor every 50 milliseconds
  if (millis() - hallSensorMillis >= 50)
  {
    //restart the TIMER
    hallSensorMillis = hallSensorMillis + 50;

    checkHallSensor();
  }

  //*****************************
  //check the FSM (finite state machine)
  checkFSM();

} //END of loop()


//                    c h e c k F S M ( )
//**********************************************************
void checkFSM()
{
  switch (FSMstate)
  {
    //*************
    case 0:
      digitalWrite(magnet_pin_one, HIGH);
      digitalWrite(magnet_pin_two, LOW);
      digitalWrite(dial_pin_three, LOW);
      digitalWrite(dial_pin_four, HIGH);

      //start the TIMER
      commonMillis = millis();

      FSMstate = 1;

      break;

    //*************
    case 1:
      //has 500ms gone by ?
      if (millis() - commonMillis >= 500)
      {
        digitalWrite(magnet_pin_one, LOW);
        digitalWrite(magnet_pin_two, LOW);
        digitalWrite(dial_pin_three, LOW);
        digitalWrite(dial_pin_four, HIGH);
        
        FSMstate = 2;
      }

      break;

    //*************
    case 2:
      //wait here and do nothing

      break;

    //*************
    case 3:
      digitalWrite(magnet_pin_one, HIGH);
      digitalWrite(magnet_pin_two, LOW);
      digitalWrite(dial_pin_three, HIGH);
      digitalWrite(dial_pin_four, LOW);

      //start the TIMER
      commonMillis = millis();
      
      FSMstate = 4;

      break;

    //*************
    case 4:
      //has 500ms gone by ?
      if (millis() - commonMillis >= 500)
      {
        digitalWrite(magnet_pin_one, LOW);
        digitalWrite(magnet_pin_two, LOW);
        digitalWrite(dial_pin_three, HIGH);
        digitalWrite(dial_pin_four, LOW);

        FSMstate = 5;
      }

      break;

    //*************
    case 5:
      //wait here and do nothing

      break;

  } //END of switch/case

} //END of checkFSM()


//             c h e c k H a l l S e n s o r ( )
//**********************************************************
void checkHallSensor()
{
  byte hallSwitchState;

  //**************
  //change state detected ?
  hallSwitchState = digitalRead(hallpin);

  if (lastHallSwitchState != hallSwitchState)
  {
    //update to the new state
    lastHallSwitchState = hallSwitchState;

    if (hallSwitchState == LOW) //use LOW or HIGH as you need
    {
      //next state in FSM
      FSMstate++;

      //reset the FSM ?
      if (FSMstate > 5)
      {
        FSMstate = 0;
      }
    }
  }

} //END of checkHallSensor()

//**********************************************************
1 Like

I believe you may want to look into using an interrupt routine based on the hall effect going high.

Start a Millis timer for 500millis

Write pin low

This will allow you to continue processing the system during that "delay"