Archive for August, 2016
Some notes on a recent acquisition that ought to allow random dots with individual brightness control (unlike my simple resistor-limited hack job):
A Colorduino is a dedicated board that combines an Arduino-class microcontroller with hardware drivers for an 8×8 RGB LED matrix, with daisy-chaining I/O to build bigger displays. The Colors Shield you see above omits the Arduino circuitry and daisy-chaining hardware: it plugs atop an ordinary Arduino UNO-class board as a dedicated 8×8 tile driver.
I do not profess to understand the ancestry & family tree of those designs and their various incarnations. This schematic doesn’t match the knockoff hardware in hand, which isn’t surprising after half a dozen years of relentless product cheapnification:
It comes close enough for a big-picture overview…
The DM163 has 8×3 constant current sink PWM pins that connect to the column cathodes of the RGB matrix. It provides either 8 or 6 bits of PWM control for each output, with either 6 or 8 bits of gamma correction to make the grayscale shades work out properly (those are separate shift registers and the PWM generators use both, so the chip doesn’t care how you divvy up the 14 bits).
The three 1 kΩ resistors set the current to 60 mA per output pin. The LED matrix might support anywhere from 70 to 120 mA peak current per LED, but I doubt the supplied matrix matches any of the available datasheets. The total current depends on the number of LEDs lit on each row, so large dark areas are a Good Thing.
The serial protocol looks enough like SPI to get by, with controls for Reset, Latch, and Bank Select.
The board has no power supply other than the single Arduino VCC pin, so you’re looking at a peak of 24 x 60 mA = 1.44 A through that pin. The Arduino regulator must supply that load pretty much full-time, which is obviously a Bad Thing; plan on plenty of dark areas.
The DM163 SPI connections don’t use the Arduino’s hardware SPI, so it’s full-frontal bit-banging all the way. Three DM163 control bits use a trio of analog inputs as digital outputs. No harm in that, works fine with the knockoff Neopixels.
The M54564 is a PNP high-side driver converting logic-level inputs to the current required for the row anodes of the matrix. The eight input bits are non-contiguous across the Arduino’s digital outputs. You could turn on all the M54564 outputs at once, which would be a Bad Thing.
You shift 24 bytes of RGB data into the DM163 and latch the data, then raise one of the M54564 inputs to enable a given row of LEDs, which light up with the corresponding colors.
The bit-banged SPI runs at 1.9 µs/bit and sending all 24 bits to the DM163 requires 450 µs. With a 100 Hz refresh, that’s a mere 5% overhead, but the fact that the board soaks up essentially all the I/O pins means the Arduino isn’t not doing much else in the way of real-world interaction.
The Arduino driver, of dubious provenance, sets Timer 0 for 100-ish Hz interrupts. Each interrupt shifts another batch of bytes into the DM163 and selects the appropriate row. The driver uses a double-buffered array that soaks up 2x8x8x3 = 384 bytes of precious RAM, in addition to a bunch of working storage.
If I were (re)designing this board…
A separate power input jack for the DM163 that might optionally feed the Arduino’s VIN raw power pin.
Use the Arduino SPI hardware, dammit.
Put an HC595 shift register behind the M54564, so you’d shift 24 + 8 = 32 bits into the board, then strobe the latches. That eliminates eight digital pins used as a parallel port.
You’d surely want to disable the row driver while switching the column drivers to avoid ghosting, so figure on a separate output enable for the HC595. That tri-states the 595’s outputs; although the M54564 has internal pulldowns, it might need more.
It’s entirely usable as-is, but sheesh it’d be so easy to do a better job. That wouldn’t be software compatible with all the Arduino Love for the existing boards out there; there’s no point.
The Epson R380 printer never gets turned off, so it rarely has a chance to complain. After a powerdown due to refreshing the UPS batteries, it lit up with the dreaded “Service required. Visit your friendly Epson repair center” message that indicates you should just throw the printer out, because replacing the internal ink absorber mats / draining the internal tank is, mmm, economically infeasible when you pay somebody else to do it.
Having done this before, though, it’s almost easy…
- Pop a PC with a Windows partition off the to-be-recycled stack
- Boot System Rescue CD
- Back up the partition to a junk hard drive, just for practice
- Copy the subdirectory of sketchy utilities to the Windows drive
- Boot Windows (with no network connection)
- Run sketchy utility to reset the ink counter
- Boot SRC, restore partition
- Return hard drive & PC to their respective piles
- Declare victory and move on
This time, a sketchy utility that resembled the Official Epson Reset Program actually reset something and the printer started up normally. As before, however, the saved MBR didn’t match the on-disk MBR, suggesting that either I don’t understand how to save / restore the MBR or that something once again meddled with the MBR in between the backup and the restore.
I’ve emptied the waste ink tank maybe three times since the last reset: plenty of ink down the drain. Fortunately, I loves me some good continuous-flow ink supply action…
Sheesh & similar remarks.
An Arduino hairball for an upcoming Digital Machinist column:
A short program monitors the switch. When it closes, the program reads the analog voltage from the pot and blinks the LED (on Pin 13, so you don’t need an external LED) for that number of milliseconds.
Some diligent rummaging produced a spectacularly bouncy switch (lower trace) with the output pulse (upper trace):
A longer timebase shows it’s rattling around for nearly half a millisecond:
The second pulse in the upper trace shows that the code gets around the
loop() fast enough to retrigger on the same button push, which is part of the lesson in the column
A midrange timebase:
You could surely get a few random numbers out of that noise, although the first few bounces seem surprisingly consistent.
We spotted this upgrade on a recent trip to a Powerhouse Theater production:
Compared with the older version, I’d say it’s a great improvement:
Who says things never get better?
This truck’s home base seems to be south of Maloney on Rt 376 and it occasionally passes me on the road:
My eye-blink reaction that it was a junker turns out to be completely wrong, as it sports a really great paint job (vinyl wrap?):
The junker aspect may not be quite what they expected…
I’m not sure that’s skeuomorphic, but I don’t know the proper term.
I generally ride somewhat further into the travel lane than some folks would prefer, but I have good reason for that. Here’s how bicycling along Raymond Avenue at 14 mph = 20 ft/s on a pleasant summer morning works out…
T = 0.000 — Notice anything out of the ordinary?
T = 1.000 — Me, neither:
T = 1.500 — Ah!
T = 2.000 — I’m flinching into the right turn required for a sharp left turn:
Less than half a second reaction time: pretty good, sez me.
T = 2.833 — End of the flinch:
T = 3.000 — Now I can lean and turn left:
T = 3.267 — This better be far enough left:
T = 3.333 — The door isn’t moving:
T = 3.567 — So I’ll live to ride another day:
I carry a spectacular scar from slashing my arm on a frameless car window, back in my college days: the driver flipped the door open as I passed his gas cap at a good clip. The collision wrecked the window, the door, and my bike, but didn’t break my arm, sever any nerves, or cut any arteries. I did discover human fatty tissue, neatly scooped from under my arm onto the window, is yellowish, which wasn’t something I needed to know.
Searching for Raymond Avenue will bring up other examples of bicycle-hostile features along this stretch of NYSDOT’s trendy, traffic-calmed design…
What’s new & different: the Entropy library measures the jitter between the ATmega328 watchdog timer’s RC oscillator and the ceramic resonator (on Pro Mini boards) driving the CPU. It cranks out four bytes of uncorrelated bits every half-second, which isn’t quite fast enough for a sparkly display, but re-seeding the Arduino PRNG whenever enough entropy arrives works well enough.
One could, of course, re-seed the PRNG with Geiger bits or junction noise to the same effect. The key advantage of the Entropy library: no external hardware required. The downside: no external hardware required, so, minus those techie transistors / resistors / op amps, it will look like Just Another Arduino Project.
In any event, the Entropy library has excellent documentation and works perfectly.
The Arduino PRNG can produce results fast enough for wonderfully twinkly output that’s visually indistinguishable from the “true” random numbers from the Geiger counter or PN junction. I dialed it back to one update every 5 ms, because letting it free-run turned the display into an unattractive blur.
The top trace shows the update actually happens every 6 ms:
The lower trace shows that each matrix row refresh takes about a millisecond. Refreshes occur on every main loop iteration and interfere with the update, not that that makes any difference. Should it matter, subtract one from the update period and it’ll be all good.
The Arduino source code as a GitHub Gist: