I have it working .. but need direction

Hi All,

Long story short ,I decided to try and control a toy car with buttons on board the case. ( code is below )
Basically what I am trying to do is:

  1. Have 2 buttons as incremental and decremental states (Standby,Lo,Med,High)
  2. Have 1 Button to switch between Forward and Reverse.
  3. Have 1 Button to tun ON/OFF blinking lights.

Currently I have managed to get it 90% working by hacking up an inc/dec sketch found here on the forums along with a standard button state sketch, and it works except I have not yet figured out how to include the blink part.
It's a learn and progress sketch so excuse the mess.

The direction I would like help on:

  1. How to clean up the mess
  2. Include the Blink part.
// Speed Control
    const int LO = 8;    // LED Standby
    const int MED = 9;   // LED Low
    const int HI = 10;   // LED Medium
    const int JET = 11;  // LED High
    const int D_BUTTON = 2;   // DOWN BUTTON
    const int U_BUTTON = 3;   // UP BUTTON
    const int OUT_1    = 15;   // Motor !!!  15 to 19 Analog 1 to 5
   
// FW/RVS Light Control
   #define OUT 2
   const int FRL_Button[OUT]={4,5};
   const int FRL_Output[OUT]={16,17};
   int OutState[OUT]={LOW,LOW};
   int buttonState[OUT];
   int lastButtonState[OUT]={LOW,LOW};

//Variables 
    int lastCounter = 3;
    int counter;              //the basic counter
    int UP;                   // Read Up
    int DWN;                  // Read Down
    
    int A;
    int B;
    int buttonPushCounter = 0;

void setup(){
    for (int i=0;i<OUT;i++) {
      pinMode(FRL_Button[i], INPUT);
      pinMode(FRL_Output[i], OUTPUT);
      digitalWrite(FRL_Button[i], HIGH);
      
    
    pinMode(UP,INPUT);
    pinMode(DWN,INPUT);

    pinMode(LO,OUTPUT);
    pinMode(MED,OUTPUT);
    pinMode(HI,OUTPUT);
    pinMode(JET,OUTPUT);
    pinMode(OUT_1,OUTPUT);
 
}
   }
    void loop(){
        for (int i=0; i<OUT; i++) {
        int reading = digitalRead(FRL_Button[i]);
        if (reading != lastButtonState[i])
        if (buttonState[i] == LOW) {
        OutState[i] = !OutState[i];
    }
        digitalWrite(FRL_Output[i], OutState[i]);
  
        UP = digitalRead(U_BUTTON);        //button pins reading
        DWN = digitalRead(D_BUTTON);
      
    if (UP == HIGH) {                    //if the up button is pressed
        counter = counter++;              //counter increases by one
    }
    
    if (DWN == HIGH) {            //if down button is pressed
        counter = counter--;       //counter decreases by one
    }

    if (counter > 4){      //check that counter won't get further than 4
        counter = 4;
    }
  
    if (counter < 2){    //check that counter won't fall bellow 1
        counter = 1;
    }
 
    switch (counter){    //depending on counter value the proper STATE is sent to the leds
  
  case 1:
      digitalWrite(LO,HIGH);
      digitalWrite(MED,LOW);
      digitalWrite(HI,LOW);
      digitalWrite(JET,LOW);
      analogWrite(OUT_1,50);   // THIS IS JUST A DUMMY VALUE
      break;
      
  case 2:
      digitalWrite(LO,LOW);
      digitalWrite(MED,HIGH);
      digitalWrite(HI,LOW);
      digitalWrite(JET,LOW);
      analogWrite(OUT_1,100);  // THIS IS JUST A DUMMY VALUE
      break;
      
  case 3:
      digitalWrite(LO,LOW);
      digitalWrite(MED,LOW);
      digitalWrite(HI,HIGH);
      digitalWrite(JET,LOW);
      analogWrite(OUT_1,150);  // THIS IS JUST A DUMMY VALUE
      break;
      
  case 4:
      digitalWrite(LO,LOW);
      digitalWrite(MED,LOW);
      digitalWrite(HI,LOW);
      digitalWrite(JET,HIGH);
      analogWrite(OUT_1,250);  // THIS IS JUST A DUMMY VALUE
      break;

  }
  
  if ( (UP == HIGH) || (DWN == HIGH) ) {            //if down button is pressed

      lastButtonState[i] = reading;

   
  }

    delay(200);         // Seems to be a good enough delay between button states     
 
   }   
}

Any and all help is appreciated :wink:

LED_Button_Play.ino (3.07 KB)

Welcome....

The standard reply for anything to do with blinkage, is to read, digest and embrace the use of millis() as used in BlinkWithoutDelay and also explained very nicely in this video and Robin2's excellent example.

const int OUT_1 = 15; // Motor !!! 15 to 19 Analog 1 to 5
....
analogWrite(OUT_1, 50); // THIS IS JUST A DUMMY VALUE

Yea... no. The analog pins do not support PWM, you want to use a pin that has the ~ symbol next to it.

You might want to add a state machine for these too, otherwise you will need to have extremely fast reflexes to stop the counter on the number you want.

if (UP == HIGH) { //if the up button is pressed
counter = counter++; //counter increases by one
}

if (DWN == HIGH) { //if down button is pressed
counter = counter--; //counter decreases by one
}

In general - you will have less headache doing the state machine in setup() and not in the loop().
Second - let each state select the next state

case 1 :
{
process state ....
change to next state
break;
}

Vaclav:
In general - you will have less headache doing the state machine in setup() and not in the loop().

Say what??? Setup() gets called once, and should do only initialization. loop() is where the functional code belongs. There is not a reason in the world a state machine won't work just fine in loop().

Regards,
Ray L.

I have no idea what it means to "do" a state machine....

JimboZA:
I have no idea what it means to "do" a state machine....

Must be similar to connecting to "the cloud".

JimboZA:
Welcome....

The standard reply for anything to do with blinkage, is to read, digest and embrace the use of millis() as used in BlinkWithoutDelay and also explained very nicely in this video and Robin2's excellent example.

Thanks , I will check it out.

HazardsMind:
Yea... no. The analog pins do not support PWM, you want to use a pin that has the ~ symbol next to it.

Yes , hence a dummy value , place holder.

At the end of the sketch there is a delay to stop this from happening

 }

    delay(200);         // Seems to be a good enough delay between button states     
 
   }

Aldeeb:
Thanks , I will check it out.

My example several things at a time is a state machine (without the fancy name).

...R

Robin2:
My example several things at a time is a state machine.

...R

..... which is why I linked it in Reply #1 :stuck_out_tongue:

JimboZA:
..... which is why I linked it in Reply #1 :stuck_out_tongue:

I know. But you were not one of the people proposing "a State Machine" and I just felt the need to clarify.
(And see the minor addition to Reply #9)

...R

I suggested the idea to use a state machine only for his buttons. I'm not sure what everyone else was suggesting.

Also maybe a proper button debounce and not delay(200);

When people recommend a "state machine", it seems like a some what hollow recommendation with little actual technical value to the issue being discussed. Kind of like when somebody is sick and others recommend they "get better".

https://www.google.com/search?as_q=state+machine&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=&as_occt=any&safe=images&tbs=&as_filetype=&as_rights=&gws_rd=ssl

zoomkat:
When people recommend a "state machine", it seems like a some what hollow recommendation with little actual technical value to the issue being discussed. Kind of like when somebody is sick and others recommend they "get better".

Nicely put.
It also conjures up in my mind something complicated and esoteric.
Which is why I don't generally bother with the term.

...R

Hi All ,

So I checked Robin2's example "several things at a time " and worked the inc/dec sketch into it, the outcome works as I want it too except that probably I would need to add debounce!! to the B control switch's as they bounce!! ever so often (needs a few key push's before they latch )

Also I still have not figured out how to switch on and off a blink function with a button, so
if I push button B once it starts the blink function and if I push it again it tuns off the blink function.
I have so far managed to only make it blink when I keep the button pressed.

    //CONTROL  
    const int LO  = 8;    // LED Standby
    const int MED = 9;    // LED Low
    const int HI  = 10;   // LED Medium
    const int JET = 12;   // LED High
    const int D_BUTTON = 2;   // DOWN BUTTON
    const int U_BUTTON = 3;   // UP BUTTON
    const int OUT_1    = 17;   // Motor !!!  15 to 19 Analog 1 to 5
   
   const int buttonInterval = 300;
   
    // B CONTROL
   
   const int ABP = 4;
   const int BBP = 5;
   const int AL = 15;
   const int BL = 16;  
 
   byte AL_State = LOW ;
   byte BL_State = LOW;
   
   //Variables and NON MESS here

     unsigned long currentMillis = 0;
     unsigned long previousAL_Millis = 0;
     unsigned long previousBL_Millis = 0;
        
     unsigned long AButtonMillis = 0; // time when button press last checked Previous
     unsigned long BButtonMillis = 0; // time when button press last checked Previous

    int lastCounter = 3;
    int counter;              //the basic counter
    int UP;                   // Read Up
    int DWN;                  // Read Down
    
    int buttonPushCounter = 0;

void setup(){
 
    pinMode (ABP,INPUT);
    pinMode (BBP,INPUT);
    pinMode (AL,OUTPUT);
    pinMode (BL,OUTPUT);
    pinMode (UP,INPUT);
    pinMode (DWN,INPUT);
    pinMode (LO,OUTPUT);
    pinMode (MED,OUTPUT);
    pinMode (HI,OUTPUT);
    pinMode (JET,OUTPUT);
    pinMode (OUT_1,OUTPUT);
 
}

   void loop(){
 
        currentMillis = millis();
        
        Ard();
        Brd();
        incdec();
        ButtA();
        ButtB();
        
                
   }
   
    void Ard(){
      if (millis() - AButtonMillis >= buttonInterval) {

      if (digitalRead(ABP) == HIGH) {
      AL_State = ! AL_State; // this changes it to LOW if it was HIGH 
                                           //   and to HIGH if it was LOW
      AButtonMillis += buttonInterval;
    }
          }
    }
   
     void Brd(){
      if (millis() - BButtonMillis >= buttonInterval) {

      if (digitalRead(BBP) == HIGH) {
      BL_State = ! BL_State; // this changes it to LOW if it was HIGH 
                                           //   and to HIGH if it was LOW
      BButtonMillis += buttonInterval;
      }  
         }
     }
   
     void ButtA(){
      digitalWrite(AL, AL_State);
     }
     
     void ButtB(){
        // This where I need to put Blinkin Led's
       digitalWrite(BL,BL_State);
     }
     
     
   void incdec(){ 
    
      UP = digitalRead(U_BUTTON);        //button pins reading
      DWN = digitalRead(D_BUTTON);
      
      if (UP == HIGH) {                    //if the up button is pressed
      counter = counter++;              //counter increases by one
    }
    
      if (DWN == HIGH) {            //if down button is pressed
       counter = counter--;       //counter decreases by one
      }

      if (counter > 4){      //check that counter won't get further than 4
      counter = 4;
  }
  
      if (counter < 2){    //check that counter won't fall bellow 1
      counter = 1;
  }
 
      switch (counter){    //depending on counter value the propper STATE is sent to the leds
  
      case 1:
      digitalWrite(LO,HIGH);
      digitalWrite(MED,LOW);
      digitalWrite(HI,LOW);
      digitalWrite(JET,LOW);
      //analogWrite(OUT_1,50);   // THIS IS JUST A DUMMY VALUE
      break;
      
      case 2:
      digitalWrite(LO,LOW);
      digitalWrite(MED,HIGH);
      digitalWrite(HI,LOW);
      digitalWrite(JET,LOW);
     // analogWrite(OUT_1,100);  // THIS IS JUST A DUMMY VALUE
      break;
      
      case 3:
      digitalWrite(LO,LOW);
      digitalWrite(MED,LOW);
      digitalWrite(HI,HIGH);
      digitalWrite(JET,LOW);
     // analogWrite(OUT_1,150);  // THIS IS JUST A DUMMY VALUE
      break;
      
      case 4:
      digitalWrite(LO,LOW);
      digitalWrite(MED,LOW);
      digitalWrite(HI,LOW);
      digitalWrite(JET,HIGH);
    //  analogWrite(OUT_1,250);  // THIS IS JUST A DUMMY VALUE
      break;

  }
  
      if ( (UP == HIGH) || (DWN == HIGH) ) {            //if down button is pressed

 
  }

      delay(200);         //  Need to Change to State (Machine!!!) as per forum discussion \m/ 
 
     }


}

I would appreciate it if I could be shown on how to include the blink function to my button
Thanks

ButtonThingsAtTheSameTime_A.ino (4.02 KB)

Example for your blinking LED. (Button Latch)

byte LEDpin = 13; //on-board LED
byte ButtonPin = 2; //digital pin 2

boolean button,last = LOW;
boolean latch = false;

void setup() {
  pinMode(LEDpin, OUTPUT);
  pinMode(ButtonPin, INPUT);
}

void loop() 
{
  button = digitalRead(ButtonPin);
  if (button == HIGH && button != last) // check if the button is pressed and does not equal its last state (HELD)
  {
    latch = !latch; // 0 -> 1 | 1 -> 0
   
    if(latch == 1) 
      digitalWrite(LEDpin, HIGH);//Here is where you substitute in the blinking part.
    else 
      digitalWrite(LEDpin, LOW);
      
    //latch ? digitalWrite(LEDpin, HIGH): digitalWrite(LEDpin, LOW); //Equal to above IF/ELSE statement.
    // Or even more simply
    //digitalWrite(LEDpin, latch);
  }
  last = button; // save the button's last state
}

Example Blinking LED

byte LED = 13; //on-board LED
unsigned long 
  oldTime = millis(),
  interval = 1000;

boolean toggle = false;

void setup() 
{
  pinMode(LED, OUTPUT);
}

void loop() 
{
  if(millis() - oldTime >= interval)
  {
    toggle = !toggle;
    digitalWrite(LED, toggle); // this works too. digitalWrite(LED, !digitalRead(LED) );
    
    oldTime += interval;
  } 
}

Life would be much easier if you read all the buttons one after the other in a single function and save the results to variables.

Then other parts of your code can do things based on the value of the variables.

If you want to be able to switch blinking on and off just write a blink function that only works if some variable has an appropriate value. Like this pseudo code

void blinkFunction() {
if (blinkSelected == false) {
digitalWrite(ledPin, LOW); // may not be necessary
}
else {
// the code to do the blinking
}
}

...R