[John Peterson] answered our call to document your hacks by discussing what he learned while building this color meter. He conceived the project as a way to precisely match the color output of LEDs driven with a PWM signal. The thought was that it could sample an LED’s output, then use that data to calculate values necessary to match the color of other LEDs. This is a good idea when using LEDs of different types, but even diodes from the same production line can show variations in color output.
Of course this project wouldn’t be featured as a Fail of the Week if it worked as he had expected. It turns out the sensor that he used, an Avago ADJD-S371-QR999 on a SparkFun breakout board, takes very quick color readings. This is great for solid objects, but not great for a light source being switched on and off like the PWM LEDs.
We like it that [John] posted a list of lesson learned on the project. The real fail is in trying to use this particular sensor, but we figure there must be some way to get meaningful data through sampling. Check out the page for the retired sensor which also includes a link to the datasheet. Can you think of a firmware hack which would allow this hardware to sample so that the PWM value could be extrapolated through averaging or other calculations? Let us know in the comments.
Fail of the Week is a Hackaday column which runs every Wednesday. Help keep the fun rolling by writing about your past failures and sending us a link to the story — or sending in links to fail write ups you find in your Internet travels.
Why not put a cap on the pwm lines to smooth the flashing?
+1
Just smooth the PWM with a simple RC filter
Fail! If you smooth the PWM, you’ll get a DC value. For a low duty cycle that DC value will be less than the forward voltage of the LED ant the LED will not illuminate.
Also the LED is a low impedance. You will need a stonking big Cap….
+1 for all those who post about their fails so we all can learn from them.
Not true. smoothing the PWM will just make a “DC” voltage that can be applied to the LED. By varying this voltage (through PWM) and using a resistor, you can specifically control the current through the diode, and thus the brightness of that color in the RGB led. Sure, if you PWM the voltage to a really low voltage, then the LED wont turn on, but just dont do that. You can still get full control of the different RGB brightnesses without making the PWM so lo that the LED doesnt turn on.
Also, the capacitor does not need to be big at all with the appropriate resistor.
I too am greatful to the author for sharing his fail.
That’s a horrible way to change LED brightness – the IV curve of the LED is steep so you get a small variation in brightness for a large variation in DC voltage.
It’s the whole reason why you use PWM to control the perceived brightness of a LED.
You got the two reversed. Once the diode is conducting, a small change in V cause a large change in I and brightness.
You are correct about the large current for small voltages across the diode, but the current limiting resistor is what I am saying controls the current. The current through the resistor is linearly proportional to the voltage. Furthermore, once the diode is on, it can be treated as a constant voltage, and therefore all the current can be controlled with the PWM voltage and the resistor.
False. The voltage of the capacitor will rise until the diode conducts, because the PWM power source won’t allow for it to discharge between cycles.
Hmmm… it appears that John was even vaguely aware of the sensor’s variable integration time. If it were me, I would have locked the integration time at it’s maximum and then performed the sensitivity calibration using only the gain register.
Quick math indicates that the slowest integration frequency for the sensor is ~6kHz. So, the LED PWM frequency should be substantially greater than that. Ideally, the PWM frequency would also be an even multiple of the integration frequency so that samples are consistent regardless of the phase relationship between the two.
If the LED on time is larger than the integration time, he *could*
synchronize the measurement. Use a separate reverse biased photodiode as
a sensor and timer capture function. (Phototransistor and CDS are very
*slow* so they aren’t useful for this.)
Inside the ISR, sample the light intensity. Once you find out what the
light intensity, work out the duty cycle with the timer, then calculate
the apparent intensity.
the lazy software solution would probably be too take a shit load of readings and average them
This. Take enough intensity samples at the maximum PWM frequency for long enough to cover the maximum period 2-3 times. As mentioned elsewhere, use a moving average filter to save on memory (only need to store a couple of values even though the average could be compiled over thousands of samples) and keep the calculations simple. Not sure if the Nyquist theory comes into play here, but as usual the higher the frequency and number of samples, the more accurate the estimate will be.
As someone else has pointed out elsewhere, I’m pretty sure that LED’s operate as either off or on, with only minute changes after the threshold voltage has been passed. This means a capacitor on the LED probably won’t fix the problem.
https://www.google.com.au/search?q=led+intensity+vs+voltage+graph&safe=active&source=lnms&tbm=isch&sa=X&ei=bIDYUoyjLM3TkAXb6oHoBA&ved=0CAcQ_AUoAQ&biw=1225&bih=714
None of the suggested approaches thus far would work. This is because the LED alternates between fully on of off on an interval determined by the PWM rate. Therefore the only real way to use THIS sensor would be to assume a linear response to PWM input, and measure the full on intensity of each color component of the LED under test. Then compare these full-on readings to the full-on readings of the other LEDs.
Correction, the idea of filtering the PWM input to the LED through a cap may work somewhat.
You realized that what I suggested to do, right?
Integration time is less than On time and synchronizing the on time with the measurement.
Again, the LED “blinks” between fully on and fully off. Our EYES average the light intensity. So all this thing will register is fully on or fully off.
My assumption is that the sampling is faster than the LED on time.
Synchronization = WAIT until LED is on, and measure the intensity for ON
intensity, so measurement done *before* LED is off! Think of it as
taking a picture of the LED with a fast shutter speed.
Once you found the on intensity, and also *measure* the duty cycle, you
would know the apparent intensity.
Strikecity’s approach would also work. Since the dual slope converter
*is* an integrator, the capacitor is in the sensor (instead of the LED).
Think of this as a very long exposure time, so it is capturing multiple
on-off sequence of the LED. In the end it is capturing the average
intensity.
*separate* sensor means the original analog sensor for intensity + an additional *fast* sensor for timing measurement and synchronization.
You can either hard code the duty cycle, add a keypad + code to enter
that or add a pot + ADC code for the software to read that. All of these
are pain in the behind when you are tweaking stuff like playing LED
intensity and need to change that number.
Reading and calculating duty cycle is a few lines of code. You’ll want
to synchronize the sampling already, so the hard part is done. In the
long run, it will save time and remove stupid assumptions that you’ll
have to fix in the future anyways.
Of course, you can even skip all these nonsense and just put a piece of
paper between the two LED and adjust their intensities until you can no
longer see light coming from the opposite sides.
Ah jeez I may have had a few. But why are you measuring the timing etc. I’m assuming you’ve programmed whatever is driving the original led. Therefore you know the timings. Just correlate the code with the readings from the sensor. Then average in code. As I’ve said I’ve had a few and I’m fully aware I could be talking nonsense. But there’s my 1.2p
You are right!
Why not a moving average filter? It’s easy to implement and consumes almost no cpu time. Consider a base-2 number of samples, so you can just right-shift your data, instead of dividing.
Find a prism to break down the spectrum and use a line sensor to read the output. The color of the LED corresponds to the peak measurement position along the line, or you can measure the whole spectrum easily instead of getting a vague RGB reading that actually tells you very little about the real color of the piece without calibration reference.
More specifically, the RGB reading depends on the color space of the sensor, or what sort of filters it has. Different colored LEDs can easily give the same readings because the sensor gamut is quite likely much smaller than what is perceptible by the human eye, so the values are not representive of true color, nor are they representative of any other device unless the sensor just happens to have sRGB gamut or similiar.
Measuring the spectrum directly gives you absolute comparison between LEDs that you can then calculate into RGB values for different devices by applying a bandpass filter at the appropriate wavelenghts.
Use a glow in the dark material in front of the sensor to act as a light capacitor to smooth out the PWM output. You can use various glow in the dark materials for each wavelength, or mix them together so that your sensor is sensitive to most visible wavelengths. As long as you are trying to compare two similar wavelength LEDs, it should work fine.
That would distort the color of the light, because the material is differently sensitive to different wavelenghts and does not emit the same wavelenght back.
It doesn’t matter if you are comparing two LEDs to get them to the same color and intensity. If the florescent dye does not produce the same results then you know your two LEDs are off. If it does produce the same results, then you know they are the same.
Oh wait! Column comes out every Wednesday, but is a fail itself as doesn’t make it till Thursday. Ok… I get it now.
None of the “analog” signal processing techniques mentioned here would work – the signal is already in the digital domain. It’s a math problem.
Assuming that none of the RGB inputs are saturated (off scale high), take about 1000 measurements of each of the RGB inputs. For each input (R, G, or B), determine what the maximum (bright) and minimum (dark) intensities are. (A histogram would help.) Discard samples that are not close to these limits. Count the remaining samples (#bright and #dark). The percent duty cycle can be calculated using (#bright) / (#bright+#dark). The intensity is the difference of the original (bright – dark) values.
With the intensity and percent duty cycle for R, G and B, you should be able to replicate the average power of any source for each of R, G, and B using some other source. The replicated source would be very similar in appearance to the original in both color and brightness.
Differences exist due to the original and replicated source peaks not matching each other or the corresponding sensor sensitivity peak for each of R, G, and B, and nonlinearity of the RGB sensors, but this would get you very close.
A second step (or alternative method) would be to repeat the same process on the replicated source, and adjust RGB PWMs to force similar readings. This eliminates sensor linearity issues.
The visual “bolometer” solution would be to position the original and replicated RGB sources so they both shine on the same screen. Then vary the RGB duty cycles of the replicated source until the brightness and color appears to match the original.