Hello i been using the button sketch to turn off and on the led but Is there a watch to latch it like so if the button is pushed the led stays on and if pushed again led turns off?
Does this make sense?
//***************************
//check if this switch has changed state
thisState = digitalRead(mySwitch);
if (thisState != lastMySwitchState)
{
//update the switch state
lastMySwitchState = thisState;
//"HIGH condition code"
//switch goes from LOW to HIGH
if(thisState == HIGH)
{
//LED on pin 9 is Push ON, Push OFF
digitalWrite(9,!digitalRead(9));
}
Yes i think i got it thank you.
I hope someone is still watching this thread. I'm new to coding and was hoping someone could help me understand where I've gone wrong...
I just added this into the Button Sketch found in the examples library.
I'm trying to use this as a base for a circuit to control a small motor, then add PWM control. First, I need to understand the latching portion.
Mine lights the LED on Pin 9 but doesn't seem to control it in any way.
I tried to add some reporting to the serial monitor, to do some debugging....
/*
Button
Turns on and off a light emitting diode(LED) connected to digital
pin 13, when pressing a pushbutton attached to pin 2.
The circuit:
* LED attached from pin 13 to ground
* pushbutton attached to pin 2 from +5V
* 10K resistor attached to pin 2 from ground
* Note: on most Arduinos there is already an LED on the board
attached to pin 13.
created 2005
by DojoDave <http://www.0j0.org>
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Button
*/
// 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
const int latchPin = 9;
boolean thisState = 0; // declare thisState as a variable and set once to zero
boolean mySwitch = 0; // declare mySwitch as a variable and set once to zero
boolean lastMySwitchState = 0; //declare lastMySwitchState as a variable and reset to zero
// 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);
pinMode(latchPin, OUTPUT);
Serial.begin(19200);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
//***************************
//check if this switch has changed state
thisState = digitalRead(mySwitch);
if (thisState != lastMySwitchState)
{
//update the switch state
lastMySwitchState = thisState;
//"HIGH condition code"
//switch goes from LOW to HIGH
if(thisState == HIGH)
{
//LED on pin 9 is Push ON, Push OFF
digitalWrite(latchPin,!digitalRead(latchPin));
}
}
Serial.print("mySwitch State ");
Serial.print(mySwitch);
Serial.print(" switch State ");
Serial.println(latchPin);
}
Here's one of many ways to do a "latch" (push ON / push OFF), run it & see if you "get it".
uint32_t start, dbStart;
const byte btn = 2, led = 9, dbTime = 15;
bool pinState = true,
btnState = true,
prevBtnState = true,
latch = false;
void setup() {
Serial.begin(19200);
pinMode(btn,INPUT);
pinMode(led,OUTPUT);
}
void loop() {
// debounce button ++++++++++++++++
if (digitalRead(btn) != pinState) // get state of pin 2
{
dbStart = millis(); // reset db timer
pinState = !pinState; // now they are equal, won't enter
} // here again unless pin state changes
if (millis() - dbStart > dbTime) // db timer has elapsed
btnState = pinState; // button state is valid
//+++++++++++++++++++++++++++++++++++
if(btnState != prevBtnState && btnState == HIGH) // btnState changed
{
// if button pressed and NOT latched
if(!latch)
{
latch = true; // prevents entry while latched
digitalWrite(led,HIGH);
}
else
{
// if button pressed while latched,
latch = false;
digitalWrite(led,LOW);
}
Serial.print( "LED is ");
if(latch)
{
Serial.println("ON");
}
else
{
Serial.println("OFF");
}
}
prevBtnState = btnState;
}
Happy sparking.
EDIT: changed btnState to normally LOW.
Wow. Thanks!
I'll try this code when I have some time today.
Being kind of new at this, I'd also like to learn something from this...
There is a lot of code there that declares values and stuff.... I think?
I know this is a lot to ask, but would you be able to add some comments to the code to help me understand what the lines (or sections) does?
Thanks if you can help.... well,..... thanks either way.
After testing, I realize this is a pretty cool little piece of code, thanks for sharing!
Could I ask a few other questions?
What does this piece of code do?
if(btnState != prevBtnState && btnState == HIGH) // btnState changed
{
// if button pressed and NOT latched
if(!latch)
{
I'm wondering specifically about that little exclamation mark? Can you walk me through the logic here?
I'm wondering about adding one more button that serves as a cancel function so that no matter what, it will shut off the LED. Eventually this extra button will be a value fed back from the current sensor on a motor shield to shut off a motor when the motor shaft is locked. This extra button will need its own const name so that it can be added to the true/false logic in the loop, but not sure how that needs to look?
! means "not"
So, != means "not equal to".
And if (!latch) means "if not latch(-ed)", or specifically "if latch== LOW".
&& means and.
So the first line means, if the button state has changed, and is high now..... That means the button is newly high, since we know it's state just changed. (As distinct from having been pressed already last time we looked.)
Then the next line which is inside the "if" of the first line means that if the button is newly high (which we know from the "if" above it) and it's not latched.... do some stuff.
Ahhh...
Thanks for the explanation.
Very helpful.
OK.
So now I am embarassed, and a tiny but frustrated with myself for not asking the complete question.
The reason I was looking for latching button code was so that I could use that logic to start and stop a motor with the Arduino Motor shield V3. However, I assumed that I could simply change the I/O declarations in the code to utilize the pins on the motorshield that the arduino doesn't need. That doesn't seem to just work the way I expected.
I think I'm missing something? is there any way to use more I/O AND the motor shield?
I'm learning so much from you guys on this forum, thanks very much.
No doubt, the answer to this question will inspire another one, and I really appreciate the help. It's how I learn
Solved part of my own problem.. Small wiring issue.
This original latch now works trough the shield. the I/O is fine...
So I'm thinking that I'd like to add a forward/ reverse motor function with this latch. First time the latch is made, run motor in the forward direction. Next time the latch is HIGH it runs in reverse. I'll experiment and post some code for sharing.
OK. Me again.
Through experimenting, I learned that it is very difficult to keep track of how many "levels" deep you are into nested IF statements....
What I'm trying to do with this code is use the button latch to start a motor AND when it goes LOW, toggle the state of the direction of the motor.
Using this code, I can get the motor to run one way only, it won't toggle to the other direction.
See code here
#include "ArduinoMotorShieldR3.h"
ArduinoMotorShieldR3 md;
uint32_t start, dbStart;
const byte btn = 2, led = 7, dbTime = 15;
bool pinState = true,
btnState = true,
prevBtnState = true,
motorFW = true,
prevMotor = true, //last motor direction state true= forward, false= reverse
latch = false;
void setup() {
Serial.begin(115200);
Serial.println("Arduino Motor Shield R3");
md.init();
pinMode(btn,INPUT);
pinMode(led,OUTPUT);
}
void loop()
{
// debounce button ++++++++++++++++
if (digitalRead(btn) != pinState) // get state of pin 2
{
dbStart = millis(); // reset db timer
pinState = !pinState; // now they are equal, won't enter
} // here again unless pin state changes
if (millis() - dbStart > dbTime) // db timer has elapsed
btnState = pinState; // button state is valid
//+++++++++++++++++++++++++++++++++++
if(btnState != prevBtnState && btnState == HIGH) // btnState changed
{
// if button pressed and NOT latched
if(!latch)
{
latch = true; // prevents entry while latched
digitalWrite(led,HIGH);
//+++++++++++++++++++++++++++++++++++++ Motor control FWD
if(motorFW = true)
{
md.setM1Speed(400);
Serial.println("M1 Speed 100% Forward");
Serial.print("M1 current: ");
Serial.println(md.getM1CurrentMilliamps());
}
//++++++++++++++++++++++++++++++++++++ Motor control REV
else if(motorFW = false)
{
md.setM1Speed(-400);
Serial.println("M1 Speed 100% Backward");
Serial.print("M1 current: ");
Serial.println(md.getM1CurrentMilliamps());
}
}
else
{
// if button pressed while latched,
latch = false;
digitalWrite(led,LOW);
md.setM1Speed(0);
}
Serial.println("Motor off");
{
Serial.print( "LED is ");
if(latch)
{
Serial.println("ON");
}
else
{
Serial.println("OFF");
}
}
}
prevBtnState = btnState;
if (latch == false && motorFW == true) {
motorFW = false;
}
}
As an experiment, I indented the code for each next level of nested deepness... Hope this won't affect the outcome.
That direction latch should be so obvious to me but I can't see it.