Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Category: Software
General-purpose computers doing something specific
For a pure indicator, it’d be easier to slap a spot on the screen with the Adafruit GFX library’sfillRect() function. If you’re setting up a generic button handler, then button bitmap images make more sense.
Being that type of guy, I want a visible indication that the firmware continues trudging around the Main Loop. The standard Arduino LED works fine for that (unless you’re using hardware SPI), but the Adafruit 2.8 inch Touch-screen TFT LCD shield covers the entire Arduino board, so I can’t see the glowing chip.
Given a few spare pixels and the Adafruit GFX library, slap a mood light in the corner:
Adafruit TFT – heartbeat spot
The library defines the RGB color as a 16 bit word, so this code produces a dot that changes color every half second around the loop() function:
millis() produces an obvious counting sequence of colors. If that matters, you use random(0x10000).
A square might be slightly faster than a circle. If that matters, you need an actual measurement in place of an opinion.
Not much, but it makes me happy…
There’s an obvious extension for decimal values: five adjacent spots in the resistor color code show you an unsigned number. Use dark gray for black to prevent it from getting lost; light gray and white would be fine. Prefix it with a weird color spot for the negative sign, should you need such a thing.
Hexadecimal values present a challenge. That’s insufficient justification to bring back octal notation.
In this day and age, color-coded numeric readouts should be patentable, as casual searching didn’t turn up anything similar. You saw it here first… [grin]
Now that I think about it, a set of tiny buttons that control various modes might be in order.
Aren’t those just the ugliest buttons you’ve ever seen?
The garish colors identify different functions, the crude shading does a (rather poor) job of identifying the states, and the text & glyphs should be unambiguous in context. Obviously, there’s room for improvement.
The point is that I can begin building the UI code that will slap those bitmaps on the Arduino’s touch-panel LCD while responding to touches, then come back and prettify the buttons as needed. With a bit of attention to detail, I should be able to re-skin the entire UI without building the data into the Arduino sketch, but I’ll start crude.
The mkAll.sh script that defines the button characteristics and calls the generator script:
It turns out, for some reasons that aren’t relevant here, that I’ll be using the Adafruit Arduino LCD panel for the sewing machine control panel, at least to get started. In mulling that over, the notion of putting text on the buttons suggests using getting simple pictures with Unicode characters.
Herewith, some that may prove useful:
Needle stop up: ↥ = U+21A5
Needle stop up: ⤒=U+2912
Needle stop down: ⤓ = U+2913
Needle stop any: ↕ = U+2195
Needle stop any: ⟳ = U+27F3
Needle stop any: ⇅ = U+21C5
Rapid speed: ⛷ = U+26F7 (skier)
Rapid speed: 🐇 = U+1F407 (rabbit)
Slow speed: 🐢 = U+1F422 (turtle)
Dead slow: 🐌 = U+1F40C (snail)
Maximum speed: 🏃 = U+1F3C3 (runner)
Bobbin: ⛀ = U+26C0 (white draughts man)
Bobbin: ⛂ = U+26C2 (black draughts man)
Bobbin winding: 🍥 = U+1F365 (fish cake with swirl)
Of course, displaying those characters require a font with deep Unicode support, which may explain why your browser renders them as gibberish / open blocks / whatever. The speed glyphs look great on the Unicode table, but none of the fonts around here support them; I’m using the Droid font family to no avail.
Back when I started fiddling with 3D printed chain mail, the whole process from model to plastic worked wonderfully well. That continued with the larger sheets, but now, occasionally, the OpenSCAD model would produce weirdly sliced links. Depending on nothing repeatable, some links wouldn’t bridge correctly: the thread paths in the bottom layer across the gap would mysteriously stop just short of one pillar, return to the start, and leave an unsupported shelf that would, of course, fall into the gap.
Shortly before Christmas, I managed to get a consistent failure that manifested differently: upon loading the STL file, Slic3r would quietly perform dozens of automatic corrections that (sometimes!) produced bizarrely distorted results. Feeding a failing model into Meshlab showed an irregular assortment of “self intersecting faces”, highlighted in red:
Chain Mail Square Armor – open – 2×2 – Meshlab self-intersecting faces
Although all four outer links in that image come from the same OpenSCAD module with identical sizes, they don’t all exhibit the same problem in the (nominally identical) faces on each of their four corners. In fact, those faces come from the intersection of two square slabs, carefully sized and positioned to avoid creating coincident planes:
Chain Mail Link – Outer shape
The central opening comes from a similar, slightly smaller, intersected-squares shape, but all four interior corner faces in each link show that they’re self-intersecting.
The STL looked fine in Meshlab, except for the highlit self-intersecting faces, so the geometry seemed OK.
When Slic3r autocorrected the “problems”, it apparently removed one vertex on the bottom surface of each bar, deleted the triangles connected to that vertex, then repaired the mesh to produce a delightfully symmetric pattern:
Chain Mail Square Armor – open – 2×2 – Slic3r corrections
Although the links are resolutely symmetric, Slic3r seemed happy with the identical vertices at the other end of the bar.
Unfortunately, the resulting G-Code won’t produce good links:
Chain Mail Square Armor – open – 2×2 – first layer G-code visualization
So, shortly before Christmas, I filed an issue on OpenSCAD’s Github repository.
The ensuing discussion showed that Meshlab flags faces as “self intersecting” when they have different vertices, even if their values are numerically equal, as well as vertices that differ by teeny amounts. Slic3r applies slightly different criteria to vertices & faces when it automagically corrects “problems” in the STL file, so that Meshlab may:
Highlight faces that don’t bother Slic3r
Apply the same highlight to faces that cause horrible problems
I don’t profess to understand much of that and may have the details wrong, but, apparently, OpenSCAD formerly used quantized coordinates that ensured all vertices within a tiny volume would have the same numeric value. In particular, all three faces that meet at a common point would, in fact, have numerically equal coordinate values for that point. The STL file format consists of a list of separate triangles, each with three coordinates for each of the three axes, and (without quantization) it was entirely possible for each of the three triangles with a common point to have three very slightly different positions for that point.
In theoretic terms, quantized coordinates cause horrible problems during geometric manipulation, because numeric values that aren’t exact can make repeated transformations come out wrong; running an object through a transformation and it’s inverse might not yield an object identical to the original one.
In practical terms, it seems that slicers and STL repair algorithms can reach incorrect conclusions based on minute differences produced by floating-point operations and numeric-to-text conversions. Those differences depend on slight changes in position, rotation, and size, so doing anything to the model produces completely different results.
That notwithstanding, the day after Christmas brought a new OpenSCAD version that uses quantized coordinates. A bit of rummaging in the source shows that the 3D grid (defined in src/grid.h) isn’t all that coarse:
const double GRID_FINE = 0.00000095367431640625;
STL files don’t carry units, so that could be in either millimeters (the Slic3r / RepRap convention) or inches (Sketchup, but we won’t go there). It’s exactly 1/10242, in case you were wondering, which produces a 5% speedup in the geometry engine compared to the more human-readable 1/10002.
With that commit in hand, all the chain mail links slice perfectly again.