NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Turn on LED with Button won't work
March 25, 2011 by lnino |
Hi at all. After I have compelted my Nerdkits Guide I tried to start a new small project, but i got stuck. Here is what I tried: I have two LEDs on my Breadboard. The green one turns on and off all the time, because its in the while(1). The red one should be turned on when I push a button. And here is my problem: The red Led won't turn on. Something wrong with my interrupt? Because when I push the button the green led freezes for a short time. The components are connected on my breadboard like this: The green LED is connected with the cathode to GND and with anode to Pin 27 (PC4) of the mCU. The red LED is connected with the cathode to GND and with anode to Pin 26 (PC3) of the MCU. The button(included in the nerdkit) is connected with C to GND and NO to Pin 24 (PC1) of the MCU. (If this is to few, I can't make a photo of my breadboard) Can anybody figure out what I have made wrong? Thanks for the help. Here is my source code:
|
---|---|
March 25, 2011 by Noter |
Maybe you should debounce your switch or change the logic in the interrupt from toggling to just be on if the switch is closed, off if the switch is open. Also, your code would read easier if you used (1<<PC3) or _BV(PC3) instead of binary constants. |
March 25, 2011 by Ralphxyz |
Noter, where does that _BV() syntax come from? I know it comes from a C library as a Macro but where, and do you have any reference tutorials on using that/those macros? Ralph |
March 25, 2011 by bretm |
It comes from an internal header in avr-libc that gets pulled in when you reference io.h. It means Bit Value and _BV(x) is the same as (1<<(x)) |
March 25, 2011 by Noter |
Some people think it's a bad idea to use _BV but I like it. If I ever need it on another platform and it's not in the system include files, I'll just define it in somewhere in my code like this.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=48246&start=0 |
March 25, 2011 by lnino |
@ Notar: Can you give me an example of your idea? I am not that familiar with this area. |
March 25, 2011 by Noter |
I didn't run it so don't hold it against me if it doesn't work but this is the general idea. See if the led lights and goes out with the button.
As for debouncing a switch, search the forum there are previous posts with examples. |
March 25, 2011 by bretm |
PCINT0_vect corresponds to PORTB. To catch PORTC changes use PCINT1_vect (I think, don't have datasheet in front of me). In Noter's example, use PINC to read port C pins, not PORTC. But PCINT0_vect was probably your problem. I wouldn't attach a pin-change interrupt to a button that didn't have hardware debouncing. The button will bounce many times and generate many interrupts, possible overlapping and missing up your logic. Either use software debouncing without pin-change interrupts, or hardware debouncing with or without interrupts. |
March 25, 2011 by lnino |
Thanks bretm. That was the mistake. I have two additional questions: 1) The button won't react good on my pushes. I have read that you have to put a delay on the button for this reason. But it won't work well. How can I put it in my code to have a working button? 2) If I put a second and a third button on my breadboard, which should do completely different things, like turn on different LEDs. Button 1 turns on LED1(red), Button 2 turns on LED2(green) and so on. How can I make a selection in my code to find out which button has been pressed and which reaction has to be done? I have realized that some time ago on a atxmega128, but how can I use this method on my atmega168? Here is my old code from my atxmega128:
|
March 26, 2011 by leedawg |
I dont think I totally understand your second question? Are you just simply trying to set up multiple switchs to turn on and off different LEDs attatched to the microcontroller? Or are you trying to read the state of each of these switchs? In any case I use if statements and variables to turn on and off things I find it works pretty well. As for question #1 I can help you with that. I had the same problem the button did not seem to work very well when I pressed it so I added a variable and put it out to the LCD screen to see what was going on and it turns out the interupt was firing about 30 or 40 times for each button press just simply due to the bouncing of the contacts inside the switch. It does not feel like it bounces but it does when your talking about the MCU running at 14.74 mhz. To solve this problem I found some by noter actually that uses a timer to control the debounce it works very well. Here is the code that I used.
This should straighten out the problems your having in your first question. Here is an example of how I turn things on and off however. I would define a variable in your init main() function such as toggle. Then set up a while statement that uses that variable and use your external interrupt to increment that variable from 0 to 1 and then simply have a line that resets the variable back to zero if it is greater than 1. So here is example of what im talking about.
Of course you would need to add to this code so that your interupt command would say increment the variable toggle up each time you have a button push and presto you are now toggling your code on and off. Alternatively you could use if statements one for on and one for off to turn the led on and off based on what you have incremented the variable to. for example
I hope this helps a little bit with both questions. Just ask on here and search I to just a few months ago was completely mystified on how to make most things happen in the avr. Just dont give up and keep trying things ive learned tons by doing that and am just starting to feel comfortable with the basics. Good luck. Lee |
March 26, 2011 by lnino |
what i have meant with my second question is the following. i want to have for example 10 buttons. every button has a different job. button one should display a 1 on the display. button 2 should display a 2 on the display. and so on. how can i realize that? thank you for your help. |
March 26, 2011 by leedawg |
oh well that should be pretty easy to do. You just want each button to write a number to the display. I would just simply define a variable then of whatever your liking is. And then just write a bunch of if statments that say if button 1 is pressed set variable equal to the number you want on the display. Then add a line at the end of the loop that will write out that variable that you are changing each time to the LCD. SO something kinda like this.
Now this is most of the code but it might not run because I may have made a mistake but you get the idea. You will of course need to put in your calls for all the necessary libraries and what have you so that it all compiles the right way and if I made some typos or did not define something properly your compiler will let you know but this is how I would accomplish what you were asking in your last post. Lee |
March 26, 2011 by Ralphxyz |
You probable will want to use a switch/case statement instead of 10 if/else statements though the if/else will work. Google C switch. Ralph |
March 27, 2011 by lnino |
Thanks for your replies. If I want additional to the output on my display that every button turns on a different LED. Can I solve this challenge also completely in the while(1) situation(like leedawg did), or do I have to use interrupts? Might this be a right thought?
I hope to get close my computer the next days to realise a programm included with you thoughts and help. |
March 27, 2011 by leedawg |
Again I dont think I understand your question. Are you saying you want to switch an LED on in addition to displaying which LED should be switched on, on your LCD screen? If this is the case you could simply just add the code to switch the pin on which ever LED you have connected to it under the respective if statments in your code or as ralph said a switch case setup. So you would just simply add something like
So this would then output the number 1 to your variable set as button and in addition do that switch on pin PC3 on the microcontroller and you would have some particular led attatched to that pin. Hope that answers your question. Lee |
March 28, 2011 by lnino |
Hi leedawg, thank you for your reply. I think now I can handle it. You can realise this challenge in the while(1) and as a interrupt. What would be the advantage/disadvantages of the while(1) version and the advantage/disadvantages of the interrupt version? Sorry for my english, but this is not my native language. Thanks a lot. |
March 28, 2011 by Ralphxyz |
One of the advantages to using interrupts is that your mcu can be doing other things while waiting to be interrupted. Doing all of your processes in the while() dedicates processor resources to "polling" your button. Both methods can be effective and useful and have had lots of deep discussions on the web. I am sure there are other explanations from people who actually know what they are talking about. Your English is fine and you are most welcome to practice here. Ralph |
March 29, 2011 by lnino |
Hi Ralph, thanks for you reply and your nice words. I was now able to realize my challenge. Now the button is doing what i want when I press it and I can go forward with my intention. |
Please log in to post a reply.
Did you know that 20 LEDs can be controlled from 11 microcontroller pins, to make a twinkling heart outline? Learn more...
|