MicroPython

Learn how to connect to the Arduino Cloud using MicroPython.

Introduction

This tutorial guides you on how to use the MicroPython library to connect your Arduino device to the Arduino Cloud. As a minimal example we will toggle the on-board LED using an Arduino Cloud dashboard widget.

It requires your board to have a version of MicroPython installed, which is covered in this article.

To find our full MicroPython documentation, head over to the MicroPython Docs page.

Goals

The goals of this tutorial are:

  • Connect your Arduino device to your Wi-Fi® network.
  • Connect your Arduino device to the Arduino Cloud via MicroPython.
  • Control an LED using the Arduino Cloud.

Hardware & Software Needed

To install MicroPython, read the MicroPython Installation Guide written for all Arduino boards.

Cloud Setup

Before we start, make sure you have MicroPython installed on your board. If you haven't you can follow this tutorial.

Then, we need to configure a Thing in the Arduino Cloud consisting of two boolean variables called

led
and
ledSwitch
. Follow the instructions below to do so.

Thing & Device Configuration

  1. Create a new Thing, by clicking on the "Create Thing" button.
  2. Click on the "Select Device" in the "Associated Devices" section of your Thing.
  3. Click on "Set Up New Device", and select the bottom category ("Manual Device"). Click continue in the next window, and choose a name for your device.
  4. Finally, you will see a new Device ID and a Secret Key generate. You can download them as a PDF. Make sure to save it as you cannot access your Secret Key again.
Device Key.
Device Key.

Create Variables

Next step is to create some Cloud variables, which we will later interact with via a MicroPython script.

  1. While in Thing configuration, click on "Add Variable" which will open a new window.
  2. Name your variable
    led
    and select it to be of an
    boolean
    type.
  3. Click on "Add Variable" at the bottom of the window.
  4. Create another variable, name it
    ledSwitch
    and select it to be
    boolean
    type.

You should now have two variables:

  • led
    - boolean
  • ledSwitch
    - boolean

It is important that they are named exactly like this, as we will be using them in the example script of this guide.

Your Thing should look something like this when you are finished:

Finished Thing interface.
Finished Thing interface.

Learn more about how variables work in the Variables documentation

Create Dashboard

When finished with creating your Thing, we also need to create a dashboard, a tool to monitor & interact with the Cloud variables.

  1. Go to the dashboards section, and create a new dashboard.
  2. In the dashboard, first create a LED widget, and link it to the
    led
    variable we created earlier.
  3. Create a Switch widget, and link it to
    ledSwitch
    .
  4. You should now have two widgets, looking something like the image below:
Dashboard with LED & Switch widgets.
Dashboard with LED & Switch widgets.

We are now finished with the Arduino Cloud configuration, and we can proceed with the MicroPython setup.

MicroPython Setup

In this section, we will install the Arduino IoT Cloud Python library on the Arduino board, and run a script that synchronizes the board with the Arduino Cloud.

Create Secret.py File

During the device configuration, you obtained a device ID and secret key. These details can be stored, along with your Wi-Fi® credentials, in a

secrets.py
file. Here is an example of how
secrets.py
should look like:

1WIFI_SSID = "myNetwork" # Network SSID
2WIFI_PASSWORD = "passwordForWiFi" # Network key
3DEVICE_ID = b"ef77wer88-0432-4574-85e1-54e3d5cac861"
4CLOUD_PASSWORD = b"TQHFHEKKKLSYMPB1OZLF"

In a MicroPython editor, you can create this file, and save it on your board running MicroPython.

This file should be copied over to the flash drive that mounts when MicroPython boots. To do so you can use the file manager tool in Arduino Lab for MicroPython. Please note that the latter option is not recommended as the file system can potentially get corrupted when copying files manually.

Install Cloud Library

To install the Arduino Cloud (Micro)Python library on your board, you can use the Python based tool

mpremote
. This requires Python to be installed. On macOS and Linux Python usually comes pre-installed. If it's not installed on your system you may download it from here. Then, to install
mpremote
you can use pip:

1$ pip install mpremote

Run

mpremote connect list
to retrieve the serial number of your device. The output will look similar to this:

1/dev/cu.usbmodem3871345733302 335B34603532 2341:055b Arduino Portenta Virtual Comm Port in HS Mode

Pass this serial number (the second value) to the install command:

1$ mpremote connect id:335B34603532 mip install github:arduino/arduino-iot-cloud-py

This will install the library and all required dependencies on the board. Another option is to manually copy the files from the library's repository to the board's file system. It's good practice to put those files into a folder called

lib
to have the files organized neatly.

For more options on how to install libraries on your board, check out our Installing Modules Guide.

Programming the Board

Here is the example code to copy and paste into your program. It connects your device to Arduino Cloud over Wi-Fi®.

1from machine import Pin
2import time
3import network
4import logging
5from arduino_iot_cloud import ArduinoCloudClient
6
7from secrets import WIFI_SSID
8from secrets import WIFI_PASSWORD
9from secrets import DEVICE_ID
10from secrets import CLOUD_PASSWORD
11
12led = Pin("LED_BUILTIN", Pin.OUT) # Configure the desired LED pin as an output.
13
14def on_switch_changed(client, value):
15 # Toggles the hardware LED on or off.
16 led.value(not value)
17 # Depending on the board you use you may need to use "led.value(value)" instead
18 # so that the LED's state reflects correctly the boolean value.
19
20 # Sets the value of the Cloud variable "led" to the current state of the LED
21 # and thus mirrors the hardware state in the Cloud.
22 client["led"] = value
23
24def wifi_connect():
25 if not WIFI_SSID or not WIFI_PASSWORD:
26 raise (Exception("Network is not configured. Set SSID and passwords in secrets.py"))
27 wlan = network.WLAN(network.STA_IF)
28 wlan.active(True)
29 wlan.connect(WIFI_SSID, WIFI_PASSWORD)
30 while not wlan.isconnected():
31 logging.info("Trying to connect. Note this may take a while...")
32 time.sleep_ms(500)
33 logging.info(f"WiFi Connected {wlan.ifconfig()}")
34
35if __name__ == "__main__":
36 # Configure the logger.
37 # All message equal or higher to the logger level are printed.
38 # To see more debugging messages, set level=logging.DEBUG.
39 logging.basicConfig(
40 datefmt="%H:%M:%S",
41 format="%(asctime)s.%(msecs)03d %(message)s",
42 level=logging.INFO,
43 )
44
45 # NOTE: Add networking code here or in boot.py
46 wifi_connect()
47
48 # Create a client object to connect to the Arduino Cloud.
49 # For MicroPython, the key and cert files must be stored in DER format on the filesystem.
50 # Alternatively, a username and password can be used to authenticate:
51 client = ArduinoCloudClient(device_id=DEVICE_ID, username=DEVICE_ID, password=CLOUD_PASSWORD)
52
53 # Register Cloud objects.
54 # Note: The following objects must be created first in the dashboard and linked to the device.
55 # This Cloud object is initialized with its last known value from the Cloud. When this object is updated
56 # from the dashboard, the on_switch_changed function is called with the client object and the new value.
57 client.register("ledSwitch", value=None, on_write=on_switch_changed, interval=0.250)
58
59 # This Cloud object is updated manually in the switch's on_write_change callback to update the LED state in the Cloud.
60 client.register("led", value=None)
61
62 # Start the Arduino Cloud client.
63 client.start()

Explanations:

  • wifi_connect()
    - Connects to your local Wi-Fi® using the credentials specified in secrets.py.
  • client.register
    - Registers a variable that will be synced with the Cloud.
  • on_switch_changed
    - Is the callback that gets executed when the
    ledSwitch
    variable is changed by toggling the switch on the Cloud dashboard. This function in turn toggles the on-board LED and updates the Cloud variable
    led
    that reflects the state of the on-board LED to be displayed in the Cloud dashboard.
  • client.start()
    - Enters a loop that runs as long as the board is connected to the Cloud and synchronises data as it runs.

Testing It Out

Open Arduino Lab for MicroPython and connect to your board. Pasting the above code and run the script. Then open your Arduino Cloud dashboard. You should see the registered "ledSwitch" and "led" widgets. Toggle the "ledSwitch", and the LED on your Arduino board should light up accordingly. The state of the "led" variable should also change, mirroring the state of the physical LED.

Using Advanced Cloud Variables

To use variables in Arduino Cloud that are not of a basic type, you can set them up like you would do with any other variable. For example, to control a colored light such as the on-board RGB led on some Arduino boards, you can create a variable of type

CloudColoredLight
.

Variable creation in Arduino Cloud
Variable creation in Arduino Cloud

On the programming side, you need to import the corresponding class in MicroPython. For the colored light example, you need to import the

ColoredLight
class:

1from arduino_iot_cloud import ColoredLight

The cloud variable needs then to be registered with the client using that type and the name that you gave it ("light" in our example):

1client.register(ColoredLight("light", swi=True, on_write=on_colored_light_changed))

In the callback function for this variable ("on_colored_light_changed") you will receive an object of the same type with populated properties. Those properties depend on the type. For example the

ColoredLight
class has the following properties:

  • swi
    : The on-value of the light switch (True/False)
  • hue
    : The hue value of the color
  • sat
    : The saturation of the color
  • bri
    : The brightness of the color

Once you receive these values from the Cloud you will need to convert them to RGB so you can set the RGB LEDs accordingly. For reasons of brevity we won't go into the code for the color conversion, it is provided however in the full example code further down. Also we need to make all three RGB LEDs available in the code so their value can be set:

1led_red = Pin("LEDR", Pin.OUT)
2led_green = Pin("LEDG", Pin.OUT)
3led_blue = Pin("LEDB", Pin.OUT)

Then each of the three LEDs' brightness needs to be set so that the resulting color is as desired. This is done using a technique called PWM:

1def set_led_brightness(led, brightness):
2 """
3 Sets the brightness (0 - 255) of an LED using PWM.
4 """
5 pwm = PWM(led)
6 max_brightness = 255
7
8 # Ensure brightness is between 0 and max_brightness.
9 brightness = max(0, min(max_brightness, brightness))
10
11 # Map input brightness from 0-max_brightness to 0-65535.
12 duty_cycle = int(brightness * 65535 / max_brightness)
13 pwm.duty_u16(duty_cycle)

With that defined we can set the corresponding values of the RGBs:

1def set_leds_from_rgb(rgb, common_cathode=True):
2 # For common cathode RGB LEDs, invert the RGB values
3 # since the LED is on when the pin is low.
4 if common_cathode:
5 rgb = (255 - rgb[0], 255 - rgb[1], 255 - rgb[2])
6 set_led_brightness(led_red, rgb[0])
7 set_led_brightness(led_green, rgb[1])
8 set_led_brightness(led_blue, rgb[2])

The missing piece is the callback handler for when the cloud variable changes that was defined when registering the variable:

1def on_colored_light_changed(client, light):
2 # Do nothing if the hue, saturation or brightness is None.
3 if light.hue is None or light.sat is None or light.bri is None:
4 return
5
6 light_enabled = light.swi
7
8 if light_enabled:
9 rgb_value = convert_hs_to_rgb(light.hue, light.sat, light.bri)
10 set_leds_from_rgb(rgb_value)
11 else:
12 set_leds_from_rgb((0, 0, 0)) # Turn LEDs off

Full Code Example

Here is the complete code to try it out:

1# This file is part of the Python Arduino Cloud.
2
3# Any copyright is dedicated to the Public Domain.
4# https://creativecommons.org/publicdomain/zero/1.0/
5from machine import Pin, PWM
6import time
7import network
8import logging
9from arduino_iot_cloud import ArduinoCloudClient
10from arduino_iot_cloud import ColoredLight
11
12from secrets import *
13
14led_red = Pin("LEDR", Pin.OUT)
15led_green = Pin("LEDG", Pin.OUT)
16led_blue = Pin("LEDB", Pin.OUT)
17
18def set_led_brightness(led, brightness):
19 """
20 Sets the brightness (0 - 255) of an LED using PWM.
21 """
22 pwm = PWM(led)
23 max_brightness = 255
24
25 # Ensure brightness is between 0 and max_brightness.
26 brightness = max(0, min(max_brightness, brightness))
27
28 # Map input brightness from 0-max_brightness to 0-65535.
29 duty_cycle = int(brightness * 65535 / max_brightness)
30 pwm.duty_u16(duty_cycle)
31
32def convert_hs_to_rgb(hue, sat, bri):
33 # Convert hue, saturation and brightness to RGB.
34 # This function is based on the algorithm described at
35 # https://www.developers.meethue.com/documentation/color-conversions-rgb-xy
36 # and https://gist.github.com/mjackson/5311256
37 h = hue / 360
38 s = sat / 100
39 v = bri / 100
40 if s == 0.0:
41 return (int(v * 255), int(v * 255), int(v * 255))
42 i = int(h * 6)
43 f = (h * 6) - i
44 p = v * (1 - s)
45 q = v * (1 - s * f)
46 t = v * (1 - s * (1 - f))
47 if i % 6 == 0:
48 return (int(v * 255), int(t * 255), int(p * 255))
49 if i % 6 == 1:
50 return (int(q * 255), int(v * 255), int(p * 255))
51 if i % 6 == 2:
52 return (int(p * 255), int(v * 255), int(t * 255))
53 if i % 6 == 3:
54 return (int(p * 255), int(q * 255), int(v * 255))
55 if i % 6 == 4:
56 return (int(t * 255), int(p * 255), int(v * 255))
57 if i % 6 == 5:
58 return (int(v * 255), int(p * 255), int(q * 255))
59
60def set_leds_from_rgb(rgb, common_cathode=True):
61 # For common cathode RGB LEDs, invert the RGB values
62 # since the LED is on when the pin is low.
63 if common_cathode:
64 rgb = (255 - rgb[0], 255 - rgb[1], 255 - rgb[2])
65 set_led_brightness(led_red, rgb[0])
66 set_led_brightness(led_green, rgb[1])
67 set_led_brightness(led_blue, rgb[2])
68
69def on_colored_light_changed(client, light):
70 # Do nothing if the hue, saturation or brightness is None.
71 if light.hue is None or light.sat is None or light.bri is None:
72 return
73
74 light_enabled = light.swi
75
76 if light_enabled:
77 rgb_value = convert_hs_to_rgb(light.hue, light.sat, light.bri)
78 set_leds_from_rgb(rgb_value)
79 else:
80 set_leds_from_rgb((0, 0, 0))
81
82def wifi_connect():
83 if not WIFI_SSID or not WIFI_PASSWORD:
84 raise (Exception("Network is not configured. Set SSID and passwords in secrets.py"))
85 wlan = network.WLAN(network.STA_IF)
86 wlan.active(True)
87 wlan.connect(WIFI_SSID, WIFI_PASSWORD)
88 while not wlan.isconnected():
89 logging.info("Trying to connect. Note this may take a while...")
90 time.sleep_ms(500)
91 logging.info(f"WiFi Connected {wlan.ifconfig()}")
92
93if __name__ == "__main__":
94 # Configure the logger.
95 # All message equal or higher to the logger level are printed.
96 # To see more debugging messages, set level=logging.DEBUG.
97 logging.basicConfig(
98 datefmt="%H:%M:%S",
99 format="%(asctime)s.%(msecs)03d %(message)s",
100 level=logging.INFO,
101 )
102
103 # NOTE: Add networking code here or in boot.py
104 wifi_connect()
105
106 # Create a client object to connect to the Arduino Cloud.
107
108 # For MicroPython, the key and cert files must be stored in DER format on the filesystem.
109 # Alternatively, a username and password can be used to authenticate:
110 client = ArduinoCloudClient(device_id=DEVICE_ID, username=DEVICE_ID, password=CLOUD_PASSWORD)
111 client.register(ColoredLight("light", swi=True, on_write=on_colored_light_changed))
112
113 # Start the Arduino Cloud client.
114
115 client.start()

Troubleshoot

If the code is not working, there are some common issues we can troubleshoot:

  • Make sure MicroPython >= 1.2 is installed on your board.
  • Check the Wi-Fi® credentials in the
    secrets.py
    file.
  • Ensure the device ID and Cloud password in the
    secrets.py
    file match with what is registered on the Arduino Cloud.
  • Make sure your Arduino Cloud Thing is correctly set up and your device is assigned to it.

Conclusion

This tutorial has guided you through the process of connecting your Arduino device to the Arduino Cloud using MicroPython. You learned how to install the necessary library, set up your device, and control an LED via the Arduino Cloud. This opens up possibilities for more complex applications, as you can control and monitor your Arduino device remotely.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.