stop while loop with variable using button on arduino - arduino

With an Arduino I'm taking analog input from a potentiometer. With the input I regulate how much my lamp blink. The problem is when I try to have a button that turn the lamp on and off so that it blinks or not blinks. I can make the button turn on the lamp but I cannot get it to turn the lamp off.
My loop that makes the lamp blink has a variable that has to be 1 for it to run. However when i change the variable to 0 with an if statement the blink loop does not stop and the lamp keeps blinking.
Here is my code:
int sensorPin = A0; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int sensorValue = 0; // variable to store the value coming from the sensor
int buttonPin = 11; //select the pin for the button
int buttonState = 0; //variable to start and stop the led
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
if(digitalRead(buttonPin)==HIGH){
buttonState = 1;
delay(1000) //So that buttonState does not instantly change back
}
if(digitalRead(buttonPin)==HIGH && buttonState == 1;){
buttonState = 0;
delay(1000) //So that buttonState does not instantly change back
}
while(buttonState == 1){
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
// turn the ledPin on
digitalWrite(ledPin, HIGH);
// stop the program for <sensorValue> milliseconds:
delay(sensorValue);
// turn the ledPin off:
digitalWrite(ledPin, LOW);
// stop the program for for <sensorValue> milliseconds:
delay(sensorValue);
}
}
Thanks for helping!

A while inside loop is always suspicious, and you provide a good example.
Inside the while loop buttonState will never change, thus you have a while forever
Simply change it to an if and your sketch will behave better.
Showing that delay(1000); is not optimal for button handling. You rather want to handle state changes (and consider bouncing buttons). But that's an advanced question. :)

Related

How to prevent an initial HIGH output in PIR Sensor

I am testing out the HC-SR501 PIR sensor on arduino. I tried a simple code tutorial online
int buzz = 13;
int pir = 2;
int value = 0;
int pirState = LOW;
void setup() {
pinMode(buzz, OUTPUT);
pinMode(pir, INPUT);
Serial.begin(9600);
}
void loop() {
delay(5000);
value = digitalRead(pir);
if (value == HIGH) {
digitalWrite(buzz, HIGH);
if (pirState == LOW) {
Serial.println("Motion Detected!");
pirState = HIGH;
}
} else {
digitalWrite(buzz, LOW);
if (pirState == HIGH){
Serial.println("Motion Ended!");
pirState = LOW;
}
}
}
This works, however, I'm trying to initialize it to a LOW output. When I first turn on the board, it initially gives me a high output, and so the buzzer activates instantly, even though I placed it away from myself. The serial prints out Motion Detected. I tried adding a delay, however it still gives out a HIGH output afterwards. Anyone knows how to solve this?
Thank you!
The pinMode sets the pin as an output, but the default state is LOW, so there should be no problem with it.
However, pin 13 is wired to onboard LED. And the onboard LED is also used by bootloader to signal its activity after the reset. You should check other pins but 13.

to stop the rotation of the motor using push button even when the Bluetooth is connected

I am using Arduino Nano, Bluetooth module HC-05 and one push button.
I want to rotate the motor when it receives signal from the Bluetooth and stop the rotation when the push button is pressed but here the Bluetooth signal should not be disconnected the motor should stop its rotation when BLuetooth is connected and the button is pressed.
The problem is when signal is passed through Bluetooth or serial , the motor rotates but when we push the button to stop the rotation the motor doesn't stops.
Below is what I tried.
#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(10,6);
const int buttonPin = 5; // the pin that the pushbutton is attached to
const int motorPin = 9;
const int ledPin = LED_BUILTIN; // the pin that the LED is attached to
int buttonState = 0; // current state of the button
int Data;
void setup() {
Serial.begin(9600);
Bluetooth.begin(9600);
Bluetooth.println("Send 1 to open LOCK. Send 0 to close LOCK");
Serial.println("Send 1 to open LOCK. Send 0 to close LOCK");
delay(1000);
Bluetooth.println("Waiting for command...");
Serial.println("Waiting for command...");
pinMode(buttonPin, INPUT);
pinMode(motorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
if (Bluetooth.available())
{
Data=Bluetooth.read();
if(Data=='1'){
Serial.println("Motor rotating");
Serial.println(buttonState);
digitalWrite(motorPin, HIGH);
}
if (Data=='1' and buttonState == 1){
Serial.println("Motor stop");
Serial.println(buttonState);
digitalWrite(motorPin, LOW);
digitalWrite(ledPin, HIGH);
}
else{;}
}
}
I tried only to control with the push button only which works well. When the button is pushed it motor stops and when unpushed it rotates.
I found the following problems with your code
The variable Data you defined as integer but you are comparing it with string '1'
In your first if condition you are not checking button status before rotating motor, make it
if(Data==1 && buttonState == 0)
Otherwise both the condition will execute when buttonState =1, which will give unexpected result of starting and stopping the motor intermittently.

Pin mode is always LOW when it should be HIGH

I'm working with simple Arduino where I'm trying to turn on a LED light by using serial print and turning off the LED Light when I click the button or use the switch on the board, when the pin is in the ground.
At the moment, I can turn on the led light by serial, however when I click the button the LED light will switch off but then never switch on, and that's happening because the state is being stuck at low all the time and never switching back to high.
Here's the code:
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 3; // the number of the LED pin
int state = 0;
// 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() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if (Serial.available())
{
state = Serial.parseInt();
if (state == 1)
{
digitalWrite(ledPin, HIGH);
Serial.println("ON");
}
}
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == LOW) {
state = 0;
// turn LED OFF:
Serial.println("off");
digitalWrite(ledPin, LOW);
}
// IMP : This Never runs. the state is always off therefore when i send to serial " 1" the led just blinks
else {
Serial.println("off");
}
}
The state is always off therefore when I send to serial " 1" the LED just blinks
I think you are reading state from PIN using wrong function.
if (Serial.available())
{
state = Serial.parseInt();
Why not use https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/ ?
Are you sure this condition is evaluated to true? if (Serial.available()) ?
You are making the logic too much complicate. Just check the serial if it is available and have the desire value turn led on else check the button and if it pressed turn the led off. On other conditions DO NOTHING. That is all you need.
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 3; // the number of the LED pin
int state = 0;
// 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()
{
if (Serial.available())
{
state = Serial.parseInt();
if (state == 1)
{
digitalWrite(ledPin, HIGH);
Serial.println("ON");
}
}
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
else if (digitalRead(buttonPin) == HIGH)
{
// turn LED OFF:
Serial.println("off");
digitalWrite(ledPin, LOW);
}
}

Arduino Button with LED

I have put together an Arduino circuit that turns the led's off when the button is pressed. How do I code it so when I press it once it comes on and stays on and will only turn off once its pressed again? Any help would be appreciated
My Current code is:
int ledred = 12;
int ledgreen = 8;
int BUTTON = 4;
int speakerPin = 1;
void setup() {
// initialize the digital pin as an output.
Serial.begin(9600);
pinMode(ledgreen, OUTPUT);
pinMode(ledred, OUTPUT);
pinMode(BUTTON,INPUT);
}
void loop() {
if(digitalRead(BUTTON) == HIGH){
digitalWrite(ledred,HIGH);
digitalWrite(ledgreen,HIGH);
}else
{
digitalWrite(ledred,LOW);
digitalWrite(ledgreen,LOW);
}
}
If all you want is do this, you can use one of the interrupt pins and watch for the RISING (or FALLING) event.
Something similar to this example:
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
Mind that you may still need some debouncing strategy.
Also, you don't need to use an interrupt for that, but then you'd need some edge-detection algorithm. These are quite well explained in the debouncing article above. I personally prefer these, since interrupt pins in the UNO board are precious enough not to be used with humble button pressings... :o)
/*
Debounce
Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
minimum delay between toggles to debounce the circuit (i.e. to ignore noise).
The circuit:
- LED attached from pin 13 to ground
- pushbutton attached from pin 2 to +5V
- 10 kilohm resistor attached from pin 2 to ground
- Note: On most Arduino boards, there is already an LED on the board connected
to pin 13, so you don't need any extra components for this example.
created 21 Nov 2006
by David A. Mellis
modified 30 Aug 2011
by Limor Fried
modified 28 Dec 2012
by Mike Walters
modified 30 Aug 2016
by Arturo Guadalupi
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Debounce
*/
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED:
digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
}

Arduino LCD Digital Input Counter

I currently have an arduino LCD and one SPDT switch connected to my board. The the common pin of the SPDT is grounded and the outer pins are each connected to a digital input. My program should increment and decrement the counter being printed to the LCD screen. I have one input working that increments the counter I do not know how to implement code for the input to decrement the counter. Code posted below.
Thank you
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5,4,3,2);
const byte buttonPin = 8;
int counter = 0; // set your counter to zero to begin with
byte buttonState; // the current reading from the input pin
byte lastButtonState = HIGH; // the previous reading from the input pin
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
lcd.begin(16, 2); // for 2x16 lcd display
}
void loop() {
// read the state of the switch into a local variable:
byte reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from HIGH to LOW), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) >= debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
counter ++;
Serial.println(counter);
lcd.setCursor(0, 1);
lcd.print(counter);
}
}
}
lastButtonState = reading;
}
You cannot simply connect one pole of a switch to an input pin an other to the ground. This will detect LOW but when when you are suppose to detect HIGH on the pin, it will be floating. Connect a pull-up resistor to your input pins.
Or you can use pinMode(InPin, INPUT_PULLUP);
This will pull your input pin to high internally and then you can detect the swithces and implememnt the code.

Resources