How to control addressable RGB lights with a ESP8266. Part 3 of 3. Episode 1 of 2.
Tags: micropython, neopixel, tutorial
Published: 2021-04-11 01:33:23

This blog will cover setting up the API response from the ESP8266. The final blog on this topic will cover the website to interact with the controller. This was too much to cover in one blog, so it needed to be split again.


### boot.py

Micropython has two files that are run automatically without having to invoke them. `boot.py` and `main.py` are run in that order with main beginning after boot finishes. Another notable feature is both files share the same namespace. Everything that is `boot.py` is available in `main.py` as if they are the same file. There isn't a particular reason to favor one over the other. You can place all of your code in either file and it will execute. Unlike Arduino main loops, `main.py` is not looped and is only called once. If your program requires a loop, you will have to create it yourself.

The way I use the files is to place configuration and functions in `boot.py` and place timer instantiation or loops in `main.py`. The best use I've found is to start WiFi connections in `boot.py` since you can be confident that the network connection will be done by the time the main program is called, and if your program depends on connectivity, your code can sleep and reboot before calling your program to try again if the network isn't available.

The following is the `boot.py` we are using.
```python
from machine import Pin
from micropython import const
import gc
from neopixel import NeoPixel
from network import WLAN, STA_IF
import ESP8266WebServer as ws

station = WLAN(STA_IF)
ssid = <your SSID>
psk = <your password>

class LightController:
  def __init__(self, *args, **kwargs):
    self.ledData = {
      'color':'white',
      'status':'off'
    }
    self.light_len = const(5)
    self.pixel = NeoPixel(Pin(2), self.light_len)
    self.all_off()
  
  def all_off(self):
    for i in range(self.light_len):
      self.pixel[i] = (0, 0, 0)
    self.pixel.write()
    self.ledData['status'] = 'off'

  def all_on(self, color = 'white'):
    for i in range(self.light_len):
      if color == 'white':
        self.pixel[i] = (200, 200, 200)
      if color == 'red':
        self.pixel[i] = (200, 0, 0)
    self.pixel.write()
    self.ledData['color'] = color
    self.ledData['status'] = 'on'

lights = LightController()

def handleOff(socket, args):
  lights.all_off()
  ws.ok(socket, '200')

def handleWhite(socket, args):
  lights.all_on(color='white')
  ws.ok(socket, '200')

def handleRed(socket, args):
  lights.all_on(color='red')
  ws.ok(socket, '200')

if not station.isconnected():
  station.active(1)
  station.connect(ssid, psk)
  while not station.isconnected():
    pass
  print(station.ifconfig())

ws.onPath('/off', handleOff)
ws.onPath('/red', handleRed)
ws.onPath('/white', handleWhite)

ws.setDocPath('/')
ws.setTplData(lights.ledData)

ws.begin()
```

This gets almost everything going that we need. The ESP8266WebServer that we imported will respond to the routes we set up and invoke the functions that wrote. This is a work in progress and can certainly be improved, but this should cover the basic functionality of what I'm trying to accomplish. The only thing left is to invoke the server and start responding to clients. We put this in `main.py`

### main.py

```python
try:
  while 1:
    ws.handleClient()
except:
  ws.close()
```

That's it. This should not block REPL access over serial if you connect to the board after loading this. I prefer rshell for file copy, there are plenty of tutorials. If you follow this guide and use rshell, the board contents are available via `/pyboard` from the rshell prompt. You can copy your `boot.py` and `main.py` using rshell or you can copy them into the /modules subfolder in the ESP8266 directory of the microypthon repo. Just follow the guides available for "freezing micropython modules" or build the firmware as in step on of this guide, but placing your created files in the /modules folder before building.

The final part of this blog, we will create a simple reactjs app to talk to the ESP8266 and turn the lights on and off for us via a web interface.