0

I am new to AVR, but i have programmed PICs before, only this time i am doing everything in linux too so you'll guess that i am using avrdude...

My goal for this project is to change a bicolor LED's color depending on a certain state.

By default, the led is RED (if you make the connections right of course), then i want it to go to yellow (which is a quick change between green and red) while the user is holding the button down then on release, it will go to green, then the next time it will turn off.

So, to recap,

LED is red

While i hold the button down its gonna be yellow

When i release it will be green

While i hold the button down again its gonna be yellow

When i release it will be off

While i hold the button down again its gonna be yellow

When i release it will be red (and so on...)

In my actual code, everything works really well sometimes, but sometimes the led gets stuck at yellow and i have no clue why

Any ideas?

Code is on ideone : http://ideone.com/LI9gH

Thanks

Dany Khalife
  • 1,850
  • 3
  • 20
  • 47

2 Answers2

1

I don't know where the problem is, but I can suggest an alternative approach if that helps. :-)

Because you're cycling through a sequence of LED states, you could merely list them in an array and step along it (wrapping around when you reach the end), updating the LED each time, whenever the button state changes.

EDIT:

Here's an alternative:

colours = [red, yellow, green, yellow, off, yellow]
current button = released
state = 0
repeat
    check button
    if button != current button
        current button = button
        state += 1
        if state >= len(colours)
            state = 0
    // showing the colour sets the LED and includes a delay
    show colours[state]
MRAB
  • 20,356
  • 6
  • 40
  • 33
  • 1
    thanks, i'll try that, (also what i posted is my 2nd approach of the same issue and with merely the same effect :D) do you think it could be hardware-related ? – Dany Khalife Jan 28 '12 at 02:11
1

I'm guessing you're simply seeing the random generator missing the button changes about 1/3rd of the time, because the debouncing is slightly off. Consider the time spent in different states:

check button
wait 10ms
check button again
if button values differ, update state
if yellow
  shine red for 1ms
  shine green for 4ms then leave green on
otherwise
  set current color

That's your main loop. As you can see, it checks the button in two instants during about 15ms time; and it doesn't compare to the last value for which it updated state, only with the value 10ms prior. Release the button during the 5ms period of "yellow", and allumerAmbre will not reset until the next release that happens to fall in the 10ms period. Also, the yellow wound up 1/15 red, possibly not the mix you intended.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
  • Thanks, that's very enlightening. So if i understood right, you're saying i should do another check of the button somehow during the yellow state ? oh and thanks for the remark about my yellow mix, you are actually right :) – Dany Khalife Jan 28 '12 at 15:47
  • 1
    I suggest you stop checking for the transition itself (lecture1 != lecture2) and instead check for the button to stabilize in the new state, whether that's pressed or not (information you already had in allumerAmbre). Also, look up a good article on [button debouncing](http://electronics.stackexchange.com/questions/6884/debouncing-buttons). – Yann Vernier Jan 28 '12 at 20:57
  • thanks @Yann , i think i got through my problem with your all suggestions! I completely rewrote the part where it checked for the transition and replaced it with a while(); and it seems to be working like a charm ! i'll post back in case i run into problems but i think its good, thanks again :) – Dany Khalife Jan 29 '12 at 00:37