Need Help w/ End of My Code

MrChips

Joined Oct 2, 2009
34,839
What I observe is, TS said they don't want to make this a hobby. They just want to fix a coding problem.
I take this to mean, I want to serve my guests a great casserole but I don't know how to turn on the stove.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
Sorry to hear that.

You are attempting to write computer code with no programming skills. Learning to do so is no different than learning any new skill. It is like trying to be a weekend mechanic or a DIY sous chef. Sure, you can learn by trial and error and learning from your mistakes.

For any student in a computer programming course, it takes 2- 4 years of hard study and practice before one can become comfortable at writing proper code.

Sorry, I don't know of any short cuts.
You might not know any shorts cuts, but if you had an answer, I'd start there since that's usually what a question is looking for. There is an extreme tendency now in forums to "teach everyone the long way" as some form of gratification for the work one involved heavily within in the field has taken. I'm not that person and don't intend to be: I just need an answer.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
Yes! The use of ELSE IF is actually a combination of the ELSE clause combined with another IF statement.
Great, I use that as a guide. Can you tell me where I need to "chop off" my code and recreate using the ELSE IF? I keep starring at it fearing I'll take off too much and ruin the effect I've already created.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
What I observe is, TS said they don't want to make this a hobby. They just want to fix a coding problem.
I take this to mean, I want to serve my guests a great casserole but I don't know how to turn on the stove.
And that sort of thinking is what keeps new people from wanting a new hobby: all the elitest mentalities to wad through makes learning impossible, so forget it being fun. I've already had to challenge this in another thread. Per your example, I can completely admit that I want a great casserole and don't know how to work the stove. I've got no problem with that. Here's the difference: a hobbyist will want to learn to cook; a hungry person will order take-out. Once they aren't hungry, they may wish to learn how to cook, but hangry isn't the time for a new skill.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
This site has a tutorial on using interrupts on an Arduino. Click on the link to see it.
I'm reading the link now, but that seems very similar to the built-in reset button on the Uno. If I press it, it interrupts the sequence of events. Is an interrupt the only way to get the led to turn off later after a timed duration?

My apologies if this is too simple and obvious. I'm wondering what differentiates an interrupt from using else-if.

In the button example, this seems to fit well with the button that comes in the beginner's kit (the one that automatically springs back rather than click open or closed). The interrupt seems well suited to this style of hardware, but I plan on using a click button that either completes the circuit or opens it; I want the programming to handle the timing portion.
 

strantor

Joined Oct 3, 2010
6,875
What I observe is, TS said they don't want to make this a hobby. They just want to fix a coding problem.
I take this to mean, I want to serve my guests a great casserole but I don't know how to turn on the stove.
That's how I interpret it too. But is that bad? I see no reason not tell them how to turn the stove on.
 

strantor

Joined Oct 3, 2010
6,875
Can you tell me where I need to "chop off" my code and recreate using the ELSE IF? I keep starring at it fearing I'll take off too much and ruin the effect I've already created.
Going with the most recent code you posted and assuming this is what you want:
Green on/red off
If button press >5s:
Green off/red on (indefinitely as long as button held)
Upon button release, after 7s, go back to initial condition (Green on/red off):

C-like:
int switchState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long previousTime = 0;
unsigned long latchTime = 0;
unsigned long currentTime = 0;
bool latchOn = false;
void setup()
{
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop()
{
  currentTime = millis();
  switchState = digitalRead(2);
  if ((switchState == LOW) and (latchOn == false))
  {
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, LOW); // red led
    previousTime = millis();
  }
  else if ((switchState == HIGH) and (latchOn == false))
  {
  if (currentTime - previousTime >= event_1)
    {
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      latchOn = true;
      latchTime = millis(); 
    }
  else if ((switchState == LOW) and (latchOn == true))
  {
    if (currentTime - latchTime >= event_2)
    {
        latchOn = false;
    }
  }
}
I had to add a couple of variables to differentiate between the normal button LOW state and the button LOW state which is when we are waiting 7 seconds.

This a basic state machine and if you want to add any more states to it as you progress, I recommend to familiarize yourself with what a Finite State Machine is, and arduino's case statements. Adding more states without using case statements will require adding more and more variables and it will get exponentially more complicated for each additional state you add.


Again, typed on phone, let me know if it doesn't work (and what the specific error is).
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
Going with the most recent code you posted and assuming this is what you want:
Green on/red off
If button press >5s:
Green off/red on (indefinitely as long as button held)
Upon button release, after 7s, go back to initial condition (Green on/red off):

C-like:
int switchState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long previousTime = 0;
unsigned long latchTime = 0;
unsigned long currentTime = 0;
bool latchOn = false;
void setup()
{
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop()
{
  currentTime = millis();
  switchState = digitalRead(2);
  if ((switchState == LOW) and (latchOn == false))
  {
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, LOW); // red led
    previousTime = millis();
  }
  else if ((switchState == HIGH) and (latchOn == false))
  {
  if (currentTime - previousTime >= event_1)
    {
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      latchOn = true;
      latchTime = millis();
    }
  else if ((switchState == LOW) and (latchOn == true))
  {
    if (currentTime - latchTime >= event_2)
    {
        latchOn = false;
    }
  }
}
I had to add a couple of variables to differentiate between the normal button LOW state and the button LOW state which is when we are waiting 7 seconds.

This a basic state machine and if you want to add any more states to it as you progress, I recommend to familiarize yourself with what a Finite State Machine is, and arduino's case statements. Adding more states without using case statements will require adding more and more variables and it will get exponentially more complicated for each additional state you add.


Again, typed on phone, let me know if it doesn't work (and what the specific error is).
Will do, thank you for your help. I will go try it right now. Only thing I can think of right off (and I'm not certain how clear I was) has to do with the button/switch.

Right now, because it is all I have, I am using a simple button that requires me to hold it in order to keep the circuit closed. This means I have to hold it for the timing conditions to happen. Does the code need to change when I build the final product using a click button/switch that can hold itself closed or open?

I still need the coding to turn the lights off after a specific duration, it's just not dependent on the button (this was my initial issue with the "interrupt" suggestion), unless of course I manually press the button again to open the circuit and/or press it again to start all over.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
Going with the most recent code you posted and assuming this is what you want:
Green on/red off
If button press >5s:
Green off/red on (indefinitely as long as button held)
Upon button release, after 7s, go back to initial condition (Green on/red off):

C-like:
int switchState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long previousTime = 0;
unsigned long latchTime = 0;
unsigned long currentTime = 0;
bool latchOn = false;
void setup()
{
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop()
{
  currentTime = millis();
  switchState = digitalRead(2);
  if ((switchState == LOW) and (latchOn == false))
  {
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, LOW); // red led
    previousTime = millis();
  }
  else if ((switchState == HIGH) and (latchOn == false))
  {
  if (currentTime - previousTime >= event_1)
    {
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      latchOn = true;
      latchTime = millis();
    }
  else if ((switchState == LOW) and (latchOn == true))
  {
    if (currentTime - latchTime >= event_2)
    {
        latchOn = false;
    }
  }
}
I had to add a couple of variables to differentiate between the normal button LOW state and the button LOW state which is when we are waiting 7 seconds.

This a basic state machine and if you want to add any more states to it as you progress, I recommend to familiarize yourself with what a Finite State Machine is, and arduino's case statements. Adding more states without using case statements will require adding more and more variables and it will get exponentially more complicated for each additional state you add.


Again, typed on phone, let me know if it doesn't work (and what the specific error is).
I tried the code. There was only a simple brace error, but I found it (surprised myself, I've been buried in brace errors all morning).

Your code produces the same initial delay-on of the red led as mine, but it doesn't revert back to the green led being on when released. In fact, the red led remains powered on even after I release the button, which is something mine doesn't do (it immediately turns the green on upon release). It's an interesting result in that I've had to manually hold the button closed for anything to happen, or else it switches the green led back on (in my original code), so the red light remaining is different.

I saved your code as a separate file so I could play with both. Any ideas?
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
And to the point whether one should "learn to cook versus calling in take-out," I am quite interested in this subject. I don't know if it has reached hobby level status, as I jumped into this to solve a problem, but I have been pleasantly surprised along the way. I'd be lying if I said I hadn't been showing off my code and circuitry work to my 6 yr old.

I'm also going back and studying every line of code, mine or those provided, to understand it better. That is why I saving every iteration as its own file and printing them to review. It may turn out to be another hobby yet, but I want my project off my mind first.
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
There is an old adage. "Give a man a fish and he will keep coming back for more."
Then I thank you for what little help you provide. Consider yourself relieved of the responsibility. No further comment is necessary, unless you'd like to prove whatever others seemingly by their adjoining comments already know.

To put it very bluntly, your quote means, "I do not wish to be involved beyond letting everyone know I know what they need but won't give it to them." Again, thank you, now find someone else to not help.
 

strantor

Joined Oct 3, 2010
6,875
There is an old adage. "Give a man a fish and he will keep coming back for more."
I haven't heard it put just like that before but I like it. One could put a twist on it out of the AOL playbook: "give a man 3 or 4 fish followed by a quote for consultancy services."
 

strantor

Joined Oct 3, 2010
6,875
Your code produces the same initial delay-on of the red led as mine, but it doesn't revert back to the green led being on when released. In fact, the red led remains powered on even after I release the button, which is something mine doesn't do (it immediately turns the green on upon release). It's an interesting result in that I've had to manually hold the button closed for anything to happen, or else it switches the green led back on (in my original code), so the red light remaining is different.
Yeah that's what I thought you wanted. The light would remain on for 7 seconds after releasing the button and then revert back. I must have misunderstood. Can you clarify exactly what you want to happen (short term and long term goal)?
 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
Yeah that's what I thought you wanted. The light would remain on for 7 seconds after releasing the button and then revert back. I must have misunderstood. Can you clarify exactly what you want to happen (short term and long term goal)?
How you described it in theory is exactly how I want it to act, but that didn't happen. The green light did delay for 3 seconds, then went low and the red light went high, with or without me continuing to hold the button (which was new, since I've had to hold it down in my own code). However, the red light never went low again or the green going back high. I had to reset the Uno manually or reload the code.

What I am trying to produce is when I press a button (for now, the simple one I have to hold; later a click version that holds itself), a timed event takes place. I'd like a green light on at some point at the beginning during the first 3 to 5 seconds sort of as confirmation that the circuit/program/whatever is active (I initially set this to be on before the button press just so I can distinguish the difference; later I can see this light not coming on until the button is pressed, maybe even 3 to 5 led's that light up as they millis counts to the desire interval).

After all that, a light comes on and stays on for a desired period (I picked 7 seconds at random thinking I could edit later) until one of two things happens: either the timer for that light runs out (the one set for 7 seconds currently) -or- the button is pressed again to turn the unit off. Then if desired, the button is pressed again and the whole show starts again.

So, button press (green light), three...two...one...(green light goes off) red light comes on for "X" seconds/minutes: let it run or push button to turn off. That is all I'm trying to do.
 

strantor

Joined Oct 3, 2010
6,875
Got it (I think). I will open it up in the actual arduino editor on the computer sometime tomorrow and see what needs to be changed. Doing it on the phone sucks because there's no auto formatting or anything and, well, because it's a phone.
 

strantor

Joined Oct 3, 2010
6,875
OK I changed this to a Finite State Machine using if/else ifs (switch/case would be more proper but I get to do this how I want, and I want if/else if).

The purpose of the requested behavior isn't obvious to me so I question if I understand correctly, but this should do what I understand you to be asking for:

C-like:
int switchState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long previousTime = 0;
unsigned long latchTime = 0;
unsigned long currentTime = 0;
int fsmState = 0;

void setup(){
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop(){
  currentTime = millis();
  switchState = digitalRead(2);
  if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state:
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, LOW); // red led
    // previousTime increments in state 0 and freezes upon leaving state 0,
    //   frozen value to be used in state 10
    previousTime = millis();
    if (switchState == HIGH) fsmState = 10;
  }
  else if (fsmState == 10){ // STATE 10: IDLE with button held down. Waiting for 5s to elapse.
    if (currentTime - previousTime >= event_1) fsmState = 20;
    else if (switchState == LOW) fsmState = 0;
    // latchTime increments in state 10 and freezes upon leaving state 10,
    //   frozen value to be used in state 20
    latchTime = millis();
  }
  else if (fsmState == 20){ // STATE 20: Switch still ON after 5s, turn red light on.
    digitalWrite(3, LOW); // green led
    digitalWrite(4, HIGH); // red led
    if ((currentTime - latchTime >= event_2) or (switchState == LOW)) fsmState = 0;
  }
}
I made another version of it you can play around with, that makes more sense to me for using a momentary pushbutton, and which demonstrates the benefit of using a Finite State Machine as a program grows and becomes more complex.

Turn on, neither LED lights up
Press once and release, red comes on
press again and release, green comes on
press again and release, both come on
Leave it on more than 7s in any of these states, and it times out, turns off.

C-like:
int buttonState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long timeEnteredState = 0;
unsigned long currentTime = 0;
int fsmState = 0;

void setup(){
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop(){
  currentTime = millis();
  buttonState = digitalRead(2);

  if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state:
    digitalWrite(3, LOW); // green led
    digitalWrite(4, LOW); // red led
    if (buttonState == HIGH) fsmState = 10;
  }
  else if (fsmState == 10){ // STATE 10: transtion state, wait for button release.
    timeEnteredState = millis(); 
    if (buttonState == LOW) fsmState = 20;
  }
  else if (fsmState == 20){ // STATE 20: red light ON, green light OFF
    digitalWrite(4, HIGH); // red led
    if (buttonState == HIGH) fsmState = 30;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
  else if (fsmState == 30){ // STATE 30: transtion state, wait for button release.
    digitalWrite(4, LOW); // red led
    timeEnteredState = millis(); 
    if (buttonState == LOW) fsmState = 40;
  }
  else if (fsmState == 40){ // STATE 40: red light OFF, green light ON
    digitalWrite(3, HIGH); // green led
    if (buttonState == HIGH) fsmState = 50;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
  else if (fsmState == 50){ // STATE 50: transtion state, wait for button release.
    digitalWrite(3, LOW); // green led
    timeEnteredState = millis(); 
    if (buttonState == LOW) fsmState = 60;
  }
  else if (fsmState == 60){ // STATE 60: Both lights ON
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, HIGH); // red led
    if (buttonState == HIGH) fsmState = 0;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
}
Imagine trying to manage this sequence with normal if/then statements instead of the Finite State Machine (fsmState). Each of your statements might look something like this:

C-like:
  if ((buttonState == HIGH) and (previousButtonState == LOW) and (redLightWasOnBeforeThat == true) and (currentTime - previousTime >= event_1) and (theresNoOtherConditionIForgotToMention == true)){
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, HIGH); // red led
  }
 
Last edited:

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
OK I changed this to a Finite State Machine using if/else ifs (switch/case would be more proper but I get to do this how I want, and I want if/else if).

The purpose of the requested behavior isn't obvious to me so I question if I understand correctly, but this should do what I understand you to be asking for:

C-like:
int switchState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long previousTime = 0;
unsigned long latchTime = 0;
unsigned long currentTime = 0;
int fsmState = 0;

void setup(){
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop(){
  currentTime = millis();
  switchState = digitalRead(2);
  if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state:
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, LOW); // red led
    // previousTime increments in state 0 and freezes upon leaving state 0,
    //   frozen value to be used in state 10
    previousTime = millis();
    if (switchState == HIGH) fsmState = 10;
  }
  else if (fsmState == 10){ // STATE 10: IDLE with button held down. Waiting for 5s to elapse.
    if (currentTime - previousTime >= event_1) fsmState = 20;
    else if (switchState == LOW) fsmState = 0;
    // latchTime increments in state 10 and freezes upon leaving state 10,
    //   frozen value to be used in state 20
    latchTime = millis();
  }
  else if (fsmState == 20){ // STATE 20: Switch still ON after 5s, turn red light on.
    digitalWrite(3, LOW); // green led
    digitalWrite(4, HIGH); // red led
    if ((currentTime - latchTime >= event_2) or (switchState == LOW)) fsmState = 0;
  }
}
I made another version of it you can play around with, that makes more sense to me for using a momentary pushbutton, and which demonstrates the benefit of using a Finite State Machine as a program grows and becomes more complex.

Turn on, neither LED lights up
Press once and release, red comes on
press again and release, green comes on
press again and release, both come on
Leave it on more than 7s in any of these states, and it times out, turns off.

C-like:
int buttonState = 0;
const int event_1 = 3000;
const int event_2 = 7000;
unsigned long timeEnteredState = 0;
unsigned long currentTime = 0;
int fsmState = 0;

void setup(){
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop(){
  currentTime = millis();
  buttonState = digitalRead(2);
  if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state:
    digitalWrite(3, LOW); // green led
    digitalWrite(4, LOW); // red led
    if (buttonState == HIGH) fsmState = 10;
  }
  if (fsmState == 10){ // STATE 10: transtion state, wait for button release.
    timeEnteredState = millis();
    if (buttonState == LOW) fsmState = 20;
  }
  if (fsmState == 20){ // STATE 20: red light ON, green light OFF
    digitalWrite(4, HIGH); // red led
    if (buttonState == HIGH) fsmState = 30;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
  if (fsmState == 30){ // STATE 30: transtion state, wait for button release.
    digitalWrite(4, LOW); // red led
    timeEnteredState = millis();
    if (buttonState == LOW) fsmState = 40;
  }
  if (fsmState == 40){ // STATE 40: red light OFF, green light ON
    digitalWrite(3, HIGH); // green led
    if (buttonState == HIGH) fsmState = 50;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
  if (fsmState == 50){ // STATE 50: transtion state, wait for button release.
    digitalWrite(3, LOW); // green led
    timeEnteredState = millis();
    if (buttonState == LOW) fsmState = 60;
  }
  if (fsmState == 60){ // STATE 60: Both lights ON
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, HIGH); // red led
    if (buttonState == HIGH) fsmState = 0;
    else if (currentTime - timeEnteredState >= event_2) fsmState = 0;
  }
}
Imagine trying to manage this sequence with normal if/then statements instead of the Finite State Machine (fsmState). Each of your statements might look something like this:

C-like:
  if ((buttonState == HIGH) and (previousButtonState == LOW) and (redLightWasOnBeforeThat == true) and (currentTime - previousTime >= event_1) and (theresNoOtherConditionIForgotToMention == true)){
    digitalWrite(3, HIGH); // green led
    digitalWrite(4, HIGH); // red led
  }
Holy mollie, you did a lot. I'm just now seeing this on my phone. I'll get into it deeper once I'm home on my computer and respond more thoroughly. Thanks a ton.
 
Top