Matik.Org

Moon Pointer Part Wwo - How to Get Started on ESP32/Micropython

Compiling and installing micropython

After I motivated you to build a moon pointer in the first part, let’s talk about the programming environment next:

I chose micropython on ESP32. The boards are cheap and plentiful, micropython is well supported and comes in double precision floating point, important for astrono mical code. By default, only the official pyboard (highly recommended) supports double precision out of the box, so you need to compile micropython from scratch for other ESP32 boards. The following is piecing together steps from semi-recent memory, I might have forgotten some step. Leave a comment and I will add missing steps.

#define MICROPY_FLOAT_IMPL                  (MICROPY_FLOAT_IMPL_DOUBLE)
PORT ?= /dev/tty.SLAB_USBtoUART
BAUD ?= 460800
FLASH_MODE ?= dio
FLASH_FREQ ?= 40m
FLASH_SIZE ?= 4MB

and adapt parameters depending on your board.

This should give you a micropython prompt if you connect via screen:

% screen /dev/tty.SLAB_USBtoUART 115200
>>> 1 + 1
2
>>>

Check whether the floating point has 52 bits of mantissa:

>>>
>>> for i in range(54): print (1 + 1.0/(1<<i) -1)
...
1.0
0.5
0.25
0.125
0.0625
.
.
.
2.22044604925e-16
0.0
>>> 

Only the last line or two of output should have a 0. If you see 0s after 24 or so non-zero numbers, you have only single precision.

Application development and Blinkenlights

I found it useful to transfer files with ampy, so install it on your dev machine:

%
% pip3 install adafruit-ampy

You may want to setup networking and save network credentials in boot.py (if you are not worried about security implications). See here. It’s also a good idea to re-read what you know about webrepls in case you use them.

I wanted to be able to display a bunch of data and manually control the moon pointer for testing, so I added a tm1638 module (<$5) to display lat/longitude, and to move the pointer manually (and maybe point at things other than the moon). I connected it to 3.3v, GNS, and used GPIO4 as STB, GPIO16 as CLK and GPIO17 as DIO. You can find the driver, tm1638.py on github.

%
% ampy -p /dev/tty.SLAB_USBtoUART put tm1638.py 

Testing that it works, say edit a file called test.py:

import tm1638
import time
from machine import Pin
tm = tm1638.TM1638(stb=Pin(4), clk=Pin(16), dio=Pin(17))

# every 2nd LED on
tm.leds(0b01010101)
time.sleep(1)


tm.show('-160 270') #latitude #longitude
time.sleep(1)

tm.number(-1234567)
time.sleep(1)
tm.hex(0xdeadbeef)
time.sleep(1)

# dim both LEDs and segments
tm.brightness(0)

# all LEDs and segments off
tm.clear()

# get which buttons are pressed
print(tm.keys())

i = 0
while True:
    tm.leds(1<<i)
    i = (i+ 1) % 8
    time.sleep(1)
	

You can then transfer this test.py to the board as main.py, which is executed after each reboot:

%
% ampy -p /dev/tty.SLAB_USBtoUART put test.py main.py
% screen /dev/tty.SLAB_USBtoUART 115200
[CTRL]-C
>>> import test

This should provide hours of entertainment ;)

OK, great. We’ll use that to test the moon pointer code later. Speaking of which, there are a few options out there, e.g.,

  1. Just call a web API. Mooncalc.org has an API

    That’s nice, but as I said, earlier, I like to have the pointer operate in disconnected mode, so I’d like to do the calculations myself. I also like a bit of a challenge, and getting a esp-side calculation was not trivial.

  2. The standard way seems to be to use a huge astronomical library (haha, get the pun?), pyephem, based on “Astronomical Algorithms” by Jean Meeus. This library is big and probably gnarly to port to ESP32, so I did not attempt that. Maybe I should, some time.

  3. There a few other libraries, but the most compact I found was https://github.com/mourner/suncalc, a javascript library that seemed feasible to port to python. So that’s what I did.

    For reference, here are a few other places I found that look interesting:

At this point, I foolishly jumped into the astro code and almost got lost, for a long, long time. Instead following this route, I’ll first describe how to set up the rest of the hardware in part 3, and return to the astro code in part 4.

Written on July 16, 2020