Go Down

Topic: Bike Strobe toggle question (Read 259 times) previous topic - next topic

newbienews

I hope this is the right thread to post this. I have breadboarded a LED strobe for my bike, with 2 modes.
I posted the code below. The problem Im having is getting the switch button to toggle between modes. It toggles, but only after a long push, and only during the HIGH transisition, otherwise it only works occasionally. Id like to get a clean transistion between modes. I suspect button bouncing, or all the delays in the code, but dont know how to implement the millis debounce code into my code to time the bounce out. Is a debounce even neccessary or can I just adjust the length of the nested if statement? thanks for any help


 
const byte switchPin = 3;
bool mode = 0;
bool state = HIGH;
int ledwstrobe = 6;           
int ledrstrobe = 10;         
const byte ledPinfour = 12;
const byte  ledPinfive = 13;
void setup() 
{ Serial.begin(9600);
  pinMode (ledPinfive, OUTPUT);
  pinMode (ledPinfour, OUTPUT);
  pinMode(ledwstrobe, OUTPUT);
  pinMode(ledrstrobe, OUTPUT);
 pinMode(switchPin, INPUT_PULLUP);
}

void loop()  { if (digitalRead(3) != state) {
    state = digitalRead(3);
    if (digitalRead(3) == LOW
    ) {
      //delay(100);
      mode = !mode;
      delay(100);
        Serial.println("mode:" + String(mode));
      }
    }

 if (mode == 0) {
    digitalWrite (ledPinfive, LOW);
    digitalWrite (ledPinfour, HIGH);
    manual();
   
   
   
  } else if (mode == 1) {
    digitalWrite (ledPinfive, HIGH);
    digitalWrite (ledPinfour, LOW);
    high ();
   
  }
 
}
       
  void manual () {
 
  digitalWrite(ledwstrobe, LOW);       //set off white strobe
  digitalWrite(ledrstrobe, LOW);       //set off red strobe
    delay(125);
  digitalWrite(ledrstrobe, HIGH);     //set on red strobe
    delay(125);
  digitalWrite(ledrstrobe, LOW);       //set off red strobe
    delay(750);
  digitalWrite(ledwstrobe, HIGH);     //set white strobe on
    delay(62);
  digitalWrite(ledwstrobe, LOW);       //set white strobe off
    delay(63);
  digitalWrite(ledwstrobe, HIGH);      //set white strobe on
    delay(62);
  digitalWrite(ledwstrobe, LOW);       //set white strobe off
    delay(63);
  digitalWrite(ledwstrobe, HIGH);     //set white strobe on
    delay(125);
  digitalWrite(ledwstrobe, LOW);      //set white strobe off
    delay(0);
}
void high (){

  digitalWrite (ledwstrobe, HIGH);
 
}

Grumpy_Mike

#1
Jul 16, 2018, 10:27 pm Last Edit: Jul 16, 2018, 10:30 pm by Grumpy_Mike
Quote
It toggles, but only after a long push, and only during the HIGH transisition, otherwise it only works occasionally.
Yes that is what you have written. So many delays that the code only occasionally looks at the button.

See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once
http://forum.arduino.cc/index.php?topic=223286.0
for how the code should be written to avoid this problem.

Also do not read the button several times in the same operation, it could change between reads, so read it once into a variable at the start of the loop function.

Also please read this:-
How to use this forum
Because your post is breaking the rules about posting code.

newbienews

Thanks for your reply.

what does this mean?

"Also do not read the button several times in the same operation, it could change between reads, so read it once into a variable at the start of the loop function."

how would I put this into a variable? I thought state was the  variable.

void loop()  { if (digitalRead(3) != state) {
    state = digitalRead(3);
    if (digitalRead(3) == LOW
    ) {
      //delay(100);
      mode = !mode;
      delay(100);
        Serial.println("mode:" + String(mode));
      }
    }

I guess there is no  way getting around using the millis debounce code


newbienews

Im trying to figure out how to implement the debounce code, for example this;

https://playground.arduino.cc/Learning/SoftwareDebounce

would I just paste this, after some adjustments, at the top of my loop?

{
  // If we have gone on to the next millisecond
  if(millis() != time)
  {
    reading = digitalRead(inPin);

    if(reading == current_state && counter > 0)
    {
      counter--;
    }
    if(reading != current_state)
    {
       counter++;
    }
    // If the Input has shown the same value for long enough let's switch it
    if(counter >= debounce_count)
    {
      counter = 0;
      current_state = reading;
      digitalWrite(outPin, current_state);
    }
    time = millis();
  }
}

Share

Grumpy_Mike

Quote
Im trying to figure out how to implement the debounce code, for example this;
Why? Your problem is nothing to do with debounce.

Quote
how would I put this into a variable?
Code: [Select]
int buttonValue = digitalRead(3);
Then for the rest of the loop use the variable buttonValue.


newbienews

Thanks for the help. I declared the variable and put the digitalRead into it like so;

void loop()  {
  if (buttonValue != state) {
    state = buttonValue;
    if (buttonValue == HIGH) {

but I didnt notice much change

Are you saying that the MCU treats a variable different than a digital read?

Grumpy_Mike

#6
Jul 17, 2018, 03:59 pm Last Edit: Jul 17, 2018, 04:00 pm by Grumpy_Mike
Quote
Are you saying that the MCU treats a variable different than a digital read?
Yes because it is the result of one digital read taken at one instant of time. If you use the code as you had it then the button could change the state while it was executing and screw up the logic of what you are trying to do.


Quote
but I didnt notice much change
You might not, but the code would not be reliable and would be liable to glitching. It is bad practice to do that.

I was not saying that it would cure your problem, just that it is one of the many things you were doing that you should not do.

Now in reply #1 I said:-
Also please read this:-

How to use this forum
Because your post is breaking the rules about posting code.

Why have you totally ignored me?

Did you read those other links as well?

newbienews

So the rule Im breaking is posting in the wrong thread?

I read your state machine and scheduler tutorial. So I need to stop using delays and use the millis and state machine instead?

Grumpy_Mike

Quote
So the rule Im breaking is posting in the wrong thread?
No the rule you are breaking is you are not posting the code in a scrolling box. The means the forum software can mangle your code and make it say things you did not put.

Yes remove delays and write as a state machine is what you need to do,

newbienews

wow that sounds complicated. anyway you could post like just some skeleton code for that, and I will try and take it from there? any help is greatly appreciated



newbienews

so basically I need to declare a bool LED state variable, set it to LOW, then change up all the digitalWrite ledstrobe HIGH etc with delays code  to functions with the if/else statements and using the led state?kind of confusing how to go about it

newbienews

this makes sense


https://www.youtube.com/watch?v=euDtSQ6Z9FU

along with your scheduler/state machine tutorial, but trying to figure out how to get the interval set up for the second led...getting the first one to blink in intervals with the milis is no issue, how to get a second led, in that loop using the same logic with different interval/freq?

Grumpy_Mike

Quote
how to get a second led, in that loop using the same logic with different interval/freq?
Use different variables. They define the interval/ frequency.

Go Up