In this first lab you are being given time to get to grips with the Arduino platform. Rather than using the standard Arduino IDE you will be using the PlatformIO tools which integrate into Visual Studio Code.
Note: If you are using the University workstations this will already have been completed.
You should start by installing Visual Studio Code and then, using the extensions tab, search for and install the PlatformIO IDE. This will install the visual plugin.
This will also install the CLI tools platformio
and pio
, you should locate these on your computer and add the path to your environemnt variable. There are instructions on the Platform.io website with more detail below.
Edit the ~/.profile
file and add the following to the end:
if [ -d "$HOME/.platformio/penv/bin" ] ; then
PATH="$HOME/.platformio/penv/bin:$PATH"
fi
This checks to see if platformio has created the correct directory and, if it has, the directory gets added to the $PATH
. Note: you will need to restart your computer for this to take effect.
Once you have done this, restart the computer and use the ECHO $PATH
command to check that this path has been added. If it has you will be able to run the platformio
command.
You will also need to install the udev rules:
$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules
Create a ~/.profile
file and add the following to the end:
PATH="$HOME/.platformio/penv/bin:$PATH"
Once you have done this, restart the computer and use the ECHO $PATH
command to check that this path has been added. If it has you will be able to run the platformio
command.
You will need to install the correct drivers. The CH34x_Install_V1.4.pkg
can be found in the exercises/macos_drivers/
directory. If you are using a board with a different chipset you will find the drivers in the appropriately-labelled sub-directory.
If you are using Windows you will also need to install the 2102 Drivers if you are using
Adding new paths in Windows is a lot more complicated. Follow these instructions to add the path
All the code used by this lab can be found in the exercises/01_arduino/
directory. As you work through these tasks, load the appropriate directory directly into VS Code.
In this first exercise you will learn about the structure of a PlatformIO Arduino project and how to compile a program to a binary file and upload this to a microcontroller.
In this lab you will be focussing on the commandline however there are a number of icons in the blue status bar that act as shortcuts to many of these commands. You should take time to get familiar with these.
Use the file menu in VS Code to open the blink/
directory then open the integrated terminal, it should point to the current project directory.
You should now use the IDE to open the exercises/02_tdd/nodemcu/
directory which contains a simple Arduino sketch with a library. Lets look at the files:
├── platformio.ini
├── readme.md
└── src
└── main.cpp
- The
platformio.ini
file is the project configuration. It defines two environment definitions:- The
nodemcuv2
environment supports the NodeMCU boards based on the ESP8266 microcontroller. - The
lolin32
environment supports the Lolin32 boards based on the ESP32 microcontroller. - The
native
definition allows us to develop and test our library using the native compiler on our workstation.
- The
- The
readme.txt
file contains the documentation. - The
src/
directory contains the main Arduino sketch. Notice that this imports:- The Arduino libraries.
- Our
avg
library.
We can compile the code for a specified environment using either the `platformio` or `pio` command. The chosen environment is indicated either using the _long flag_ `--environment` or the _short flag_ `-e`. All of the commands listed below are equivalent:
```shell
$ platformio run --environment nodemcuv2
$ pio run --environment nodemcuv2
$ platformio run -e nodemcuv2
$ pio run -e nodemcuv2
This will compile the code, checking for dependencies but won't upload to the board. You should use this to check for syntax and dependency errors.
To upload to the board you need to include the --target
or -t
flag. This will compile the code and attempt to upload it to the attached board. The first example uses long flags whilst the second uses the short versions:
$ platformio run --environment nodemcuv2 --target upload
$ pio run -e nodemcuv2 -t upload
If you get an error uploading to the board it will either be due to not finding the serial port or board or it may be because of an error transferring the data.
To see a list of all the available ports and the drivers installed, use the following command:
$ platformio device list
/dev/ttyUSB0
------------
Hardware ID: USB VID:PID=10C4:EA60 SER=0001 LOCATION=2-2.2
Description: CP2102 USB to UART Bridge Controller
In the sample output above you can see that PlatformIO has detected a device called /dev/ttyUSB0
which has been created by the drivers we installed earlier. Once you know the name of the port it can be added to the platformio.ini
file (this option is currently commented out).
If there is a data transfer error you can edit the platformio.ini
file and reduce the upload speed. There is a comment in the sample file that lists the speeds permitted. Start with the lowest (9,600 baud). If this works you can try faster speeds.
Once the binary has uploaded to the microcontroller it will start to execute. The code in the main.cpp
file does two things:
- It blinks the built-in LED on and off once every 2 seconds.
- It generates a random integer between 10 and 20 and sends it through the serial port back to the computer.
There is a serial monitor that can be attached to the USB port and used to display any data being sent from the microcontroller to the computer. To open this use the following command:
$ pio device monitor
- Create a dice simulator that displays the results of two dice being thrown. Send this to the serial monitor.
In this section you will learn how to import third-party libraries. You will be displaying data on the built-in screen on the ESP32 microcontroller. We will be using the code in the screen/
directory. Open this in VS Code.
The screen is an SSD1306 and we need to search for a suitable library. The PlatformIO CLI has a fully documented lib
subcommand, lets try running this:
$ platformio lib
Commands:
builtin List built-in libraries
install Install library
list List installed libraries
register Register a new library
search Search for a library
show Show detailed info about a library
stats Library Registry Statistics
uninstall Uninstall libraries
update Update installed libraries
As you can see we need to provide an additional command. Looking at the list, search
looks like a good option. Use the documentation to understand how the search command works, try the following:
$ platformio lib search --framework arduino --platform espressif32 SSD1306
$ pio lib search -f arduino -p espressif32 SSD1306
$ pio lib search -f arduino -p espressif32 -n SSD1306
$ pio lib search -f arduino -p espressif32 --json-output SSD1306
Lets look at the documentation for a library:
$ pio lib show 562
$ pio lib show ssd1306
This displays the detailed documentation for the library. If there are more than one library matching the name you will be presented with a summary of each and prompted to enter the ID for the one you mean, enter 1904
and press enter. The most useful part of this is a list of links to some examples which show how you can import and use the library. Take a look at some of these to get an idea of how they work.
To use a library you need to list it in the platformio.ini
file. If you open this you can see we have already listed the library we want to use.
The final step is to build (to check the dependencies and code) then upload to the Microcontroller. Notice that PlatformIO automatically installs all the libraries listed in the platformio.ini
file.
$ pio run -e lolin32
$ pio run -e lolin32 -t upload
- Send the data (milliseconds since bootup) to the serial monitor.
- Calculate the number of seconds and send to the serial monitor.
- Display the number of seconds on the screen, under the milliseconds.
- Display random percentages on a third line (don't forget the % symbol).
- Make the font a lot larger! You may need to changed the text on screen to include all the data.
Now we will connect a DHT11 sensor and publish the temperature data to both the screen and the serial monitor. Before we connect anything we need to understand the different pins on the mocrocontroller.
Now its time to wire up a real sensor. In addition to the NodeMCU you will need a solderless breadboard and a DHT11 sensor as well as some jumper wires to connect everything together. The data pin should be connected to GPIO2 (pin 2) on the ESP32 microcontroller.
If you are using the ESP8266 you should connect your wires like this (use pin D4) and modify main.cpp
where indicated:
Notice that although the sensor has 4 pins we only need 3 of them.
- VCC/+ (connects to the 3.3v power rail)
- DATA/OUT (connects to pin 15/D4)
- NC (not connected)
- GND/- (connects to the ground rail)
If your sensor is mounted on a breakout board it will only have 3 pins and these will be clearly labelled.
The current program simply reads an analog value from the sensor however this contains information on both temperature and humidity. To access each individual reading you will need to use a dedicated DHT11 library.
- Search for a suitable library for the DHT11 and add it to the
platformio.ini
file. - Use the knowledge from this lab to build a program to capture both temperature and humidity.
- Send this data (together with the correct units) to the serial monitor.
Up to this point the overall project structure has been provided for you but how was this done? PlatformIO provides the init
subcommand that creates the required directory structure and builds a basic ini file.
The command requires you to pass it the board identifier ID. This can be found using the Boards Catalog, the Boards Explorer or by running the boards
subcommand. Run the following command to find a board ID for the nodemcu:
$ platformio boards nodemcu
Platform: espressif32
-----------------------------------------------------------------------------
ID MCU Frequency Flash RAM Name
-----------------------------------------------------------------------------
nodemcu-32s ESP32 240MHz 4MB 320KB NodeMCU-32S
Platform: espressif8266
-----------------------------------------------------------------------------
ID MCU Frequency Flash RAM Name
-----------------------------------------------------------------------------
nodemcu ESP8266 80MHz 4MB 80KB NodeMCU 0.9 (ESP-12 Module)
nodemcuv2 ESP8266 80MHz 4MB 80KB NodeMCU 1.0 (ESP-12E Module)
From this we can see that the platform for our ESP8266 is expressiv8266
and the ID is either nodemcu
or nodemcuv2
, we have the latest version (v2).
Lets repeat this for the more powerful ESP32-based board. This board is labelled wemos
. Searching for this returns:
$ platformio boards wemos
Platform: espressif32
--------------------------------------------------------------------------------
ID MCU Frequency Flash RAM Name
--------------------------------------------------------------------------------
lolin_d32 ESP32 240MHz 4MB 320KB WEMOS LOLIN D32
lolin_d32_pro ESP32 240MHz 4MB 320KB WEMOS LOLIN D32 PRO
lolin32 ESP32 240MHz 4MB 320KB WEMOS LOLIN32
wemosbat ESP32 240MHz 4MB 320KB WeMos WiFi & Bluetooth Battery
Platform: espressif8266
--------------------------------------------------------------------------------
ID MCU Frequency Flash RAM Name
--------------------------------------------------------------------------------
d1 ESP8266 80MHz 4MB 80KB WEMOS D1 R1 (Retired)
d1_mini ESP8266 80MHz 4MB 80KB WeMos D1 R2 & mini
d1_mini_lite ESP8266 80MHz 1MB 80KB WeMos D1 mini Lite
d1_mini_pro ESP8266 80MHz 16MB 80KB WeMos D1 mini Pro
Since we know the MCU is an ESP32, not an ESP8266 we focus on the first table. The version we need is the lolin32
.
Create a new directory called sound/
in the 01_arduino/
directory.
Once you have created your project directory you should run the init
inside it, passing the IDs of the boards we want to use:
$ platformio init --board nodemcuv2 --board lolin32
You can use the init
command multiple times to add additional boards. Add environments for every microcontroller board in your kit.
This creates a project and defines multiple environments. You will need to add the Native environment manually by editing the platformio.ini
file and adding:
[env:native]
platform = native
Create a program in your sound/
directory to capture the noise level and display this in the Serial Monitor.