… or what you get if you video concentric RGB LED rings and put them out of focus.

work as if you live in the early days of a better nation
I want to make an edge-lit numeric display. These were a common technology before numeric LEDs were available. They use 10 illuminated slides to display individual numbers. Here’s my first try at the display:
The 74LS42 logic chip (4-Line BCD to 10-Line Decimal Decoder) seems a likely candidate to drive such a display. You feed it a 4-bit binary-coded decimal input, and the chip activates one of ten outputs. It’s a low-voltage version of the old 7441 chip used for driving Nixie tubes. Here’s what I got working as a demo of the 7442, driven by an Arduino:
(Video link for the iframe-averse: https://www.youtube.com/watch?v=cETGB2M8iUw)
From the video you can see that:
Making a clean breadboard layout for this circuit was a little more work than I’d anticipated. It just fits on a half-sized breadboard:
Because the 7442 will only activate one output at a time, it’s okay to use a single current-limiting resistor for all ten output LEDs. The chip also uses active low outputs: the outputs go from high to low when activated. The negative side of each LED goes to an output pin, and the chip sinks current when an output is selected, lighting the LED.
The components get in the way of seeing the wiring, so here’s another picture from Fritzing with just the wires and the breadboard:
Apart from the 74LS42 chip itself, the components I used were 10× 3mm orange LEDs on the outputs and 4× 3mm green LEDs on the inputs. I don’t have a spec for them (they were from a bargain selection box from PCBoard.ca) so my use of ridiculously precise 332 Ω 1% resistors to limit current is a little unnecessary. (I have a bunch of these precision resistors from a project that didn’t go ahead, so using them is cheaper for me than digging about for a 5% one.)
Finally, here’s the Arduino sketch I wrote to drive the chip for the demo video. All it does is cycle through digital outputs 4–7, incrementing a bit every half second.
/* SeventyfourFortytwo - Arduino demo of a 74LS42 - 4-line BCD to 10-line decimal decoder Steps through 0-15, two steps per second Shows the 74LS42's blocking of values 10-15 as invalid Wiring: Arduino 74LS42 ======== ======= 4 - 15 Input A (bit 0) 5 - 14 Input B (bit 1) 6 - 13 Input C (bit 2) 7 - 12 Input D (bit 3) scruss - 2016-09-23 */ int n = 0; void setup() { pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW); } void loop() { digitalWrite(4, n & 1); digitalWrite(5, n & 2); digitalWrite(6, n & 4); digitalWrite(7, n & 8); n++; if (n > 15) n = 0; delay(500); }
If you felt really fancy, you could drive the LED inputs through PWM, and come up with just the right of flicker to make this look like a Nixie tube. You should also be able to chain the inputs through some shift registers, too.
You may still be able to get surplus Sayso Globord programmable LED signs in surplus stores. It’s a 7×24 LED scrolling sign that you can program with a lightpen or with audio input.
The unit comes with no software, but has a link to https://www.dropbox.com/sh/q1q9yhahwtblb23/AACpMeXQjYyD8ZWC-65vNgcxa printed on the box. It’s an archive of the programming software, manual, and canned audio files for a whole bunch of standard messages. Here’s an archive if the dropbox link goes away: SaySo.zip
The audio files used for programming the display are clearly FSK-encoded, but I haven’t quite worked out the relationship between the tones and the display bits. Here’s what I’ve worked out so far:
The editor runs nicely under DOSBox, so you can experiment and save samples as WAV files. Here’s a sample display with its corresponding audio linked underneath:
I’m not sure how much extra work I have time or inclination to put in on getting this working, but I hope that my preliminary work will be useful to someone (maybe this person).
Phil sent me a note last week asking how to turn an LED on or off using Python talking through Firmata to an Arduino. This was harder than it looked.
It turns out the hard part is getting the value from the Tkinter Checkbutton itself. It seems that some widgets don’t return values directly, so you must read the widget’s value with a get()
method. This appears to work:
#!/usr/bin/python # turn an LED on/off with a Tk Checkbutton - scruss 2012/11/13 # Connection: # - small LED connected from D3, through a resistor, to GND import pyfirmata from Tkinter import * # Create a new board, specifying serial port # board = pyfirmata.Arduino('/dev/ttyACM0') # Raspberry Pi board = pyfirmata.Arduino('/dev/tty.usbmodem411') # Mac root = Tk() var = BooleanVar() # set up pins pin3 = board.get_pin('d:3:o') # D3 On/Off Output (LED) def set_led(): # set LED on/off ledval = var.get() print "Toggled", ledval pin3.write(ledval) # now set up GUI b = Checkbutton(root, text = "LED", command = set_led, variable = var) b.pack(anchor = CENTER) root.mainloop()
This is explained quite well here: Tkinter Checkbutton doesn’t change my variable – Stack Overflow. I also learnt a couple of things about my previous programs:
(Arduino + LoL Shield + hand drawn 14×9 GIFs [,
, and
] + this)
There were some flaws in the post HSV colour cycling LED on Arduino. This does much more what I wanted:
/* HSV fade/bounce for Arduino - Stewart C. Russell - scruss.com - 2010/09/19 Wiring: LED is RGB common cathode (SparkFun sku: COM-09264 or equivalent) * Digital pin 9 → 165Ω resistor → LED Red pin * Digital pin 10 → 100Ω resistor → LED Green pin * Digital pin 11 → 100Ω resistor → LED Blue pin * GND → LED common cathode. */ #define RED 9 // pin for red LED; green on RED+1 pin, blue on RED+2 pin #define DELAY 2 long rgb[3]; long rgbval, k; float hsv[3] = { 0.0, 0.5, 0.5 }; float hsv_min[3] = { 0.0, 0.0, 0.4 // keep V term greater than 0 for smoothness }; float hsv_max[3] = { 6.0, 1.0, 1.0 }; float hsv_delta[3] = { 0.0005, 0.00013, 0.00011 }; /* chosen LED SparkFun sku: COM-09264 has Max Luminosity (RGB): (2800, 6500, 1200)mcd so we normalize them all to 1200 mcd - R 1200/2800 = 0.428571428571429 = 109/256 G 1200/6500 = 0.184615384615385 = 47/256 B 1200/1200 = 1.0 = 256/256 */ long bright[3] = { 109, 47, 256 }; void setup () { randomSeed(analogRead(4)); for (k=0; k<3; k++) { pinMode(RED + k, OUTPUT); rgb[k]=0; // start with the LED off analogWrite(RED + k, rgb[k] * bright[k]/256); if (k>1 && random(100) > 50) { // randomly twiddle direction of saturation and value increment on startup hsv_delta[k] *= -1.0; } } } void loop() { for (k=0; k<3; k++) { // for all three HSV values hsv[k] += hsv_delta[k]; if (k<1) { // hue sweeps simply upwards if (hsv[k] > hsv_max[k]) { hsv[k]=hsv_min[k]; } } else { // saturation or value bounce around if (hsv[k] > hsv_max[k] || hsv[k] < hsv_min[k]) { hsv_delta[k] *= -1.0; hsv[k] += hsv_delta[k]; } } hsv[k] = constrain(hsv[k], hsv_min[k], hsv_max[k]); // keep values in range } rgbval=HSV_to_RGB(hsv[0], hsv[1], hsv[2]); rgb[0] = (rgbval & 0x00FF0000) >> 16; // there must be better ways rgb[1] = (rgbval & 0x0000FF00) >> 8; rgb[2] = rgbval & 0x000000FF; for (k=0; k<3; k++) { // for all three RGB values analogWrite(RED + k, rgb[k] * bright[k]/256); } delay(DELAY); } long HSV_to_RGB( float h, float s, float v ) { /* modified from Alvy Ray Smith's site: http://www.alvyray.com/Papers/hsv2rgb.htm H is given on [0, 6]. S and V are given on [0, 1]. RGB is returned as a 24-bit long #rrggbb */ int i; float m, n, f; // not very elegant way of dealing with out of range: return black if ((s<0.0) || (s>1.0) || (v<0.0) || (v>1.0)) { return 0L; } if ((h < 0.0) || (h > 6.0)) { return long( v * 255 ) + long( v * 255 ) * 256 + long( v * 255 ) * 65536; } i = floor(h); f = h - i; if ( !(i&1) ) { f = 1 - f; // if i is even } m = v * (1 - s); n = v * (1 - s * f); switch (i) { case 6: case 0: // RETURN_RGB(v, n, m) return long(v * 255 ) * 65536 + long( n * 255 ) * 256 + long( m * 255); case 1: // RETURN_RGB(n, v, m) return long(n * 255 ) * 65536 + long( v * 255 ) * 256 + long( m * 255); case 2: // RETURN_RGB(m, v, n) return long(m * 255 ) * 65536 + long( v * 255 ) * 256 + long( n * 255); case 3: // RETURN_RGB(m, n, v) return long(m * 255 ) * 65536 + long( n * 255 ) * 256 + long( v * 255); case 4: // RETURN_RGB(n, m, v) return long(n * 255 ) * 65536 + long( m * 255 ) * 256 + long( v * 255); case 5: // RETURN_RGB(v, m, n) return long(v * 255 ) * 65536 + long( m * 255 ) * 256 + long( n * 255); } }
Pretty much everyone tries the RGB colour cycler when they get their first Arduino. This variant cycles through the HSV colour wheel, though at fixed saturations and values.
Code:
// HSV fade/bounce for Arduino - scruss.com - 2010/09/12 // Note that there's some legacy code left in here which seems to do nothing // but should do no harm ... // don't futz with these, illicit sums later #define RED 9 // pin for red LED #define GREEN 10 // pin for green - never explicitly referenced #define BLUE 11 // pin for blue - never explicitly referenced #define SIZE 255 #define DELAY 10 #define HUE_MAX 6.0 #define HUE_DELTA 0.01 long deltas[3] = { 5, 6, 7 }; long rgb[3]; long rgbval; // for reasons unknown, if value !=0, the LED doesn't light. Hmm ... // and saturation seems to be inverted float hue=0.0, saturation=1.0, value=1.0; /* chosen LED SparkFun sku: COM-09264 has Max Luminosity (RGB): (2800, 6500, 1200)mcd so we normalize them all to 1200 mcd - R 1200/2800 = 0.428571428571429 = 109/256 G 1200/6500 = 0.184615384615385 = 47/256 B 1200/1200 = 1.0 = 256/256 */ long bright[3] = { 109, 47, 256}; long k, temp_value; void setup () { randomSeed(analogRead(4)); for (k=0; k<3; k++) { pinMode(RED + k, OUTPUT); rgb[k]=0; analogWrite(RED + k, rgb[k] * bright[k]/256); if (random(100) > 50) { deltas[k] = -1 * deltas[k]; // randomize direction } } } void loop() { hue += HUE_DELTA; if (hue > HUE_MAX) { hue=0.0; } rgbval=HSV_to_RGB(hue, saturation, value); rgb[0] = (rgbval & 0x00FF0000) >> 16; // there must be better ways rgb[1] = (rgbval & 0x0000FF00) >> 8; rgb[2] = rgbval & 0x000000FF; for (k=0; k<3; k++) { // for all three colours analogWrite(RED + k, rgb[k] * bright[k]/256); } delay(DELAY); } long HSV_to_RGB( float h, float s, float v ) { /* modified from Alvy Ray Smith's site: http://www.alvyray.com/Papers/hsv2rgb.htm */ // H is given on [0, 6]. S and V are given on [0, 1]. // RGB is returned as a 24-bit long #rrggbb int i; float m, n, f; // not very elegant way of dealing with out of range: return black if ((s<0.0) || (s>1.0) || (v<0.0) || (v>1.0)) { return 0L; } if ((h < 0.0) || (h > 6.0)) { return long( v * 255 ) + long( v * 255 ) * 256 + long( v * 255 ) * 65536; } i = floor(h); f = h - i; if ( !(i&1) ) { f = 1 - f; // if i is even } m = v * (1 - s); n = v * (1 - s * f); switch (i) { case 6: case 0: return long(v * 255 ) * 65536 + long( n * 255 ) * 256 + long( m * 255); case 1: return long(n * 255 ) * 65536 + long( v * 255 ) * 256 + long( m * 255); case 2: return long(m * 255 ) * 65536 + long( v * 255 ) * 256 + long( n * 255); case 3: return long(m * 255 ) * 65536 + long( n * 255 ) * 256 + long( v * 255); case 4: return long(n * 255 ) * 65536 + long( m * 255 ) * 256 + long( v * 255); case 5: return long(v * 255 ) * 65536 + long( m * 255 ) * 256 + long( n * 255); } }
The different resistor values are to provide a limited current to the Triple Output LED RGB – Diffused, as each channel has different requirements. The 165Ω resistor is actually two 330Ω in parallel; I didn’t have the right value, and this was the closest I could make with what I had.
Saw my first retail LED domestic bulb today – $14 at Rona. Looked more like a novelty than anything else, but it did have a stated 100,000 hour life…
The PhotoSmart has an ability to print various ruled paper forms: lined, todo lists, and graph paper. But what they print for graph paper is merely squared paper:
Graph paper’s the stuff with 1mm squares. Personally, I was disappointed that it wouldn’t print log ruled and Smith charts, but that’s just me …
One of the baddies in Upton Sinclair’s The Jungle is a political henchman called Bush Harper. No further comment is required.
GO train tickets say: “Ticket must be cancelled to be valid.” Wha?
I’ve always thought that Adobe missed a great opportunity when they didn’t make their basic PDF writer freely available for Windows. Other OSs now have transparent print-to-PDF options. If you’re lucky, a corporate PC might have MS Office Document Image Writer installed, but a 300dpi monochrome TIFF can’t compare to a PDF.
Still, one can always install PDFCreator (if you have admin rights to the PC, of course). It’s a shame they decide to bundle a marginally dodgy toolbar/spyware package with it, but you don’t get that if you use the MSI installer package.
I reckon that if I took a random street poll anywhere (anywhere outside Canada, that is), no more than 3 out of 10 people would consider Canada as having a leadership role. I do not wish to make light of the soldiers’ plight; I just don’t want them there in my name.
(I was going to make a comment about the nearest thing to a role to most Canadians would be a Swiss Chalet 1/4 chicken dinner, but that doesn’t work in a written context, and barely works when spoken.)
Our tree is filled with Ruby-crowned Kinglets, and the title is Peterson’s poetic description of them. I guess they’re feeding up to migrate a bit south. Give news of yourselves when you bring spring back with you!
Got yet more mercury alloy trowelled into my head tonight by Dr Choi. I have to say, the best bit about going to the dentist is the squidgy noise the filling paste makes as it compresses into the cavity. It means it’s nearly over, and the burring slow drill is banished until next time.
Came home, said hello to the fish, and did a quick count; I was one loach down, and the CO2 generator had an orange tail …
Seems that one of the loaches had decided it was way cool to get wedged up the back of the gas generator, and couldn’t get back out. I gingerly pulled off the device from the side of the tank, and the loach fluttered off, a little dazed.
No sooner had I put the generator back did another loach zoom up and get jammed. It must’ve been told that you got a “wicked headrush, dude”.
And for this reason, loaches don’t rule the earth.
Goodbye: