Pin mode is always LOW when it should be HIGH - arduino

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);
}
}

Related

Arduino Mega: How do I switch an LED's colour using the same authenticated RFID tag and using a button too?

I'm having some issues getting my code to do what I want on my Arduino Mega. What I'm aiming to do is to have the same RFID tag change an LED colour from red to green and when presented again from green to red. I also want to do this with a button. This is for a door lock so that the door can been locked and unlocked from both sides of the door.
The code below will allow an RFID tag to change the colour from red to green and vice versa but as soon as I try to test for an authenticated card it fails miserably. Also when I try to add the button to it my code ends up getting very messy and unusable. I've tried various things but I think my major problem is because the code sites inside the loop function. I've tried while(1) when trying to set the LED to a particular colour but it just doesn't work properly.
This I thought would be fairly trivial to do, maybe it is, I'm just not familiar enough with this.
Can anyone help point me in the right direction which will help me move further forward with this?
#include <SPI.h>
#include <MFRC522.h>
// constants won't change. They're used here to set pin numbers:
const int BUTTON_PIN = 2; // the number of the pushbutton pin
#define BLUE 7
#define GREEN 6
#define RED 3
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 53 // Configurable, see typical pin layout above
// Variables will change:
String authKeyFob = "54321098765";
String card_ID="";
//int lastState = HIGH; // the previous state from the input pin
//int currentState = LOW; // the current reading from the input pin
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
int ledState = 0; // remember current led state
int rfidState = 0;
int lastRfidState = 0;
bool toggle = false;
bool cardValid = false;
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// initialize the pushbutton pin as an pull-up input
// the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed.
pinMode(BUTTON_PIN, INPUT);
pinMode(GREEN, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(BLUE, OUTPUT);
}
void loop() {
// read the state of the switch/button:
buttonState = digitalRead(BUTTON_PIN);
// Look for new cards, and select one if present
if (mfrc522.PICC_IsNewCardPresent() || mfrc522.PICC_ReadCardSerial() ) {
if(toggle == false){
toggle = true;
} else {
toggle = false;
}
delay(200);
}
if(toggle == 1){
digitalWrite(GREEN, HIGH);
digitalWrite(RED, LOW);
} else if (toggle == 0) {
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
}
}
All you need to do is to have another if statement that reads your button and toggles your toggle variable just like you do for the card. See if you understand what's going on here:
void loop() {
// read the state of the switch/button:
oldButtonState = LOW; // NEED TO ADD A DECLARATION FOR THIS BEFORE SETUP
buttonState = digitalRead(BUTTON_PIN);
// Look for new cards, and select one if present
if (mfrc522.PICC_IsNewCardPresent() || mfrc522.PICC_ReadCardSerial() ) {
toggle = !toggle; // A way easier way to write the if statements you had.
}
// if the button just became pressed...
if(buttonState == HIGH && oldButtonState==LOW){
toggle = !toggle; // same thing, toggle our variable.
}
oldButtonState = buttonState; // save the button state for next time
if (toggle) {
digitalWrite(GREEN, HIGH);
digitalWrite(RED, LOW);
} else {
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
}
}
See the State Change Example to see why I store the old state of the button. I also changed that set of if statements to just set toggle to not toggle, that's an easier way to reverse a boolean value. I also made that last else if just an else since a boolean can only have two values. If it isn't true then it must be false.
This is my updated version with the RFID tag working consistently with the button and LED.
void loop() {
// read the state of the switch/button:
oldButtonState = LOW; // NEED TO ADD A DECLARATION FOR THIS BEFORE SETUP
buttonState = digitalRead(BUTTON_PIN);
// Look for new cards, and select one if present
if (!mfrc522.PICC_IsNewCardPresent() ) {
}
if(mfrc522.PICC_ReadCardSerial() ){
toggle = !toggle;
delay(200);
}
// if the button just became pressed...
if(buttonState == HIGH && oldButtonState==LOW){
toggle = !toggle; // same thing, toggle our variable.
delay(200);
}
oldButtonState = buttonState; // save the button state for next time
if (toggle) {
digitalWrite(GREEN, HIGH);
digitalWrite(RED, LOW);
} else {
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
}
}

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.

Prevent ButtonState Toggle From HIGH to LOW

Functionality:
Before the red dome button is pressed (not a 2 state button), the serial monitor will print a list "0"s and when the red dome button is pressed, the button state will toggle from LOW to HIGH, hence at the serial monitor will print a list of "1"s.
However, when the button is in the state of HIGH, serial monitor print "1"s and user will not be able to toggle the button state from HIGH to LOW. Hence, the button can only toggle from HIGH to LOW automatically after a period, delay(25s).
Therefore, correct behaviour:
Initial state print => 00000000000000(when user presses the red dome button => buttonstate change LOW to HIGH)111111111111111111(when user presses the button, nothing happens)111111111111111111(after 25s delay, buttonState will toggle HIGH to LOW)0000000000000
ISSUE:
At this point in time, users are able to toggle between LOW to HIGH and HIGH to LOW. Meaning, the flow => 00..000(user press button, Toggle LOW to HIGH)111...111(user press button, toggle HIGH to LOW)0000...
And I am not really sure on how to enable the button to only toggle from LOW to HIGH but disable the button to toggle from HIGH to LOW.
Meaning when user push the button, it can change the button state from "0" to "1" but not able to change the button state when it is in "1".
Hence, I would like to request for some help that will allow the following correct behaviour.
Thanks
Code:
const int buttonPin = 2; //the number of the pushbutton pin
const int Relay = 4; //the number of the LED relay pin
uint8_t stateLED = LOW;
uint8_t btnCnt = 1;
int buttonState = 0; //variable for reading the pushbutton status
int buttonLastState = 0;
int outputState = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(Relay, OUTPUT);
digitalWrite(Relay, LOW);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// Check if there is a change from LOW to HIGH
if (buttonLastState == LOW && buttonState == HIGH)
{
outputState = !outputState; // Change outputState
}
buttonLastState = buttonState; //Set the button's last state
// Print the output
if (outputState)
{
switch (btnCnt++) {
case 100:
stateLED = LOW;
digitalWrite(Relay, HIGH); // after 10s turn on
break;
case 250:
digitalWrite(Relay, LOW); // after 20s turn off
//Toggle ButtonState to LOW from HIGH without user pressing the button
digitalWrite(buttonPin, LOW);
break;
case 252: // small loop at the end, to do not repeat the LED cycle
btnCnt--;
break;
}
Serial.println("1");
}else{
Serial.println("0");
if (btnCnt > 0) {
// disable all:
stateLED = LOW;
digitalWrite(Relay, LOW);
}
btnCnt = 0;
}
delay(100);
}
You need set outputState and let it set until it will be reset after 25 seconds. If button is still pressed then it will loop on 251.
const int buttonPin = 2; //the number of the pushbutton pin
const int Relay = 4; //the number of the LED relay pin
uint8_t stateLED = LOW;
uint8_t btnCnt = 1;
bool outputState = false;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(Relay, OUTPUT);
digitalWrite(Relay, LOW);
}
void loop() {
outputState |= digitalRead(buttonPin); // if pushButton is high, set outputState (low does nothing)
// Print the output
if (outputState)
{
switch (btnCnt++) {
case 100:
stateLED = LOW;
digitalWrite(Relay, HIGH); // after 10s turn on
break;
case 250:
digitalWrite(Relay, LOW); // after 20s turn off
//Toggle ButtonState to LOW from HIGH without user pressing the button
outputState = false; // reset state to low
break;
case 251: // loop (it might happen, if previous step sets outputState=false but button is still pressed -> no action)
--btnCnt;
outputState = false;
break;
}
Serial.println("1");
}else{
Serial.println("0");
if (btnCnt > 0) {
// disable all:
stateLED = LOW;
digitalWrite(Relay, LOW);
}
btnCnt = 0;
}
delay(100);
}

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;
}

LED Strings attached to Arduino programmed to light brighter one after the other repeatedly, stops working after 4 cycles.

I have made a circuit involving 3 strings of LEDs.
They are supposed to glow at a low intensity initially.
Now when pin 2 on Arduino goes HIGH momentarily, the LED strings glow brighter one by one and then stop. AND, if the pin 2 is kept HIGH, then the transition should continue as long as pin 2 is HIGH.
The problem is that if I make pin 2 HIGH permanently via a push button, the transition occurs 4 times and then it stops. No transition occurs after that even if i again make the pin 2 HIGH after some time.
The code is given below:
const int pin1 = 9;
const int pin2 = 10;
const int pin3 = 11;
const int button = 2;
int val = 0;
//int brightness = 0;
void setup(){
Serial.begin(9600);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin3, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
while(true)
{
val = digitalRead(button);
if(val == HIGH)
{
if(Serial.available())
{
long int brightness = Serial.read();
analogWrite(pin1, 255);
delay(1000);
analogWrite(pin2, 255);
delay(1000);
analogWrite(pin3, 255);
delay(1000);
analogWrite(pin1, brightness);
analogWrite(pin2, brightness);
analogWrite(pin3, brightness);
delay(1000);
}
}
}
}
If you really want to configure your dimmed brightness after each reset of your arduino, you should rearrange your source in a way that reading from the serial port doesn't block your transition, while still making sure your "brightness" has a predefined value:
// global variable with preset value
long int brightness = 64;
// loop function
// http://arduino.cc/en/pmwiki.php?n=Reference/Loop
void loop(){
// check for new brightness value
if(Serial.available())
{
int brightness = Serial.read();
}
// check for pressed button
val = digitalRead(button);
if(val == HIGH)
{
// start light cycle
analogWrite(pin1, 255);
delay(1000);
analogWrite(pin2, 255);
delay(1000);
analogWrite(pin3, 255);
delay(1000);
analogWrite(pin1, brightness);
analogWrite(pin2, brightness);
analogWrite(pin3, brightness);
delay(1000);
}
}

Resources