Skip to main content

Programming the ESP8266 pHAT from the Raspberry Pi

There are lots of guides on programming an ESP8266 micro-controller, and several on doing this from Linux  and/or from a Raspberry Pi. However I encountered a few gaps in the complete process.
Disclaimer: I am not an electronics expert, I did an "O/A Level" in the topic about 30 years ago!

This article will 

  • provide a short guide to getting started with the ESP8266 pHAT from Pimoroni (also known as the ESP IoT pHAT), referencing the established guides
  • setting the permissions on the /dev/ttyAMA0 serial port
  • installing the commandline firmware uploader platformio
  • configuring a project

Getting Started

The ESP8266 pHAT is a simple esp12f (essentially the same as the esp12e) micro-controller linked to the Pi via the GPIO header, and exposes several digital GPIO pins and the ADC pin
See the pin-out for connectivity

The first steps in getting started are covered nicely in these articles:
 the first has a clear guide in using the AT commands to test and set the wifi.

Flashing the OEM firmware (and a couple of alternatives)

Pimoroni also provide the firmware to be able to reflash (since the OEM firmware is otherwise difficult to track down and install)
You can reflash the firmware using the following
https://github.com/pimoroni/espiot-phat/tree/master/firmware

$ git clone https://github.com/pimoroni/espiot-phat/tree/master/firmware
which provides a number of python scripts

Programming from the command line

In order to program the ESP8266 (ie create programes , compile the new firmware and flash the microcontroller) from the command line a good tool is platformIO for Core .
A guide to installing platformIO is here:

serial port permissions

Despite following the instructions, and copying the appropriate "udev" rules, I still had issues with the permission on the serial port. Rather than having to use the tool as root, I performed the following change
  1. ensure the user ( [pi] in my case ) is a member of the dialout group
    • $ sudo usermod -a -G dialout pi
  2. change the group ownership of  the serial port
    • $ sudo systemctl mask serial-getty@ttyAMA0.service

creating a simple program

The ubiquitous "blink" program is found in many places. For the Arduino, it blinks the onboard led. For my case, I connected pin 16 (which would appear to be the pin number for LED_BUILTIN) to a 10k resistor, to the anode (+, longer wire) of a simple LED, and the cathode (1, shorter wire / notched) to the GND (ground)

$ mkdir blink
$ cd blink
$ platformio init --board=esp12e
$ echo "upload_port = /dev/ttyAMA0" >> platformio.ini
$ echo "upload_speed = 115200" >> platformio.ini

src/blink.cpp:
#include "Arduino.h"

int ledPin = LED_BUILTIN;
void setup() {
pinMode(ledPin, OUTPUT);
}

void loop() {
digitalWrite(ledPin, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(ledPin, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}


setting  firmware mode

So now the command for uploading the firmware works
$ platformio run --target uploadbut the esp chip doesn't get put into the correct flash mode, without manually doing it using the espflash.py script
The best solution I could work out was to make a custom pre/post script for the --target upload command
http://docs.platformio.org/en/latest/projectconf.html#before-pre-and-after-post-actions
by creating a "extra_scripts.py" that incorporates the essence of espflash.py
and add that to the platformio.ini

platformio.ini:
[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
upload_port = /dev/ttyAMA0
upload_speed = 115200
extra_script = extra_script.py


extra_script.py:
Import("env")
from time import sleep
import RPi.GPIO as GPIO


# declaration of chip reset and program pins
def GPIO_custominit():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(17,GPIO.OUT,initial=1)
    GPIO.setup(27,GPIO.OUT,initial=1)

#
#  Upload actions
#

def before_upload(source, target, env):
    print "before_upload"
    # do some actions
    GPIO_custominit()
    # bringing chip into program mode
    GPIO.output(17,0)
    sleep(0.5)
    GPIO.output(27,0)
    sleep(0.5)
    GPIO.output(17,1)
    sleep(0.5)
    GPIO.output(27,1)
    sleep(1.5)
    # information for user
    print "Your board is now in firmware mode"


def after_upload(source, target, env):
    print "after_upload"
    # do some actions
    # resets the board
    GPIO.cleanup()
    GPIO_custominit()
    GPIO.output(17,0)
    sleep(2)
    GPIO.output(17,1)
    sleep(0.5)
    # clean exit
    GPIO.cleanup()

print "Current build targets", map(str, BUILD_TARGETS)

env.AddPreAction("upload", before_upload)
env.AddPostAction("upload", after_upload)

Comments