To know the road ahead, ask those coming back ~ Anonymous

Making your designs Interactive using Switches- avrPrayog #2

We design systems that interacts, interaction is the most important thing in our lives. Just try to imagine a situation where you can't communicate with your machine. We like interactive things, whatever it may be toys, machines, people, Girls etc. So we are here to design interactivity.

It's a wireless age, yes i am talking about 21st century, but 20th century was button age. Now, we interact with our machines by means of wireless techniques, still buttons and switches are still there in most of the machines as a reliable old friend, because buttons are still a very nice and reliable way of interacting with machines. So this tutorial teach you exactly how can you use buttons to make your electronics designs interactive. (See, Interactive here implies to the responsiveness)

In case of taking input at any of the pins of controller it is very neccessary to externally or internally pullup the pin. Pull up is basically a resistance of about 10K which is used to pull the input pin in high state when the switch is not pressed. It is necessary because avrPrayog can be programmed to detect change in logic condition and respond to that, for that there should be an initial state, we achieve that initial state of High logic using Pull up resistor, when you press the switch logic goes LOW and avrPrayog detects the change in logic at its pins. Here we are using AVR microcontroller (avrPrayog board uses an ATmega8 running at 16MHz) which has internel pull-ups so no need to use external one.

In order to read from a PIN of AVR MC, it must be programmed as input. While a pin of AVR MC is in input configuration it does not drive the port pin and the port pin is said to be floating. A floating pin can be taken to any voltage level by even a weak drive or EMI. So our input pin must have some initial fixed logic state which is achived using pull up resistor, which is inbuilt in AVR MC.

To enable the internal Pull Ups of an AVR while using it as input; configure that pin (input pin(n)) as input (DDRx(n)=0) and write a logic '1' on that pin initially.

Showing a basic circuit towards right, showing the concept of Pull Up resistor, are you able to get the idea, Literally “PULL-UP”, Pull it UP !

Enough talks, Show me the code !

Ohh is it? then take it, see it and try to understand it !

#include <avr/io.h>
#define LED 1 // LED connected to PORTD_1
#define SWT 3 // Switch connected to PORTD_3
int main(void)
{
    DDRD =  1<<LED | ~(1<<SWT);  // LED Pin as output Switch pin as input
    PORTD = 1<<SWT;  // LED Off, Pull Up for Switch
    while(1)
    {
        if(!(PIND&(1<<SWT)))
        {
             PORTD |= 1<<LED; // remember 'OR'ing with 0 does not affect
        }
        else
        {
             PORTD &= ~(1<<LED); // and 'AND'ing with 1 doest not affect
        }
    }
    return 0;
}

Switch Press Program without Debounce

Lots of bit wise stuff

If you got all the bit wise tricks used in above code, you are awesome ! but those who have not got few or any of them, You are Suupper awesome, because you are my potential reader for next few lines or paragraphs

So, Let me explain it one by one…

trying to explain, PORTx |= 1<<Y ?

Doing some Software Tricks to achieve switch debounce

when we press a mechanical switch, we think that it goes pressed for only once, but when we look the phenomenon in a microscopic way, it get pushed many times, which results in a undetermined state at last and this shown an abnormal behaviour when interfaced with the MCU. So to get rid off this problem concept of debounce is used.

Figure showing the actual response of switch when debouncing isn't used

Debounce can be implemented in two ways

  • Hardware Debounce - Using a series RC network
  • Software Debounce - Using coding tricks

Hardware Debounce Circuit

Software Debouncing

#include <avr/io.h>
#include <util/delay.h>
#define LED 1 // LED connected to PORTD_1
#define SWT 3 // Switch connected to PORTD_3
#define toggle(x,y) x^=1<<y;
int main(void)
{
    DDRD =  1<<LED | ~(1<<SWT);  // LED Pin as output Switch pin as input
    PORTD = 1<<SWT;  // LED Off, Pull Up for Switch
    while(1)
    {
        if(!(PIND&(1<<SWT)))     // Check if switch is pressed
        {
            while(!(PIND&(1<<SWT)));   // Wait for switch release
            _delay_ms(10);             // Give a small delay
            toggle(PORTD,LED);         // Toggle the LED
        }
    }
    return 0;
}

Switch Debouncing

Downloads


Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 72 bytes) in /home/electroo/public_html/wiki/inc/auth/plain.class.php on line 290