I've got some of each of these, so we'll go through and try them each out one-by-one. Let's pick the digital inputs first.
To demonstrate this interface, I'm going to use a push-button switch. These things are everywhere. Most of mine were harvested from an old VCR. This is the simplest sensor for use with your arduino, because, well, the output is either 1 or 0. (We will ignore debounce for now.)
Since you can read the input simply by reading in the pin, the easiest thing to do would be to put this logic into your
loop()
routine and do it repetitively. Alternatively, you could set up an interrupt. Interrupts are special creatures that allow a routine (commonly referred to as an Interrupt Service Routine, ISR for short) to get called when a pin's state changes. By migrating your "on change" code into the ISR, you're doing less work on every loop.I'm deciding to go the interrupt path, because it allows me to demonstrate more things at once, and well, it sounds like more fun. My sketch will have a button that turns off our LED from the previous examples. The button will trigger the
toggleLed()
ISR. Also, for the sake of simplifying the electronics, the pin adjacent to the BUTTON_PIN
(I'm calling it DRIVE_PIN
) will be used to identify the button state and the button will be between the two pins. When the button is pressed, the BUTTON_PIN
will observe a low state (based on the state of the DRIVE_PIN
) and vice-versa. To ensure that the BUTTON_PIN
state is high by default, we are using internal pull-up resistors in the chip. The schematic for this set-up is below:/* * Push Button Test * */ #define LED_PIN 13 #define INTERRUPT_NUM 1 // This identifies the interrupt number for // our chipset: // 0 = digial pin 2 // 1 = digital pin 3 #define BUTTON_PIN 3 // set up the button pin to match the interrupt // number. #define DRIVER_PIN 4 // set up the a pin drive the button volatile int led_state = HIGH; // identify the current LED state // this is volatile because the toggleLed // routine which changes the value will be // called from an interrupt. void toggleLed() { // read in the current state of the button // and enable the LED state based on the button state led_state=digitalRead(BUTTON_PIN); // write the new state out to the LED pin digitalWrite(LED_PIN, led_state); } void setup() { // set up the same LED as we have been pinMode(LED_PIN, OUTPUT); // add the driver pin pinMode(DRIVER_PIN, OUTPUT); // set the driver pin to LOW digitalWrite(DRIVER_PIN, LOW); // add the driver pin pinMode(BUTTON_PIN, INPUT); // enable the pull-up register digitalWrite(BUTTON_PIN, HIGH); // Identify the routine and conditions for our interrupt. An interrupt // can have only one routine attached, and that routine takes no inputs // and returns no output. The specified routine will be called in // the midst of the normal loop processing, so any variables that are // changed should probably be marked as volatile, if they are real-time // critical. For our purposes, it's not necessary, but it may be // significant if we have more robust processing of data changed in an // interrupt routine. attachInterrupt(INTERRUPT_NUM, toggleLed, CHANGE); } void loop() { // nothing to do here, since it's all taken care of in the interrupt }
Now, we can control the state of the LED manually by pressing a button. This isn't earth shattering or particularly complex, but it does demonstrate a couple of principles (ISRs, Digital write, digital read, internal pull-up resistors.) Another interesting note is that you don't need to actually read the interrupt pin in the ISR, it could be used to trigger something completely different, like reading different pins' values, or enabling some additional behavior, or even waking up the arduino (think back to the sleep mode we entered in the last post).
No comments:
Post a Comment