Last updated June 30, 2017
This is a project using an NodeMCU ESP8266, a Waveshare 4.3inch e-Paper display, and optionally a PCB from electronictrik to create an Internet of Things door sign. This variation uses MicroPython on the ESP8266, Flask on a Raspberry PI, and the Google Calendar API.
Here's what I used:
- NodeMCU ESP8266 Development board
- Waveshare 4.3 e-Paper
- High Tech E-paper IoT Door Sign PCB (Optional)
- Raspberry PI 3 Model B (Optional)
- LiPoly charger (Optional)
- 2 SMD switches (Optional)
- 3.7v LiPoly battery (Optional)
WARNING: The way the plug for the battery is drawn on the PCB led to some confusion. When running from battery power the first time, we fried our charger and ESP8266 beyond repair. Check for continuity before powering with a battery: the battery positive should be going to ‘B+’ on the charger and the battery negative should be going to ‘B-’.
display_project
README.md
- device
display.py
display_deep_sleep.py
eink.py (from dhallgb)
secret.py (you make this)
- server
+ env
app.py
client_secret.json (from Google)
helpers.py
requirements.txt
rooms.py (you make this)
First you'll want to download a few things:
- MicroPython for the ESP8266 (recent stable build)
- e-Ink Library for MicroPython
- Custom Project Files
The device side of things has a few dependencies:
- pip: Python package management
- esptool: For flashing the ESP firmware
- ampy: For managing files on the ESP
To determine the path to your ESP8266, start with it unplugged and run this in your terminal:
ls /dev
Now plug in your ESP8266 and run the ls /dev
command again. You should see something new - for me the path to my ESP8266 is /dev/tty.SLAB_USBtoUART
. Now let's flash the firmware (you'll need to replace the path to your device and the path to the firmware):
pip install esptool
esptool.py --port /dev/tty.SLAB_USBtoUART erase_flash
esptool.py --port /dev/tty.SLAB_USBtoUART --baud 115200 write_flash --flash_size=detect 0 esp8266-20170526-v1.9.bin
If you run into any issues, you may need to adjust the baud rate and make sure you're getting enough power to the ESP8266 (I had to use a powered USB hub for this). If you're still having issues, try these steps:
- Start with the ESP8266 unpowered
- Hold down the
FLASH
button - While holding down the button, plug in the ESP8266
- While continuing to hold the button down, run the above
esptool.py
commands - When
esptool.py
connects, release the button
Now's a good time to create a secret.py
file for your ESP8266:
# secret.py
WIFI_SSID = '<YOUR WIFI NETWORK>'
WIFI_PASS = '<YOUR WIFI PASSWORD>'
SERVER_ADDRESS = '<THE FLASK SERVER>'
Now we're going to get the files on the ESP using ampy. The files we need are:
display.py
ordisplay_deep_sleep.py
: this is my custom script for displaying room informationeink.py
: this is the e-ink library by dhallgbsecret.py
: this is the file you created above
The display.py
file will be renamed main.py
so that it gets run after booting:
pip install adafruit-ampy
ampy --port /dev/tty.SLAB_USBtoUART put display.py /main.py
ampy --port /dev/tty.SLAB_USBtoUART put eink.py
ampy --port /dev/tty.SLAB_USBtoUART put secret.py
When we restart the ESP, it will run /main.py
and begin checking in with the Flask server. Realize that display.py
will need to be modified according to your needs (same with the Flask server).
If you need to troubleshoot at this point, you may want to try booting with dhallgb's demo.py
file:
ampy --port /dev/tty.SLAB_USBtoUART put demo.py /main.py
When you boot, you should see some fun displays. The demo is a good place to start to see how the e-Ink library works.
WARNING: Originally I was flashing display.py to /boot.py. I've found that it's best to leave /boot.py alone and use /main.py instead.
I'm not going to get too bogged down in documenting Google's API - their API is already well documented. Here are some resources to lead the way though:
The second link will walk you through getting your client_secret.json
. Then you'll need a room directory so the Flask server can translate room names to calendarIds:
# rooms.py
rooms = {
'moss': '<GOOGLE CALENDARID>',
}
With the Google stuff and a directory of rooms, we should be all set to start the Flask server. We're going to do this in a virtual environment per Flask's suggestion:
virtualenv env
source env/bin/activate
pip install -r requirements.txt
python app.py
The first time you do this, you'll be asked to login to your Google account via a browser popup. Google's code in helpers.py
will save the credentials so that you won't be asked again in the future.
It's recommended that you don't rely on the Flask development server in production. For my prototyping needs it worked (mostly) fine, but a live launch will probably need something like Gunicorn and Nginx.
My code probably isn't going to work for you unless you have a room named Moss. Besides making secret.py
, rooms.py
, and getting client_secret.json
, you'll probably want to change a few things:
# Timezones may need to be updated
# helpers.py
now = datetime.datetime.now(pytz.timezone("US/Pacific")).isoformat()
# app.py
res['todays_date'] = datetime.datetime.now(pytz.timezone("US/Pacific")).strftime('%-m/%-d')
# Each ESP8266 will need to be assigned a room name
# display.py
ROOM_NAME = 'moss'
The ESP8266 reaches out to the Flask server via something like GET http://192.168.1.1/moss
, the Flask server takes the parameter and converts it to the Google CalendarId, a request for the next three events of the day for that room is made with the Google Calendar Resource API, the Flask server formats the response before handing a small JSON file to the ESP8266, and then the ESP8266 displays the data.
The battery life isn't ideal, which is why I'm working on display_deep_sleep.py
to put the ESP8266 into deep sleep in between API calls.
Hopefully this gives some pointers to anyone trying to work with an ESP8266 and E Ink display in MicroPython. Feel free to dig through the source code; I went through and commented everything so it should be pretty accessible.
Thanks for looking!