Strange behavior with setRGBled

And the plot thickens!

Ahh this thread explains a lot, I thought I was going crazy when I tried to make a red LED and it went blue.

@bateske I wouldn’t worry too much, it would be a nice feature to have but it’s really not the end of the world, all the units work fine other than that and it’s possible to fix yourself. Actually delivering is more than every hardware kickstarter I’ve backed.

I was planning on implementing a health display system using the LED but I find having it on all the time annoying to my eyes anyway so I can just try to make it an optional thing. But is there anyway to detect in software if the LED is flipped? I would assume not but if there is then it would be nice to be able to make sure people aren’t looking at blue when it should be red :smiley:

1 Like

I was thinking about this shortly after the problem was discovered. It might be possible. It depends on exactly how the I/O pins behave if configured a certain way. The datasheet isn’t detailed enough to say for sure. Experimenting to see if it can be done is on my “to do” list.

1 Like

I’m sorry to say that, after doing some more research, I don’t think detecting a reversed RGB LED via software is possible.

Technical details for anyone interested:

My technique involved reading the pin that controls the green LED using the ADC. Unfortunately, I thought the green LED was on a pin that could be read by the ADC but it’s not. (The red and blue LEDs are both on ADC capable pins but, due to the way the LEDs are wired, the technique won’t work with them.)

Had the green LED pin been ADC capable, here’s what I thought might work:

I assumed that if a pin is set as a digital input, and has the internal pullup resistor enabled, then the pullup will remain active if an analog read is performed on the pin. This is the experimenting I planned to do, to verify if this is true.

If it turned out to be true that the input pullup remained active, you would set the green LED pin this way and then set the red LED pin to a digital low output.

If the LED was installed properly the green pin would be at close to the battery voltage. If the LED was reversed, the voltage on the green pin would be pulled down through the red LED to less than 2 volts.

You would then set the ADC reference to Vcc and use the ADC to read the green pin. Using an 8 bit precision read, a value greater than around 210 would indicate that the LED was installed properly. A value below this would mean the LED was reversed.

If you turn whatever pin the anode is on, push voltage through the led and you get any voltage on that pin, it’s showing the voltage that comes through the led. I’d have to check the schematic to know what exact pins.

How about you publish the schematic?

But an LED is a diode. It only passes current in one direction. Plus it has a fairly large voltage drop across it when conducting. These two facts complicate things.

1 Like

Well I had my arduboy at work today and during lunch decided I was going to flip the rgb led around. (I do regular surface mount led’s it’s part of my job, so rgb ones should be no problem).

The ones below here are backwards, fixed is above…



The process is simple for me, using a scope add flux, heat with hot air smd blower, pull up with tweezers, rotate, clean solder away from three pads using solder iron, re-apply led using tweezers, solder with solder iron, add solder to the last three legs/pads. Finally run the led test:)

Probably not for everyone but I am loving these little arduino’s!

1 Like

Some people have the best toys to play with !

3 Likes

@Ground7 Can you confirm with the RGB test you can control the colors correctly?

The green line indicates the direction of the anode and it should be pointed right to the silkscreen mark.

It was my assumption that all 8,000 units with out the speaker holes had been configured incorrectly but it appears that may not be the case. The LED should glow red during the boot screen so if that’s working… you’ve got the correct configuration and a working LED.

Let me know! I’ll PM you also!

Oh you are right! I have fixed the wording in my original post, I had my pics flipped around.

Here is a video showing the fixed and not fixed one I just took.

And here’s a photo of the two led’s I just took as well.

Green line goes toward the polarity mark to be right. The green arduboy is the one I flipped to make right.

Sorry for the confusion, I blame being excited the cause of my mistake.

2 Likes

Would it be possible to add a simplified “LEDon” call to the library, which uses a ‘turns on no matter what’ setup? As a developer, you could restrict your use to this call, knowing that you have given up multi-color, but at least gained the ability to have it work with all kickstarter (and likely future) Arduboys?

I realize one could likely do that right now by using the right color choice in the call, but I would be concerned that might be confusing down the road. It would make code clearer for any looking at it in the future - they can easily tell that the code is intending to be only on/off, not multi-color.

Not possible. The LED is installed backwards, so some of the pins aren’t connected correctly, and being a diode, as noted above, electricity only goes one way. Thus some pins don’t get any electricity, so won’t light up no matter how much you want it to. Flipping the LED is the only way to fix it.

A full fix will certainly only be made by flipping the device. And that is not going to happen for the vast majority of devices. But all the posts here make clear that even the backwards device can be at least partly on in some fashion, some of the time.

I think perhaps I was not clear. I don’t expect to get any control of color back with a simplified call. All you get is “there is something lit” or “there is nothing lit”. It might be red, blue, or something else. The goal was not to fix the LED, but provide a meaningful communication mechanism for developers, via the API, so that you get a consistent “on” and “off”. Because at least that much is possible for both types of Arduboys.

You don’t need to add a new function to the library for this. In a sketch, just only control the red and/or blue LED and always leave the green one off. For an incorrectly installed RGB LED, blue will be red and red will be blue, but as long as you leave green fully off, something will light up.

I was thinking…
As I’ve discussed above, it’s likely not possible to test if the RGB LED has been reversed, using software. However, we could add a flag in the library’s reserved system EEPROM area which indicates whether the unit has the LED installed correctly or not. Users that knew their LED was wrong could load a sketch which would set this flag. The same sketch could also allow resetting the flag for a unit that was repaired or if the flag was wrong for some other reason. This sketch would only have to be run once (or again any time the flag was wrong) because setting EEPROM is non-volatile. This sketch could be included as one of the examples in the library, so it would be easy for users to load and run.

A function named something like rgbLEDincorrect() could be added to the library, which would read the flag and return true or false. A sketch could use the result of calling this function to control the RGB LED according to what it was capable of, like so:

#ifdef AB_DEVKIT
  // running on a Dev Kit, so only control the blue LED (which is all it has)
#else
if (arduboy.rgbLEDincorrect()) {
  // code that uses blue as red and red as blue and always leaves green off
}
else {
  // code that uses the full capabilities of the RGB LED
}
#endif

So, is this something that’s worth doing? Would enough sketches make use of the feature, or would adding it be a waste of time and a waste of a byte in EEPROM? Would owners be bothered to run the sketch required to set the flag properly, if necessary?

2 Likes

I’ve actually been working on a utility sketch and I think I could add that as an option. It would ask a question like “what color is the rgb led” and you just pick red or blue, setting the correct flag in the process.

So the question remains, if we do this is anyone going to take advantage of the feature, or will it just sit there unused while wasting some EEPROM space?

Well - my five pack finally arrived!

And … they all have the backward LED.

I’ve written a test utility to both run up the skills and also check out what works and what does not. One of the things I worked out is exactly what the backwards LED can show.

If you want full compatibility, there are only two settings: BLACK #000000 and MAGENTA #ff0ff … these two should display the same on every production Arduboy. That would be setRGBled(0,0,0) and setRGBled(255,0,255).

For reasons I don’t quite follow, varying the individual red and blue lines does not influence the blue and red (respectively) color intensity. It appears that R=#00 gives no blue, but all of R=#01 through R=#FF give “bright blue”. This is also the case for varying the blue line to influence the red LED. It might be because of the values of the resistors and the odd configuration of them that results when the LED is reversed.

This does mean that there are only four “interesting” red/blue values … #00/#00 #00/#ff #ff/#00 and #ff/#ff. These correspond to Black (off), and Red, Blue, and Magenta colors (on).

For any “on” value, it appears that the intensity can be controlled using the Green line. A green value of #00 gives full intensity, while #ff gives “off”, no matter what state the R/B lines are in. The intensity drop is not linear across the range, but it is noticable for most changes of the G line.

For the value of the EEPROM byte, it would be nice if the byte could be used with a simple converter function that would let you avoid code constructs like the one shown above. Is it possible to use a macro (included from a *.h) which overrides the setRGBled method on your arduboy instance as it exists, replacing it with one that knows about the setting byte and how to map colors? That way, in a nice future with very few funkyLED Arduboys, the code could be dropped just by removing the include that brought it in.

When I get a little time to work out using standard code sharing, I’ll post my “Button & LED Tester”.

1 Like

Yes, I think it would be useful. I’m writing a fun thing that uses the serial port and being able to reliably set the led to red or blue for the two different connection modes would be neat.

Strange. I can’t see why that would be. At the very least, you should be able to vary red or blue individually, while the other one is set to off (along with green off).

So are you saying that, for you, the blue LED just goes from on to off, instead of fading down, when the ARDUBOY logo scrolls down at the start of a sketch that uses begin() with the standard Arduboy library?

Instead of a macro, it would probably be better to add a new function to the library, like setRGBledCorrected(), which would do the mapping you propose and then call setRGBled(). A sketch that wanted the LEDs to work the same on all Arduboys would call setRGBledCorrected(). A sketch that wanted to have full control of a correctly installed LED, or map it themselves, and possibly save some code space, would call setRGBled(). Since for an incorrect LED, green can never be turned on, it would probably be best if setRGBledCorrect() only accepted values for red and blue (so maybe just call it setRBled()?).

We would still need a flag in EEPROM, so the routine would know how to properly map the values.

Read on for a technical explanation of why this is so:

To simplify things, I’ll mostly ignore the resistors in the circuit. The resistors just limit the current, to determine the maximum brightness possible, and prevent the LEDs from burning out.

The RGB LED contains an individual red, green and blue LED in a package that has 4 leads. An LED is a two leaded device. To get 3 LEDs (6 leads total) into a 4 lead package, one lead of each LED is tied to a single common lead in the package. This single lead provides power to all three LEDs. (Technically, this is known as a “common anode” RGB LED.) The other lead of each LED is connected to its own I/O pin (through a resistor), providing the capability to individually control each LED in software.

One thing to understand is that an LED will only work when voltage is applied to it in one direction. One lead (the anode) has to be positive and the other (the cathode) negative. If you reverse the voltage, it won’t light.

Another thing to understand is that the actual logic for the LEDs is reversed. The common lead is tied to a positive voltage, so the I/O pin must be set low to turn it on. The setRGBled() routine compliments the values passed to it, so this “reverse logic” is transparent to the user.

With the RGB LED package installed reversed, the green LED ends up being reversed across the power and its I/O pin. Being reversed, the green LED can never light.

Instead of being attached to power, the common lead is now attached to the green LEDs I/O pin, meaning the red and blue LEDs now get their power from green LEDs I/O pin. Because of the “reverse logic” described above, to turn off an LED the I/O pin is set high. So, when the green LED is off, the high on its I/O pin provides the power to the red and blue LEDs. Setting the green LEDs I/O pin low, to turn it on, provides no power to the red and blue LEDs, which is why they won’t light when green is on.

Now, if the intensity of the green LED is varied between full on and off, it varies the power being supplied to the red and blue LEDs, thus controlling their intensity. Because of the resistors in the circuit, there will be some interaction between the LEDs and, as observed, control may not be linear.

(All “settings” are setRGBled() parameters)

Setting 0,0,0 gives “black” (off)

Setting 1,0,0 gives blue.
Setting 0,0,1 gives red
Setting 1,0,1 gives “magenta”

Setting 255,0,0 gives blue.
Setting 0,0,255 gives red
Setting 255,0,255 gives “magenta”.

The colors in the second bunch are just as bright as the first bunch.

So I can certainly control the red and blue individually. But the control (using only the single dedicated color line) is a minimal level of control at best.

For example - 0,0,1 is essentially indistinguishable from 0,0,255. In my utility, those two settings are only two quick button pushes apart. It seems pretty clear that there is no brightness distinguishing these two.

Now, during the initial scroll down of “ARDUBOY”, the blue led does taper off in color.

I can reproduce that behaviour, but only by manipulating the green line.

1,0,0 is bright blue.
1,128,0 is only slightly dimmed
1,160,0 is more dimmed
1,240,0 is well dimmed, but each step up to
1,254,0 is still dimmer until
1,255,0 is black

One of my button options is a random LED setting. Given the lack of variation in red and blue control, and that for most of the green line range, the red and blue are still quite bright, most pushes of the random button give you “bright magenta”.