Arduino Forum

Using Arduino => Introductory Tutorials => Topic started by: groundFungus on Nov 01, 2020, 06:47 pm

Title: state change detection in the 21st century
Post by: groundFungus on Nov 01, 2020, 06:47 pm
I often point new users to the State Change Detection example (https://www.arduino.cc/en/Tutorial/BuiltInExamples/StateChangeDetection).  That example is great for teaching about edge detection but uses a momentary switch with an external pull-down resistor.  Using the same switch, but with the internal pullup enabled and wired to ground is better practice (in most cases).  Enable the internal pullup (https://www.arduino.cc/en/Tutorial/DigitalInputPullup) with pinMode (https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/):
Code: [Select]
pinMode(pin, INPUT_PULLUP);

The switch is wired as shown.  The resistor is not required if the internal pullup is used, but may be necessary if the switch is at the end of long wires. Stronger pullup with lower resistor values (min. 1K).  The cap is optional, but will provide some hardware debounce and if the switch is at the end of long wires can filter noise that can cause false indications.  Also shown is the safe way to wire the ever popular 6mm tactile switches.
(https://forum.arduino.cc/index.php?action=dlattach;topic=711767.0;attach=387741)

Here is the code from the example modified to use the internal pullup and ground for an active LOW switch.  Active LOW means that the switch is LOW when closed (pressed) and HIGH when open (not pressed).
Code: [Select]

/*
The circuit:
   - pushbutton attached to pin 2 from ground
   - the internal pullup on pin 2 is enabled
   - LED attached from pin 13 to ground (or use the built-in LED on most
    Arduino boards)
*/

// this constant won't change:
const byte  buttonPin = 2;    // the pin that the pushbutton is attached to
const byte ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

void setup()
{
   // initialize the button pin as a input:
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   pinMode(ledPin, OUTPUT);
   // initialize serial communication:
   Serial.begin(9600);
}


void loop()
{

   static unsigned long timer = 0;
   unsigned long interval = 20;
   if (millis() - timer >= interval)
   {
      timer = millis();
     
      // read the pushbutton input pin:
      buttonState = digitalRead(buttonPin);

      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         // if the state has changed, increment the counter
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button went from off to on:
            buttonPushCounter++;
            Serial.println("on");
            Serial.print("number of button pushes: ");
            Serial.println(buttonPushCounter);
         }
         else
         {
            // if the current state is HIGH then the button went from on to off:
            Serial.println("off");
         }
          // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
      }
      // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
   }

   // turns on the LED every four button pushes by checking the modulo of the
   // button push counter. the modulo function gives you the remainder of the
   // division of two numbers:
   if (buttonPushCounter % 4 == 0)
   {
      digitalWrite(ledPin, HIGH);
   }
   else
   {
      digitalWrite(ledPin, LOW);
   }

}


Please see here for further information on hardware and software debounce. (http://www.skillbank.co.uk/arduino/switchbounce.htm)
Title: Re: state change detection in the 21st century
Post by: TheMemberFormerlyKnownAsAWOL on Nov 04, 2020, 09:38 pm
Code: [Select]
buttonState = digitalRead(buttonPin); In the 21st century, "buttonState" doesn't have global scope (it wouldn't be a Boolean either)
Title: Re: state change detection in the 21st century
Post by: fionning_macara on Nov 05, 2020, 04:11 am
Why not Boolean?

Title: Re: state change detection in the 21st century
Post by: TheMemberFormerlyKnownAsAWOL on Nov 05, 2020, 08:49 am
Why not Boolean?


Because digitalRead returns an int, and LOW and HIGH are not boolean values.
Title: Re: state change detection in the 21st century
Post by: fionning_macara on Nov 05, 2020, 10:36 am
Fair enough ;)

Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 07, 2020, 10:46 am
I don't understand the comment about wiring diagonally to avoid a short? Isn't it sometimes more convenient to wire 'laterally', i.e. on same side of the button?
Title: Re: state change detection in the 21st century
Post by: fionning_macara on Nov 07, 2020, 11:09 am
Diagonals are always switched, so it's a good way to guarantee you don't connect two wires permanently as would happen if you accidentally used terminals 3 and 4 in the red box below for example.


(http://forum.arduino.cc/index.php?action=dlattach;topic=526076.0;attach=243722)
Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 07, 2020, 11:59 am
Thanks, understood. So avoiding connecting the opposite pins on the longer sides. I still occasionally find it convenient to wire between 2 & 4 or 1 & 3.
Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 07, 2020, 12:05 pm
@groundFungus: What tool do you use for your neat schematics please?
Title: Re: state change detection in the 21st century
Post by: groundFungus on Nov 07, 2020, 02:21 pm
Quote
What tool do you use for your neat schematics please?
I use Express Sketch which comes with the EspressPCB software. (https://www.expresspcb.com/)  I downloaded it years ago.  Don't know how the newest is, but I love the older one that I have.  I used to use OrCad but since I no longer work for a company I can't afford it.
Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 07, 2020, 02:49 pm
Thanks. I'm using a program that's probably even older, CircuitMaker Pro, but I'll take a close look at Express Sketch.

Staying OT for a minute, do you also use the Fritzing app BTW, that I see mentioned frequently?
Title: Re: state change detection in the 21st century
Post by: groundFungus on Nov 07, 2020, 02:57 pm
I have used Fritzing, but only to make simple PC boards* (I route them on my little CNC router).  Fritzing will generate the Gerber files for free.   Express PCB charges for Gerber files.  I  do not use the Fritzing breadboard view or schematic drawing.  People don't like Fritzing breadboard views, generally, because they leave out a lot of information that would be on a good schematic. 

*I find Eagle and KiCad too complex for the simple boards that I make.
Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 09, 2020, 12:49 pm
@groundFungus,

Trying your sketch while learning about states.
LED is ON after start or reset. One press takes it OFF. Three more presses (four in total) takes it ON again.

Is that the intended behaviour? How would I change it to be OFF at the start, please, awaiting four presses? I tried taking the LED low during Setup but that didn't do it.
Title: Re: state change detection in the 21st century
Post by: larryd on Nov 09, 2020, 03:29 pm
" I tried taking the LED low during Setup but that didn't do it."

@ Terrypin

When you try something and still have trouble, always show us 'what' you tried.




Use CTRL T to format your code.
Attach your 'complete' sketch between code tags

[code]Paste your sketch here[/code]
 



Title: Re: state change detection in the 21st century
Post by: groundFungus on Nov 09, 2020, 06:07 pm
Quote
How would I change it to be OFF at the start, please
All of the LED action takes place in the last few lines of the program.
Code: [Select]
if (buttonPushCounter % 4 == 0)
Until the first button press, buttonPushCounter = 0.  0 % 4 = 0 so the LED is HIGH. 
Unless the buttonPushCounter is greater than 0 do not turn the LED on.

Code: [Select]
if (buttonPushCounter % 4 == 0 && buttonPushCounter > 0)
   {
      digitalWrite(ledPin, HIGH);
      }
   
   else
   {
      digitalWrite(ledPin, LOW);
   }
Title: Re: state change detection in the 21st century
Post by: Terrypin on Nov 09, 2020, 08:52 pm
All of the LED action takes place in the last few lines of the program.
Code: [Select]
if (buttonPushCounter % 4 == 0)
Until the first button press, buttonPushCounter = 0.  0 % 4 = 0 so the LED is HIGH.  
Unless the buttonPushCounter is greater than 0 do not turn the LED on.

Code: [Select]
if (buttonPushCounter % 4 == 0 && buttonPushCounter > 0)
   {
      digitalWrite(ledPin, HIGH);
      }
  
   else
   {
      digitalWrite(ledPin, LOW);
   }

Thanks, understood.
Title: Re: state change detection in the 21st century
Post by: windoze_killa on Nov 17, 2020, 04:25 am
*I find Eagle and KiCad too complex for the simple boards that I make.
I have used Altium for years but since I am trying to avoid Windoze like the plague and I am now using Linux I have installed KiCad and for a freebie it is awesome. Maybe a bit complex for simple stuff but I make some not quite so simple stuff.
Title: Re: state change detection in the 21st century
Post by: dougp on Dec 17, 2020, 10:39 pm
Code: [Select]
buttonState = digitalRead(buttonPin);
 In the 21st century, "buttonState" doesn't have global scope (it wouldn't be a Boolean either)
+ reply #3


Would bool buttonState = (bool) digitalRead(buttonPin); be more correct?
Title: Re: state change detection in the 21st century
Post by: TheMemberFormerlyKnownAsAWOL on Dec 17, 2020, 10:41 pm
Code: [Select]
bool buttonState = digitalRead(buttonPin) == HIGH; Might be. Or maybe even "== LOW"
Title: Re: state change detection in the 21st century
Post by: runaway_pancake on Jan 03, 2021, 04:29 am
Is the issue bad form?

If my sketch has --
bool pbState;
and 
pbState = digitalRead(pb);
then

if (pbState)

works [correlating 1, HIGH, true; 0, LOW, false)]
Title: Re: state change detection in the 21st century
Post by: aarg on Jan 14, 2021, 04:18 am
If truth be told, HIGH and LOW are very prosaic names. If they weren't already all over the Arduino planet, I'd be quite happy using 0 and 1 for I/O states.
Title: Re: state change detection in the 21st century
Post by: larryd on Jan 14, 2021, 04:27 am
_5volts
_0volts



VCC
GND


:D



Title: Re: state change detection in the 21st century
Post by: TheMemberFormerlyKnownAsAWOL on Jan 14, 2021, 08:50 am
_5volts
_0volts



No - discriminatory towards the 3.3V variants :D
Title: Re: state change detection in the 21st century
Post by: lastchancename on Jan 14, 2021, 10:41 am
Just being pedantic...

It would be nice to flip your initial schematics horizontally to depict signal flow from left to right...
Just a thought to introduce the learners to logical schematic layout.

You did well with positive higher, and negative lower.

Sorry !