arduino:arduino_crash_course:digital_input
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
arduino:arduino_crash_course:digital_input [2012/11/04 19:10] – mithat | arduino:arduino_crash_course:digital_input [2017/12/06 01:13] (current) – [Digital Input] mithat | ||
---|---|---|---|
Line 3: | Line 3: | ||
The Arduino literature refers to " | The Arduino literature refers to " | ||
- | An Arduino digital input is one that responds to two different levels; anything above a certain | + | An Arduino digital input is one that responds to two different levels: anything above a certain |
<WRAP center round important 60%> | <WRAP center round important 60%> | ||
Line 9: | Line 9: | ||
</ | </ | ||
- | Typically, digital input signals are designed so that when HIGH they have a value equal to the supply voltage and when LOW they are equal to 0 volts. | + | Digital output |
- | We've already seen an example of Arduino digital inputs in the [[arduino: | + | We've already seen an example of Arduino digital inputs in the [[arduino: |
- | FIXME with const and boolean | + | We have also added the '' |
- | ===== Toggling state ===== | + | <file c LightSwitchPullup2a.ino> |
- | + | ||
- | Below is an attempt to write an Arduino program that //toggles// power to an LED when a button is pressed. In other words, if the button is pressed and the LED is off, it should turn on; when the button is pushed again, the LED should turn off. | + | |
- | + | ||
- | To implement this functionality, | + | |
- | + | ||
- | Our first attempt at writing the program is below. Be cautioned that it won't work as expected. It is logically correct, but it doesn' | + | |
- | + | ||
- | <file c NumPushes.ino> | + | |
/* | /* | ||
- | NumPushes | + | LightSwitchPullup2a |
- | Count the number of times a push button is pushed | + | Turn an LED on and off. |
+ | | ||
*/ | */ | ||
const int pushButtonPin = 2; // connect the push button to digital pin 2 | const int pushButtonPin = 2; // connect the push button to digital pin 2 | ||
- | int numPushes | + | const int ledPin |
- | int lastButtonState = LOW; // value of buttonState from previous loop iteration | + | boolean buttonState; // stores current button state |
void setup() { | void setup() { | ||
- | Serial.begin(9600); | ||
- | |||
pinMode(pushButtonPin, | pinMode(pushButtonPin, | ||
digitalWrite(pushButtonPin, | digitalWrite(pushButtonPin, | ||
+ | pinMode(ledPin, | ||
} | } | ||
void loop() { | void loop() { | ||
- | | + | buttonState = digitalRead(pushButtonPin); |
- | // if button goes down and before it was high... | + | // set LED state accordingly |
- | | + | // note the inverted logic resulting from using pullup resistors. |
- | // increment numPushes by 1 | + | |
- | numPushes++; | + | |
- | + | ||
- | | + | |
- | Serial.print(" | + | |
- | Serial.print(numPushes); | + | |
- | Serial.println(" | + | |
- | } | + | |
- | + | ||
- | lastButtonState = buttonState; | + | |
} | } | ||
</ | </ | ||
+ | |||
+ | ===== Toggling state ===== | ||
+ | |||
+ | Below is an attempt to write an Arduino program that //toggles// power to an LED when a button is pressed. In other words, if the pushbutton is pressed while the LED is off, it should turn on; when the pushbutton is pressed again, the LED should turn off. | ||
+ | |||
+ | To implement this functionality, | ||
+ | |||
+ | Our first attempt at writing the program is below. Be cautioned that it won't work as expected. It is logically correct, but it doesn' | ||
<file c LightToggleLogic.ino> | <file c LightToggleLogic.ino> | ||
Line 79: | Line 70: | ||
boolean buttonState = digitalRead(pushButtonPin); | boolean buttonState = digitalRead(pushButtonPin); | ||
- | // if button goes down and before | + | // if button goes down and previously |
if (buttonState == LOW && lastButtonState == HIGH) { | if (buttonState == LOW && lastButtonState == HIGH) { | ||
if (ledState == HIGH) // toggle LED | if (ledState == HIGH) // toggle LED | ||
Line 88: | Line 79: | ||
digitalWrite(ledPin, | digitalWrite(ledPin, | ||
} | } | ||
- | | + | |
lastButtonState = buttonState; | lastButtonState = buttonState; | ||
} | } | ||
Line 97: | Line 88: | ||
==== Software debouncing ==== | ==== Software debouncing ==== | ||
- | A very simple approach debouncing is to introduce a delay whenever a relevant switch press is detected. The amount of delay will vary from switch to switch, so experimentation will likely be required. | + | A very simple approach |
- | + | ||
- | FIXME | + | |
<file c LightToggleDebounced.ino> | <file c LightToggleDebounced.ino> | ||
Line 114: | Line 103: | ||
boolean lastButtonState = HIGH; // value of buttonState from previous loop iteration | boolean lastButtonState = HIGH; // value of buttonState from previous loop iteration | ||
boolean buttonState = HIGH; | boolean buttonState = HIGH; | ||
+ | |||
+ | boolean debounce(int pinNum) { | ||
+ | delay(debounceTime); | ||
+ | return digitalRead(pinNum); | ||
+ | } | ||
void setup() { | void setup() { | ||
Line 120: | Line 114: | ||
pinMode(ledPin, | pinMode(ledPin, | ||
digitalWrite(ledPin, | digitalWrite(ledPin, | ||
- | } | ||
- | |||
- | boolean debounce(boolean lastState) { | ||
- | boolean nowState = digitalRead(pushButtonPin); | ||
- | if (lastState != nowState) { | ||
- | delay(debounceTime); | ||
- | nowState = digitalRead(pushButtonPin); | ||
- | } | ||
- | return nowState; | ||
} | } | ||
void loop() { | void loop() { | ||
- | buttonState = debounce(lastButtonState); // read the input pin | + | buttonState = debounce(pushButtonPin); // read the input pin |
- | // if button goes down and before | + | // if button goes down and previously |
if (buttonState == LOW && lastButtonState == HIGH) { | if (buttonState == LOW && lastButtonState == HIGH) { | ||
- | buttonState = digitalRead(pushButtonPin); | ||
- | |||
ledState = !ledState; | ledState = !ledState; | ||
} | } | ||
Line 146: | Line 129: | ||
</ | </ | ||
- | More elaborate debouncing techniques have also been used. For example, you can measure the time between HIGH-to-LOW or LOW-to-HIGH transitions and when they have gotten long enough you can assume that the switch is no longer bouncing. We leave the reader to research and explore these. | + | More elaborate debouncing techniques have also been used. For example, you can measure the time between HIGH-to-LOW or LOW-to-HIGH transitions and when they have gotten long enough you can assume that the switch is no longer bouncing. We leave it to the reader to research and explore these. |
- | === Using a user-defined | + | === User-defined |
- | + | ||
- | The following example takes the example above and places the switch reading and debouncing code into its own **function**. One advantage of doing this is that it creates more clarity in the code by allowing us to give a good name to the process it encapsulates. Another reason is that it makes it easier to change and experiment with different debouncing algorithms. Yet another reason is that it gives you a clear block of code that you can re-use in other projects. | + | |
- | + | ||
- | TODO | + | |
+ | The the example above places the switch reading and debouncing code into its own **function**. One advantage of doing this is that it creates clarity in the code by allowing you to give a good name to the process you have encapsulated. Another reason is that it makes it easier to change and experiment with different algorithms for, in this case, debouncing. Yet another reason is that it gives you a clear block of code that you can re-use in other projects. | ||
==== Hardware debouncing ==== | ==== Hardware debouncing ==== | ||
- | Debouncing switch contacts in software is appealing because of its cost: since it's done entirely in software, there are no added hardware expenses. However, often times you will not be able to use software debouncing. For example, because of the Arduino' | + | Debouncing switch contacts in software is appealing because of its cost: since it's done entirely in software, there are no added hardware expenses. However, often times you will not be able to use software debouncing. For example, because of the Arduino' |
There are many approaches that have been taken to debouncing switches in hardware. These will not be covered here, but a Web search for the topic should lead you to a number of options. | There are many approaches that have been taken to debouncing switches in hardware. These will not be covered here, but a Web search for the topic should lead you to a number of options. | ||
===== Multiple state ===== | ===== Multiple state ===== | ||
- | (multiple lights on/off) | ||
+ | The example above is a program that is essentially in of two states: the LED is on or off. Below are two examples where the program has multiple states. The first is a timer-driven and the second a push-button driven three-light blinky-thing. | ||
+ | |||
+ | <file c MultipleLEDsTimer.ino> | ||
+ | /* | ||
+ | | ||
+ | Cycle through three LEDs with a timer. | ||
+ | */ | ||
+ | |||
+ | const int delayTime = 500; // time to wait between LED changes | ||
+ | const int led0 = 13; // connect an LED to pin 13 | ||
+ | const int led1 = 12; // connect an LED to pin 12 | ||
+ | const int led2 = 11; // connect an LED to pin 11 | ||
+ | |||
+ | int ledState; | ||
+ | |||
+ | void setup() { | ||
+ | // make LED pins outputs | ||
+ | pinMode(led0, | ||
+ | pinMode(led1, | ||
+ | pinMode(led2, | ||
+ | |||
+ | // initialize state | ||
+ | ledState = 0; | ||
+ | | ||
+ | // turn the correct LED on and the others off | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | delay(delayTime); | ||
+ | ledState = (ledState + 1) % 3; // cycle through 0,1,2 | ||
+ | |||
+ | // turn the correct LED on and the others off | ||
+ | if (ledState == 0) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else if (ledState == 1) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else if (ledState == 2) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else // turn all LEDs on to indicate an error state. | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file c MultipleLEDsPushButton.ino> | ||
+ | /* | ||
+ | | ||
+ | Cycle through three LEDs with a pushnutton | ||
+ | */ | ||
+ | |||
+ | const int pushButtonPin = 2; // connect the push button to digital pin 2 | ||
+ | const int led0 = 13; // connect an LED to pin 13 | ||
+ | const int led1 = 12; // connect an LED to pin 12 | ||
+ | const int led2 = 11; // connect an LED to pin 11 | ||
+ | |||
+ | const int debounceTime = 5; // number of millisecods to delay after button press | ||
+ | |||
+ | int ledState; | ||
+ | boolean lastButtonState = HIGH; // value of buttonState from previous loop iteration | ||
+ | boolean buttonState = HIGH; // start by assuming button is unpressed | ||
+ | |||
+ | boolean debounce(int pinNum) { | ||
+ | delay(debounceTime); | ||
+ | return digitalRead(pinNum); | ||
+ | } | ||
+ | |||
+ | void setup() { | ||
+ | pinMode(pushButtonPin, | ||
+ | digitalWrite(pushButtonPin, | ||
+ | |||
+ | // make LED pins outputs | ||
+ | pinMode(led0, | ||
+ | pinMode(led1, | ||
+ | pinMode(led2, | ||
+ | |||
+ | // initialize state | ||
+ | ledState = 0; | ||
+ | | ||
+ | // turn the correct LED on and the others off | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | buttonState = debounce(pushButtonPin); | ||
+ | |||
+ | // if button goes down and previously it was high... | ||
+ | if (buttonState == LOW && lastButtonState == HIGH) { | ||
+ | ledState = (ledState + 1) % 3; // cycle through 0,1,2 | ||
+ | } | ||
+ | |||
+ | // turn the correct LED on and the others off | ||
+ | if (ledState == 0) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else if (ledState == 1) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else if (ledState == 2) | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | else // turn all LEDs on to indicate an error state. | ||
+ | { | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | | ||
+ | lastButtonState = buttonState; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Switch-case selection structure ===== | ||
+ | |||
+ | Both examples above use the //nested if-else// selection structure. Arduino' | ||
+ | |||
+ | <file c MultipleLEDsTimer2.ino> | ||
+ | /* | ||
+ | | ||
+ | Cycle through three LEDs with a timer. | ||
+ | This version uses a switch-case selection structure. | ||
+ | */ | ||
+ | |||
+ | const int delayTime = 500; // time to wait between LED changes | ||
+ | const int led0 = 13; // connect an LED to pin 13 | ||
+ | const int led1 = 12; // connect an LED to pin 12 | ||
+ | const int led2 = 11; // connect an LED to pin 11 | ||
+ | |||
+ | int ledState; | ||
+ | |||
+ | void setup() { | ||
+ | // make LED pins outputs | ||
+ | pinMode(led0, | ||
+ | pinMode(led1, | ||
+ | pinMode(led2, | ||
+ | |||
+ | // initialize state | ||
+ | ledState = 0; | ||
+ | |||
+ | // turn the correct LED on and the others off | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | delay(delayTime); | ||
+ | ledState = (ledState + 1) % 3; // cycle through 0,1,2 | ||
+ | |||
+ | // turn the correct LED on and the others off | ||
+ | switch (ledState) { | ||
+ | case 0: | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | break; | ||
+ | case 1: | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | break; | ||
+ | case 2: | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | break; | ||
+ | default: | ||
+ | digitalWrite(led0, | ||
+ | digitalWrite(led1, | ||
+ | digitalWrite(led2, | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | </ |
arduino/arduino_crash_course/digital_input.txt · Last modified: 2017/12/06 01:13 by mithat