empowering creative people

Internet of Things with Pycom and Adafruit IO - From Zero to Hero

Introduction

We’re going from zero to hero. Starting from nothing we’ll get a WiPy communicating with Adafruit IO, an IoT service out on the Internet. We’ll be able to send data from the device to the cloud and control the device from the website at Adafruit IO. While this is a long guide it’s the fastest path to Pycom satisfaction. From here you can do anything!

UPDATE! Project code now available on Github.

Requirements

We'll need:

  • Windows PC with WiFi
  • A wireless access point with Internet access
  • Any Pycom board (WiPy 3.0, SiPy, LoPy, GPy or FiPy)
  • Any Pycom expansion board (Expansion Board 2.0, PySense or PyTrack)
  • USB 2.0 Micro-B cable
  • Single jumper wire (male-male)

When using a Pycom board with one of the available expansion boards; orient them with the LED to the USB socket.

WARNING: External aerials must be attached before attaching power to LoRa, Sigfox or cellular LTE devices! That’s LoPy, SiPy, GPy or FiPy.

Driver Setup

I’ll cover only the basics with getting the hardware working. The Pycom documentation is excellent, head to docs.pycom.io for help if you get stuck. After connecting the expansion board to the PC with a micro-USB cable, open Device Manager to see if the Pycom board is set up.

device manager showing fully installed WiPy

Device Manager showing WiPy installed

device manager showing WiPy not installed

Device Manager showing WiPy not installed

Installing the Pycom WiPy manually:

  1. Even in Windows 10 I found the board is not set up automatically. No problem, we can get a link to the correct driver from the Pycom documentation (1.3.1 Updating Firmware).
  2. Scrolling down the page shows all the available drivers. I have a 64-bit Windows system, so I’ll pick that driver.
  3. Once downloaded, extract the file.
  4. Go back to Device Manager and right click on the FT230X Basic UART under Other Devices, pick Update Driver
  5. Choose the option to Browse my computer for driver software … 
  6. Click the Browse button and navigate to the folder where you extracted the download file. Click OK.
  7. Click Next. The driver should be installed. The device is now identified as a USB Serial Converter.
  8. Click Close. The new USB Serial Converter is located under Universal Serial Bus Controllers
  9. If you look under Other devices, you’ll see another device that’s not installed. It’s called USB Serial Port.
  10. Right click on the USB Serial Port under Other Devices, pick Update Driver
  11. Choose the option to Browse my computer for driver software …
  12. The correct folder should already be selected. Click Next.
  13. After installing the device it’s now called USB Serial Port. Click Close
  14. Now in Device Manager you can see the USB Serial Port is now listed under Ports (COM & LPT)
  15. 15. Take a note of the COM number associated with the port. Mine is COM3.

The WiPy is now fully installed.

Firmware Upgrade

It’s quite probable that any issues you might have getting started with a device have already been fixed. So always update your firmware.

  1. Download and install the Pycom Firmware Updater from the Firmware Update Tools page. Allow the app to start at the end of installation but stop on the Welcome screen.
  2. Unplug the USB cable from the WiPy. Add a jumper from G23 to GND. Plug the USB back in.
  3. Work through the Pycom Upgrade wizard. Read everything. This process will not work if don’t follow it fully. But don’t worry about breaking your Pycom device. If it’s not unplugged during the update, it’ll be fine!

After the update is complete you should find your WiPy is broadcasting its own WiFi network called (something like) wipy-wlan-238c. We’ll use this in a minute.

Communicating with the WiPy

Your WiPy is ready to communicate! It can “talk” Telnet and FTP right out of the box. Because MicroPython doesn’t need to be compiled first then uploaded, we can write code and run it immediately. Python calls this Read-Evaluate-Print-Loop, or REPL for short. You need a Telnet application (like PuTTY) to do this. Here’s what it looks like:

using putty

Using PuTTY to Telnet directly to the WiPy

Check the documentation for more: 2.3.2 Telnet and 2.4 FTP.

Software Setup

So that we can have a nice place to write code for our Pycom devices, we need an Integrated Development Environment (IDE). This will give use a REPL prompt, like Telnet, as well as the ability to create multiple code files, run these directly on the device and upload/download features. Atom is good, so we’ll install that.

The Atom IDE

atom ide

The Atom IDE

  1. Go to Atom on Github and scroll down the page to find the Windows heading. Find the Atom installer link and click that to go to the download page for the latest version of Atom.
  2. There are all kinds of downloads available. If you’re using 64-bit Windows version, download the AtomSetup-x64.exe file, otherwise get AtomSetup.exe.
  3. After downloading, run the file to install the Atom IDE. It’s fully automatic. When Atom is installed it will open by itself.
  4. A dialog will be asking to Register as default atom:// URI handler?. Click Yes, Always.
  5. Below that question, find Install a Package and click it. Then click Open Installer.
  6. The left side of Atom now shows the Install Packages heading.
  7. Search for pymakr. When the latest pymakr package is found, install it. It might take a minute or two.

Atom is now installed and pymakr is ready to communicate with the WiPy. At this point Atom should have opened an empty panel across the bottom of the application. It should be Connecting on 192.168.4.1… but failing. We mentioned the WiPy will broadcast its own WiFi network. We need to join it now. When I look at the list of networks near my computer, one is called wipy-wlan-238c. That’s the one I will use. Join this WiFi network using the username micro and password python.

wifi networks list

WiFi networks list

Having joined to the network created by the WiPy we can now go back to Atom and click in the bottom panel to connect. When connected, you’ll see a triple “greater than” which is the command prompt for MicroPython.

Trying It Out

Tradition dictates our first program should print out “Hello World”. Boring. Let’s print something else!

pycom rocks

Pycom ROCKS!

You may have noticed the WiPy gives a blue flash “heartbeat” ever 4 seconds. That LED is something we can play with. Have a look at the RGB LED page in the Tutorials & Examples section of the Pycom documentation. When I enter this code, I get a bright green on the LED:

>>> print("Pycom ROCKS!")
Pycom ROCKS!
>>> import pycom
>>> pycom.heartbeat(False)
>>> pycom.rgbled(0x00FF00)
>>>

This ability to write code directly on the microcontroller isn’t available on some other device. If you know Arduino, then you’ll know you need to Verify (compile) and Upload (transfer) your entire project every time you want to run it. But MicroPython can Read, Evaluate, Print and Loop (REPL) without any compile or upload process. Fantastic!

Switching to Serial

Because we want to connect our WiPy to the Internet to do cool things, we need to change over to communicating with it by serial. We can do this simply in the Atom IDE. One of the tabs open should be called Settings. You can close the rest. If we scroll down in Settings, we can find the Device Address box. Let’s replace Default 192.168.4.1 with COM3 (Use the COM number you saw in Device Manager earlier). You should be able to Disconnect and Connect using the buttons above the REPL prompt.

Adafruit IO Configuration

Now we need to configure our “IoT cloud service” so the WiPy has something to communicate with.

  1. Go to Adafruit IO
  2. Click Get Started for Free at the top of the page
  3. Fill in the form, you only need an email address. Click Create Account at the bottom.
  4. Jump back to Adafruit IO, the top of the page should show you’re signed in.
  5. Hit the Learn link in the menu to find out how it works!

The project I’ve contrived is one where the WiPy creates random numbers and sends them to Adafruit IO every 5 seconds. We want Adafruit IO to make a nice graph from them. We also want the WiPy to be controllable from Adafruit IO, so we’ll use a Toggle Button on the website to send messages back to the WiPy. It shouldn’t be too hard to make both things work at the same time.

adafruit io dash

Adafruit IO Dashboard

Adafruit IO uses ‘feeds’ to describe separate sets of data. We’ll create a feed called ‘randoms’ and one called ‘lights’. We’ll also create a dashboard with a graph of the random numbers and a toggle to send an ON/OFF command to the WiPy via the ‘lights’ feed.

As per Adafruit IO Basics tutorial:

  1. In Adafruit IO, click Feeds in the navigation
  2. Scroll to the bottom of the page. From the Actions menu, select Create a New Feed.
  3. Name this feed randoms. Click Create.
  4. Add a second feed called lights

We’ll add a line chart as well:

  1. Click Dashboards on the navigation.
  2. Scroll to the bottom of the page. From Actions menu, select Create a New Dashboard. Name your dashboard. Click Create.
  3. When you get back to the dashboard list, click the name of the dashboard you just created.
  4. Click the blue + button to Create a New Block. Pick Line Chart.
  5. We now have to link it to a feed so there’s data for the chart. Select randoms then click Next step
  6. We can just use the default values for the chart. Click Create Block.
  7. Click the blue + button again and add a Toggle
  8. Connect it to the lights feed
  9. Accept the default configuration for the toggle

Done. When the Python code is done the WiPy can respond to changes to the Lights toggle. We now have an Internet “cloud” service ready to talk to our WiPy. We also have the WiPy set up so we can develop software on it. Great!

Atom Project

To more easily manage our files, we should create an Atom project. This is just a folder.

  1. From the File menu, click Open Folder...
  2. Navigate to where you’d like to put your project folder.
  3. While still inside the Open Folder dialog, create a new folder by right-clicking in the file list area
  4. Give your new folder a descriptive name
  5. A new Atom window opens and a Project pane is shown on the left. We can close the previous Atom window now.

If your WiPy is squeaky clean and new it will only have the files boot.py and main.py on it. If not, you can reset it.

  1. Click in the lower pane to connect to the WiPy. Ensure you’re connected on a COMx port, not on IP address (192.168.4.1)
  2. Click the Download button to pull back a copy of the files on the WiPy. You should get boot.py and main.py. If the download fails, press the reset switch on the WiPy, then try again.

Let’s create a new code file that we can experiment with. From the File menu, pick New File then save it straight away. I’m going to call mine AdafruitIO.py. As this tutorial is already very long, I’ll skip a full walkthrough on the code. I have documented the code and that should be sufficient to give you an understanding of what it does and why. Here is the WiPy code file: [github link]. Paste this code into your new code file; I’m putting mine into AdafruitIO.py.

# https://github.com/micropython/micropython-lib/blob/master/umqtt.simple/example_sub_led.py

from network import WLAN      # For operation of WiFi network
import time                   # Allows use of time.sleep() for delays
import pycom                  # Base library for Pycom devices
from umqtt import MQTTClient  # For use of MQTT protocol to talk to Adafruit IO
import ubinascii              # Needed to run any MicroPython code
import machine                # Interfaces with hardware components
import micropython            # Needed to run any MicroPython code

# BEGIN SETTINGS
# These need to be change to suit your environment
RANDOMS_INTERVAL = 5000 # milliseconds
last_random_sent_ticks = 0  # milliseconds

# Wireless network
WIFI_SSID = "IoT"
WIFI_PASS = "password77#" # No this is not our regular password. :)

# Adafruit IO (AIO) configuration
AIO_SERVER = "io.adafruit.com"
AIO_PORT = 1883
AIO_USER = "CoreChris"
AIO_KEY = "83e6218dc6ad47d698ab1747566f3561"
AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id())  # Can be anything
AIO_CONTROL_FEED = "CoreChris/feeds/lights"
AIO_RANDOMS_FEED = "CoreChris/feeds/randoms"

# END SETTINGS

# RGBLED
# Disable the on-board heartbeat (blue flash every 4 seconds)
# We'll use the LED to respond to messages from Adafruit IO
pycom.heartbeat(False)
time.sleep(0.1) # Workaround for a bug.
                # Above line is not actioned if another
                # process occurs immediately afterwards
pycom.rgbled(0xff0000)  # Status red = not working

# WIFI
# We need to have a connection to WiFi for Internet access
# Code source: https://docs.pycom.io/chapter/tutorials/all/wlan.html

wlan = WLAN(mode=WLAN.STA)
wlan.connect(WIFI_SSID, auth=(WLAN.WPA2, WIFI_PASS), timeout=5000)

while not wlan.isconnected():    # Code waits here until WiFi connects
    machine.idle()

print("Connected to Wifi")
pycom.rgbled(0xffd7000) # Status orange: partially working

# FUNCTIONS

# Function to respond to messages from Adafruit IO
def sub_cb(topic, msg):          # sub_cb means "callback subroutine"
    print((topic, msg))          # Outputs the message that was received. Debugging use.
    if msg == b"ON":             # If message says "ON" ...
        pycom.rgbled(0xffffff)   # ... then LED on
    elif msg == b"OFF":          # If message says "OFF" ...
        pycom.rgbled(0x000000)   # ... then LED off
    else:                        # If any other message is received ...
        print("Unknown message") # ... do nothing but output that it happened.

def random_integer(upper_bound):
    return machine.rng() % upper_bound

def send_random():
    global last_random_sent_ticks
    global RANDOMS_INTERVAL

    if ((time.ticks_ms() - last_random_sent_ticks) < RANDOMS_INTERVAL):
        return; # Too soon since last one sent.

    some_number = random_integer(100)
    print("Publishing: {0} to {1} ... ".format(some_number, AIO_RANDOMS_FEED), end='')
    try:
        client.publish(topic=AIO_RANDOMS_FEED, msg=str(some_number))
        print("DONE")
    except Exception as e:
        print("FAILED")
    finally:
        last_random_sent_ticks = time.ticks_ms()

# Use the MQTT protocol to connect to Adafruit IO
client = MQTTClient(AIO_CLIENT_ID, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY)

# Subscribed messages will be delivered to this callback
client.set_callback(sub_cb)
client.connect()
client.subscribe(AIO_CONTROL_FEED)
print("Connected to %s, subscribed to %s topic" % (AIO_SERVER, AIO_CONTROL_FEED))

pycom.rgbled(0x00ff00) # Status green: online to Adafruit IO

try:                      # Code between try: and finally: may cause an error
                          # so ensure the client disconnects the server if
                          # that happens.
    while 1:              # Repeat this loop forever
        client.check_msg()# Action a message if one is received. Non-blocking.
        send_random()     # Send a random number to Adafruit IO if it's time.
finally:                  # If an exception is thrown ...
    client.disconnect()   # ... disconnect the client and clean up.
    client = None
    wlan.disconnect()
    wlan = None
    pycom.rgbled(0x000022)# Status blue: stopped
    print("Disconnected from Adafruit IO.")

Hit the Run button below the code in Atom. You should get an error:

>>>
>>> Traceback (most recent call last):
  File "", line 10, in 
ImportError: no module named 'umqtt'
>
MicroPython v1.8.6-849-d0dc708 on 2018-02-27; WiPy with ESP32
Type "help()" for more information.
>>>
>>>

The top of our code file contains the line from umqtt import MQTTClient. But the error says ImportError: no module named 'umqtt'. This is because umqtt is not built-in to MicroPython. It’s a code file we need to add to our project. So:

  1. Add a new file to the project, call it umqtt.py
  2. Open this code file from github. It’s called simple.py, but we’ll paste this code into our umqtt.py file.
  3. Copy and paste the code from simple.py into your umqtt.py file.
  4. Save umqtt.py.

Now click the Run button again. What happened? We got the same error again. Why? Well, although we’ve added umqtt.py to our project, we don’t have a copy of it yet on our WiPy. We need to Upload it first. So hit the Upload button. Wait for the prompt to return, then hit Run again.

This time you should see the WiFi is connected and, if the connection to Adafruit IO succeeds, the RGB LED on the WiPy turns green. If you open the dashboard on Adafruit IO you can see a new number being graphed every 5 seconds. When you operate the toggle switch you should see the RGBLED on the WiPy turning on (white) and turning off.

Making the WiPy Run at Start

To make our WiPy run the AdafruitIO.py code at startup we can just copy the code into main.py and upload it. Now when the WiPy is powered it will immediately run main.py and connect to Adafruit IO. Now you can see that the RGB LED is very useful for displaying the internal status of the program. As per the notes in the code: red = not connected, orange = WiFi connected, and green = Adafruit IO connected. When we cancel the program, it turns blue.

We now need to remember that when the WiPy is powered it immediately runs the application we uploaded. You can’t connect to it on 192.168.4.1 anymore because the internal WiFi is requesting and receiving an IP address from the local network. Remember that you can use the built in COM port to gain access. If you want to run in “hands off” mode, you should set up your boot.py to configure the WiFi to use a fixed IP address.

That’s it then! I hope this helps you to prototype your big IoT idea.

Introduction We’re going from zero to hero. Starting from nothing we’ll get a WiPy communicating with Adafruit I...

Have a question? Ask the Author of this guide today!