Pages: [1]   Go Down
Author Topic: Current in opposite directions (bicolor LED)  (Read 1164 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello!

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. smiley-cry

Thank you!
Logged

Hollywood, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
Actor / Engineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Jon McPhalen
Hollywood, CA

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Hollywood, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
Actor / Engineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Check_Yellow_LED:
  IF runMode = M_PAUSE THEN
    ledPort = ledPort ^ %1100                  ' flip red & green
  ENDIF


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.
« Last Edit: December 29, 2007, 11:04:16 pm by JonnyMac » Logged

Jon McPhalen
Hollywood, CA

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Hollywood, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
Actor / Engineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Jon McPhalen
Hollywood, CA

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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

    cli();
    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);
  }
}
« Last Edit: December 30, 2007, 01:34:47 pm by mem » Logged

Hollywood, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
Actor / Engineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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."
Logged

Jon McPhalen
Hollywood, CA

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6652
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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...
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-wink,   '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.

« Last Edit: December 31, 2007, 05:19:51 am by mem » Logged

Pages: [1]   Go Up
Jump to: