This is an old revision of the document!
Table of Contents
InT Networks: Laboratory 1 - Introduction
Introduction to the IoT programming.
During labs, you will likely use Visual Studio Code with PlatformIO plugin, to author code for the IoT device. Devices are connected to the PC via USB cable but they expose a serial port to the operating system. You need to check the COM port number as it varies from PC to PC, and configure your project accordingly.
Hardware
Each team is given the following IoT microcontroller:
- Wemos D1 R2 development board:
Note, this microcontroller even if its board reminds Arduino Uno has different logic voltage (here 0..3.3V while Arduino Uno uses classical 0..5V logic) and has different pinout numbering. Detail on the following figure:
- DHT 11 temperature and humidity sensor
- 2x16 characters LCD shield with keypad
VSCode, PlatformIO and project configuration
In any case, creating a new project under PlatformIO should follow this general settings, regarding Board and Framework (see figure 5):
This configuration brings the following project configuration file platformio.ini:
[env:d1_mini] platform = espressif8266 board = d1_mini framework = arduino
It is also necessary to configure the serial port name that is used for uploading your firmware and to monitor. In the case of this microcontroller, it is the same port, so the platformio.ini file should be modified with the following (assuming the serial port is i.e. COM3):
... upload_port = COM3 monitor_port = COM3 ...
Running your code
To execute your code you need to compile it and upload it to the microcontroller.
The easiest way to interact with PlatformIO is to use its blue ribbon bar, located at the bottom of the VSCode (image 6:
Hardware-software components and libraries
Interfacing hardware requires the use of particular GPIOs. Laboratory nodes and hardware used needs specific configuration. Following chunks of code will help to set up proper hardware-software configuration.
LCD display
Built-in LED on the microcontroller development board can help to manage simple tracing of the code execution:
#define LED_BUILTIN 14
Your LCD shield is a 2×16 character one, driven by a Hitachi HD44780 controller. You can use a library to use it easily. The PlatformIO will pull the library automatically if defined in platformio.ini file:
lib_deps = Arduino-libraries/LiquidCrystal
#include <LiquidCrystal.h>
To initialise it and instantiate controller object, use following GPIO definition and initialisation:
const int rs = 12, en = 13, d4 = 4, d5 = 0, d6 = 2, d7 = 14; LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
It is also necessary to tell the library about the display organisation as there is a variety of configurations possible. Here, the organisation is 2 lines, 16 columns each, so in the code, you need to explicitly initialise it:
... lcd.begin(16,2); ...
Keypad
The LCD shield has 6 buttons. One of them is hard-wired to the reset function, but other buttons (marked SELECT, UP, DOWN, RIGHT, LEFT) can be read through voltage analysis delivered into the AD0 (Analogue to Digital Converter, Channel 0) existing in the ESP8266 chip. Buttons are connected the way that they short the connection and every button creates a separate voltage divider between pull-up and respectable resistance, different for each button (see figure 7 for connection diagram). To estimate readings you can calculate voltage appearing on the AD0 input using Ohm's law.
Note, there is an assumption that you press only one button at a time. If no button is pressed, Vcc goes to the AD0 and you get maximum reading (see schematics on figure 7 above and warning note below, on readings AD0).
Reading an AD0 is as simple as:
#define ADCPIN 0 ... int nAdcReading = 0; ... nAD0 = analogRead(ADCPIN); ...
Temperature and humidity sensor
There is a DHT11 (blue) sensor connected to the GPIO 5.
There are two libraries needed to handle reading from the sensor: a common sensor communication library and a specific for DHT sensors, both by Adafruit, so two more entries are needed in the platformio.ini file, and obviously you need to refer to it in the source code:
lib_deps = adafruit/Adafruit Unified Sensor@^1.1.4 adafruit/DHT sensor library@^1.4.3
#include <Adafruit_Sensor.h> #include <DHT.h>
To access sensor readings it is necessary to instantiate a communication class that binds the hardware to the code:
#define DHTTYPE DHT11 // DHT 11 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE,50);
It is also necessary to initialise the sensor class and give it some time to set up:
... dht.begin(); delay(1000); ...
The sensor class returns data (among others) in a float containing temperature (in C) and relative humidity (in per cent):
... float hum = dht.readHumidity(); float temp = dht.readTemperature(); ...
Software
String formatting may be a challenge. An easy approach is to allocate a character buffer of the size of the LCD or just one display's line, or any other size, large enough to handle your text.
... char buffer [50]; ...
To convert float into the string with formatting use sprintf function:
... sprintf(buffer,"%2.1f C",temp); ... sprintf(buffer,"%2.1f%%Rh",hum); ...
sprintf uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on sprintf. Here %2.1f
means: having float number render it to string using two digits before decimal point and one after. Temperature in our lab is always above 10C.
%%
is an escape character to print a
%
(percent) symbol.
delay(time)
is measured in milliseconds.
Tracing
There is no direct debugging capability in this environment yet it is possible to send log/trace messages to the PC console over a serial (serial over USB) port, the same that is used for flashing.
To open serial communication, one must invoke begin with appropriate bps setting on the Serial singleton object (usually in Setup() function:
Serial.begin(9600);
9600 is the default speed but you can change it in the platformio.ini file. It is possible to send virtually any message to the console (keep in mind, you need explicitly open Serial Monitor in the VS code) using:
... Serial.print(...); //or Serial.println(...);
Both functions accept a wide range of argument types with no need to explicitly convert to string.
Networking
There is a WiFi 2.4GHz, IPv4 network available to the students. This is a PRIVATE network. This network is separated from the Internet but all connected devices to it can talk to another. There is a DHCP server with networking addressing scope 192.168.90.10-192.168.90.254.
To connect to the wireless network, use the following credentials:
- SSID: internal.IOT
- Passkey: IoTlab32768
- IP address: DHCP, 192.168.90.10-192.168.90.254
Network services
MQTT
There is an MQTT Broker, binding WiFi PRIVATE network and the PUBLIC Internet. This way you can route MQTT messages from your end node devices connected to the internal.IOT network to the external tools i.e. cloud-based dashboard or storage via i.e. publishing from your end node IoT device through the PRIVATE network to MQTT Broker and subscribing to those messages from the cloud using PUBLIC Internet.
You can access it from the Internet PUBLIC network, using the following configuration and credentials:
- Address: 157.158.56.54
- Port: 1883 for plain text, 8883 for secure communication
- User: vrel
- Password: vrel2018
You can also access it from the aforementioned PRIVATE network, using the following configuration and credentials:
- Address: 192.168.90.5
- Port: 1883 for plain text, 8883 for secure communication
- User: vrel
- Password: vrel2018
Node Red and Node Red Dashboard
A Node RED server is working on same Raspberry Pi 2 as MQTT and in private address pool only, available through internal.IoT on 192.168.90.5 address, port 1880:
- http://192.168.90.5:1880 - main editor
- http://192.168.90.5:1880/ui - Node RED dashboard
Login using the following credentials:
- User: contact supervisor
- Password: contact supervisor
Laboratory scenarios
All teams share the same scenario yet please note that in particular, MQTT messages exchanged between devices shall be coordinated among team members not to overlay one another.
Scenario 1
Getting ready with your development environment
In this scenario, you will write your first “Hello World” application for ESP8266.
Using the selected IDE, write code that:
- Flashes built-in LED every 1 second (1s on; 1s off);
- Sends a message via serial port to the serial port monitor:
Hello World
...
#define LED_BUILTIN 14
...
The standard serial port speed is 9600 (bps). Connect COM port monitor (a plug icon in the PlatformIO toolbar), once you compile and upload your code, to see the “Hello World” message.
... Serial.begin(9600); ...
Advanced:
- Use timer/interrupt to flash the LED instead of an infinite loop.
Report:
- Describe your approach and include source code in the report
Scenario 2
** Using LCD **
In this scenario, you will write an application that writes on the LCD Display.
Your code shall implement a message Hello IoT in the upper line, and a counter ticking every second in the lower one.
Report:
- Present algorithm.
- Include source code.
Scenario 3
** Using Keypad **
Extend Scenario 2 with a counter that increments on the keypress of the Keypad Shield (any but SELECT!).
Report:
- Describe how did you solve the problem of the asynchronous processing of the keypresses/releases.
- Include source code.
