Hi,
I need some help to store the led state on eeprom and read it after restart. My sketch is attached below:
If i am using external pullup resistor its working fine but when I change it to internal pullup as in belo sketch than led state is opposite like
if it was high after restart it will high for few millisecond and than will LOW.
if it was low after restart it will flicker and than low.
Is am doing something wrong in definitions or some secrate with internal pullup ?.
#include <EEPROM.h>
const int buttonPin = A0; // pushbutton pin
const int ledPin = 13; // LED pin
int ledState; // variable to hold the led state
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
// set input and output
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
//check stored LED state on EEPROM using function defined at the end of the code
checkLedState();
}
void loop() {
// read the state of the switch into a local variable
int reading = digitalRead(buttonPin);
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 state
digitalWrite(ledPin, ledState);
// save the current LED state in the EEPROM
EEPROM.update(0, ledState);
// save the reading. Next time through the loop,
// it'll be the lastButtonState
lastButtonState = reading;
}
// Prints and upates the LED state
// when the Arduino board restarts or powers up
void checkLedState() {
ledState = EEPROM.read(0);
if(ledState == 1) {
digitalWrite(ledPin, HIGH);
}
if(ledState == 0) {
digitalWrite(ledPin, LOW);
}
}
I wonder why you update the EEPROM with every iteration of loop(). It's sufficient to update when the value changes.
Please understand that a integer variable can have 64k states, not only 0 and 1. Test in checkLedState() for only one of these values, and handle everything else in the "else" part. Typically 0 is False, and everything else is considered True. This also is how the compiler handles logical values.
Set the ledPin to output only after you know the value to output.
If i am using external pullup resistor its working fine but when I change it to internal pullup as in belo sketch than led state is opposite like
There should be no difference between an external and an internal pullup. What value is the external pull up resistor? How is the button wired?
The logic of your code is such that the led will always toggle from the last operating state at startup.
Your code toggles the led on a LOW to HIGH transition. It will toggle on a button release when you have a pullup. Your initialization of state and last state as LOW means that the first reading of loop with the pullups will be a HIGH value and the code will respond with a toggle.
There will also be some flickering of the led on 13 at reset/power on.
if it was high after restart it will high for few millisecond and than will LOW.
if it was low after restart it will flicker and than low.
The first statement is what your code should do. The second does not make sense to me.
At startup, the led will be written LOW based on initial conditions. Then you read the eeprom and set the led HIGH or LOW. Then you enter loop and you should toggle that eeprom condition, and your led will wind up opposite to where it was last running. All this happens very fast.
In my opinion, the external or internal pullup should make no difference unless there are unusual circumstances for the value of the internal and external resistors is very different and there is some environmental condition requiring a strong pullup. Your program logic will invert the saved running state of the led.
Dr.Diettrich makes a good point about not using an int for 0 and 1. A byte will do. Have you confirmed that you are reading the correct value from the eeprom.
DrDiettrich:
I wonder why you update the EEPROM with every iteration of loop(). It's sufficient to update when the value changes.
Initially I keep it simple to understand that what's going on. Later on I will add comparison with internal gap voltage and value will save only when power fail.
But currently I cannot judge why internal and external pull up is giving different results.
But currently I cannot judge why internal and external pull up is giving different results.
You will have to document the wiring for the external pullup.
Thanks for All,
I just change the complete button debouncing sketch and working fine now.
#include <EEPROM.h>
const uint32_t debounceTime = 10; // 5 mSec, enough for most switches
const uint8_t switchPin1 = A0; // with n.o. momentary pb switch to ground
#define ledPin1 7
const bool switchOn = false; // using INPUT_PULLUP
const bool switchOff = true;
bool lastState1 = switchOff;
bool newState1 = switchOff;
bool toggleState1 = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode ( switchPin1, INPUT_PULLUP );
pinMode(ledPin1, OUTPUT);
checkLedState();
}
void loop() {
// put your main code here, to run repeatedly:
newState1 = digitalRead( switchPin1 );
if ( lastState1 != newState1 ) // state changed
{
delay( debounceTime );
lastState1 = newState1;
// push on, push off
if ( newState1 == switchOn && toggleState1 == false )
{
toggleState1 = true;
digitalWrite(ledPin1, HIGH);
Serial.println("ON");
}
else if ( newState1 == switchOn && toggleState1 == true )
{
toggleState1 = false;
digitalWrite(ledPin1, LOW);
Serial.println("OFF");
}
}
// set the LED state
digitalWrite(ledPin1, toggleState1);
// save the current LED state in the EEPROM
EEPROM.update(0, toggleState1);
}
void checkLedState() {
Serial.println("LED status after restart: ");
toggleState1 = EEPROM.read(0);
if(toggleState1 == 1) {
Serial.println ("ON");
digitalWrite(ledPin1, HIGH);
}
if(toggleState1 == 0) {
Serial.println ("OFF");
digitalWrite(ledPin1, LOW);
}
}