Device Configuration#

Device configuration files define the names and files on microcontrollers.

They are in yaml format and located in $IOT_PROJECTS/devices. One or more configurations may by saved in the same or different files. The file name does not matter but must end with .yaml.

Device Name#

ide49 refers to devices by their UID, obtained from the micrcocontroller by executing

uid = bytes(6)
try:
    import machine
    uid = machine.unique_id()
except:
    import microcontroller
    uid = microcontroller.cpu.uid
print(":".join("{:02x}".format(x) for x in uid), end="")

The %discover magic shows un-named devices by their UID.

%discover
30:ae:a4:30:84:34  serial:///dev/ttyUSB1  

Names are assigned in yaml configuration files stored in folder $IOT_DEVICES/devices. Create this directory (in case it does not exist already).

!mkdir -p $IOT_PROJECTS/devices

Now create the configuration file. Don’t forget to update the UID in the cell below to match your microcontroller. You can also change the name (esp32) to something more descriptive or change it later. The name of the file is irrelevant, but it must have the extension yaml. You can create as many configurations files as you wish if you have several devices.

%%writefile $IOT_PROJECTS/devices/example.yaml
esp32:
    uid: 30:ae:a4:30:84:34
Writing /home/iot/iot49.org/docs/projects/devices/example.yaml

Now the device is known by its name.

%discover
%connect esp32
esp32  serial:///dev/ttyUSB1  
Connected to esp32 @ serial:///dev/ttyUSB1

File Management#

Copying all necessary libraries and other files to microcontrollers can be tedious. ide49 helps with this. In addition to low level magics (%cp, %rm, …), the following magics help with the process:

  • %rlist: list all files on the presently connected microcontroller

  • %rdiff: show the difference between files on the host and microcontroller

  • %rsync: copy & delete files to synchronize the microcontroller and the host

Which files to copy to a particular microcontroller is defined in its device configuration.

The following configuration entry copies all files in $IOT_PROJECTS/balance/code to the microcontroller.

%%writefile $IOT_PROJECTS/devices/example.yaml
esp32:
    uid: 30:ae:a4:30:84:34
    path: balance
    resources:
        - code
Writing /home/iot/iot49.org/docs/projects/devices/example.yaml
%%bash

cd $IOT_PROJECTS/balance/code
ls -R
.:
lib
main.py

./lib:
ble_advertising.py
ble_uart_peripheral.py
button.py
scale.py
ssd1306.py
# show differences without making changes
%rdiff
ADD     /lib/ble_advertising.py
ADD     /lib/ble_uart_peripheral.py
ADD     /lib/button.py
ADD     /lib/scale.py
ADD     /lib/ssd1306.py
ADD     /main.py

Commit the differences. By default, %rsync copies all specified files from the host to the micrcontroller and deletes files on the microcontroller that are not also on the host. Use the -u flag to only upload files but not delete any. It is also possible to specify filters, e.g. to copy only files of certain types or to ignore entire folders on the microcontroller or host from synchronization.

%rsync
ADD     /lib/ble_advertising.py
ADD     /lib/ble_uart_peripheral.py
ADD     /lib/button.py
ADD     /lib/scale.py
ADD     /lib/ssd1306.py
ADD     /main.py

%rsync uses the file size and modification time to determine if a file needs updating.

!touch $IOT_PROJECTS/balance/code/lib/scale.py
%rsync
UPDATE  /lib/scale.py

Configuration files are quite flexible. The code searches for files on the host in $IOT_PROJECTS/libs and copies them the the microcontroller.

%%writefile $IOT_PROJECTS/devices/example.yaml
esp32:
    uid: 30:ae:a4:30:84:34
    path: libs
    resources:
        - code:
            path: balance
        - neopixel.py
        - vl53l0x.py:
            install-dir: /lib
        - bno055: /lib
Writing /home/iot/iot49.org/docs/projects/devices/example.yaml
%rdiff
ADD     /lib/bno055.py
ADD     /lib/bno055_base.py
ADD     /lib/bno055_test.py
ADD     /lib/vl53l0x.py
ADD     /neopixel.py
UPDATE  /lib/scale.py

path specifies where files can be found on the host, install-dir (default: /) determines where files copied to on the microcontroller. If a resource (e.g. bno055 in the above example) refers to a directory on the host, the contents are copied. This behavior is different for packages: if a __init__.py file is present in the directory, it will be copied verbatim.

Reference#

Sample Folder Layout on the Host#

Example:

~/projects/
    libs/
        neopixel.py
        bno055/
            bno055.py
            bno055_base.py
            bno055_test.py
    my_project/
        code/
            main.py
            lib/
                adc.py
                robot/
                    motor.py
                    encoder.py    

Annotated Configuration#

name:
    uid: 24:0a:02:12:87:7c
    path: my_project      # relative to $IOT_PROJECTS, 
                          # Default: .
    install-dir: /flash   # location of files on microcontroller
                          # Default: /
    include-patterns:     # Files/folders to include
        - "./**/*.py"     
        - "./**/*.mpy"
        - "./**/"
    exclude-patterns:     # Files/folders to ignore (on host and MCU)
        - "boot_out.txt"
        - "/data"    
    resources:
        - file1.py        # single file in $IOT_PROJECTS/my_project
                          # copied to /flash
        - file2.py: /lib  # copied to /lib
        - file3.py:       # override values specified above:
            path: libs    # $IOT_PROJECTS/my_project/libs/file3.py copied to /
            install_dir: /
        - dir1            # contents of folder copied /flash
        - dir2:           # folder dir2 copied /flash
            unpack: false
        - dir3: /ssd      # contents of /ssd copied to /flash
        - package1        # if package1 contains __init__.py,
                          # entire folder (not just contents) is copied
        - package2:       # force unpacking:
            unpack: true  # only contents are copied

Include patterns are processed by glob and exclude uses the fnmatch. The defaults are:

  • include-patterns: ./**/*.py, ./**/*.mpy, ./**/

  • exclude-patterns: boot_out.txt

Use the %rdiff and %info -v magics to diagnose complex configurations.

%info -v
Hide code cell output
name            esp32
platform        esp32
implementation  micropython
uid             30:ae:a4:30:84:34
url             serial:///dev/ttyUSB0
configuration   example.yaml
resources:
   317 /secrets.py                    libs/secrets.py
    51 /webrepl_cfg.py                internet/code/webrepl_cfg.py
  1737 /boot.py                       internet/code/boot.py
  6479 /lib/mqtt_client.py            internet/code/lib/mqtt_client.py
  3181 /lib/urequests.py              internet/code/lib/urequests.py
  1883 /lib/http_server.py            internet/code/lib/http_server.py

secrets.py#

A Python file at $IOT_PROJECTS/libs/secrets.py is used to define confidential information such as passwords.

Example:

# secrets.py

# wifi
wifi_ssid = 'WIFI_SSID'
wifi_pwd  = 'WIFI_PASSWORD'

# timezone
tz_offset = -8*3600    # PST

# mp wireless "repl" password
mp_pwd  = '&(*HFODjp429sdf30i%^&'

# webrepl password, 4 .. 9 characters
webrepl_pwd = 'fjlk4lsad'

# https://openweathermap.org/
openweathermap_apiid = "354f336ac61adsf2b73af8f"

Some of these variables (e.g webrepl_pwd) are accessed by MicroPython and ide49.