Sunday, September 15, 2019

Misadventures with an ESP-01 board (ESP8266 wifi module)

To add wifi capability to an electronics project, the ESP8266 chip is apparently a popular choice.  It is a microcontroller with a wireless ethernet stack built in.  We got three ESP-01 boards that feature this chip, an antenna, and some flash memory (1 MB).  They are very small!

The tutorials on this board are generally quite confusing, as you can incorporate it easily into a project of your choosing in many ways.  Many makers are familiar with the Arduino platform and are comfortable with its development tools, even though this isn't entirely necessary.  Also, there appears to be a tradition of "hello world = flashing LED" tutorials for Arduino.  This tradition extends to ESP-01 boards in a somewhat unfortunate way. 

The ESP-01 board ships with an old-school Hayes-modem "AT" command interface.  It talks to a host via serial at 115200 baud out of the box -- though with 3.3 V signaling instead of 5 V or RS-232 levels.  (Nearly everyone warns you that 5 V will kill the device, but that actually seems a bit suspect.  I imagine RS-232 levels would really toast it, though!)  In any case, if you hook up a serial terminal, you can talk AT commands and pretty easily connect the board to a nearby access point.  The commands are


If you want to see what access points are visible, use


If you want to see what IP you've been assigned once connected, use


The documentation for all the commands is located here. a nice short listing of commands is here.  It's essentially like a cross between old-school modem commands and sockets programming.

Since modern computers don't have a hardware serial port (and most old hardware serial ports don't support 115200 baud), you typically use a USB-to-serial converter.  There are many of these available -- I have several -- but for a quick hack you can coerce an Arduino into helping.  Actually, "coerce" is the right word, because what you do is hold the Arduino in a reset state (it's effectively disabled) while you hijack its USB-to-serial chip.  Here's the circuit that I used.  The resistors form a voltage divider that brings the Arduino's 5 V signaling down to 3.3 ish volts.  (It didn't make much of a difference when I hooked the RX lines directly together, though that is apparently ill-advised...) 

Since I am using an Arduino Mega held in reset, it seems that plenty of 3.3 V is available for the ESP-01, contrary to the many tutorials warning that a separate power supply is required.  I imagine you might have problems if you allow the Arduino to boot up.

OK, back to the unfortunate part of the story.  Since the tradition is to make an LED flash as your first project, there are many tutorials explaining how to make an ESP8266 flash an LED.  This involves -- naturally enough -- overwriting the flash memory with a program that simply toggles one of the GPIO pins.  However, this means that the modem firmware gets overwritten!  If you're a newbie (or even if you're not), this means that the ESP-01 board is now useless as a wifi dongle!  Putting the original firmware back is not exactly a trivial task.

I was faced with the task of reflashing 2 of the 3 ESP-01 boards we have.  (The remaining one was fortunately unharmed, so I was able to figure out how it was supposed to work!)

First of all, you need special software that understands how to flash memory on the board with the ESP8266 chip.  Fortunately, the right tool for the job is an open source python script esptool which has minimal dependencies.  Starting this up was no problem, and I started by re-using my existing circuit.  I figured that I would start by clearing the flash memory, since I already knew it to be useless...

$ python --port /dev/ttyACM0 erase_flash

Sadly, this just hung while "connecting".  I hooked up my logic analyzer to the TX and RX lines, and was able to verify that data was getting transferred, so it looked like the chip was merely ignoring the commands.  After digging some more, I found that the right course of action was to ground the GPIO0 pin first.  This puts the ESP8266 chip into a "flash mode", which is required for programming it.  To start programming, you briefly pulse the RST pin to ground to reset the chip.  Then it happily started flashing the memory, or so I thought. 

However, as it turns out my board has a flash chip that doesn't like the default SPI settings.  Unfortunately, they appear to work just fine, and the files I flashed even verify correctly through esptool.  But they are wrong!  There are some dark words in Amazon reviews for the ESP-01 about defective boards, but that didn't seem to add up.  The boards were indeed talking -- I could watch the data transfer both directions on my logic analyzer -- so I didn't think they were defective. 

After a bit more poking, I found the solution.  The problem is that the default setting in epstool optimizes runtime, using the fastest protocol to write the flash.  Apparently this isn't supported by all flash chips, and it silently causes problems with some of them.  There's a detailed explanation of what's going on in the esptool documentation and on the Wikipedia page for the Serial Peripheral Interface


Let's flash the board correctly!

You can use the stock firmware, by following detailed instructions about the flash map in their documentation.  But there is also an enhanced version of the firmware that adds a few additional AT commands.  It's a little easier to flash the enhanced version since it's all in one contiguous block starting at address 0x00000 rather than several separate files flashed into different addresses, which is how the stock firmware is distributed.  In any case, the command to do the job is

$ python --port /dev/ttyACM0 write_flash 0x00000 AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin --flash_mode dout

This set things right, and the boards once again respond to AT commands!

Saturday, September 14, 2019

Morse code trainer

This is a quick weekend project.  I wanted something that would send random strings of characters in Morse code, grouped into sets of 3 or 4 at at time.  This little box has a power switch, a speaker, a knob for volume, and a knob for sending speed.  It's powered by a 9v battery, and is controlled by an Arduino Nano.  There's really not much else to it except for the code.

Sunday, July 7, 2019

Violin sound pin setting tool

The sound pin in Zachary's violin was inadvertently knocked over.  There's a tool for fixing this problem, and it is not expensive.  However, it was also not available on short notice, so I made one.

The tool is a 1/8" steel rod set in a handle of rosewood.  To make the tip, I hammered the end of the rod into a spade shape, hardened it, and then ground it to a sharp flat blade.  I then bent the rod to fit the shape of the violin, which is a standard 4/4 size.  Afterwards, I polished the rod, oiled it slightly, and set it in the handle.  The handle was a short segment of a hard rose cane I had taken during pruning, and was shaped on the belt sander.

To use the tool, stab the sharp end into the sound pin (grainwise), carefully thread the pin and tool through the F-hole, and then carefully upright the pin just below the treble foot of the bridge. This took me a few tries, but it wasn't too demanding.  Just make sure the bridge is already mostly in place with the strings just barely tightened before you begin, otherwise uprighting the bridge will surely topple the sound pin. 

Friday, July 5, 2019

Clock 4 now runs with intermittent impulsing

"Intermittent" can be a problem, but not in this case!  Based on the numerous power budget calculations I've done, impulsing the pendulum in Clock 4 every minute is too much to ask.  After having gotten the escapement to impulse every period (2 seconds) reliably, with run times around 8 hours, it seemed like the right time to go back to trying to get the intermittent part working again.  Especially, the run times without intermittent escaping were limited by drive cord length -- I had a four fall pulley in place for the clock to run that long. 

Therefore, I added more deep cuts to the count wheel, now five in total.

This means that the escapement should be triggered every 30/5 = 6 pendulum periods, or every 12 seconds.  The pin wheel has 30 pins, so will then have a period of 12 seconds * 30 = 360 seconds = 6 minutes.  The pin wheel is driven through a 1:10 mesh for the drive wheel, so it should make a rotation every hour.  I can therefore drive the minute hand from the drive wheel, although it will run counter clockwise.

With some tuning, the Clock 4 runs with 8 lb of drive weight, directly driving a barrel of 1.2 inches.  The clock's run isn't perfect, as (1) the count wheel double counts immediately following an impulse and (2) sometimes this double-counting skips over an impulse.

But given these issues, Theodore measures the following periods in current configuration:
  • 53 seconds for the count wheel
  • 4 minutes 24 seconds for pin wheel

Given these measurements the drive barrel will make one rotation about every 44 minutes.  In that time, the weight will have dropped 3.7 inches. 

Thus the power consumed is:

3.7 inches / (12 in/ft)  * 8 lb / (44 min * (60 s/min)) = 9.4 * 10^(-4) ft lb / s = 1.28 mW

Wednesday, June 12, 2019

Laser cut equatorial sundials!

Just for fun, here are two laser cut sundials!

They are made from the 20190612_equatorial.svg file in my github repo.  You can't see the shadow of the gnomon on the clear one, but you can totally see it projected (correctly) on the ground!  The etching on the white background didn't show up initially, so I set some ink onto.  It's nothing fancy; I just smeared black whiteboard marker ink over the face of the dial, and then wiped off the excess ink with my hand.  It's not waterproof...

Thursday, May 30, 2019

Astrolabe upgrade

American University's Design and Build Lab got a new laser cutter.  Since the astrolabe I made before was drawn as a set of SVG files, I figured that it might be nice to make another astrolabe on the laser cutter.  Indeed, the result is beautiful!

This astrolabe is cut from 1/4" black acrylic with a 1/8" clear acrylic rete (star chart).  I etched the rete on the back of the clear acrylic, so there is no visible parallax error.  The pointer is 3d printed PLA. The brass hardware was hand turned on my lathe.  All of the hardware is friction fit with no adhesive used.  This astrolabe is for a fixed latitude (39 degrees North), so the center pin is (essentially) permanent.  The movement is smooth, but tight.  This is a nice improvement over my previous astrolabe, in which the hole in the rete has enlarged over time.

Unfortunately, we had trouble aligning the back.  The horizontal alignment is perfect, but it's vertically shifted by about 2 mm.  This means that the elevation scale runs off the top of the astrolabe. None of the back scales are very useful as a result, even though it is still attractive.  I think the cause of the vertical shift was an alignment key (which doubles as the ring attachment point) that we added to the front layer, but not the back layer.  We attempted to compensate for this difference, but evidently failed.  However, the compass scale on the front can still be used for elevation sighting, although this requires subtracting 90 degrees from the reading to obtain elevation.

Monday, May 13, 2019

More power calculations with Woodward's intermittent grasshopper

By joining the count wheel pusher lever of the the Woodward escapement to the escapement trigger, you can make the escapement trigger once per period.  This is the most frequent that the intermittent grasshopper can be triggered.  Triggering every period already happened by accident, but I decided to force it to occur by linking the mechanisms together without using the count wheel.  This way, I could debug the escapement mechanism... and there were indeed problems there.  I think I've resolved them, and this modified mechanism reliably runs until the weight hits the floor.

Currently, the mechanism runs on 1 lb 14 oz, falling 3.9 inches every 10 minutes.  Converting to standard units, this means that the weight falls

3.9 inches * 25.4 mm/inch / (10 min * 60 s/min) = 0.17 mm/s
1 lb 14 oz = 0.85 kg = 8.3 N

Thus the power consumption is 0.17 mm/s * 8.3 N = 1.37 mW.

This is substantially more pessimistic than my previous figure of 0.325 mW averaged over one minute for the count wheel assembly.  This is even with an improvement resulting from a few changes I made.  The pendulum is now hung from two sharp brass points resting in brass cups.

This new hanger ensures a positive positional lock and a definite axis of rotation for the pendulum with substantially less friction than before.

I also made a number of small improvements including reshaping one of the pin wheel pinion teeth, aligning the impulse hook, and stopping the detent's fall a bit earlier.  Finally, I removed every other pin in the pin wheel, which means that the period of the pin wheel is one minute.

Update: 5/13/2019.
By clipping off the tail of the locking detent to make it somewhat more delicately balanced, I can reduce the drive weight by 6.5 oz.  Thus, the power consumption is

3.9 inches * 25.4 mm/inch / (10 min * 60 s/min) * (1.47 lb * 4.43 N/lb) = 1.08 mW.