Go Down

Topic: Current in opposite directions (bicolor LED) (Read 2039 times) previous topic - next topic



How can one pass current in two directions simultaneously from the Arduino to get yellow out of a red/green LED?

So far I have been able to get this LED to light up red and green by setting two digital outputs to HIGH+LOW and LOW+HIGH, respectively.  Unsurprisingly setting them both to HIGH or LOW does nothing. =(

Thank you!


You have to switch the HIGH/LOW and LOW/HIGH combinations very quickly.  When using the SX28 I do this with an interrupt; I'm not sure how to do it cleanly with the Arduino yet.


Thanks Jon; alternating quickly in my loop() works well.  I will look into interrupts for doing this.


Dec 30, 2007, 05:01 am Last Edit: Dec 30, 2007, 05:04 am by JonnyMac Reason: 1
I don't know how to do this with the Arduino [yet] but this is a snippet of code from an SX28 project (programmed in SX/B) that will toggle the LED bits when the LED mode is set to yellow.

[font=Courier New]Check_Yellow_LED:
 IF runMode = M_PAUSE THEN
   ledPort = ledPort ^ %1100                  ' flip red & green

This snippet is from the interrupt that runs every 10 microseconds.  The LED has to be in red or green mode (one pin high, the other low) before setting the state to M_PAUSE so that the XOR of the two bits flips them.


Have a look at the code here: http://www.arduino.cc/playground/ComponentLib/Servotimer1

It is intended to drive a servo but can be simplified for your use. It takes advantage of the arduino's abilities to drive pins 9  or 10 from the hardware clock without using interrupts.


That page says to install the library the lib/targets/libraries folder, but that doesn't exist.  I put it under C:\Program Files\Arduino\arduino-0010\hardware\libraries and the IDE complains when I start it.  Can you give me a bit of guidance?  I'd like to understand what you've done with ServoTimer1 so that I might apply it to other functions.


Dec 30, 2007, 07:23 pm Last Edit: Dec 30, 2007, 07:34 pm by mem Reason: 1
Jon, its not my code but I posted the reference to indicate a way to toggle a pin without using interrupts. The fragment below is the core functionality lifted from the source code in ServoTimer1.zip. It will need tweeking for OPs application but I hope will be helpful in indicating one way to do what is required.
Code: [Select]

void startPulsingPin(uint8_t pin)
// following code lifted from ServoTimer1.zip
  if ( pin = 9 || pin == 10) {
    uint8_t oldSREG = SREG;

   TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
   TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
     | _BV(CS11) /* div 8 clock prescaler */
   OCR1A = 3000;
   OCR1B = 3000;
   ICR1 = clockCyclesPerMicrosecond()*(20000L/8);  // 20000 uS is a bit fast for the refresh, 20ms, but
                                                   // it keeps us from overflowing ICR1 at 20MHz clocks
                                                   // That "/8" at the end is the prescaler.
   TIMSK0 &= ~( _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
   SREG = oldSREG;  // undo cli()    
       // set up timer flags for the appropriate pins
   if ( pin == 9)
     TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);
   else  // pin 10
     TCCR1A = TCCR1A & ~_BV(COM1B0) | _BV(COM1B1);


I've got a lot to learn about the Atmel device; none of that makes immediate sense -- but then, I've spent the last year doing nothing but SX coding for my book, "Practical SX/B."


Code: [Select]
if ( pin = 9 || pin == 10) {
Surely a bug...

Does this work?  To get mixed colors out of a 2-pin bipolar LED, you have to toggle IO pins on BOTH sides of the LED, out of phase with each other; you can't just use PWM to toggle one side.  You could presumably use up two PWM signals (one for each side), but that seems pretty wasteful...


Dec 31, 2007, 11:17 am Last Edit: Dec 31, 2007, 11:19 am by mem Reason: 1
It is wasteful but if these pins are not needed for this app then what the heck.

BTW, there is at least one bug in the fragment posted above  ;),   'pin = 9' should have been  'pin == 9'. And, the code was not intended to drive the bicolor LEDs, just to show how to toggle pins without using an interrupt.

Go Up