I will definitely update the deprecated calls. Of note, though, I think they are that way in the packaged examples.
As for the LED?
I’m feeling pretty draconian on this one. Pull the PWM capability out of the library - because a timer is a limited and valuable resource. If a project wants to dedicate a timer to the LED control, so be it, but that should not be permanently setup that way. Save the space and resources from the library and return it to project discretion.
Let setRGBled take on/off for each bit, using a color number (make it just setLed(); ). I know that gives you only eight colours and one of those is off. Use g-b-r to assign bits to the numbering so that 0,1,2,3 work everywhere, but 4,5,6,7 only work if you have a proper LED. The LED control byte in EEPROM is nothing more than a marker that says ‘switch the r/b bits’ on the way out to the port.
Push all the specialized stuff - PWM in particular (both for LED and sound) back into selectable libraries. That way, if a project wants the timers for a different purpose, there is a standard way to not attach them to LEDs and sounds.
I realize this is not the somewhat spiffy LED that was expected. But this is no longer a theoretical or design discussion. 80% of the Arduboys cannot light their green LED – and they are going to stay that way. Time to make the best of the hardware that is actually deployed.
If I correctly sketched out the “right” and “wrong” versions, I’m wondering if there might still be a way to test this.
Consider the blue LED line. Wired correctly, it starts at Vcc, goes through the blue LED, through a resistor, and to the control pin. If the pin is a low voltage sink, the LED lights. If the pin is a high voltage source, the LED is dark. If the pin is a high impedance input, then I would expect the pin to float somewhat high - possibly to Vcc less the voltage drop across the blue LED.
Now consider the blue LED line. Wired IN-correctly, it starts at the green control line, goes through a resister, through the red LED, through a resistor, and to the control pin. If the pin is a low voltage sink, the red LED lights - but only if the green pin is a high voltage source. If the pin is a high voltage source, the LED is dark. If the pin is a high impedance input, then I would expect the pin to float again - but this time to the value of the green pin less the voltage drop across the red LED.
As I see it, in the correct case, swinging the green LED line up and down as an output cannot influence the blue LED line readings as an ADC. In the incorrect case, those readings can be influenced. This suggests that configuring green as an output and blue as an ADC input, and then running a series of up and down swings on the green line while monitoring the blue line would result in different readings for the correct and incorrect cases.
Am I missing something? Perhaps my understanding of the wiring is wrong, and I have been mislead by my diagrams?
Take a look at the polarity of the red LED in this case. There will be no consistent voltage drop across the red LED because if you pull the green pin low, the red LED will be reverse biased.
If the blue LED pin is a high impedance input which is being read with the ADC, you have two cases:
Green LED pin output high: The red LED will be very high impedance until the blue pin is lower than the green pin by the value of the red LEDs forward voltage drop when lit (about 1.8V). Since the blue pin is an input, there’s nothing to actually pull the blue pin down. Stray noise from any EMI could be picked by the blue pin, resulting in an ADC reading anywhere between Vcc and Vcc-1.8V.
Green LED pin output low: Again, for the red LED to not be high impedance the blue pin must drop below the green pin by at least 1.8V. Since the green pin is now at ground, this can never happen. Stray noise from any EMI could be picked by the blue pin, resulting in an ADC reading anywhere between Vcc and ground.
So, if external random noise causes the ADC to occasionally read something below Vcc-1.8V when the green pin is low, there’s a good chance that the RGB LED is incorrect. However, if the ADC never reads below Vcc-1.8V that doesn’t mean the RGB LED is correct. There just might not be any random noise pulling the blue pin down.
However, the above cases are evaluating DC characteristics. An LED has some internal capacitance and therefore will conduct an AC signal to some extent. It’s possible that if you were to toggle the green LED pin at a high enough frequency, it would be coupled through the capacitance of the red LED and could be sensed by an ADC reading on the blue pin.
I considered this possibility previously, but didn’t feel like spending the effort to experiment. It would require a fair amount of code and I didn’t feel it would be worth it for the value that it provides. Besides, with me not having an actual Arduboy, I’m not sure any results that I get from my home made system would apply to the real thing. (The RGB LED I’m using isn’t the same one that the Arduboy uses.)
Just forcing the owner to set a flag in EEPROM one time is a far simpler solution, if even doing that is worth it.
I admit we are now deep in the parts of the datasheet that nobody usually reads.
Although the input impedance of the ADC is high, it is not infinite. And although the reverse current through a reverse biased diode is extremely low, it is not zero.
The input impedance might be megaohms, and the reverse current might be microamps.
In this case, however, both of these things work in our favor. Nothing is dragging the blue pin high, and both non-infinite input impedance and reverse current will leak any small potential out of the reading. I would think that the result would be a relatively high assurance that the ADC reading will not stay even above 1/2 Vcc. That would give a very high probability that the two circumstances can be reliably separated.
In such circumstances, I don’t think you even need to go into AC territory. Simply setting up the second configuration and holding it for a tenth of a second would likely be enough to let the reading stabilize. Alternatively, rather than a timer, just repeatedly read the ADC until it stabilizes (with a very high timeout cap on the number of readings) and then use that result.
All that said - this needs to be done with the real parts, and on more than one device. Variability in reverse bias current could be quite high (although always absolutely low).
You have notably more experience at setting up the test scenarios. Is the code overly complex? If it could be embedded in a callable subroutine (which likely needs to override some of the normal Arduboy setup) I can provide test feedback from the five units in my fun pack.
We already know that an ADC input has a high enough impedance and low enough leakage current that external noise can be picked up by an unconnected pin. That’s why reading an unconnected ADC pin is often used to seed a random number generator. From the Arduino randomSeed() documentation:
If it is important for a sequence of values generated by random() to
differ, on subsequent executions of a sketch, use randomSeed() to
initialize the random number generator with a fairly random input, such
as analogRead() on an unconnected pin.
Unless the reverse leakage through the LED is fairly high, and thus the impedance fairly low, I think external noise will still swamp any attempts at getting a meaningful DC reading, especially if someone’s finger is close to the input.
However, I’ve realised that the ADC is of the sample and hold type. It has a resistor (specified to be between 1K and 100K ohms) between the pin and the ADC sample/hold capacitor (which is about 14pF). This could be used as an RC filter to smooth out a high frequency PWM signal. If this PWM signal were generated on the red LED pin, it might make it through the blue LED’s capacitance and present a fairly stable specific reading on the green pin ADC, in the case of a reversed RGB LED.
So what would have to be done is:
Reprogram timer 0 or timer 1 to produce a high frequency PWM signal, with a high percentage low duty cycle, on the green LED pin.
Take an ADC reading on the red LED pin, using a long integration time so the voltage on the S/H capacitor will stabilise.
Once the reading (or multiple readings for better confirmation) is taken. The timer is reset to its original configuration.
If the RGB LED is reversed, the ADC reading will be a low value, close to the duty cycle of the PWM output, which was coupled through the capacitance of the blue LED. If the RGB LED is correct, the ADC reading will be clamped to above Vcc-1.8V by the red LED, which has its other lead tied to Vcc.
All of this would have to be done by direct control of the hardware. I doubt that any standard Arduino functions would be suitable.
I don’t really have the time or interest to work on this at the moment, but you or someone else is welcome to have a go.
One additional factor - we’re working on the red LED here. At the same time, program the blue LED (or the “other” LED, such as it is) to be fully on.
This will maximize the ambient light, and it will be high energy blue light in the case we are considering. Ambient high-energy light will maximize the reverse current in the other LED, driving us more to the case we are interested in exploring.
Although I realize it has a low chance of success, I may give the fully static scenario a try, as I think it is easier to set up than the AC coupled case. If I can distribute the code, we can get some statistics from deployed Arduboys to see what happens out there.
The opposite approach has been taken: Remove the tunes code so that the timers are usable by the RGB LED with PWM. If you want sound, you can use ArduboyTones, which doesn’t interfere with the RGB LED.
Also, my Arduboy2 library has a digitalWriteRGB() function, if you want to control the RGB LED using standard digital I/O instead of PWM.
I didn’t even realize that an RGB led was installed, haha! Upon running the above mentioned code, I also can confirm that I only have Red and Blue. If I could be adventurous I may have a go at rotating the SMD, but I think I won’t bother. For one colour, I will just purchase the next model, with more improved features Good job guys, I still love this thing even if it’s 1/3 the colour down!
I didn’t know it had an LED until this thread, I did assume mine didn’t work, but running the test it does actually work correctly. It’s so bright though I can’t imagine using it for much. If someone is playing at night they are going to be blinded!
You might also wish to look into balancing the brightness of each LED. I know it’s cheaper and easier to use the same dropping resistor value for all 3 LEDs but the current required for a given (apparent) brightness and the voltage drop on each LED varies, thus requiring a different resistor value for each.
For instance, on my home made system I found a good balance by running at about 3.2mA for red, 2.3mA for blue, and only 0.8mA for green. On a real Arduboy with a fully charged battery, I’ve measured 8.6mA for red, 4.8mA for blue and 5.2mA for green. The RGB LED I’m using is a different part but the characteristics will be similar.
I submitted a request for the store credit through the contact form on Aug 18, and got a reply from Celine on Aug 19 that they would, “check in with the store back-end, and I will email you back with more information”. It’s been 5 weeks and no further communication.
I have to say I got my Arduboy yesterday. And it works perfectly i have used all of your led testing codes (no need to reinvent the wheel) I have no issues with the led. I have a green Arduboy if that matters.