SR latch with two push buttons and one LED (Arduino) - c++

What is wrong with my code ? I keep getting
lvalue required as left operand of assignment
Im trying to build a SR latch with 2 push buttons ,if the two push buttons are pressed the LED should be on LOW. And if either of them are pressed the LED should be able to stay on until it's reset by the other button
#include <arduinio.h>
const int buttonPin[] = {2,3}; // the number of the pushbutton pins
const int ledPin = 4; // the number of the LED pin
// variables will change:
int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0;
void setup() {
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// initialize the pushbutton pin as an input:
pinMode(2,INPUT);
pinMode(3,INPUT);
}
void loop(){
buttonState1 = digitalRead (2);
buttonState2 = digitalRead (3);
Serial.println(buttonState1);
Serial.println(buttonState2);
if (buttonState1 = 1 && buttonState2 = 0) {
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else if (buttonState1 = 0 && buttonState2 = 1) {
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else if (buttonState1 = 0 && buttonState2 = 0) {
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else {
// turn LED on:
digitalWrite(ledPin, LOW);
}
}

The problem is that you use = instead of == in if conditions. It should be like this:
if (buttonState1 == 1 && buttonState2 == 0) {}

Related

Control pwm with push button

I'm new to arduino and I have been trying to control pwm with push buttons. My task is to change the PWM of pin 3~ to different values when different buttons is pressed (button 1: 25%, button 2 : 50%, button 3 : 75%, and 0 when no button is pressed) and print out the length of HIGH value in pin 3. But when I don't press any button it still print out some weird number (I expect it to print out 0) and when I push any button the value doesn't change (around 1595-1605). Any idea how to fix it?
Video when I try to run it
https://drive.google.com/file/d/16lE8LDmHdlz0SbHj0AGGMQ8nNEcT8rIT/view?usp=sharing
//
int button1 = 8;
int LED1 = 2;
int button2 = 11;
int LED2 = 4;
int button3 = 12;
int LED3 = 7;
int pwm3 = 3;
int pwm3V;
unsigned long duration;
void setup()
{
pinMode(2, OUTPUT);
pinMode(8, INPUT);
pinMode(4, OUTPUT);
pinMode(11, INPUT);
pinMode(7, OUTPUT);
pinMode(12, INPUT);
pinMode(3, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if (digitalRead(button1)== HIGH)//Press Button 1
{
digitalWrite(LED1, HIGH);
pwm3V = 64;//pwm value 25%
}
if (digitalRead(button1)== LOW)// Unpress Button 1
{
digitalWrite(LED1, LOW);
pwm3V = 0;//pwm value
}
if (digitalRead(button2)== HIGH)//Press Button 2
{
digitalWrite(LED2, HIGH);
pwm3V = 64*2;//pwm value 50%
}
if (digitalRead(button2)== LOW)// Unpress Button 2
{
digitalWrite(LED2, LOW);
pwm3V = 0;//pwm value
}
if (digitalRead(button3)== HIGH)// Press Button 3
{
digitalWrite(LED3, HIGH);
pwm3V = 64*3;//pwm value 75%
}
if (digitalRead(button3)== LOW)// Unpress Button 3
{
digitalWrite(LED3, LOW);
pwm3V = 0;//pwm value
}
analogWrite(pwm3, pwm3V); //set pwm value
duration = pulseIn(pwm3, HIGH);
Serial.print(duration); //print lenght of HIGH
} ```
The value of the variable pwm3V will always be 0 unless button3 is pressed at the right time; the problem is in the control structure. Since a pull-up resistor is used in the circuit diagram of the buttons, when the button is pressed, a low signal is read on the Arduino Board.
In the solution I developed below, I took your source code as a basis, but I made extensive edits. I made things easier by defining the button and led pins as a series. I checked if the pins are low level to check the button pressed status. I designed a control mechanism using the loopControl variable so that the output is not cleared in the iteration after the button is pressed.
int buttonPins[] = {8, 11, 12}, ledPins[] = {2, 4, 7}, pwmPin = 3;
size_t size = sizeof(buttonPins)/sizeof(buttonPins[0]);
int pwmOutputValue;
unsigned long duration, loopControl;
void setup(){
for(size_t i = 0 ; i < size ; ++i){
pinMode(buttonPins[i], INPUT);
pinMode(ledPins[i], OUTPUT);
}
pinMode(pwmPin, OUTPUT);
Serial.begin(9600);
}
int readButtons(){
for(size_t index = 0 ; index < size ; ++index)
if(digitalRead(buttonPins[index]) == LOW)
return index;
return -1;
}
void updatePWMValue(){
analogWrite(pwmOutputValue, pwmPin);
duration = pulseIn(pwmOutputValue, HIGH);
Serial.print(duration);
}
void loop(){
int result = readButtons();
if(result != -1){
digitalWrite(result, HIGH);
pwmOutputValue = 64 * result;
}
else {
if(++loopControl > 100000){ // If this line is cancelled, the whole state is updated in the first cycle after the button is pressed.
for(size_t i = 0 ; i < size ; ++i)
digitalWrite(ledPins[i], LOW);
pwmOutputValue = 0;
loopControl = 0;
}
}
updatePWMValue();
}

Problem in arduino if run system how to fix

Hello i have problem :
state sensor = sensor steps "IF" anyone "steps now = impulse " = all code run"perfect good work im happy" but if sensor LOW a did not detect any motion while loading the code = broke stop all , even if it is at the end close or halfway, it will stop when there is no traffic "" (stage_sensor == HIGH)"", i dont have idea how to fix this//
Please help or sugestion
EDIT : There may be syntax errors (is not consistent), but just wanted to present a problem, the system only works under "if" and this is problem, i dont know how to fix
#include <AccelStepper.h> //accelstepper library
// #define light
// #define move_sensor
// #define pump_water
// #define fan_blowing
// #define fan_extractor
// #define blue
// #define red
// #define green
const byte limitSwitch_1 = 26;
const byte limitSwitch_2 = 25;
bool switchFlipped = false;
bool previousFlip = true;
int switchCounter;
int newSpeed;
int state_sensor = 0; // <--- stage sensor //
int light = 2;
int blue = 3;
int red = 4;
int green = 5;
int fan_blowing = 6;
int water_pump = 8;
int move_sensor = 9;
int fan_extractor = 10;
AccelStepper stepper(1, 22, 23);
void setup()
{
pinMode(water_pump, OUTPUT);
pinMode(light, OUTPUT);
pinMode(fan_blowing, OUTPUT);
pinMode(fan_extractor, OUTPUT);
pinMode(blue, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(move_sensor, INPUT);
pinMode(limitSwitch_1, INPUT_PULLUP); //pin 1 engine (IF touch)
pinMode(limitSwitch_2, INPUT_PULLUP); //pin 2 engine (IF touch)
Serial.begin(9600);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
stepper.setSpeed(1000);
delay(500);
}
void loop()
{
digitalWrite(light, HIGH);
digitalWrite(blue, HIGH);
state_sensor = digitalRead(sensor_move);
if (state_sensor == HIGH) // <--- stage sensor IF anyone move = all code run but if sensor LOW did not detect movement all code broke stop all //
{
digitalWrite(blue, LOW);
digitalWrite(red, HIGH);
stepper.runSpeed();
engine();
}
}
void engine()
{
if(digitalRead(limitSwitch_1) == LOW)
{
switchCounter++;
delay(1000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.setSpeed(newSpeed);
}
if(digitalRead(limitSwitch_2) == LOW)
{
switchCounter++;
delay(1000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.stop();
fans();
}
}
void fans()
{
digitalWrite(red, HIGH);
{
digitalWrite(fan_blowing, HIGH);
digitalWrite(fan_extractor, HIGH);
delay(1000);
digitalWrite(water_pump, HIGH);
}
delay(1000);
digitalWrite(red, LOW);
digitalWrite(water_pump, LOW);
digitalWrite(green, HIGH);
delay(1000);
digitalWrite(fan_blowing, LOW);
digitalWrite(fan_extractor, LOW);
digitalWrite(green, LOW);
digitalWrite(blue, HIGH); //this blue RGB light "ON" but if sensor_steps "ON" = active cycle , blue light led off
delay(1000);
}
What you could do is set up a global "stage" variable:
#include <AccelStepper.h> //accelstepper library
const byte limitSwitch_1 = 26;
const byte limitSwitch_2 = 25;
bool switchFlipped = false;
bool previousFlip = true;
int switchCounter;
int newSpeed;
int stage;
AccelStepper stepper(1, 22, 23);
void setup()
{
pinMode(limitSwitch_1, INPUT_PULLUP);
pinMode(limitSwitch_2, INPUT_PULLUP);
Serial.begin(9600);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
stepper.setSpeed(1000);
delay(500);
stage = 0;
}
void loop()
{
stepper.runSpeed();
runner();
}
void runner()
{
if(stage == 0 && digitalRead(limitSwitch_1) == LOW)
{
switchCounter++;
delay(5000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.setSpeed(newSpeed);
++stage;
}
if(stage == 1 && digitalRead(limitSwitch_2) == LOW)
{
stepper.setSpeed(1000);
delay(1000);
stepper.setSpeed(0);
++stage;
}
if (stage == 2) {
// do next thing, then ++stage;, etc.
}
}

Coding arduino traffic ligth with timer and button

I need make a traffic light that works on countdown:
when number on timer == 0 or if button pressed green led should turn on
otherwise red led
There is my loop,
I tried without for loop and button worked but if I add for loop (for timer) button not responding
thank you
crosswalk_button = digitalRead(2); //That will read the state of the button, if it's pressed or not
for (int i = numberfor7digit; i >= 0; i--) { //numberfor7digit is = 9
numbers(i); //numbers is a function i wrote which shows int it takes currently i
delay(1000);
if (crosswalk_button == 0) { //If you press the button for the crosswalk on with the green one for the crosswalk
numbers(0);
greenhigh(); // green high is a function too, which turns on green light
}
// when number in 7 segment is 0 it will turn on green
else if (i == 0) {
numbers(0);
greenhigh();
}
// for any other number it turns on red
else {
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
}
}
}
Few things which will help you to design this system effectively are:
Use Interrupts to read the value of the button
This will make the turning on Green Light irrespective of what's been executed by the Arduino when the button is pressed.
Example: Illustration to show how to configure a button for interrupt
int interruptPin = 2; //button attached to this pin
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), greenhigh, LOW);
}
void loop() {
//Your code inside this loop
}
void greenhigh() {
//Your code for turning green light high
numbers(0);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
}
Seven Segment Display
Now, since the button is fixed writing code for seven segment display will be simpler.
Example: Illustration to show SSD working
digitalWrite(RED_LED, HIGH);
for (int i = numberfor7digit; i >= 0; i--) {
numbers(i);
delay(1000);
}
greenhigh();
delay(5000);
Conclusion
Complete code can be written as:
int interruptPin = 2; //button attached to this pin
int numberfor7digit = 9;
int GREEN_LED = 10; //TODO: Input here your actual green led
int RED_LED = 11; //TODO: Input here your actual red led
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), greenhigh, LOW);
}
void greenhigh() {
//TODO: Your code for turning green light high
numbers(0);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
}
void numbers(int n) {
//Your implementaion of numbers()
}
void loop() {
digitalWrite(RED_LED, HIGH);
for (int i = numberfor7digit; i >= 0; i--) {
numbers(i);
delay(1000);
}
greenhigh();
delay(5000);
}
You have to read the status of your button every time the loop runs i.e. the for loop that you are using.
And I have also removed the delay and replaced it with an if statement similar to blink without delay example.
One more thing, there is no need to create a crosswalk_button variable
You can directly replace it with digitalRead(2)
Use this code, it should work.
void loop() {
for(int i = numberfor7digit; ; i >= 0; i--) {
static long previousMillis = 0;
if(millis() - previousMillis >= 1000) {
numbers(i);
previousMillis = millis();
}
crosswalk_button = digitalRead(2);
if(crosswalk_button == false || i == 0) {
i = 0;
numbers(i);
greenhigh();
} else {
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW):
}
}
}

How can I call three different functions based on if my button was A) just pressed, B) being held Down and C) Just released?

I'm writing an Arduino program to control a minigun for a friend's cosplay. I need to write a program that when the button is pressed the motor ramps up from 0 to a given value (for now lets say "analogWrite(output_pin,200);") then loop at that RPM until the button is released, at which point it needs to ramp down back to zero.
When I try to put ramping into a loop it doesn't finish the code. I
I need something like this in c++ code for the Arduino button. (I've tried similar things using the "delay" function to no avail)
motorspeed = 0
if buttonpress == True:
buttonheld = True
for i in range (0,10):
delay(1)
motorspeed =+ 20
if buttonpress == False:
motorspeed = 0
if buttonheld == True:
motorspeed = 200
if buttonpress == False:
for i in range(0,10):
delay(1)
motorspeed =- 20
else:
#shut off motor
#Play error sound
Here is the current code that only runs the motor at one speed when the button is held down.
const int button1 =4;
int BUTTONstate1 = 0;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(9, OUTPUT);
pinMode(button1, INPUT);
}
void loop()
{
//set button to read
BUTTONstate1 = digitalRead(button1);
//if button is pressed
if (BUTTONstate1 == HIGH)
{
//run current through motor
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
//set speed
//Rampup
analogWrite(9,200);
}
else
{
digitalWrite(2, LOW);
digitalWrite(3, LOW);
}
}
Here is a virtual environment for the circuit
https://www.tinkercad.com/things/cLOBc9JJuTz-copy-of-dayloncircuitrefinecode/editel?sharecode=b6cqTLlNqUCCN09-mQ_zykp5sMnXx6KLt_KNqlXJmcs
I would recommend using interrupts, it's pretty well documented in Arduino reference:
Arduino reference - Interrupts
Most helpful is "Parameters" and "Example code" section. I think you should prepare two methods and attach interrupt to your input (button) pin on RISING and FALLING trigger.
Make sure that the button pin can be used for interrupt (on Arduino UNO / NANO only pin 2 and 3).
I think it should look similar to this (I haven't tested that):
#define buttonPin 2; // pin usable for interrupt
#define outputPin 9;
#define powerPinA 3;
#define powerPinB 4;
bool running = false;
int currentSpeed = 0;
void buttonUp()
{
digitalWrite(powerPinA, LOW);
digitalWrite(powerPinB, LOW);
running = false;
}
void buttonDown()
{
digitalWrite(powerPinA, LOW);
digitalWrite(powerPinB, HIGH);
running = true;
}
void setup()
{
pinMode(outputPin, OUTPUT);
pinMode(powerPinA, OUTPUT);
pinMode(powerPinB, OUTPUT);
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonUp, RAISING);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonDown, FALLING);
}
void loop()
{
delay(1);
if (running && currentSpeed < 200)
currentSpeed += 20;
else if (!running && currentSpeed > 0)
currentSpeed -= 20;
analogWrite(outputPin, currentSpeed);
}
Here's an example that doesn't rely on any interrupts. Just reading the button and remembering the state in a variable and remembering the time of the last step in a variable to check against millis() (Compiled but Untested)
int buttonPin = 5;
int lastButtonState = HIGH;
unsigned long lastRampStep;
unsigned int stepTime = 10; // 10ms steps. Set to whatever you want.
int analogPin = 3;
int analogLevel = 0;
int maxLevel = 200;
int analogStepSize = 10;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // will read LOW when pressed
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
// The button just changed!
if (buttonState == LOW) {
// was just now pressed
analogLevel = 0; // start ramp up
lastRampStep = millis(); // note the time that we took this step
} else {
// Button just released.
// not sure what you want to happen here
}
}
else if (buttonState == LOW) {
// While button is held ramp until we reach the max level
if(analogLevel < maxLevel){
if(millis() - lastRampStep >= stepTime){
analogLevel += analogStepSize;
lastRampStep = millis();
}
}
} else {
// While button is released (HIGH) ramp back down:
if(analogLevel > 0){
if(millis() - lastRampStep >= stepTime){
analogLevel -= analogStepSize;
lastRampStep = millis();
}
}
}
analogWrite(analogPin, analogLevel);
lastButtonState = buttonState;
}
You could use interrupts to handle pressed/release, set a value, and handle the ramp up/down in the loop.
Keep in mind that you should also debounce the button.
Below is some pseudocode:
const byte maxLevel = 200; // some example values (max 255)
const int rampDelay = 5;
volatile byte targetLevel = 0;
byte currentLevel = 0;
// ...
ISR for Button { // Could be in one ore two ISR's
if pressed
targetLevel = maxLevel;
// possible other calls
if released
targetLevel = 0;
// possible other calls
}
void loop()
{
if (currentLevel < targetLevel) {
SetLevel(++currentLevel);
}
else if (currentLevel > targetLevel) {
SetLevel(--currentLevel);
}
// if currentLevel == targetLevel nothing changes
// if your device is battery powered you could even put the mcu
// to sleep when both levels are zero (and wake up from the ISR)
// no need for constantly polling the button when using ISR
delay(rampDelay);
}
This will also start ramping down immediately if the button is released before the motor is at full speed.

How can I blink a LED differently when I press a toggle button?

I'm trying to blink a LED according to press of toggle button. If I press the first toggle switch the first time, LED blinks at 5 Hz, when I press the toggle button for the second time, LED blink at 6 Hz and when I press the third time, LED turns off.
I tried using the program below, but It's not working as I wanted.
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
// variables will change:
int buttonState = 0;
// variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
int x=0;
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
Serial.print(x);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH && x==0) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
Serial.print(x);
} else {
// turn LED off:
x = x+1;
}
if (buttonState == HIGH && x==1) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
delay(2000);
Serial.print(x);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
x = x+1;
}
if (buttonState == HIGH && x==2) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(3000);
digitalWrite(ledPin, LOW);
delay(3000);
Serial.print(x);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
x = x+1;
}
if (buttonState == HIGH && x==3) {
// turn LED off:
digitalWrite(ledPin, LOW);
x = 0;
}
}
When I use this code it works for first case that is LED blinks at 1000 ms delay, but if I toggle switch it again works for first condition. How can I make it to execute second condition i.e. to blink at delay of 2000 ms?
Firstly this is your circuit. I tried this circuit and code and worked for me. I used interrupt for checking button state. And millis calculation is simple.
Frequency = 1 / Period
Period = Ton + Toff
6Hz = 1000 millis / T => T = 166 millis
166 = Ton + Toff (for %50 duty cycle Ton=Toff) => Ton = Toff = 83 millis
enter image description here
const int ledPin = 13;
const int buttonPin = 2;
int state = -1;
bool willLightOn = false;
unsigned long currentDelay = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), changeState, FALLING);
}
void loop() {
if(state % 3 == 0) { //6Hz
currentDelay = 83;
willLightOn = true;
} else if (state % 3 == 1) { //5Hz
currentDelay = 100;
willLightOn = true;
} else if (state % 3 == 2) { //LED off
currentDelay = 0;
willLightOn = false;
digitalWrite(ledPin, LOW);
}
currentMillis = millis();
if (currentMillis - previousMillis >= currentDelay && willLightOn) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin));
}
}
void changeState() {
state++;
}
Right now your logic checks 3 times for the value of x in a single loop.
Below code toggles light whenever x is greater than zero. x's value is changed when button is pressed.
But there is a big problem here: If button is pressed when there's something else going on in the processor or it is sleeping (like the long delays you want to use), it may be ignored. So you better study interrupts and implement this behavior using them.
if (x > 0)
{
digitalWrite(ledPin, HIGH);
delay(1000 * x);
digitalWrite(ledPin, LOW);
}
if (buttonState == HIGH)
{
x++;
if (x > 3)
x = 0;
}
You should create a global state of the application. This state is where you remember if you are blinking at 50hz/60hz/off. Then you can use a switch to do the right thing.
Then you check if the button is pressed and change the application state.
See my example below:
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
// variables will change:
int applicationState = 0;
bool lightOn = true;
int currentDelay = 1000;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
// variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
if (digitalRead(buttonPin) == HIGH) {
applicationState++;
if(applicationState >= 3) {
applicationState = 0;
}
delay(100);
}
switch(applicationState){
case 0:
currentDelay = 1000;
lightOn = true;
break;
case 1:
currentDelay = 2000;
lightOn = true;
break;
case 2:
digitalWrite(ledPin, LOW);
lightOn = false;
break;
}
currentMillis = millis();
if (currentMillis - previousMillis >= currentDelay && lightOn) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin));
}
}
I hope you understand what I try to say and demo with the example code.
Your code can not work:
You do need to check if the button state changes, detect when there is a edge. And make sure you detect a single edge only once.
You must repeat the blinking it in a loop till the button is pressed, then you can change the frequency.
You must check the button while you sleep, otherwise your program do not recognize when you press the button.
To make it work, you must change the complete program.
#define BLINK_SLEEP_TIME <some value> // insert value for 16.6666ms
//return 1 after a positive edge
bool button_read(void)
{
static bool lastState=1; //set this to 1, so that a pressed button at startup does not trigger a instant reaction
bool state = digitalRead(buttonPin);
if(state != lastState)
{
state=lastState;
return state;
}
return 0;
}
//Blink the LED with a given period, till button is pressed
//Times are in x*16.666ms or x/60Hz
//At least one time should be more than 0
void blink(uint8_t ontime, uint8_t offtime)
{
while(1)
{
for(uint8_t i=0;i<ontime;i++)
{
led_setOn();
delay(BLINK_SLEEP_TIME);
if(button_read())
{
return;
}
}
for(uint8_t i=0;i<offtime;i++)
{
led_setOff();
delay(BLINK_SLEEP_TIME);
if(button_read())
{
return;
}
}
}
}
const uint8_t time_table[][]=
{
{0,50},//LED is off
{6,6}, //LED blinks with 5Hz, 60Hz/2/6=5Hz
{5,5}, //LED blinks with 6Hz, 60Hz/2/5=6Hz
}
void endless(void)
{
uint8_t i=0;
for(;;)
{
i++;
if(i>2)
{
i=0;
}
blink(time_table[i][0],time_table[i][1]);
}
}
A better approach would be to use a hardware PWM-Module and change the values after a edge on the button.