Wednesday, November 8, 2017

"Experience is what you get when you were expecting something else."

That was the little bio. tag-line for someone on the Arduino forums.  (I didn't make a note of their handle.  Apologies!)  Granted, if you're trolling through the Arduino forums, you're already feeling that.  But boy howdy, that hit a little too close to home for me.

Backstory:  The chicken coop is almost finished from a structural standpoint.  For monitoring temperature, humidity, and ammonia (NH3) levels, I decided to take the cue from my neighbour and roll with a wifi-based interface vs. Bluetooth/Android. 

The wifi breakout board that I'm holding up below is the ESP8266:  Version 1.0 form-factor with the Version 12 firmware.  Go figure.



I've known for well over a year what a difficult little beastie it is.  
  • The above form-factor's pinout is downright breadboard-hostile. (Two rows of pins?  Just...whyyyyyyyyyy????) 
  • It runs on 3.3 volts (vs. 5 volts for most other things).
  • Like all electronics that transmit a signal, it's a PIG for current (~300mA peak).
  • Constructing and sending an HTTP GET request is super-fussy about syntax (including carriage returns) and timing.  At the time of writing, HTTP POST is above my pay-grade.
And as the proverbial cherry on top of all that lamesauce, my (Ubuntu 12.04) workstation has this nasty, sneaky tendency to quietly drop USB -> Serial connections.  When you're in the middle of debugging and already inclined to blame your code, this can waste scads of time.

But this, in addition to being my first full Internet of Things project (well, first non-proof-of-concept project, anyway) was only my second rodeo with a smaller microprocessor.  I've already gone a few rounds with the Atmega328 chip running on a breadboard.  It's the same chip used in the Arduino UNOs, which streamlines development (as much as development can be streamlined).

The squee little ATtiny85 is the baby of the Arduino family.  Its surface-mount form-factor is the brains of Adafruit's Trinket, so I'm already familiar with some of its...errrrr..."quirks."  (So, yeah, the "baby" can sometimes swing to more of the "Stewie Griffin" than the "Maggie Simpson" end of the spectrum.)

The biggest quirk is that peeking inside the head of the ATtiny chips is almost impossible.  (I've done it with another full Arduino and an FTDI/UART programmer, but the wiring alone would make Rube Goldberg shake his head.)  All the usual protocols you'd use with a full-size Arduino chip (I2C, SPI, full Serial) are not supported.  The best that the ATtinys can manage is the SoftwareSerial library.  Which looks all fancy-schmancy on the surface, but under the hood does something known as "bit-banging."

Now, without wading into the intricacies of two- and three-wire communication, let's just compare bit-banging to an intersection where the drivers only sorta-kinda follow the protocol of taking turns and where the cars don't always arrive at neat intervals.

The bigger Atmega328 chips require you to supply an external "clock" (a crystal oscillator plus a couple of capacitors) to time the exchange of ones and zeros.  And while you have that option with the ATtinys, you do it at the cost of two pins -- of which there are only five on the ATtiny85.  The remaining (and default) option is to rely on the chip's 8 MHz internal clock.

As it turns out, that clock doesn't exactly run with the tightest tolerances.  According to one reply on the Arduino forums, the slop can be as high as +/- 10%.

Yeeeee-OWCH.

The upshot was that the hit-to-miss ratio of the HTTP GET request even making it to the router intact was absolutely abysmal.  By contrast, when I ported the code to a full Arduino UNO, the ratio flipped.  Still not perfect, but more than acceptable.  When I wired up an Atmega328 on a breadboard and uploaded the self-same code to it, the results were the same as the UNO.  The relative reliability of the external clock made all the difference in the world.

Pity.  I had high hopes for that little cutie-pie of a chip.  I still plan on wiring up and coding a Bluetooth-based proof-of-concept with it.  Mainly to get a handle on its reliability..  As I mentioned, HTTP GET is hella-finicky.  The AT-commands used with Bluetooth are simpler, so there is some hope there.

In the meantime, I'm going into production with a slightly over-engineered "Mark I."  I still need to pick up a replacement NH3 sensor from BJW in Moncton (because guess who hosed up soldering headers and then nearly ripped off a couple of pads trying to de-solder them?), burn it in, and kick its tires.  And, finally, knock together a screened enclosure to proof the whole contraption against, ahem, "re-wiring" by a trio of curious -- and probably bored -- chickens.  (I've seen the movie Chicken Run, y'all, and I would not put it past any of them.  Related:  Remind me never to let them watch Iron Man either.)

For the longer-term, I have a couple more sketches for the "library" of Arduino code accumulating in a Mercurial repository.  For this project I imported the temperature and humidity code lock, stock and barrel and it worked right out of the box.  Which is the whole point of a well-organised code-library.  And with a tenacious sinus infection knocking me flat in the middle of this project, don't think that I don't appreciate my past self for that!

And, most important, this radically expanded my notes.  Most especially the "Gotcha" section of an Arduino-on-a-breadboard ("Boarduino") presentation that I might give sometime in the next few months.  Because while I consider this latest round of butt-kicking just another installment of paying my dues, I benefited hugely from the forums, etc.  And so I'm paying that forward.  Mind you, I don't worry about the next generation becoming soft and spoiled.  Because even if I spare someone this particular butt-kicking, there are plenty more lurking out there with each new project. Oh yes, yes there are...