Introduction To The Iot Practical Project

  • Uploaded by: tariq
  • 0
  • 0
  • March 2021
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Introduction To The Iot Practical Project as PDF for free.

More details

  • Words: 29,751
  • Pages: 131
Loading documents preview...
Table of Contents 1. Versions .................................................................................................... 7 2. Preface ...................................................................................................... 8 3. Project Information ..................................................................................... 9 4. Introduction to the Remote Distant Laboratories............................................. 10 5. VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3 ..13 5.1. Introduction ......................................................................................... 13 5.2. Prerequisites ........................................................................................ 13 5.3. Sensors............................................................................................... 13 5.3.1. Technical details for the flap position monitor...................................... 13 5.4. Actuators............................................................................................. 15 5.5. Software, libraries and externals............................................................. 16 5.6. Communication .................................................................................... 16 5.7. Limits ................................................................................................. 17 5.8. Support............................................................................................... 17 6. VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4 ....18 6.1. Introduction ......................................................................................... 18 6.2. Prerequisites ........................................................................................ 18 6.3. Technical details ................................................................................... 18 6.4. Sensors............................................................................................... 19 6.5. Actuators............................................................................................. 19 6.6. Software, libraries and externals............................................................. 20 6.6.1. Support ......................................................................................... 22 7. VREL #6: Color Temperature and Brightness Compensation Laboratory .............23 7.1. Introduction ......................................................................................... 23 7.2. Prerequisites ........................................................................................ 24 7.3. Technical details ................................................................................... 24 7.4. Sensors............................................................................................... 26 7.5. Actuators............................................................................................. 27 7.6. Software, libraries and externals............................................................. 28 7.7. Communication .................................................................................... 28 7.8. Limits ................................................................................................. 29 7.9. Support............................................................................................... 29 8. VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring ....................................................................................... 30 8.1. Introduction ......................................................................................... 30

2

8.2. Prerequisites ........................................................................................ 30 8.3. Sensors............................................................................................... 30 8.3.1. Technical overview of the node and air pressure chamber overview .......31 8.4. Actuators............................................................................................. 32 8.5. Software, libraries and externals............................................................. 33 8.5.1. LCD Display.................................................................................... 33 8.5.2. Servo ............................................................................................ 33 8.3.1. Fan ............................................................................................... 31 8.6. Communication .................................................................................... 34 8.7. Limits ................................................................................................. 35 8.8. Support............................................................................................... 35 9. Hands-on lab scenarios for SUT VREL nodes .................................................. 36 9.0.1. B1: Basic operations on the 4x20 LCD screen .................................... 36 9.0.2. B2: Presenting temperature and humidity on the LCD ......................... 39 9.0.3. B3: Handling LED brightness using PWM via I2C controller................... 41 9.0.4. B4: E-paper display operations ........................................................ 44 9.0.5. B6: Presenting air pressure on the LCD ............................................. 45 9.0.6. B7: Controlling servo ...................................................................... 48 9.0.7. B8: Controlling fan using PWM ......................................................... 51 9.0.8. U1: Connecting to the network in STA mode ...................................... 53 9.0.9. U2: Exposing access point (AP) ........................................................ 56 9.0.10. U3: Sending MQTT messages ......................................................... 58 9.0.11. U4: Receiving and handling MQTT messages .................................... 63 9.0.12. U7: Controlling fan speed and servo angle via MQTT ......................... 68 9.0.13. U8: Visualising and sending flap state ............................................. 73 9.0.14. U9: A CoAP client ......................................................................... 76 10. ITT modular component laboratory ............................................................. 81 10.1. ITT Controller module basics ................................................................ 81 10.1.1. Introduction.................................................................................. 81 10.1.2. Prerequisites................................................................................. 81 10.1.3. Technical details............................................................................ 81 10.1.4. Specifications................................................................................ 82 10.1.5. Electrical connection ...................................................................... 82 10.1.6. Actuators ..................................................................................... 82 10.1.7. Software, libraries and externals ..................................................... 82 10.1.8. Communication ............................................................................. 83 10.1.9. Limits .......................................................................................... 83

3

10.2. ITT RGB LED module ........................................................................... 83 10.2.1. Introduction.................................................................................. 83 10.2.2. Prerequisites................................................................................. 84 10.2.3. Technical details............................................................................ 84 10.2.4. Hands-on labs............................................................................... 84 10.2.5. Support........................................................................................ 86 10.3. ITT Temperature and humidity sensor module ........................................ 86 10.3.1. Introduction.................................................................................. 86 10.3.2. Prerequisites................................................................................. 87 10.3.3. Technical details............................................................................ 87 10.3.4. Hands-on labs............................................................................... 87 10.3.5. Support........................................................................................ 88 10.4. ITT Servo module ............................................................................... 88 10.4.1. Introduction.................................................................................. 88 10.4.2. Prerequisites................................................................................. 89 10.4.3. Technical details............................................................................ 89 10.4.4. Hands-on labs............................................................................... 90 10.4.5. Support........................................................................................ 91 10.5. ITT Relay module................................................................................ 91 10.5.1. Introduction.................................................................................. 91 10.5.2. Prerequisites................................................................................. 92 10.5.3. Technical details............................................................................ 92 10.5.4. Hands-on labs............................................................................... 93 10.5.5. Support........................................................................................ 94 10.6. ITT OLED display module ..................................................................... 94 10.6.1. Introduction.................................................................................. 94 10.6.2. Prerequisites................................................................................. 94 10.6.3. Technical details............................................................................ 94 10.6.4. Hands-on labs............................................................................... 95 10.6.5. Support........................................................................................ 98 11. SmartMe Network Laboratory: Arduino Nodes 1-5......................................... 99 11.1. Introduction ....................................................................................... 99 11.2. Prerequisites ...................................................................................... 99 11.3. Technical details ................................................................................. 99 11.3.1. Node schematic........................................................................... 100 11.4. Sensors ........................................................................................... 102 11.5. Actuators ......................................................................................... 103

4

11.6. Software, libraries and externals ......................................................... 104 11.7. Communication ................................................................................ 105 11.8. Limits.............................................................................................. 106 11.9. Support ........................................................................................... 106 11.9.1. IB1: Basic operations on the 2x16 LCD screen................................. 106 11.9.2. IB2: Presenting temperature and humidity values on the LCD ........... 109 11.9.3. IB3: PWM mode (~) of digital pins, programming threshold values .... 113 11.9.4. IU1: Showing temperature, humidity and dust values on the 2x16 LCD screen .................................................................................................. 116 11.9.5. IM1: MQTT to publish a message with a topic .................................. 121 11.9.6. IM2: MQTT to subscribe to a topic to receive messages .................... 126

5

Authors IOT-OPEN.EU consortium selected partners collective monography. The full list of contributors is juxtaposed below.

ITT Group ▪

Raivo Sell, Ph.D., ING-PAED IGIP



Rim Puks, Eng.



Mallor Kingsepp, Eng.

Silesian University of Technology ▪

Piotr Czekalski, Ph.D., Eng.



Gabriel Drabik, Ph.D., Eng.



Oleg Antemijczuk, M.Sc., Eng.



Jarosław Paduch, M.Sc., Eng.

University of Messina ▪

Salvatore Distefano, Ph.D., Eng.



Riccardo Di Pietro, Eng.



Giovanni Merlino, Ph.D., Eng.



Carlo Scaffidi, Eng.

Graphic design and images ▪

Blanka Czekalska, M.Sc., Eng., Arch.



Małgorzata Wiktorczyk, B.Sc. Eng.

6

1. Versions

1. Versions This page keeps track of the content reviews and versions done as a continuous maintenance process Table 1: Versions and Content Updates #

Version

Change Date

1

v 0.1

01.01.2019 Preliminary content

2

v 0.2

11.08.2019

Fixed pre publishing for limited number of labs

3

v 0.3

29.10.2019

Reorganised chapters to fit ToC

4

v 0.4

29.10.2019 Layout correction

5

v 0.5

29.10.2019

Images standardisation and code wrapping

6

v 0.6

28.04.2020

VREL nodes description

7

v 0.7

VREL nodes 8-11 scenarios 05.05.2020 and reorganisation of the ToC

8

v 0.8

06.05.2020

VREL nodes 8-11 platformio.ini update

9

v 0.9

07.05.2020

VREL nodes 8-11 platformio.ini update

Content updates summary

8-11

Other comments

(no scenarios yet)

10 v 0.91

VREL nodes 8-11 There is a problem with BMP280 12.05.2020 platformio.ini update, U9 library (still) unsolved in some scenario added cases.

11 v 0.92

17.05.2020 U7 scenario updated

7

2. Preface

2. Preface This book and its offshoots were prepared to provide an additional and practical add-on for the main book on the Internet of Things. The primary goal of this book is to provide a detailed description of the VREL - IoT laboratories with remote access for those who interface our labs remotely. Its secondary goal is to give ideas on the IoT projects to the bachelor students, master students, technology enthusiasts and engineers. This book is also a good starting point for teachers, tutors and educators to start preparing of other materials for their implementation of the practical course on IoT, construct their laboratories, develop a module or even full curriculum related to the IoT. We (authors) assume that persons willing to study this content are already familiar with our “Introduction to the IoT book” or has equivalent knowledge and has at least elementary skills on programming in C, Python and C#. We believe this manual will help to seamlessly start your work with real IoT devices, whether you have them on your desk or you access them remotely using our VREL model. Note: Practice makes a master, so enjoy programming IoT!

8

3. Project Information

3. Project Information This Intellectual Output was implemented under the Erasmus+ KA2: Strategic Partnerships in the Field of Education, Training, and Youth – Higher Education. Project IOT-OPEN.EU – Innovative Open Education on IoT: Improving Higher Education for European Digital Global Competitiveness. Project number: 2016-1-PL01-KA203-026471. Erasmus+ Disclaimer This project has been funded with support from the European Commission. This publication reflects the views only of the author, and the Commission cannot be held responsible for any use which may be made of the information contained therein. Copyright Notice This content was created by the IOT-OPEN.EU consortium: 2016–2019. The content is Copyrighted and distributed under CC BY-NC Creative Commons Licence, free for Non-Commercial use.

In case of commercial use, please contact IOT-OPEN.EU consortium representative.

9

4. Introduction to the Remote Distant Laboratories

4. Introduction Laboratories

to

the

Remote

Distant

Laboratories can be accessed via a single entry point, using web platform available here: http://distance.roboticlab.eu/. Please note that there is a variety of hardware specifications, and almost every node has different peripherals and physical properties. Following chapters present a list of the laboratories and their documentation. Read it carefully before jumping in into the programming it. To be able to connect to the labs you need to create an account and book a device as all devices can be used in exclusive mode only. You can book more than one at a time to create a fully-featured distributed IoT solution, even across a few countries! Note, even remotely, you're facing real, physical devices with actuators thus you always must consider in your experiments physical phenomena like time, friction, pendulum, and so on. Each document has subchapters with hands-on labs to launch your experience with the device. You can extend those scenarios yourself! List of laboratories: SUT The Silesian University of Technology, laboratories location: Gliwice, Poland All nodes are using NodeMCU v.3 (ESP-12E) MCUs. ▪

Node 1 and Node 3 VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3 - air RX



Node 2 and Node 4 VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4 - air TX



Node 5 roboarm (under maintenance)



Node 6 VREL #6: Color Temperature and Brightness Compensation Laboratory



Node 7 rooftop (under maintenance)



Node 8 through 11 VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring

10

4. Introduction to the Remote Distant Laboratories

Figure 2: SUT Physical location of the VREL nodes Laboratory provides access to the uniform WiFi, private and separated network with MQTT and NodeRED services able to relay and route application-level messages to and from the Internet (devices remain separated, however). This way you can contact any of the nodes as they present themselves in a single IPv4 “internal.IOT” WiFi network. Nodes 1 through 4 are in a physical distance able to “see” one another, but separated from other devices. Nodes 8 through 11 are in a physical distance able to “see” one another, but separated from other devices. Node 6, node 7 and node 5 are in physically distant locations so there is no warranty that setting up the device as AP enables to connect to them from any other node. If you want to implement communication scenarios independent on the provided WiFi AP, please note to use VRELs 1 through 4 or 8 through 11. ITT Group, laboratories location: Tallinn, Estonia All nodes are using ESP8266 MCUs ▪

Node 1 Remote lights



Node 2 Temperature/Humidity controlled rooms

UME University di Messina, laboratory location: Messina, Sicilia, Italy Nodes 1 through 5 use Arduino Uno with Ethernet Shield while Node 6 uses Arancino board.

11

4. Introduction to the Remote Distant Laboratories ▪

Node 1-5 SmartME Network Laboratory Arduino.



Node 6 SmartME Network Laboratory Arancino.

12

5. VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3

5. VREL #1 and #3: General Purpose Laboratory, air receiving nodes 1 and 3

IoT

The laboratory is located at Silesian University of Technology, Gliwice, Poland, Akademicka 16, room 310. There are two nodes of this kind: Node 1 and 3, one per two air ducts, constituting a pair of working devices along with Nodes 2 and 4 respectively.

5.1. Introduction The lab consists of a mechanical airflow indicator going from the pipe (connected to a neighbour, TX lab). The indicator is a vertical flap, which changes position depends on airflow. The position of the flap is observable, using the camera and measurable using a photoelectric proximity sensor. The signal from the sensor is sent to the AD converter and additionally is displayed on needle gauge.

5.2. Prerequisites The user needs to know: ▪

physical effect of the airflow,



elementary rules od light propagation,



work of the unbalanced bridge.

5.3. Sensors The sensor of flap position is made which photoresistors. For reference, next to the flap there is an immovable surface made with the same material like the flap. Like in case of flaps, here is an identical photoresistor. Both of resistor make an unbalanced bridge, with is balanced, if the flap is in the start position (without airflow). For balancing bridge in the start position, two another resistors in the bridge, are build which potentiometer.

5.3.1. Technical details for the flap position monitor End of the air duct is fitted to rectangle flap, The flap is hanging loosely and can be pushed by the airflow. The flap is lighted by LED form the top, and at the opposite side of the flap, there is the photoresistor, which measures light intensity, reflected from the flap. The flap sensing system is connected to the analogue input A0.

13

5. VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3

Independent, in the lab there is a sensor of temperature and humidity, DHT22, connected to the D4/GPIO2.

14

5.4. Actuators

5.4. Actuators There are no mechanical actuators in this laboratory. LCD Display is 4×20 characters. LCD is controlled via I2C extender: LCM1602. The I2C extender address is 0x3F and the I2C bus is connected to the pins D1/GPIO5 and D2/ GPIO4 (D1 is SCL and D2 is SDA). As you do not have any access to the serial console, use LCD to visually trace the progress of your program, connection status, etc. By the LCD display, there are two LEDs that can be used to trace status. One LED is connected to the pin GPIO 16 while the other one to the GPIO pin 2. The former one (GPIO 2) is connected to the Serial Port TX as well so expect it flashing when communicating over serial protocol (i.e. flashing new firmware that is beyond the control of your code). Please note cameras are running only with some 5-10fps so do not implement quick flashing light as you may not be able to observe it remotely. Same note applies to the

15

5. VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3 quick changes of the LCD contents. Build in LEDs (both) are active with signal LOW so setting HIGH on GPIO 16 or 4 switches them off while setting LOW switches them on.

5.5. Software, libraries and externals LCD display requires a dedicated library. Of course, you can control it on the low-level programming, writing directly to the I2C registers, but we do suggest using a library first. As there are many universal libraries, and many of them are incompatible with this display, we strongly recommend using ''LiquidCrystal_I2C by Tony Kambourakis''. The LCD I2C control library can be imported to the source code via: #include

Then configure your LCD controller: LiquidCrystal_I2C lcd(0x3F,20,4);

// set the LCD address to 0x3F // for a 20 chars and 4 line display

Platformio.ini ; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:d1_mini] platform = espressif8266 board = d1_mini framework = arduino lib_deps = Wire, EmonLib, Adafruit NeoPixel, Encoder,DHT sensor library, Adafruit Unified Sensor, LCD, PubSubClient, KS0108_PCF8574, 2120

5.6. Communication You can connect your ESP8266 microcontroller via its integrated WiFi interface to the separated IoT network. Then you can communicate with other nodes and players, already connected devices and even provide some information to the cloud. In details, there is a dedicated MQTT broker waiting for you. You can also set up your soft Access Point and connect another node directly to yours. The communication among the devices can be done using MQTT messages, exchanging data among other nodes (M2M) and you can even push them to the Internet via MQTT broker. Using your Node, you can access it and publish/subscribe to the messages once you

16

5.7. Limits connect your ESP to the existing wireless network (this network does not provide access to the global internet and is separated but please note there are other developers and IoT nodes connected to this access point: ▪

SSID: internal.IOT



Passkey: IoTlab32768



Setup your microcontroller for DHCP, to automatically obtain an IP address, your ESP will obtain the address from the 192.168.90.X pool.



MQTT server is available under the fixed address: 192.168.90.5, and the credentials to publish/subscribe are: ▪

User: vrel



Password: vrel2018

The same MQTT server/broker is visible under public IP: 157.158.56.54 port 1883 (nonsecure) and 8883 (secure) to let you exchange data with the world and control your devices remotely.

5.7. Limits At the same time, only one user can be programming the controller, although analysing the signal by others (unlimited number) the user has sense. Model is provided to work continuously, without service breaks. For more interesting experiments, the user should be access to complementary Tx lab at the same time.

5.8. Support [email protected]

17

6. VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4

6. VREL #2 and #4: General Purpose Laboratory, air pushing nodes 2 and 4

IoT

The laboratory is located at Silesian Technical University, Poland, Gliwice Akademicka 16, room 310.

6.1. Introduction The node is an airflow generator, connected to the appropriate air receiving node. There is an air duct that connects nodes (node 2 send air to node 1, while node 4 send air to node 3). The lab consists of the fan which is a source of airflow going to the air duct. The beam of the airflow can be regulated in two ways: ▪

by changing the rotation speed of the fan,



by changing the position of the closing flap, mounted in front of the fan.

The voltage on the fan is visible on needle multimeter.

6.2. Prerequisites The user needs to know: ▪

physical effect of the airflow,



PWM control method,



working od servo-motors and its control.

6.3. Technical details End of the pipe is fitted to fan which is covered by rectangle flap. The flap is hanging on servomotor lever. Both fan and servomotor, are connected to the PWM outputs (each has its pin, enabling to control them independently) from the SoC. It is possible to change the rotating speed of the fan, and also the position of the flap. Parallel, the voltage on the fan (effective value), is displayed on analogue spindle voltage meter and can be observed via camera.

18

6.4. Sensors

6.4. Sensors There is a temperature and humidity sensor in the lab node: DHT22, connected to the GPIO0 (D4).

6.5. Actuators There are two actuators (fan, servo) and LCD display. ▪

The fan is a DC controlled one, where using PWM one can change rotation speed. ▪





the pin is GPIO 15/ D8

The servo is an analogue servo, Emax ES08A II: ▪

min timing 1500us max timing 1900us



the pin is GPIO 14 / D5

LCD is I2C controlled, present under address 0x3F on the I2C bus ▪

I2C bus is connected to the: ▪

SDA GPIO5 / D1



SCL GPIO4 / D2

19

6. VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4

6.6. Software, libraries and externals LCD display requires a dedicated library. Of course, you can control it on the low-level programming, writing directly to the I2C registers, but we do suggest using a library first. As there are many universal libraries, and many of them are incompatible with this display, we strongly recommend using ''LiquidCrystal_I2C by Tony Kambourakis''. The LCD I2C control library can be imported to the source code via: #include

Then configure your LCD controller: LiquidCrystal_I2C lcd(0x3F,20,4);

// set the LCD address to 0x3F // for a 20 chars and 4 line display

Platformio.ini ; PlatformIO Project Configuration File ;

20

6.6. Software, libraries and externals ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:d1_mini] platform = espressif8266 board = d1_mini framework = arduino lib_deps = Wire, EmonLib, Adafruit NeoPixel, Encoder,DHT sensor library, Adafruit Unified Sensor, LCD, PubSubClient, KS0108_PCF8574, 2120

Communication You can connect your ESP8266 microcontroller via its integrated WiFi interface to the separated IoT network. Then you can communicate with other, already connected devices and even provide some information to the cloud. In details, there is a dedicated MQTT broker waiting for you. You can also set up your soft Access Point and connect another node directly to yours. The communication among the devices can be done using MQTT messages: exchanging data among other nodes (M2M) and you can even push them to the Internet. Reference data Using your Node, you can access it and publish/subscribe to the messages once you connect your ESP to the existing wireless network (this network does not provide access to the global internet and is separated, but please note there are other developers and IoT nodes connected to this access point: ▪

SSID: internal.IOT



Passkey: IoTlab32768



Setup your microcontroller for DHCP, to automatically obtain an IP address, your ESP will obtain the address from the 192.168.90.X pool.



MQTT server is available under the fixed address: 192.168.90.5, and the credentials to publish/subscribe are: ▪

User: vrel



Password: vrel2018

Limits At the same time, only one user can program the controller, although analysing the signal by others (unlimited number) the users is reasonable. Model is provided to work continuously, without service breaks. For more interesting experiments, the user should be access to complementary Rx lab at the same time (applies to the advanced lab scenarios).

21

6. VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4 6.6.1. Support [email protected]

22

7. VREL #6: Color Temperature and Brightness Compensation Laboratory

7. VREL #6: Color Temperature and Brightness Compensation Laboratory The laboratory is located at Silesian Technical University, Poland, Gliwice Akademicka 16, room 319.

7.1. Introduction The lab consists of two light sources placed on top of the pyramid-shaped tower (figure ##REF:Tower_diagram##). The tower is divided into two sections: ▪

Bright side - opened to ambient light and simultaneously illuminated by LEDs



Dark side - only illuminated by LEDs

The user can experiment with controlling the brightness of LEDs and measuring the intensity and colour of the light.

23

7. VREL #6: Color Temperature and Brightness Compensation Laboratory

7.2. Prerequisites The user needs to know: Beginners: ▪

Basic knowledge of ESP8266 NodeMCU v2,



ESP8266 Arduino programming,



Basic knowledge of I2C Interface,



Basic knowledge of I2C programming using Arduino I2C library,



Knowledge of PWM controller chip PCA9685,



Operation and method of PWM current control,

Undergraduates additionally: ▪

Knowledge of PWM controller chip PCA9685,



Knowledge of I2C extender chip TCA9548A,



Knowledge of light sensor chip TCS34725,



Division of white light sources due to colour temperature,



Measure of light intensity,

Masters additionally: ▪

Construction and operation of Cree Dynamic White LEDs,



Knowledge of PWM controller chip PCA9685,



Knowledge of I2C extender chip TCA9548A,



Knowledge of light sensor chip TCS34725,



Division of white light sources due to colour temperature,

7.3. Technical details The main aim of the laboratory is to do different experiments with LED light. The user can start with simple PWM controlling of LED. Next, try to keep a constant level of brightness on a bright part of the model. The other aim is to keep the same level of lighting on a dark part of the model, as is on the bright side. The diagram of the main part is shown in figure 3, and diagram of LEDs connection is in figure 4

24

7.3. Technical details

Figure 3: Microcontroller with PWM and sensors.

25

7. VREL #6: Color Temperature and Brightness Compensation Laboratory

Figure 4: LEDs connections

7.4. Sensors A camera gives a general view on the bright side of the tower, and the second camera at the bottom of the tower gives a view of how both parts of the ground are illuminated (bright and dark) ambient light and RGB sensors are used as sensors for measuring brightness and colour of light. The following devices are connected directly to the main I2C controller: I/O Device I2C address

Description

PCA9685A

0x40h

PWM LED controller

TCA9548A

0x70h

I2C Extender

In the system, there are three TCS34725 light sensors. Sensors have the same I2C addresses (0x29h) but are connected to different channels of I2C extender (TCA9548A). I2C extender address is 0x70h. Remember to always select the appropriate multiplexer channel before referring to the correct light sensor

26

7.5. Actuators TCA9548A I2C channel

I2C Address

Sensors

Position

Channel Sensor TCS34725 RGB Bottom 0x29h 0 Main brightside Bottom of darkside

of

Input/ output

Remarks

Output

Main sensor mixed light

Output

Sensor of only LED light Ambient light sensor

Channel Sensor TCS34725 RGB 1 DarkSide

0x29h

Channel Sensor TCS34725 RGB 2 Ambient

0x29h Top of Tower

Output

Channel 3

-

-

Output N/C

Channel 4

-

-

Output N/C

Channel 5

-

-

Output N/C

Channel 6

-

-

Output N/C

Channel 7

-

-

Output N/C

of

7.5. Actuators In the system, there are two CREE dynamic LEDs. Each consists of four LED structures with two cold-white and two warm-white lightning. First LED is placed on top of the bright/openside of the tower and the second LED is placed on top of the dark/close side. The each LEDs light intensity must be appropriately controlled using PWM current controller which is separate for every white colour of each LED. ( Each PWM channel controls two LED structures with identical light colour.) As PWM controller has been used a 16-channel PWM chip - PCA9685 (Address - 0x40H). PCA9685 is connected directly to the microcontroller's I2C master interface. Actuator

Position

Input/output

Remarks

Channel 0

On the board Input

LED1/bright side warm-white

Channel 1

On the board Input

LED1/bright side cold-white

Channel 2

On the board Input

LED2/dark side warm-white

Channel 3

On the board Input

LED2/dark side cold-white

Channel 4

On the board Input

N/C

Channel 5

On the board Input

N/C

Channel 6

On the board Input

N/C

Channel 7

On the board Input

N/C

Channel 8

On the board Input

N/C

27

7. VREL #6: Color Temperature and Brightness Compensation Laboratory Actuator Channel 9

Position

Input/output

Remarks

On the board Input

N/C

Channel 10 On the board Input

N/C

Channel 11 On the board Input

N/C

Channel 12 On the board Input

N/C

Channel 13 On the board Input

N/C

Channel 14 On the board Input

N/C

Channel 15 On the board Input

N/C

7.6. Software, libraries and externals Platformio.ini ; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:d1_mini] platform = espressif8266 board = d1_mini framework = arduino lib_deps = Wire, EmonLib, Adafruit NeoPixel, Encoder,DHT sensor library, Adafruit Unified Sensor, LCD, PubSubClient, KS0108_PCF8574, CoAP simple library

7.7. Communication You can connect your ESP8266 microcontroller via its integrated WiFi interface to the separated IoT network. Then you can communicate with other, already connected devices and even provide some information to the cloud. In details, there is a dedicated MQTT broker waiting for you. You can also set up your own soft Access Point and connect another node directly to yours. The communication among the devices can be done using MQTT messages, exchanging data among other nodes (M2M) and you can even push them to the Internet. Using your Node, you can access it and publish/subscribe to the messages once you connect your ESP to the existing wireless network (this network does not provide access to the global internet and is separated but please note there are other developers and IoT nodes connected to this access point: ▪

SSID: internal.IOT



Passkey: IoTlab32768

28

7.8. Limits ▪

Setup your microcontroller for DHCP, to automatically obtain an IP address, your ESP will obtain the address from the 192.168.90.X pool.



MQTT server is available under the fixed address: 192.168.90.5, and the credentials to publish/subscribe are: ▪

User: vrel



Password: vrel2018

7.8. Limits At the same time, only one user can be programming the controller, although analysing the signal by others (unlimited number) the user has sense. Model is provided to work continuously, without service breaks.

7.9. Support In case of problems contact: [email protected]

29

8. VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring

8. VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring The laboratory is located at Silesian University of Technology, Gliwice, Poland, Akademicka 16, room 316 There are four nodes of this kind: Node 8,9,10 and 11. Nodes may look different, in particular, nodes 8 and 10 are a mirror to the 9 and 11.

8.1. Introduction The lab consists of a set of devices presenting various sensors and actuators. Each laboratory is independent of the physical point of view, however, using a combination of different devices connected via the network is advised. Note, you may also use other nodes, 1 through 7, and external services. Each node contains a yellow air chamber with a pressure sensor inside it and a DC fan, able to increase air pressure in the chamber, when on. An airflow limiter located by the other side, opposite to the fan, limits airflow running out of the chamber.

8.2. Prerequisites The user needs to know: ▪

physical effect of the airflow and air pressure phenomena,



PWM control principals.

8.3. Sensors Each node contains the following set of sensors: ▪

DHT sensor measuring temperature and humidity (Blue is DHT11, White is DHT22) connected to the D4/GPIO2.



Bosch BMP280 air pressure sensor, reporting absolute air pressure measurements in Pa, located inside of the yellow air chamber (operating of the fan changes pressure reported by the sensor when the fan is off, it measures absolute air pressure - please note, the laboratory is located at the 3rd floor + base floor, so it is not a ground-level pressure). This sensor uses I2C protocol and is connected to the D1 and D2 GPIOs (D2 is SDA, D1 is SCL). The sensor I2C address is 0x76.

30

8.3. Sensors 8.3.1. Technical overview of the node and air pressure chamber overview

Figure 5: Air chamber

31

8. VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring

Figure 6: VREL #8-#11 components (circuit)

8.4. Actuators There are two mechanical actuators in this laboratory: ▪

Classical servo (180 degrees) controlled via pin D5 with arrow presenting its position.



DC fan, located in the inlet of the air chamber, controlled with pin D8.

LCD Display is 4×20 characters. LCD is controlled via I2C extender: LCM1602. The I2C extender address is 0x3F for nodes 8 and 9 and 0x27 for nodes 10 and 11. The I2C bus

32

8.5. Software, libraries and externals is connected to the pins D1/GPIO5 and D2/GPIO4 (D1 is SCL and D2 is SDA). As you do not have any access to the serial console, use LCD to visually trace the progress of your program, connection status, etc. By the LCD display, there are two LEDs that can be used to trace status. One LED is connected to the pin GPIO 16 while the other one to the GPIO pin 2. The former one (GPIO 2) is connected to the Serial Port TX as well so expect it flashing when communicating over serial protocol (i.e. flashing new firmware that is beyond the control of your code). Please note cameras are running only with some 5-10fps so do not implement quick flashing light as you may not be able to observe it remotely. Same note applies to the quick changes of the LCD contents. Build in LEDs (both) are active with signal LOW so setting HIGH on GPIO 16 or 4 switches them off while setting LOW switches them on. Even if 20×4 LCD displays look same in different nodes, nodes 8 and 9 use 0x3F address while nodes 10 and 11 use 0x27. Using invalid I2C address in your code causes the display to become inoperable.

8.5. Software, libraries and externals LCD display requires a dedicated library. Of course, you can control it on the low-level programming, writing directly to the I2C registers, but we do suggest using a library first. As there are many universal libraries, and many of them are incompatible with this display, we strongly recommend using ''LiquidCrystal_I2C by Tony Kambourakis''.

8.5.1. LCD Display The LCD I2C control library can be imported to the source code via: #include

Then configure your LCD controller for nodes 8 and 9: LiquidCrystal_I2C lcd(0x3F,20,4);

// set the LCD address to 0x3F // for a 20 chars and 4 line display // Nodes 8 and 9

or for nodes 10 and 11 LiquidCrystal_I2C lcd(0x27F,20,4); // set the LCD address to 0x3F // for a 20 chars and 4 line display // Nodes 10 and 11

8.5.2. Servo The easiest way to control a servo it is using a dedicated library. Still, low-level PWM programming is possible. #include <Servo.h>

33

8. VREL #8 through #11: General Purpose IoT Laboratory with air chamber for pressure monitoring ... #define servoPin D5 Servo servo; servo.attach(servoPin);

8.5.3. Fan Fan operation is controlled via classical PWM. We control fan using analogWrite. Suggested PWM frequency is about 250 Hz: #define PWMFanPin D8 ... pinMode(PWMFanPin,OUTPUT); analogWriteFreq(250); analogWrite(PWMFanPin,0); //stop FAN

Setting too high PWM frequency causes fan to operate binary (on/off) and limits controlling range.

Platformio.ini ; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:d1_mini] platform = espressif8266 board = d1_mini framework = arduino lib_deps = Wire, LCD, [email protected], [email protected], 2120

The library numbers and their enforced versions are necessary to compile your code. You may get library errors if using other versions and referencing libraries by name, not by ID.

8.6. Communication You can connect your ESP8266 microcontroller via its integrated WiFi interface to the separated IoT network. Then you can communicate with other nodes and players, already connected devices and even provide some information to the cloud. In details, there is a dedicated MQTT broker waiting for you. You can also set up your soft Access Point and connect another node directly to yours.

34

8.7. Limits The communication among the devices can be done using MQTT messages, exchanging data among other nodes (M2M) and you can even push them to the Internet via MQTT broker. Using your Node, you can access it and publish/subscribe to the messages once you connect your ESP to the existing wireless network (this network does not provide access to the global internet and is separated but please note there are other developers and IoT nodes connected to this access point: ▪

SSID: internal.IOT



Passkey: IoTlab32768



Setup your microcontroller for DHCP, to automatically obtain an IP address, your ESP will obtain the address from the 192.168.90.X pool.



MQTT server is available under the fixed address: 192.168.90.5, and the credentials to publish/subscribe are: ▪

User: vrel



Password: vrel2018

The same MQTT server/broker is visible under public IP: 157.158.56.54 port 1883 (nonsecure) and 8883 (secure) to let you exchange data with the world and control your devices remotely.

8.7. Limits At the same time, only one user can be programming the controller, although analysing the signal by others (unlimited number) the user has sense. ode does not require physical human interaction and is supposed to work continuously, without service breaks.

8.8. Support [email protected]

35

9. Hands-on lab scenarios for SUT VREL nodes

9. Hands-on lab scenarios for SUT VREL nodes A table below presents a relation between SUT's IOT VREL nodes and their capabilities to handle presented hands-on-labs scenarios. Please be aware that scenarios are strictly related to the hardware, thus using an inappropriate scenario in the context of the VREL node that presents incompatible hardware may lead to the inability to obtain desired results or even to the hardware damage. ▪

B class scenarios present introductory level to the hardware handling,



U class scenarios present more advanced levels, including networking, and their implementation usually requires familiarity with B class ones. Table 2: SUT's scenarios coverage matrix for VREL nodes SUT's VREL laboratory node number Group 1

Group 2

#1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 B1 x

x

x

x

x

x

x

x

x

B2 x

x

x

x

x

x

x

x

x

B6

x

x

x

x

B7

x

x

x

x

B8

x

x

x

x

B3

x

B4

x

B5

U1 x

x

x

x

x

x

x

x

x

U2 x

x

x

x

x

x

x

x

x

U3 x

x

x

x

x

x

x

x

x

U4 x

x

x

x

x

x

x

x

x

U5 U6 U7 U8 x

x

x x

9.0.1. B1: Basic operations on the 4x20 LCD screen Whatever you do, you expect to have some output of the system. Sometimes there is a

36

9. Hands-on lab scenarios for SUT VREL nodes blinking LED, sometimes information about connected/disconnected network and some other time simply trace algorithm progress. In laboratories where you have physically connected MCU to your programming device (i.e. computer), you usually would choose Serial port to report about what is going on. However here all you have is access via the video stream. Perhaps those are reasons you will use this LCD display in your every lab work. Note, the video stream from the camera is limited in bandwidth and presents some 5-10fps maximum (usually around 1 fps) so you shouldn't change display content nor LED state faster than once every 2 seconds, to let you notice any change!

Target group This hands-on lab guide is intended for the Beginners but other target groups may benefit from it, treating it as a tool for advanced projects.

Prerequisites There are no other prerequisites than LCD I2C library. Mind, LCD is controlled via the I2C bus. LCD Display is 4×20 characters. LCD is controlled via I2C extender: LCM1602. The I2C extender address is 0x3F or 0x27 (depends on the laboratory node, please refer to the documentation!) and the I2C bus is connected to the pins D1 and D2 (D1 is SCL and D2 is SDA). There are two types of I2C extenders differing their I2C address: ▪

Nodes 1 through 5, 8 and 9 use 0x3F



Nodes 10 and 11 use 0x27

Scenario Initialize LCD screen, clear it then write some fancy text on it, i.e. “Hello IOT!” in the first line then your first name in the second line and the name of the city you're in, in the third. In the fourth line, print right-aligned number of loop iterations (delay it for 1 second between updates - yes, 1, to observe video stream lag and delays). Note, delays are provided in ms, not in s.

Result You should see the texts and ticking counter in the video stream.

Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library:

37

9. Hands-on lab scenarios for SUT VREL nodes #include

Step 2 Instantiate software controler component for the LCD display: LiquidCrystal_I2C lcd(0x3F,20,4);

// set the LCD address to 0x3F // for a 20 chars and 4 line display

Step 3 Declare some variables: counter i, its length n and buffer for the into to string conversion: int i = 0; char buffer [50]; int n;

We will use them in further part of the code.

Step 3 Initialize display - we suggest to do it in setup() function: ... lcd.init(D2,D1); lcd.backlight(); ...

// initialize the lcd I2C // switch on the backlight

Step 4 Clear the contents, set cursor and draw static text - still in setup() function: ... lcd.home(); lcd.print("Hello IOT!"); lcd.setCursor(0, 1); lcd.print("James Bond here"); lcd.setCursor(0,2); lcd.print("London"); ...

Step 5 Implement loop() to draw number of loop executions: ... i++; n=sprintf(buffer,"%d",i); lcd.setCursor(20-n,3); lcd.print(i); delay(1000);

38

9. Hands-on lab scenarios for SUT VREL nodes ...

sprintf uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on sprintf. Here %d means: having integer number render it to string and as we do not specify number of digits, it is up to the engine to convert it properly.\\delay(time) is measured in milliseconds.

Result validation Observe text, its position and counter ticking in lower, right corner.

9.0.2. B2: Presenting temperature and humidity on the LCD In this scenario, you will present temperature and humidity as read by the attached DHT22 sensor, on the LCD screen.

Target group Beginners

Prerequisites You need to know, how to print and position text on the LCD display. Use LCD I2C library to control it: #include

The temperature and humidity sensor is all-in-one, DHT22 sensor (white) or DHT11 (blue), connected to the pin D4. Observe your camera to check which sensor is equipped with your lab and consult node documentation. To read data you may use a dedicated library (libraries): #include #include

Scenario Once you initialise sensor and LCD display, read sensor data (temperature and humidity, mind they're float values, not integers) and then display them in the loop. Give each loop execution some 5-10s delay. Do not try to read temperature and humidity too frequent. Once every 5s is quite enough both for information and safe enough to not let your readings race with the communication protocol. If you read too frequent, your sensor may not be able to deliver data on time and you will obtain a 'nan' (not a number) instead of temperature and humidity. The first line of the LCD should display: “Temperature is:“ The second line should provide temperature within the ”NN.N C” form, in Celcius. The third line should display: “Humidity is:“

39

9. Hands-on lab scenarios for SUT VREL nodes Finally, the fourth should present relative humidity: ”NN.N%Rh“ You will use sprintf function to format string and convert from float to string.

Result You should be able to see temperature and humidity readings on the LCD display using the video stream.

Start There are no special steps to be performed.

Steps Step 1 Include LCD and DHT sensor driver libraries: #include #include #include

Step 2 Instantiate software controler components for the LCD display and DHT sensor:

LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x3F for nodes 1 through 5, 8 a //LiquidCrystal_I2C lcd(0x27,20,4); // for nodes 10 and 11 only! // for a 20 chars and 4 line display DHT dht(DHTpin,DHT22,50);

Step 3 Declare a buffer for sprintf function: char buffer [10];

Step 4 Initialize LCD and DHT sensor: ... lcd.init(D2,D1); lcd.backlight(); lcd.home(); ... dht.begin(); delay(1000); ...

40

// initialize the lcd

// give it a second to let the sensor initialize

9. Hands-on lab scenarios for SUT VREL nodes Step 5 Read in the loop: ... float hum = dht.readHumidity(); float temp = dht.readTemperature(); ...

To convert float into the string with formatting use sprintf function: ... sprintf(buffer,"%2.1f C",temp); ... sprintf(buffer,"%2.1f%%Rh",hum); ... delay(5000); ...

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.

Result validation Observe temperature and humidity readings on the LCD. Temperature ranges between 20-30C while humidity between 35-60%Rh.

9.0.3. B3: Handling LED brightness using PWM via I2C controller This is the simple example of setting brightness of LED using PWM controller.

Target group This hands-on lab guide is intended for the Beginners.

Prerequisites The user needs to know: Basic knowledge of ESP8266 NodeMCU v.2. ESP8266 Arduino

41

9. Hands-on lab scenarios for SUT VREL nodes programming, Basic knowledge of I2C Interface. Basic knowledge of I2C programming using Arduino I2C library.

Scenario All important information including the address of devices is enclosed in the description of the laboratory. In that scenario, the user should write a program in the Arduino platform which turns on and off LEDs for the specified time 15 seconds. The LEDs brightness can be controlled by setting variable “level” from 0 to 4095.

Result As a result user can control in cameras program execution.

Start In the beginning, both cameras must show that all LEDs are off. Steps

Step 1 First load an example project, include appropriate libraries and declare variable ledDriver: #include <Wire.h> #include

Step 2 Instantiate PWM controler component: #define PCA9685_ADDRESS PCA9685 ledDriver;

0x40

or #define PCA9685_ADDRESS 0x40 PCA9685 ledDriver(PCA9685_ADDRESS);

Step 3 Initialize properly hardware, we suggest to do it in setup() function: First initialize I2C controller and join i2c bus to correct pins of NodeMCU: ... Wire.begin(D1, D2); /* join i2c bus with SDA=D5 and SCL=D4 of NodeMCU */ ...

and then enable PWM controller ( pin /EN of PCA9685 is connected to pin D0 of

42

9. Hands-on lab scenarios for SUT VREL nodes NodeMCU): ... pinMode( D0, OUTPUT ); // define pin D0 as output digitalWrite( D0, LOW); // enable PWM ...

Step 4 Turn the desired led to any PWM level from 0 to 4095: The diodes are numbered from 0 to 3 PWM level 0 means that LED is off and level value 4095 means that diode is full-on. ... ledDriver.setLEDDimmed( number , level); ... Function setLEDDimmed cannot be used in a loop to give you a pleasant "turning-up" of the LED. This is because each time you set a level for a LED it will calculate random timing intervals for the PWM function in the chip This is done in order to distribute current consumptions of the full-time period.

Step 5 Write a simple programme which: ▪

Turn LED0 placed on the bright side to warm-white fully on for 15 seconds



Turn LED0 off



Turn LED1 placed on the bright side to cold-white fully on for 15 seconds



Turn lED1 off



Turn LED2 placed on the dark side to warm-white fully on for 15 seconds



Turn LED2 off



Turn LED3 placed on the dark side to cold-white fully on for 15 seconds



Turn lED3 off

Step 6 Repeat step 5 ten times.

Result validation The only way for validation is to check display by the camera. Both cameras must show that LEDs are changing brightness in given periods of time.

43

9. Hands-on lab scenarios for SUT VREL nodes 9.0.4. B4: E-paper display operations In the example of B3, the only way to see the results was to preview the image in the camera. Sometimes You need to have some other output of the system. So now, in our example, we use e-paper display attached to the system.

Target group This hands-on lab guide is intended for the Beginners, but other target groups may benefit from it, treating it as a tool for advanced projects.

Prerequisites There are no other prerequisites than knowledge of e-paper library. Mind, the display is controlled by a specialised interface connected to selected GPIO ports of the system.

Scenario Initialise e-paper screen, clear it then write some fancy text on it, i.e. “Hello IOT!” in the first line.

Result As a result, the user can check the text displayed on the screen in the camera.

Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library: #include #include #include #include

<SPI.h> <epd2in13.h> <epdpaint.h> "imagedata.h"

Step 2 Choose uncolored verison display: #define COLORED #define UNCOLORED

0 1

Step 3 Declare buffer for image and instantiate software controller component for the e-ink display:

44

9. Hands-on lab scenarios for SUT VREL nodes unsigned char image[1024]; Paint paint(image, 0, 0); Epd epd;

Step4 Initialize display - we suggest to do it in setup() function: … if (epd.Init(lut_full_update) != 0) { Serial.print("e-Paper init failed"); return; } …

Step 5 Clear the contents, set cursor and draw static text - still in setup() function: ... epd.ClearFrameMemory(0xFF);

// bit set = white, bit reset = black

paint.SetRotate(ROTATE_0); paint.SetWidth(128); // width should be the multiple of 8 paint.SetHeight(24); ...

Step 6 Place text “Hello IOT!” in frame buffer: … /* For simplicity, the arguments are explicit numerical coordinates */ paint.Clear(UNCOLORED); paint.DrawStringAt(30, 4, "Hello IOT!", &Font12, UNCOLORED); epd.SetFrameMemory(paint.GetImage(), 0, 10, paint.GetWidth(), paint.GetHeight()); …

Step 7 Display buffer” ... epd.DisplayFrame(); ...

Result validation The only way for validation is to check display by the camera.

9.0.5. B6: Presenting air pressure on the LCD In this scenario, you will present absolute air pressure reading, on the LCD screen.

45

9. Hands-on lab scenarios for SUT VREL nodes Target group Beginners

Prerequisites You need to know, how to print and position text on the LCD display. Use LCD I2C library to control it: #include

The air pressure sensor is Bosch BMP280 sensor, connected to the I2C bus, shared with LCD display. To read data you may use a dedicated library (libraries): #include #include

Scenario Once you initialise sensor and LCD display, read sensor data (air pressure) and then display them in the loop. Give each loop execution some 5-10s delay. Do not try to read air pressure too frequent. Once every 5s is quite enough both for information and safe enough to not let your readings race with the communication protocol. The first line of the LCD should display: ”Air pressure is:“ The second line should provide temperature within the ”NNNN.NN hPa“ form, in hPa. Note - your readings are in Pa (not hPa) so you're supposed to divide them by 100 before presenting on the screen! You will use sprintf function to format string and convert from float to string.

Result You should be able to see air pressure readings on the LCD display using the video stream. Some fluctuations are natural. If the fan connected to the air chamber is on, air pressure measured may be higher than the ambient air pressure observed and higher disturbances will be observed.

Start There are no special steps to be performed.

Steps Step 1 Include LCD and sensor driver libraries:

46

9. Hands-on lab scenarios for SUT VREL nodes #include #include #include

Step 2 Instantiate software controler component for the LCD display: LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x3F for nodes 1 through 5, 8 //LiquidCrystal_I2C lcd(0x27,20,4); // for nodes 10 and 11 only! Adafruit_BMP280 bmp;

Step 3 Declare a buffer for sprintf function and floating point value (single precision is enough) for storing last air pressure reading: char buffer [11]; float pres;

Step 4 Initialize LCD and BMP sensors: ... lcd.init(D2,D1); // initialize the lcd lcd.backlight(); lcd.home(); ... if(!bmp.begin(0x76)) { lcd.print("Bosch Sensor Error!"); delay(1000); }; lcd.home(); bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, Adafruit_BMP280::SAMPLING_X2, Adafruit_BMP280::SAMPLING_X16, Adafruit_BMP280::FILTER_X16, Adafruit_BMP280::STANDBY_MS_500); ...

/* /* /* /* /*

Operating Mode. */ Temp. oversampling */ Pressure oversampling */ Filtering. */ Standby time. */

The BMP sensor address is 0x76 and, if not initialised, display error on the LCD screen.

Step 5 Read in the loop: ... pres = bmp.readPressure()/100; ...

47

9. Hands-on lab scenarios for SUT VREL nodes bmp.readPressure() function returns air pressure in Pa. You must convert it hPa, dividing by 100. To convert float into the string with formatting use sprintf function: ... sprintf(buffer,"%4.2f hPa",pres); ... delay(5000); ...

sprintf uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on sprintf. Here %4.2f

means: having float number render it to string using four digits before decimal point and two after it. Air pressure readings should be somewhere between 890 and 1060 hPa. delay(time) is measured in milliseconds.

Result validation Observe air pressure readings on the LCD. Note - small oscillations are natural - you can implement moving average (i.e. of 10 subsequent reads, FIFO model) to “flatten” readings.

9.0.6. B7: Controlling servo In this scenario, you will control a servo to rotate it to the predefined positions. Servo is under the red arrow you can see in the video stream, to let you easily observe its position. Servo is connected to the GPIO D5.

Target group Beginners

Prerequisites You need to understand how typical servomotor looks like and how it works. The servo is controlled using predefined, precise PWM timing. Most servos share exactly the same model (0-180 degree servos), regardless of their size and power voltage. Classical, analogue servo frequency is 50Hz = 20ms period and duty cycle of the high signal is 1ms for 0deg and 2ms for 180deg. So changing the PWM duty cycle from 1ms to 2ms (5% to 10%) rotates servo. There is no need, however, to implement manually (still you can do) but you will use a predefined library instead of manually setting-up PWM. This brings features like range mapping to control servo logical way (i.e. providing angle, not duty cycle). The library is Servo.h. According to the algorithm of your choice to implement your code, you may hard code

48

9. Hands-on lab scenarios for SUT VREL nodes rotations one by one or i.e. declare a table with rotation targets and then iterate over it, so familiarity with array operations in C is essential in this case.

Scenario In this scenario, you will rotate the servo to the 0 degrees, then 45, 90, 135 and 180 degrees counter wise, then 180, 90, 0, clockwise. Note - Arrow pointing left means servo is set to 0, pointing right is 180 degrees, and when 90 degrees, arrow points down. We use LCD to get feedback about requested servo angle and to compare it with the result, but please note, it is just for information only and is not necessary to implement servo rotation. Please DO NOT use loop() to implement infinite servo rotation as it will wear out quickly and can even burn. Servo is NOT INTENDED to rotate as a motor. Instead, implement your code to run once or twice in the setup() function. You may reset the node to restart your code without the need to recompile.

Result You should see the red arrow rotating as predefined in the scenario.

Start There are no special steps to be performed.

Steps Step 1 Include servo driver library: #include <Servo.h>

Step 2 Define a servo management class: ... Servo servo; ...

If you intend to implement your solution with rotation targets array, here is a hint on array declaration: ... int angles[] = {0,45,90,135,180,90,0}; ...

Step 3 Instantiate software controller component for the LCD display:

49

9. Hands-on lab scenarios for SUT VREL nodes ... LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x3F for nodes 1 through 5, 8 //LiquidCrystal_I2C lcd(0x27,20,4); // for nodes 10 and 11 only! ...

Step 4 In the setup() function initialize LCD and attach servo, then implement your code: ... lcd.init(D2,D1); // initialize the lcd lcd.backlight(); lcd.home(); lcd.print("Starting"); ... servo.attach(servoPin); servo.write(0); // rotate to 0 degrees. ...

Setting servo to desired angle is as simple as calling servo.write(angle);. Default mapping is 0…180 degrees for micro servos we use here. If you implement your solution using rotation targets array, here is a hint on how to implement the for loop to iterate over an array: ... for(int i=0; i<sizeof(angles); i++) { ...

The sizeof operator above brings you automated evaluation of the array size during compilation, thus if you add or remove an item(s) from the array in the declaration section, loop will automatically change iteration scope, according to the new array size. Give it at least 2s gap between setting subsequent rotation target for the servo. Otherwise, you may be unable to reliably observe results via video stream.

Step 5 Keep loop() dummy, empty method not to overheat the servo or to wear out it's gears: ... void loop() { }

Result validation Observe the arrow rotating to the desired angle.

50

9. Hands-on lab scenarios for SUT VREL nodes 9.0.7. B8: Controlling fan using PWM In this scenario, you will control a fan using PWM. The fan pushes air into the air chamber so you may expect air pressure readings provided via integrated BMP280 pressure sensor to increase a bit. Changes should reflect fan rotation speed (non-linear way, as noted below). Servo is connected to the GPIO D8. Relation between rotation speed and PWM duty cycle is non-linear, thus i.e. switching duty cycle from 200 to 400 does not bring you twice the rotation speed of the fan, as well as won't generate twice as much airflow nor pressure inside air chamber.

Target group Beginners

Prerequisites Students should get familiar with BMP pressure readings and presenting their value on the LCD display. he fan is controlled raw PWM signal generated as “analogue” output. There is no need to include any library to operate the fan.

Scenario In this scenario, you will start rotating fan (0 means fan is stopped) and observe air pressure change on the LCD display. Keep periodical changes of the fan rotation (i.e. every 10s) and experiment with different speeds. The valid range is between 0 and 1023.

Result You should see the fan rotating in the camera. Note, it will be hard to observe rotation speed via camera, so you can observe result indirectly via observing pressure changes on the LCD display.

Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library as presented in scenarios B1 and B2. You need to include a generic Arduino library to control PWM frequency. No other libraries are necessary but for convenience and programming purity, you may define the pin that controls the fan: #include ... #define PWMFanPin D8

51

9. Hands-on lab scenarios for SUT VREL nodes Step 2 In the setup() section of the code, define GPIO D8 as output and define PWM frequency. It is also a good idea to stop the fan at the beginning of your code. Also, give some time for the BMP sensor (once initialised) to let it relax in current pressure and stabilise readings. At least 10s delay is suggested. ... pinMode(PWMFanPin,OUTPUT); analogWriteFreq(250); ... analogWrite(PWMFanPin,0); //stop FAN ... delay(10000);

Step 3 Change the fan rotation speed using analogWrite(pin, value) and keep delays between consecutive changes to let the BMP280 sensor go along with new air pressure in the air chamber: ... analogWrite(PWMFanPin,500); delay(5000); ... //here read air pressure delay(5000); ... // next rotation speed

Step 4 Once you're done with your lab, please execute following code to stop the fan. Thank you! Once finished your experiments, please execute the following code, to stop fan: #include #define PWMFanPin D8 void setup() { pinMode(PWMFanPin,OUTPUT); analogWriteFreq(250); analogWrite(PWMFanPin,0); //stop FAN } void loop() { //This section was intentionally left blank }

52

9. Hands-on lab scenarios for SUT VREL nodes Result validation Observe air pressure changes on the LCD. Try to evaluate minimum and maximum values (related to the fan stopped and operating on max rpm. Remeber to execute fan stopping code once all your experimentation is finished.

9.0.8. U1: Connecting to the network in STA mode Most IoT (if not all of them) require your device to communicate via a network. Here we connect to the existing WiFi network, 2.4GHz. All laboratory nodes can access common access point and require credentials to connect to it (see laboratory description section for the credentials and latest updates). ESP 8266 has a built-in WiFi interface, so you're using it to connect to the network. Every ESP has an individual MAC address. An IP address is assigned to the ESP via DHCP server, automatically, so you will present it on the LCD screen

Target group Undergraduate / Bachelor / Engineering Students

Prerequisites You will need to know the credentials of the network - see node description for details. Mind, those may be different than in the code chunks presented below. You need to know how to handle 4×20 characters LCD screen. In case of doubt re-work on scenarios B1 and B2.

Scenario In this scenario, you will create a WiFi client to connect to the AP then present connection status (eventually the failure, with attempts) on the LCD screen. Then you will show on the LCD given IP address and MAC address of your ESP8266. While attempting to connect, the first line of the LCD should present information “Connecting Wifi” and the second line should present the attempt number. When connected, the first line of the LCD should present information “WiFi connected”, following one your given IP address including “IP: XXX.XXX.XXX.XXX”. As MAC address is pretty long (17 chars including separators, here we will use the fourth line to present it, while “MAC: ” header should be present in the third line of the LCD. Note, there is a ticker, showing that the device is alive, implemented the same way as in scenario B1, for beginners. We suggest putting connection and information code into the separate function that you will call from the setup() one, just for cleaner code.

Result The LCD screen should present the current situation and all the necessary information. Once connected, observe the IP address assigned by the DHCP server and device's MAC.

53

9. Hands-on lab scenarios for SUT VREL nodes Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Note - in this scenario, you connect only once. If your connection breaks, you will have no information about it here. To handle such situation, there are multiple solutions: you can check in the loop() if the connection is OK and in case it is down, you can call your re-connecting function, or you can use one of the asynchronous handlers, triggered automatically via the WiFi manager. To use the latter approach, refer to the ESP8266 WiFi implementation for Arduino documentation.

Steps Following steps do not present full code - you need to supply missing parts on your own!

Step 1 Include all necessary libraries. The minimum set here is: #include #include <ESP8266WiFi.h> #include ...

Step 2 Give it some definitions as identifiers for cleaner code: #define wifi_ssid "internal.IOT" #define wifi_password "IoTlab32768"

Always refer to the node documentation to ensure you know current SSID and passphrase. They may differ to those in the code above!

Step 3 Print some information about starting connecting to WiFi, configure network interface as a WiFi client and give it a try to connect to the AP: delay(10); WiFi.mode(WIFI_STA); WiFi.begin(wifi_ssid, wifi_password); n=0;

delay(10) is necessary to give it a breath before you ask it to connect to the web - wifi interface itself boots slower than rest of the ESP8266 because of radio physics. n=0 is an iterator here - you will use it to show a number of attempts - you should usually succeed in one or couple. If attempts start ticking up, look for the code mistakes and

54

9. Hands-on lab scenarios for SUT VREL nodes check your SSID and passphrase. Please, explicitly use interface mode setting: WiFi.mode(WIFI_STA);. See FAQ section for details.

Step 4 Check if connected, if not, give it next attempt: while (WiFi.status() != WL_CONNECTED) { lcd.setCursor(0,1); n++; sprintf(buffer,"Attempt %d",n); lcd.print(buffer); delay(1000);

Step 5 When connected, show details to the camera: lcd.clear(); lcd.home(); lcd.print("WiFi connected!"); //Print IP String s = WiFi.localIP().toString(); sprintf(buffer,"IP: %s",s.c_str()); lcd.setCursor(0,1); lcd.print(buffer); //Print MAC lcd.setCursor(0,2); lcd.print("MAC:"); s = WiFi.macAddress(); lcd.setCursor(0,3); lcd.print(s.c_str());

IP address returned by the WiFi.localIP() function of the WiFi manager returns IPAddress structure so you need to convert it to String. Supprisingly, MAC address is an already pre-formatted String object.

Step 6 In the loop() function present ticker in the 3rd line, right side of the LCD. The 4th line is all occupied by the MAC address, if you followed 1:1 the guide. In case your UI looks different, handle coordinates appropriatelly.

Result validation Run your code and observe LCD presenting information on connection progress, IP and MAC addresses.

FAQ Does IP address change over time?: Yes. First of all, IP is given automatically by the DHCP server. There is no strict rule saying, your IP is always going to be the same.

55

9. Hands-on lab scenarios for SUT VREL nodes Second, IP address reservation is done for some period of time and then DHCP server may assign you other IP so it may change over runtime, not necessarily between restarts only. Does MAC address change: No. It is a factory given one and should be unique worldwide. Anyway, you can programmatically change it - this technique is commonly used by hackers to mimic other devices. Do I need to use WiFi.mode(WIFI_STA);?: Yes, please do. Theoretically, if consecutive compilations use STA (client to AP) mode of the ESP8266 wifi interface, your code may work without it. However, you never know if the previous user used STA or AP (or both). Your code may fail then if not explicitly stated!

9.0.9. U2: Exposing access point (AP) In this scenario, you set up your own access point. Please note, in this case, a number of devices you can connect to the AP is really limited. VRELs 1, 2, 3 and 4 are physically located together, while VREL 6 and VREL 7 are in two remote locations, thus you may not be able to reach hosted AP.

Target group Undergraduate / Bachelor / Engineering Students

Prerequisites You need to know how to handle 4×20 characters LCD screen. In case of doubt re-work on scenarios B1 and B2. Warning: In no case should you give your AP the internal.IOT SSID name! You will mess up the laboratory environment and block other users from accessing network infrastructure. We consider this behaviour as hacking and it will be penalized under legal jurisdiction! In no case give your AP the internal.IOT SSID! You will mess up the laboratory environment and block other users from accessing network infrastructure. We consider this behaviour as hacking and it will be penalized under legal jurisdiction! To fully experience this scenario, you need to book another node (one of 1,2,3 or 4), to let the other node act as your networking client. You can use scenario U1 for this purpose but mind to update network SSID and passphrase in your code, to let it connect to your server. Students physically present in the SUT IoT laboratory room 320 may use their own devices like laptops or mobile phones to connect to your AP.

Scenario In this scenario, you will set up an access point and present on the LCD screen number of clients connected. The devices that connect to your AP obtain automatically an IP address from your AP so actually it hosts a DHCP server out of the box! The IP range is from the 192.168.4.x subnet, but you can configure it for another one if you only wish via wifi.ap.shcp.config() function. if you use the default configuration, your AP is 192.168.4.1.

56

9. Hands-on lab scenarios for SUT VREL nodes Result On the LCD you should present that AP is active, its name (SSID) and passphrase (select one no longer than 20 characters, to fit single line). In the last line of the LCD, there should be present a number of connected devices.

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. you will use loop() to display a number of connected devices to your network. There do exist asynchronous way (event-based) to do it, but here we use a simplified, blocking approach. If you want to test the other one, refer to the ESP8266 WiFi implementation for Arduino documentation.

Steps Following steps do not present full code - you need to supply missing parts on your own!

Step 1 Include all necessary libraries. The minimum set here is: #include #include <ESP8266WiFi.h> #include ...

Step 2 Give it some definitions as identifiers for cleaner code, remember to change ssid name to yours! #define wifi_ssid_ap put_your_unique_id_here //give it some unique name-change here #define wifi_password_ap "1234567890"

Never use internal.IOT as your SSID name wifi_ssid_ap - you will overlap existing network infrastructure and we consider it as hacking that is subject to jurisdiction! Your account will be imediatelly banned!

Step 3 Print some information about starting software WiFi AP, configure network interface as a WiFi AP and give it a try to start: ... delay(10); ... WiFi.mode(WIFI_AP);

57

9. Hands-on lab scenarios for SUT VREL nodes delay(100); boolean result = WiFi.softAP(wifi_ssid_ap, wifi_password_ap); if(result == true) { ... //Announce success, print status, SSID and passphrase to the LCD } else { ... //Announce failure. Print it on LCD } ...

Step 4 Implement in the loop() an information about number of connected clients, i.e. like this: ... void loop() { lcd.setCursor(0,3); sprintf(buffer, "Stations: %d", WiFi.softAPgetStationNum()); lcd.print(buffer); delay(3000); } ...

Result validation Check your AP is active on LCD eventually observe failure. If works OK, compile U1 scenario on another node(s), mind to update SSID and passphrase in the U1 source code then observe if connected clients counter increases.

FAQ Do I need to use WiFi.mode(WIFI_AP);?: Yes, please do. Theoretically, if consecutive compilations use AP (software server) mode of the ESP8266 wifi interface, your code may work without it. However, you never know if the previous user used STA or AP (or both). Your code may fail then if not explicitly stated!

9.0.10. U3: Sending MQTT messages In this scenario, you will send MQTT message exposing temperature and humidity to the MQTT server available on the internal.IOT network. By sending sensor data, you will learn, how to expose the device's state and how to inform others that your device stopped working uncontrolled way.

Target group Undergraduate / Bachelor / Engineering Students

58

9. Hands-on lab scenarios for SUT VREL nodes Prerequisites We assume you already know how to: ▪

handle DHT sensor to read temperature and humidity,



handle LCD screen to present information,



connect to the existing WiFi network: internal.IOT,



additionally we will ask you to install and use an MQTT client of your choice. We suggest using MQTT Spy, but any MQTT client that will let you subscribe to the MQTT messages is OK. You connect it to the public IP of the MQTT broker (see below).

MQTT broker present in the internal.IOT network is also visible under public address. So whenever you publish an MQTT message using VREL node that is connected to the internal.IOT network, you may subscribe to it using other devices connected to the internal.IOT, i.e. other VREL node or if you're physically present at SUT in the IOT laboratory room 320, then you can connect your mobile and laptop to the internal.IOT network and use “internal” IP address. However, if you're in a remote location, you can access the same broker under public IP as stated in the node description. Same messages published on the internal network are also visible on the public side. Mind, to access MQTT broker you need to use IP, user and password (applies to both public and private IPs of the MQTT Broker). Refer to the node documentation for the latest information. Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the MQTT Broker.

Scenario In this scenario, you will connect to the infrastructure as a client (STA) and use the MQTT server to publish information about temperature, humidity. Also, you will expose device state using MQTT “last will” mechanism: on startup, you will configure MQTT broker to send an MQTT message with payload automatically off when connection breaks (i.e. your device goes down) and your starting code will send the same message with payload on to notify subscribers that you're (back) on-line. Parallelly, you will present temperature and humidity data on the LCD screen. In this scenario, you do not subscribe your device to any messages, you only publish them.

Result You should be able to see connection status, temperature and humidity on the screen while your MQTT subscriber should be able to present you readings delivered via MQTT. It should be equal to the data presented in the LCD screen you observe locally, via video stream.

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full

59

9. Hands-on lab scenarios for SUT VREL nodes line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Note - in this scenario, you connect only once. If your connection breaks, you will have no information about it here. To handle such situation, there are multiple solutions: you can check in the loop() if the connection is OK and in case it is down, you can call your re-connecting function, or you can use one of the asynchronous handlers, triggered automatically via the WiFi manager. To use the latter approach, refer to the ESP8266 WiFi implementation for Arduino documentation.

Steps Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. We also do not present in details on how to organise and print DHT22 sensor data on the LCD screen. Please refer to the scenario B2 if you need a recall.

Step 1 Include all necessary libraries. We use PubSubClient library to contact MQTT broker. The minimum set here is: #include #include #include #include #include ...

<ESP8266WiFi.h>

Declare some identifiers to let you easier handle necessary modifications and keep code clear: #define #define #define #define #define ...

wifi_ssid "internal.IOT" wifi_password "IoTlab32768" mqtt_server "192.168.90.5" mqtt_user "vrel" mqtt_password "vrel2018"

Step 2 Declare some identifiers, here MQTT messages' topics, MQTT client ID and payloads for the status notification (on / off). Use unique names for topics and for the MQTT client, do some random, use your MAC as part of it. It is important because MQTT broker identifies client using its name thus if your device shares name with some other that is already working, you may not get information about connection lost because another device with the same name is still active on the network. Unique topics are also essential: if you accidentally overlap, you may get an invalid reading with someone that is using the same topic but different payload.

60

9. Hands-on lab scenarios for SUT VREL nodes #define MQTTClientName ...... #define tempTopic ...<some topic for temperature>... // give it some unique topic // i.e. including your name #define humTopic ...... // as above //MQTT last will #define lastWillTopic ...<some topic for exposing state and last will>... // give it some unique topic // i.e. including your name #define lastWillMessage "off" #define mqttWelcomeMessage "on"

Step 3 By the regular variables related to you WiFi Esp network client, DHT sensor, buffer for string processing and so on, here you need to configure an object additionally to handle communication with MQTT broker. As you may use many brokers in your app, you need to instantiate it yourself. The constructor accepts WiFiClient as a parameter, so here you need explicitly declare one: // WiFi & MQTT WiFiClient espClient; PubSubClient client(espClient);

Configure your network client, remember to set ESP.mode(WIFI_SFA). Once you're done with starting, initialise MQTT broker client. Once you're done with connecting to the WiFi, configure your MQTT PubSubClient: client.setServer(mqtt_server, 1883);

You can call it i.e. in the setup() function, after a successful connection to the WiFi AP but before you execute step 4.

Step 4 If your WiFi client is working, your MQTT client is configured it is time to connect to the MQTT broker. It is a good idea to have this procedure separated to call as needed if your connection with MQTT broker goes down for any reason. Here we encapsulate it in the reconnect() function: void reconnect() { // Loop until we're reconnected while (!client.connected()) { if (client.connect(MQTTClientName, mqtt_user, mqtt_password, lastWillTopic, 0, true, lastWillMessage)) { client.publish(lastWillTopic, mqttWelcomeMessage, true); } else { // Wait 5 seconds before retrying delay(5000); } }

61

9. Hands-on lab scenarios for SUT VREL nodes lcd.setCursor(0,1); lcd.print("MQTT Connected!"); }

Function retries every 5 seconds, in case it is unable to connect to the MQTT broker. You can call it in the very beginning of the loop() function, checking in advance if your client is connected or not, i.e. this way: ... if (!client.connected()) { reconnect(); //reconnect MQTT } ...

Step 5 Prepare a code that publishes MQTT messages. You will call it periodically within loop() section. Do not try to send data too frequently. Once every 10-20s is pretty enough as nor humidity nor temperature will change rapidly. On the other hand, sending too frequently causes network bottlenecks and heavy load on the MQTT broker. Your publishing routine may look somehow like this: void mqttPublish() { hum = dht.readHumidity(); temp = dht.readTemperature(); if(client.connected()) { if (!(isnan(temp)||isnan(hum))) { client.publish(tempTopic, String(temp).c_str(), false);

// Do not retain // messages

client.publish(humTopic, String(hum).c_str(), false); } } }

If you choose to implement this routine as a ticker/timer, you will experience ESP crash every execution of this loop (you will observe it as your device may freeze or restart every execution). The reason is if you use timer/ticker, those routines are not giving extra time for the WiFi handling routine (while main loop() indeed does). reading from the DHT sensor takes so much time, blocking here device to handle WiFi communication, so hardware watchdog will trigger an exception and break your code execution! To handle this issue you must read DHT sensor in the main loop() and insert them into the variables then limit MQTT publish procedure just to only prepare and send data over the network (this is legit). Anyway, we do not consider this kind of scenario here as we call publishing code directly from within the loop() function so it is safe. Finally your loop() may look like this: void loop()

62

9. Hands-on lab scenarios for SUT VREL nodes { if (!client.connected()) { reconnect(); } client.loop(); sprintf(buffer,"Temp is %2.1f C",temp); lcd.setCursor(0,2); lcd.print(buffer); sprintf(buffer,"Humidity is %2.1f%% Rh",hum); lcd.setCursor(0,3); lcd.print(buffer); mqttPublish(); delay(5000); }

the client.loop() is to handle incoming MQTT messages. There are none here but it is good practice to have it in your code.

Result validation Observe connection progress on the LCD via video stream. Once WiFi and MQTT are connected you should be able to see temperature and humidity readings on the LCD and additionally those should be sent over the MQTT messages to the MQTT broker. Connect your MQTT client and subscribe to your messages (you may do it using a wildcard character) i.e. with means of the MQTT spy application. Remember to connect MQTT spy to public IP address unless you're a student physically present in our laboratory room and you have direct access to the internal.IOT network. Observe data on the LCD screen the same as over MQTT messages (note, there may be a delay because of the network bottlenecks and MQTT broker load).

FAQ What topic should I choose?: Up to you. Anyway, we suggest using non-trivial ones just not to overlap with other users. Why MQTT broker uses two IP addresses?: As programming ESP826 devices may issue many hacking scenarios, we decided to use separated WiFi network. On the other hand, it should be a way to exchange some data with the external world. Here comes the solution: our MQTT broker is connected one leg to the separated internal.IOT network while another interface connects to the public Internet. This way any message you publish from within the private network is visible (you can subscribe to it) on both sides: public and private one. This way you can send information to the i.e. IBM Watson cloud or Microsoft Azure to store it and visualise. Opposide, you can drive the node device connected to the internal.IOT solely from the Internet, i.e. implementing some interface using dashboard. All you need is to publish to our MQTT broker on its public interface and write a code that subscribes to those messages on the private side. Simple and safe.

9.0.11. U4: Receiving and handling MQTT messages In this scenario, you will subscribe to the MQTT broker for MQTT messages and handle them. Most of the code yo will implement here is similar to the scenario U3, including LCD handling and connecting to the MQTT broker.

63

9. Hands-on lab scenarios for SUT VREL nodes Target group Undergraduate / Bachelor / Engineering Students

Prerequisites We assume you already know how to: ▪

handle DHT sensor to read temperature and humidity,



handle LCD screen to present information,



connect to the existing WiFi network: internal.IOT,



additionally we will ask you to install and use an MQTT client of your choice. We suggest using MQTT Spy, but any MQTT client that will let you subscribe to the MQTT messages is OK. You connect it to the public IP of the MQTT broker (see below).

MQTT broker present in the internal.IOT network is also visible under public address. So whenever you subscribe to the MQTT message using VREL node that is connected to the internal.IOT network, you may publish to it using other devices connected to the internal.IOT, i.e. other VREL node or if you're physically present at SUT in the IOT laboratory room 320, then you can connect your mobile and laptop to the internal.IOT network and use “internal” IP address. However, if you're in a remote location, you can access the same broker under public IP as stated in the node description. When you publish an MQTT message using public IP, it will be delivered to the subscribers in the private internal.IOT network as well. Mind, to access MQTT broker you need to use IP, user and password (applies to both public and private IPs of the MQTT Broker). Refer to the node documentation for the latest information. Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the MQTT Broker.

Scenario In this scenario, you will connect to the infrastructure as a client (STA) and use the MQTT server to subscribe to the messages sent by some publisher. You will present received MQTT message on the LCD screen. We will implement a “remote display”, where you handle remote requests to put contents on specific (one of four) LCD lines. MQTT payload should be a string then. We assume that the last character of the topic determines line number (between 0 and 3) so you need to construct MQTT topics as i.e. like /mydevice/ someuniqueID/LCDcontent/0 for the first line, /mydevice/someuniqueID/LCDcontent/ 1 for the second one, and so on. Mind to update “someuniquieID” with your ID not to overlap with other students as you share single MQTT broker!

Result You should be able to visualise payload of the subscribed messages on the LCD screen. Note, you handle only a limited number of messages that you subscribe to. When subscribing, do not go “too wide” using wildcards cause you won't be able to present all of them on the LCD display. Remember, you share MQTT broker with other users so tailor your subscriptions to those that apply to your device.

64

9. Hands-on lab scenarios for SUT VREL nodes Subscribing to # is a really bad idea in production, live system. You will get a flood of messages!

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Note - in this scenario, you connect only once. If your connection breaks, you will have no information about it here. To handle such situation, there are multiple solutions: you can check in the loop() if the connection is OK and in case it is down, you can call your re-connecting function, or you can use one of the asynchronous handlers, triggered automatically via the WiFi manager. To use the latter approach, refer to the ESP8266 WiFi implementation for Arduino documentation. To handle incoming MQTT messages, you will need to implement a callback function that will be triggered, whenever a new message comes. You will receive only those messages that you've subscribed to. Note you need to check and decode message topics yourself.

Steps Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. Please refer to scenario B1, if you need a recall on how to handle LCD screen.

Step 1 Include all necessary libraries. We use PubSubClient library to contact MQTT broker. The minimum set here is: #include #include #include #include #include ...

<ESP8266WiFi.h>

Declare some identifiers to let you easier handle necessary modifications and keep code clear: #define #define #define #define #define ...

wifi_ssid "internal.IOT" wifi_password "IoTlab32768" mqtt_server "192.168.90.5" mqtt_user "vrel" mqtt_password "vrel2018"

Step 2 Declare some identifiers, here MQTT messages' topic (one with wildcard, for four LCD lines) and MQTT client ID.

65

9. Hands-on lab scenarios for SUT VREL nodes Use unique names for topics and for the MQTT client, do some random, use your MAC as part of it. It is important because MQTT broker identifies the client using its name. Also note, the set of MQTT topics that you use to send information to your LCD should be unique, otherwise some other users may “inject” information to your display. Use topics that their last character is a line number (0 till 3) to easily suit lcd.setCursor(x,y) requirements, i.e. as below: // MQTT messages #define MQTTClientName "thisissomeuniqueclientname" #define lcdTopicWithWildcard "/sut/mydevice/LCD/+"

Valid MQTT messages are: ▪

/sut/mydevice/LCD/0 - delivers payload for line 1 of the LCD screen,



/sut/mydevice/LCD/1 - delivers payload for line 2 of the LCD screen, and so on.

Step 3 We will declare an MQTT handler callback function that is called whenever new MQTT message comes. Mind - only those messages that you've subscribed to are triggering this function, so you do not need to check the topic other than decoding its part to obtain, which LCD line number comes (this is the last character of the MQTT topic): void mqttCallback(char* topic, byte* payload, unsigned int length) { char nLine = topic[strlen(topic)-1]; n = atoi(&nLine); if (n>=0 && n<=3) { lcd.setCursor(0,n); lcd.print(" "); //clear one line for (int i = 0; i < length; i++) { lcd.setCursor(i, n); lcd.write((char)payload[i]); } } }

Note - header of the function is interface declared by the mqtt PubSubClient library. topic is MQTT message topic, payload is a content and length is payload's length. As payload is binary, length is essential to know, how to handle payload contents.

Step 4 By the regular variables related to your WiFi ESP network client and so on, here you need to configure an object additionally to handle communication with MQTT broker. As you may use many brokers in your code, you need to instantiate it yourself, there is no singleton class as in case of the network interface. The constructor accepts WiFiClient as a parameter, so here you need explicitly declare one, to gain access to it: // WiFi & MQTT WiFiClient espClient;

66

9. Hands-on lab scenarios for SUT VREL nodes PubSubClient client(espClient);

Configure your network client, remember to set ESP.mode(WIFI_SFA). Once you're done with starting, initialise MQTT broker client. Once you're done with connecting to the WiFi, configure your MQTT PubSubClient and give it a handler function to let it be called, whenever a new message comes (here mqttCallback: client.setServer(mqtt_server, 1883); client.setCallback(mqttCallback);

You can call it i.e. in the setup() function, after a successful connection to the WiFi AP but before you execute step 4.

Step 5 If your WiFi client is working, your MQTT client is configured it is time to connect to the MQTT broker. It is a good idea to have this procedure separated to call as needed if your connection with MQTT broker goes down for any reason. Here we encapsulate it in the reconnect() function where we also subscribe to the number of topics delivering LCD content in the payload: void reconnect() { // Loop until we're reconnected while (!client.connected()) { if (client.connect(MQTTClientName, mqtt_user, mqtt_password)) { client.subscribe(lcdTopicWithWildcard); } else { // Wait 5 seconds before retrying delay(5000); } } lcd.setCursor(0,1); lcd.print("MQTT Connected!"); }

Step 6 Finally your loop() may look like this: void loop() { if (!client.connected()) { reconnect(); } client.loop(); }

The client.loop() is to handle incoming MQTT messages.

Result validation Compile and run your code then wait till it connects to the network and MQTT broker.

67

9. Hands-on lab scenarios for SUT VREL nodes Once it is connected, use your favourite MQTT client to connect to the MQTT broker and issue a number of MQTT messages that their topics are: ▪

/sut/mydevice/LCD/0



/sut/mydevice/LCD/1



/sut/mydevice/LCD/2



/sut/mydevice/LCD/3

and the payload is a text you want to display on your LCD. Note, your display ix 20 characters each line only so keep your payload within those limits.

FAQ This section is to be extended as new questions appear. When using the printed version of this manual please refer to the latest online version of this document to obtain the valid and up-to-date list of the FAQ. Provide some FAQs in the following form: Question?: Answer.

9.0.12. U7: Controlling fan speed and servo angle via MQTT In this scenario, you will learn how to remotely control fan speed using PWM and how to control servo angle using MQTT messages. This scenario is a practical extension to the scenario U4 where you learned, how to receive and handle MQTT messages.

Target group Undergraduate / Bachelor / Engineering Students

Prerequisites We assume you already know how to: ▪

handle LCD screen to present information,



connect to the existing WiFi network: internal.IOT,



receive and handle MQTT messages using PubSubClient library



additionally we will ask you to install and use an MQTT client of your choice. We suggest using MQTT Spy, but any MQTT client that will let you subscribe to the MQTT messages is OK. You connect it to the public IP of the MQTT broker (see below).

MQTT broker present in the internal.IOT network is also visible under public address. So whenever you subscribe to the MQTT message using VREL node that is connected to the internal.IOT network, you may publish to it using other devices connected to the internal.IOT, i.e. other VREL node or if you're physically present at SUT in the IOT laboratory room 320, then you can connect your mobile and laptop to the internal.IOT network and use “internal” IP address. However, if you're in a remote location, you can access the same broker under public IP as stated in the node description. When you publish an MQTT message using public IP, it will be delivered to the subscribers in the private internal.IOT network as well. Mind, to access MQTT broker you need to use IP, user and password (applies to both public and private IPs of the MQTT Broker). Refer to

68

9. Hands-on lab scenarios for SUT VREL nodes the node documentation for the latest information. Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the MQTT Broker. Warning - physical servo range is ONLY between 0 and 90 degrees! Going over 90 degrees may cause a break to the equipment and you may be charged for repair!

Scenario In this scenario, you will handle incoming MQTT messages (one for controlling fan, other for servo, opening and closing the flap. Parallelly you will present incoming messages on the LCD screen.

Result You should be able to remotely control fan rotation speed and flap angle (0..90 degrees), observe connection status and incoming MQTT messages for your device on the LCD screen.

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators and storing current PWM for servo and fan. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Reading analogue input brings you an integer value. Servo is controlled using GPIO pin D5 (GPIO14) while the fan is controlled using GPIO pin D8 (GPIO15). As servo we use is a small one, it is powered and controlled directly through the ESP8266 while in case of the FAN, it is controlled indirectly, using a transistor. Legal range for the servo is 0…90 degree! Exceeding over 90 degrees may break the construction! Valid range for controlling fan is 0 (stopped) till 4095 (full speed). Please note, characteristics are non-linear, so setting output 2047 does not mean that rotation speed nor airflow is half of the maximum.

Steps Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. Please refer to scenario B1, if you need a recall on how to handle LCD screen. In case you're in doubt how to handle MQTT messages communication (here publishing/ sending), please refer to the U4 scenario.

Step 1 Include all necessary libraries. We use PubSubClient library to contact MQTT broker. The

69

9. Hands-on lab scenarios for SUT VREL nodes minimum set here is: #include #include #include #include #include ...

<ESP8266WiFi.h> <Servo.h>

Here we use Servo.h library to easily handle servomotor control for regular, modeller's servos, mostly used in RC toys. Declare some identifiers to let you easier handle necessary modifications and keep code clear: #define #define #define #define #define ...

wifi_ssid "internal.IOT" wifi_password "IoTlab32768" mqtt_server "192.168.90.5" mqtt_user "vrel" mqtt_password "vrel2018"

Step 2 Declare some identifiers, here MQTT messages' topics, MQTT client ID and payloads for the status notification (on / off). Use unique names for topics and for the MQTT client, do some random, use your MAC as part of it. It is important because MQTT broker identifies client using its name thus if your device shares name with some other that is already working, you may not get information about connection lost because another device with the same name is still active on the network. Unique topics are also essential: if you accidentally overlap, you may get an invalid reading with someone that is using the same topic but different payload. // MQTT messages #define MQTTClientName "myVREL2clientname" #define servoTopic ...<some topic for servo>... // // #define fanTopic ...<some topic for fan>... // //

give i.e. give i.e.

it some unique including your it some unique including your

topic name topic name

//MQTT last will #define lastWillTopic ..<some topic for exposing state and last will>... // give it some unique topic // i.e. including your name #define lastWillMessage "off" #define mqttWelcomeMessage "on"

Finally, declare GPIOs pin numbers connecting to the servo and fan: //Hardware #define PWMFanPin D8 #define servoPin D5

70

9. Hands-on lab scenarios for SUT VREL nodes Step 3 Declare WiFiCilent, PubSubClient, initialise, instantiate and connect to the network. If in doubt, refer to the scenario U4 on how to prepare networking code for your solution. Additionally, instantiate a servo controlling the flap: ... Servo servo; ...

Later, in your initialisation section (possibly in setup() function) bind your servo with physical one using appropriate GPIO and set it to 0 degrees (close the flap, down). Also, initialise fan's GPIO for output, to control PWM and set it to 0 (stop fan): ... void setup() { ... // Servo and PWM fan servo.attach(servoPin); servo.write(0); //set servo down to 0 degrees pinMode(PWMFanPin,OUTPUT); analogWrite(PWMFanPin,0); //stop FAN ...

Note - here you see how to control servo and fan. In the case of the servo, we use a Servo library, so function servo.write(deg) sets servo to the desired number of degrees. While the fan is controlled using RAW values on 12bit resolution (in fact it is PWM as well) from 0 to 4095, using analogWrite(pin, value). Word “analog” may mislead you here: output on the digital pin is not a continuous analogue voltage value, but its approximation using PWM anyway, it works perfectly for the fan and many other devices.

Step 4 Implement MQTT callback - a function that is being called, whenever there comes an MQTT message. You should have subscribed only to the selected MQTT messages (one for the fan, other for the servo) so only those messages may trigger your callback function. Anyway, it is a matter to distinguish, which one message comes. Your function may look like this: void mqttCallback(char* topic, byte* payload, unsigned int length) { lcd.setCursor(0,2); lcd.print("Servo:"); lcd.setCursor(0,3); lcd.print("Fan:"); String sTopic(topic); if(sTopic.startsWith(servoTopic)) { //Handle servo message for(int i=0; i< length; i++) { buffer[i] = (char)payload[i];

71

9. Hands-on lab scenarios for SUT VREL nodes } buffer[length]='\0'; srv = atoi(buffer); servo.write(srv); lcd.setCursor(9,2); sprintf(buffer,"%2d deg",srv); lcd.print(buffer); } if(sTopic.startsWith(fanTopic)) { //Handle fan message for(int i=0; i< length; i++) { buffer[i] = (char)payload[i]; } buffer[length]='\0'; fan = atoi(buffer); analogWrite(PWMFanPin,fan); lcd.setCursor(7,3); sprintf(buffer,"%4d PWM",fan); lcd.print(buffer); } // give it some unique topic i.e. including your name }

As you see, we do not only receive the value but also drive LCD display to present it. Still you may inject some validation code, particularly for the servo, i.e. check if incoming MQTT payload for the servo message is more than 90 degres then truncate it not to break the device physically.

Step 5 Remember to bind your MQTT callback function to the MQTT PubSubClient. Perhaps you will do it in the setup() or in the reconnect() functions: ... client.setCallback(mqttCallback); ...

Result validation Observe flap moving out and in. As the fan is mounted perpendicular to the video camera, you cannot observe rotation directly (video stream is too slow to present it on the other hand). You can observe value on the analogue gauge to the right but also indirectly through the flap mounted in the corresponding air receiving node (RX). Those are VREL1 and VREL3 for sending nodes VREL2 and VREL4 respectively. You will see the air stream pushing the flap thus you can monitor the airflow.

FAQ What is the valid range for controlling the fan?: The fan is connected to the digital pin and controlled via PWM (12-bit resolution). Thus valid range is from 0 (min) to 4095 (max). Note rotation speed and airflow do not have linear characteristic vs PWM controlling value, So issuing 2047 on the GPIO pin controlling the fan won't make your fan to rotate 50% nor the airflow will be 50% of the maximum one. You need to

72

9. Hands-on lab scenarios for SUT VREL nodes experiment individually! What is the valid range for controlling the servo?: The valid range is from 0 to 90 degrees. Exceeding 90 degrees can break the construction! Never go beyond 90 degrees!

9.0.13. U8: Visualising and sending flap state In this scenario, you will use to monitor the voltage of the unbalanced resistance bridge connected to the analogue input. Voltage level reflects the flap inclination via the light level, reflected from the flap (compared to the reference one).

Target group Undergraduate / Bachelor / Engineering Students

Prerequisites We assume you already know how to: ▪

handle LCD screen to present information (refer to the scenarios B1 and B2 when in doubt),



connect to the existing WiFi network: internal.IOT,



publish to the MQTT broker available in your network,



additionally, we will ask you to install and use an MQTT client of your choice. We suggest using MQTT Spy, but any MQTT client that will let you subscribe to the MQTT messages is OK. You connect it to the public IP of the MQTT broker (see below).

MQTT broker present in the internal.IOT network is also visible under public address. So whenever you publish an MQTT message using VREL node that is connected to the internal.IOT network, you may subscribe to it using other devices connected to the internal.IOT, i.e. other VREL node or if you're physically present at SUT in the IOT laboratory room 320, then you can connect your mobile and laptop to the internal.IOT network and use “internal” IP address. However, if you're in a remote location, you can access the same broker under public IP as stated in the node description. Same messages published on the internal network are also visible on the public side. Mind, to access MQTT broker you need to use IP, user and password (applies to both public and private IPs of the MQTT Broker). Refer to the node documentation for the latest information. Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the MQTT Broker. Note - Analog input in ESP8266 measures voltage on the pin A0, ranging from 0 to 3.3V (in reality somewhere from 0.1-0.2V to 3.2V) using 4096 distinguishable values - the A/ D converter resolution is then 12bit and return values you may expect, range from 0 to 4095 - in fact they're much more narrowed.

Scenario I this scenario, once you get connected to the WiFi as AP and then to the MQTT server to publish data, you will periodically read A0 (analogue) input of the ESP8266 and publish

73

9. Hands-on lab scenarios for SUT VREL nodes its RAW value to the MQTT server. You will also visualise the RAW value of the A0 input reading on the LCD screen.

Result You should be able to read data stream via MQTT message, presenting flap position. Parallel, data should be displayed on the LCD, along with connection status. Note - flap position refers to the airflow: you may need to control it using VREL2 and VREL4 for VREL1 and VREL3, respectively. Airflow in nodes 2 and 4 can be controlled twofold: using PWM to control fan rotation speed and using the flap to open/close air duct.

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Reading analogue input brings you an integer value.

Steps Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. Please refer to scenario B1, if you need a recall on how to handle LCD screen. In case you're in doubt how to handle MQTT messages communication (here publishing/ sending), please refer to the U3 scenario.

Step 1 Include all necessary libraries. We use PubSubClient library to contact MQTT broker. The minimum set here is: #include #include #include #include ...

<ESP8266WiFi.h>

There is no need to use a special library to read analogue input representing relative flap position here. Declare some identifiers to let you easier handle necessary modifications and keep code clear: #define #define #define #define #define ...

74

wifi_ssid "internal.IOT" wifi_password "IoTlab32768" mqtt_server "192.168.90.5" mqtt_user "vrel" mqtt_password "vrel2018"

9. Hands-on lab scenarios for SUT VREL nodes Step 2 Declare some identifiers, here MQTT messages' topics, MQTT client ID and payloads for the status notification (on / off). Use unique names for topics and for the MQTT client, do some random, use your MAC as part of it. It is important because MQTT broker identifies client using its name thus if your device shares name with some other that is already working, you may not get information about connection lost because another device with the same name is still active on the network. Unique topics are also essential: if you accidentally overlap, you may get an invalid reading with someone that is using the same topic but different payload. // MQTT messages #define MQTTClientName ...... #define analogOutTopic ...<some topic for flap>... // give it some unique topic // i.e. including your name //MQTT last will #define lastWillTopic ...<some topic for exposing state and last will>... // give it some unique topic // i.e. including your name #define lastWillMessage "off" #define mqttWelcomeMessage "on"

Step 3 Declare WiFiCilent, PubSubClient, initialise, instantiate and connect to the network. If in doubt, refer to the scenario U3 on how to prepare networking code for your solution.

Step 4 Prepare MQTT publishing code, here we publish periodically one value (flap position, relative), i.e. like this: void mqttPublish() { flap = analogRead(A0); if(client.connected()) { client.publish(analogOutTopic, String(flap).c_str(), false);

// Do not retain // messages

} }

Reading analogue input is pretty easy: all you need to do is to use analogRead(A0). Note, ESP8266 has only one analogue input A0.

Step 5 Your loop() function should include call to the aforementioned mqttPublish and printing on the LCD screen once every 5 seconds.

75

9. Hands-on lab scenarios for SUT VREL nodes void loop() { if (!client.connected()) { reconnect(); } client.loop(); mqttPublish(); sprintf(buffer,"Flap is %d ",flap); lcd.setCursor(0,2); lcd.print(buffer); delay(1000); }

Mind to keep a delay(…), not to saturate MQTT broker and communication channel. Minimum reasonable delay between issuing consecutive MQTT messages is about 200ms. The flap variable is a global one, set in the mqttPublish using analogRead(A0). This way you have it set for sprintf formating function.

Result validation Observe connection progress on the LCD via video stream. Once WiFi and MQTT are connected, you should be able to see analogue input readings on the LCD, and additionally, those should be sent over the MQTT messages to the MQTT broker. Connect your MQTT client and subscribe to your messages (you may do it using a wildcard character), i.e. with means of the MQTT spy application. Remember to connect MQTT spy to public IP address unless you're a student physically present in our laboratory room and you have direct access to the internal.IOT network. Observe data on the LCD screen the same as over MQTT messages (note, there may be a delay because of the network bottlenecks and MQTT broker load).

FAQ I want to implement PID controller of the position of the flap, using TX air pushing node (VRELS 2 and 4). 200ms latency between consecutive reads seems too large, to implement efficient loopback. What to do?: In this case, you should drop MQTT communication and communicate directly between nodes, i.e. your RX node (VREL1 and 3) can send a UDP message over the network. Our WiFi internal.IOT is a pretty efficient one, and should handle it with ease.

9.0.14. U9: A CoAP client In this scenario, you will interact with a CoAP server implemented as a NodeRED node. You will perform simple CoAP request to the NodeRED server, waiting for you. In return, you will obtain a secret code.

Target group Undergraduate / Bachelor / Engineering Students

76

9. Hands-on lab scenarios for SUT VREL nodes Prerequisites We assume you already know how to: ▪

handle LCD screen to present information (refer to the scenarios B1 and B2 when in doubt),



connect to the existing WiFi network: internal.IOT,



additionally, we will ask you to install and use a CoAP client of your choice. We suggest using chrome extension Cooper4Cr, chrome plugin, but any CoAP client will work here. You connect your solution to the private IP of the NodeRED server but the same information is available on the public IP as well, so you can check it from your home.

NodeRED CoAP server is present in the internal.IOT network and it is also visible under public address. Refer to the node documentation for the latest information. Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the NodeRED access. CoAP server data is: ▪

IP address (implemented with NodeRED) is: 192.168.90.5 as seen from the internal.IOT network, or 157.158.56.54 when accessing from the public space;



The only implemented URI is ”“ (simply root resource) - for other URIs you will get 4.04 (Not Found) error;



CoAP port is 5683 (default);

Scenario I this scenario, once you get connected to the WiFi as AP and then you will make a UDP request using CoAP protocol to the NodeRED server acting as CoAP server. Please note, we do not implement here discovery services for CoAP, for simplicity and because of constrained resources, so you won't be able to use clients' CoAP discover feature. You will obtain a secret code from the server (it varies over time). As a bonus, you may try to discover the secret code generation algorithm :-). You're expected to present the results of the CoAP query on the LCD screen. To implement a CoAP client feature you will use a dedicated library ESP-CoAP simple library, available via Platformio library management system.

Result You should be able to obtain a UDP message in CoAP, with the payload containing an ASCII text with secret code, and present it on the LCD screen.

Start Define some identifiers to separate and update AP's SSID and passphrase easily. To simplify conversion, use IPAddress class to create IP address of the CoAP server. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your

77

9. Hands-on lab scenarios for SUT VREL nodes code. You do not need to instantiate WiFi communication class - as you have only one interface here, it is singleton class you can refer directly using WiFi. Reading analogue input brings you an integer value. Note, you're supposed to instantiate your MCU as AP even if using UDP communication.

Steps Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. Please refer to scenario B1, if you need a recall on how to handle LCD screen.

Step 1 Include all necessary libraries. We use ESP-CoAP simple library to contact CoAP server as a client. Note, this library also implements a CoAP server features but we do not use it in our scenario here. The minimum set here is: #include #include #include #include ...

<ESP8266WiFi.h> "coap_client.h"

Declare some identifiers and variables/class instances to let you easier handle necessary modifications and keep code clear: #define wifi_ssid "internal.IOT" #define wifi_password "IoTlab32768" IPAddress ip(192,168,90,5);//take NodeRed Address int port = 5683; ...

Step 2 Declare coapClient and WiFi client, to implement CoAP client instance, PubSubClient, initialise, instantiate and connect to the network. If in doubt, refer to the scenario U3 on how to prepare networking code for your solution: ... coapClient coap; ...

Step 3 Prepare CoAP client response asynchronous handler. CoAP uses UDP for communication, so you will be informed asynchronously, when response to your request appears. That is fully handled by asynchronous response handler and mechanism is implemented by the library.

78

9. Hands-on lab scenarios for SUT VREL nodes As messages may come quickly in the queue (many replies) due to the heavy use or UDP nature, you are required to make a copy of the payload ASAP, best using memcpy, as first operation in your asynchronous response handler. void callback_response(coapPacket &packet, IPAddress ip, int ... // coap client response callback void callback_response(coapPacket &packet, IPAddress ip, int char p[packet.payloadlen + 1]; //declare memcpy(p, packet.payload, packet.payloadlen); //quickly p[packet.payloadlen] = NULL;

port); port) { local buffer for the payload copy payload contents

//response from coap server - check if this is regular one (response to your request), o if(packet.type==3 && packet.code==0){ //that means you've obtained a ping request so handle it (i.e. show on LCD) ... } ... //handle payload. } ...

Step 4 Start your CoAP client in the setup() function: ... // remember to initialise it AFTER you make a WiFi connection, not before coap.respinse(callback_response); // add response handler coap.start(); //start coap client

Step 5 Your loop() function should include call to the CoAP client methods. Here we use only CoAP GET, as this is the only one implemented by the NodeRED server, we provide to you: void loop() { ... int msgid = coap.get(ip,port,""); bool state = coap.loop(); ... delay(10000); }

Mind to keep a delay(…), not to saturate NodeRED server with issuing dozens of UDP requests. Minimum reasonable delay between issuing consecutive requests is about 500ms.

Result validation Observe connection progress on the LCD via video stream. Once WiFi is connected, you should be able to see secret code as a return from CoAP server. Note, you may want to implement presentation of the communication status, i.e. present msgid and state of the

79

9. Hands-on lab scenarios for SUT VREL nodes coap.loop().

FAQ Secret changes over time so do not be surprised that you will obtain different numbers when returning to this exercise or executing in loop for a time. Note, to distinguish from random data, there is always some extra, textual message to let you be sure that server returned a value.

80

10. ITT modular component laboratory

10. ITT modular component laboratory 10.1. ITT Controller module basics 10.1.1. Introduction This chapter describes the IOT ITT controller module. The controller module is necessary for any other module to work.

10.1.2. Prerequisites General knowledge of MQTT protocol: topics, brokers, subscribe, publish. General knowledge on microcontrollers and Arduino IDE.

10.1.3. Technical details The ITT IoT controller module is based on the Wemos D1 Mini controller. Its pinout can be seen in the following schematic.

81

10. ITT modular component laboratory 10.1.4. Specifications ▪

11 digital input/output pins



Micro USB connector



Compatible with ArduinoIDE



Compatible with nodemc



4 MB flash-memory

10.1.5. Electrical connection Modules are using following I/O ports ▪

RGB LED Shield GPIO4



Relay Shield GPIO5



OLED Display Shield GPIO4, GPIO5



Motor Shield GPIO4, GPIO5



Temperature/Humidity DHT Pro Shield GPIO2



Sensor Shield (ITT ver. 1.1) GPIO4, GPIO5, GPIO6, GPIO7, A0

10.1.6. Actuators As this is the controller module, no actuators or sensors are installed to it.

10.1.7. Software, libraries and externals To program the controller module ITTIoT library is used. This is a custom library made specifically for ITT IoT kits. It aims to make the board easier to use with simple but yet effective methods. A non-exclusive list of methods is presented below: Method

Description

iot.setup()

Does the operations necessary for setting up the ITTIoT framework and MQTT communications.

iot.printConfig()

Prints the module configuration to the serial port.

iot.handle()

Does the background work necessary for the communications to work. For example, checks if the communication with the broker is still working and checks if any new messages have been received. This method has to be called periodically.

iot.connected()

A method defined by the user that is called when the connection with the MQTT broker has been established. It is primarily used to subscribe to topics with the method iot.subscribe().

iot.subscribe(String topic)

Subscribes to the topic specified as the operand. For example iot.subscribe(“IoT/button”) subscribes to the topic “IoT/ button”.

iot.received(String

User-defined method that is called when the controller

82

10.2. ITT RGB LED module Method topic, String msg)

Description receives a message from one of the subscribed topics. The topic from which the message is received is the string “topic” and the body of the message is the string “msg”.

iot.publishMsgTo(String Publishes the message “msg” to the topic “topic”. Boolean topic, String msg, bool retain informs the broker if the message should be saved into retain) the memory of the broker.

10.1.8. Communication The user can connect to and program this controller using the Distancelab environment.

10.1.9. Limits At the same time, one user can program the controller. But all users connected to the Distancelab MQTT broker can subscribe to and publish messages to the topics.

10.2. ITT RGB LED module This laboratory is located in the office of ITT Group in Tallinn, Estonia.

10.2.1. Introduction This laboratory consists of an RGB LED module connected to the ITT IoT controller module. The module contains one RGB LED. This node can be used to create very basic MQTT systems but can also be used as a signalling part of other more complicated systems.

83

10. ITT modular component laboratory 10.2.2. Prerequisites General knowledge of MQTT protocol: topics, brokers, subscribe, publish.

10.2.3. Technical details This laboratory conisists of a ITT IoT controller module connected to a RGB LED module.

Actuators This laboratory involves a WS2812B RGB LED. RGB LEDs are basically three LEDs (red, green, blue) that are built inside one shell. They include a WS2812 driver that makes it possible to use only one pin to control them.

Specifications ▪

LED size: 5050



Colors: 16777216

Electrical connection Connected to port GPIO4.

Software, libraries and externals To control WS2812B RGB LED the following libraries are used: ▪

ITTIoT libary - used to program the controller module.



Adafruit NeoPixel libary - used to control the RGB LED.

Communication The user can connect to this controller using the Distancelab environment.

Limits At the same time, one user can program the controller. But all users connected to the Distancelab MQTT broker can control the RGB LED, assuming they use the topic described in the controller program.

10.2.4. Hands-on labs Example code #include #include #include #define PIN

D2

// When we setup the NeoPixel library, we tell it how many pixels, // and which pin to use to send signals.

84

10.2. ITT RGB LED module // Note that for older NeoPixel strips you might need to change // the third parameter--see the strandtest // example for more information on possible values. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800); // https://stackoverflow.com/questions/9072320/split-string-into-string-array String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = {0, -1}; int maxIndex = data.length()-1; for(int i=0; i<=maxIndex && found<=index; i++) { if(data.charAt(i)==separator || i==maxIndex) { found++; strIndex[0] = strIndex[1]+1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found>index ? data.substring(strIndex[0], strIndex[1]) : ""; } // Change RGB LED color // mosquitto_pub -u test -P test -t "ITT/IOT/3/rgb" -m "51;255;153" void iot_received(String topic, String msg) { Serial.print("MSG FROM USER callback, topic: "); Serial.print(topic); Serial.print(" payload: "); Serial.println(msg); String r = getValue(msg,';',0); String g = getValue(msg,';',1); String b = getValue(msg,';',2); Serial.print("R: "); Serial.println(r); Serial.print("G: "); Serial.println(g); Serial.print("B: "); Serial.println(b); // Moderately bright green color. pixels.setPixelColor(0, r.toInt(), g.toInt(), b.toInt()); pixels.show(); // This sends the updated pixel color to the hardware. } void iot_connected() { Serial.println("MQTT connected callback"); iot.subscribe("rgb"); iot.log("IoT NeoPixel example!"); }

85

10. ITT modular component laboratory void setup() { Serial.begin(115200); Serial.println("Booting"); iot.printConfig(); // print json config to serial iot.setup(); pixels.begin(); // This initializes the NeoPixel library. } void loop() { iot.handle(); delay(200); }

10.2.5. Support [email protected]

10.3. ITT Temperature and humidity sensor module This laboratory is located in the office of ITT Group in Tallinn, Estonia.

10.3.1. Introduction This laboratory can be used to practice reading values from sensors and send them over MQTT. It can be used as a simple task of sending the sensor value or part of a bigger system, where actuators from other modules perform actions based on the sensor values received.

86

10.3. ITT Temperature and humidity sensor module 10.3.2. Prerequisites For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing.

10.3.3. Technical details This laboratory consists of a DHT22 temperature and humidity sensor module attached to the ITT IoT controller module.

Sensors This laboratory uses the DHT22 temperature and humidity sensor. It uses a capacitive humidity sensor and a thermistor to measure temperature. The sensor only transmits digital data (no analogue values). The sensor is calibrated and doesn't require extra components so you can get right to measuring relative humidity and temperature.

Specifications ▪

1-wire digital interface



Humidity from 0-100% RH



-40 - 80 degrees C temperature range



+-2% RH accuracy



+-0.5 degrees C

Electrical connection The 1-wire data connection is connected to port GPIO2.

Software, libraries and externals ▪

ITTIoT libary - used to program the controller module.



Adafruit DHT sensor libary - used to read the values from the DHT22 sensor.

Communication The user can connect and program this controller using the Distancelab environment.

Limits At the same time, only one user can program the controller. But all users connected to the Distancelab MQTT broker can read the values if they are being transmitted over MQTT. That is assuming they use the topic described in the controller program.

10.3.4. Hands-on labs Example code #include

87

10. ITT modular component laboratory #include #include #define DHTPIN D4 // what pin we're connected to #define DHTTYPE DHT22 // DHT 22 (AM2302) DHT dht(DHTPIN, DHTTYPE); void iot_connected() { Serial.println("MQTT connected callback"); iot.log("IoT DHT example!"); } void setup() { Serial.begin(115200); Serial.println("Booting"); iot.printConfig(); // print json config to serial iot.setup(); pinMode(16, OUTPUT); dht.begin(); } void loop() { iot.handle(); float h = dht.readHumidity(); float t = dht.readTemperature(); char buf[10]; // Put whatever length you need here String(t).toCharArray(buf,10); digitalWrite(16,HIGH); iot.publishMsg("temp",buf); delay(2000); digitalWrite(16,LOW); String(h).toCharArray(buf,10); iot.publishMsg("hum",buf); delay(2000); }

10.3.5. Support [email protected]

10.4. ITT Servo module This laboratory is located in the office of ITT Group in Tallinn, Estonia.

10.4.1. Introduction This laboratory can be used to practice controlling the servo motor attached to the

88

10.4. ITT Servo module controller.

10.4.2. Prerequisites For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing.

10.4.3. Technical details This laboratory consists of a servo with the add-on module attached to the ITT IoT controller module.

Sensors This laboratory does not have any sensors.

Specifications Table 3: Servo specifications

89

10. ITT modular component laboratory Specification

Value

Speed at 6V

0,07 sec/60°

Stall torque at 6V

0,042 N-m

Speed at 4,8V

0,09 sec/60°

Stall torque at 4,8V 0,028 N-m

Electrical connection The signal lead of the servo is connected to D3 pin of the controller.

Software, libraries and externals ▪

ITTIoT libary - used to program the controller module.



Servo libary - used to control the servo.

Communication The user can connect and program this controller using the Distancelab environment.

Limits At the same time, only one user can program the controller. But all users connected to the Distancelab MQTT broker can subscribe and publish to topics specified.

10.4.4. Hands-on labs Example code /* * IoT Servo example * * This example subscribe to the "servo" topic. When a message received, then it * change servo position * * Created 11 Sept 2017 by Heiko Pikner */ #include #include <Servo.h> #include //Pin definition for the Servo (D3) #define SERVO_PIN D3 Servo myservo;

// create servo object to control a servo

// Change the servo position (value between 0 and 180) // mosquitto_pub -u test -P test -t "RL/esp-{ESP-ID}/servo" -m "51" // = this calls servo motor to change position void iot_received(String topic, String msg)

90

10.5. ITT Relay module { Serial.print("MSG FROM USER callback, topic: "); Serial.print(topic); Serial.print(" payload: "); Serial.println(msg); Serial.print("Servo: "); Serial.println(msg); myservo.write(msg.toInt()); } // Function started after the connection to the server is established void iot_connected() { Serial.println("MQTT connected callback"); // Subscribe to the topic "servo" iot.subscribe("servo"); iot.log("IoT Servo example!"); } void setup() { Serial.begin(115200); Serial.println("Booting"); // Print json config to serial iot.printConfig(); // Initialize IoT library iot.setup(); myservo.attach(SERVO_PIN); } void loop() { // IoT behind the plan work, it should be periodically called iot.handle(); delay(200); }

10.4.5. Support [email protected]

10.5. ITT Relay module This laboratory is located in the office of ITT Group in Tallinn, Estonia.

10.5.1. Introduction This laboratory can be used to practice controlling the relay module attached to the controller.

91

10. ITT modular component laboratory

10.5.2. Prerequisites For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing. Also the basics of relays and where they can be used.

10.5.3. Technical details This laboratory consists of a relay module attached to the ITT IoT controller module. The relay module is an electrically operated switch of the mains voltage. It means that it can be turned on or off, letting the current go through or not. Many relays use an electromagnet to mechanically operate the switch and provide electrical isolation between two circuits.

Sensors This laboratory does not have any sensors.

Specifications ▪

5V 1-Channel Relay interface board



Relay: SRD-05VDC-SL-C (AC 250V 10A, DC 30V 10A NO/NC)

Electrical connection The signal lead of the servo is connected to GPIO5 pin of the controller.

Software, libraries and externals ▪

ITTIoT libary - used to program the controller module.

Communication The user can connect and program this controller using the Distancelab environment.

92

10.5. ITT Relay module Limits At the same time, only one user can program the controller. But all users connected to the Distancelab MQTT broker can subscribe and publish to topics specified.

10.5.4. Hands-on labs Example code #include #include #define RELAY_PIN 5 // If the message received switch relay void iot_received(String topic, String msg) { Serial.print("MSG FROM USER callback, topic: "); Serial.print(topic); Serial.print(" payload: "); Serial.println(msg); if(msg == "1") { digitalWrite(RELAY_PIN, HIGH); } if(msg == "0") { digitalWrite(RELAY_PIN, LOW); } } void iot_connected() { Serial.println("MQTT connected callback"); iot.subscribe("relay"); iot.log("IoT relay example!"); } void setup() { Serial.begin(115200); Serial.println("Booting"); iot.printConfig(); // print json config to serial iot.setup(); pinMode(RELAY_PIN, OUTPUT); } void loop() { iot.handle(); delay(200); }

93

10. ITT modular component laboratory 10.5.5. Support [email protected]

10.6. ITT OLED display module This laboratory is located in the office of ITT Group in Tallinn, Estonia.

10.6.1. Introduction This laboratory can be used to practice displaying messages on the OLED screen.

10.6.2. Prerequisites For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing. Also, knowledge about I2C interface is recommended but not mandatory.

10.6.3. Technical details This laboratory consists of an OLED display module attached to the ITT IoT controller module. Oled module contains an organic light-emitting diode, that is a light-emitting

94

10.6. ITT OLED display module diode in which the emissive electroluminescent layer is a film of organic compound that emits light in response to an electric current. === Sensors ===Relay This laboratory does not have any sensors.

Specifications Table 4: OLED screen specifications Specification

Value

Screen size

64×48 pixels (0,66”)

Driver IC

SSD1306

Interface

I2C

I2C address

0x3C or 0x3D

Electrical connection Connected to ports GPIO4 (SDA) and GPIO5 (SCL).

Software, libraries and externals ▪

ITTIoT libary - used to program the controller module.



Adafruit GFX library - general libary for Adafruit displays



Adafruit SSD1306 Wemos Mini OLED - libary for controlling the OLED screen.

Communication The user can connect and program this controller using the Distancelab environment.

Limits At the same time, only one user can program the controller. But all users connected to the Distancelab MQTT broker can subscribe and publish to topics specified.

10.6.4. Hands-on labs Example code #include #include #include #include #include #include #include #include

<Ticker.h> <ESP8266WiFi.h> <SPI.h> <Wire.h>

#define OLED_RESET 0

// GPIO0

95

10. ITT modular component laboratory Ticker timeTicker; Adafruit_SSD1306 display(OLED_RESET); // ITT splashs screen bitmap. Generator: http://javl.github.io/image2cpp/ static const unsigned char PROGMEM logo16_glcd_bmp[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x1f, 0xe3, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x1f, 0xe3, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe3, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0x10, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x10, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x10, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x10, 0xe3, 0xfc, 0xff, 0xf8, 0x00, 0x00, 0x07, 0x10, 0xe3, 0xfc, 0xff, 0xf8, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0x10, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #if (SSD1306_LCDHEIGHT != 48) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif bool isBootModeNormal; bool sendDataFlag; int i = 0; // Ticker library callback, which will occur 0.5 second interval. void sendData() { sendDataFlag=true; }

96

10.6. ITT OLED display module // Function started after the connection to the server is established. void iot_connected() { Serial.println("MQTT connected callback"); iot.log("IoT OLED screen example!"); isBootModeNormal = true; } void setup() { Serial.begin(115200); Serial.println("Booting"); // initialize with the I2C addr 0x3C (for the 64x48) display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Since the buffer is intialized with an Adafruit splashscreen // internally, we should clear it display.clearDisplay(); // Load ITT splash screen into buffer display.drawBitmap(0, 0, logo16_glcd_bmp, 64, 48, 1); // Show image buffer on the display display.display(); // Display splashscreen two second delay(2000); // print IoT json config to serial iot.printConfig(); // Initialize IoT library iot.setup(); // Initialize Ticker interval and callback timeTicker.attach(0.5, sendData); } void loop() { // IoT behind the plan work, it should be periodically called iot.handle(); // Increase counter value i++; // Display counter value and boot mode on the OLED screen display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Counter: "); display.println(i); display.setCursor(0,30); if(isBootModeNormal) {

97

10. ITT modular component laboratory display.println("Mode: NORM"); } else { display.println("Mode: BOOT"); } display.display(); // Send counter value to the server if(WiFi.isConnected() && isBootModeNormal) { if(sendDataFlag) { sendDataFlag = false; String msg = String(i); iot.publishMsg("count", msg.c_str()); Serial.println(msg); } } }

10.6.5. Support [email protected]

98

11. SmartMe Network Laboratory: Arduino Nodes 1-5

11. SmartMe Network Laboratory: Arduino Nodes 1-5 The SmartMe lab is located at the Engineering building of the University of Messina, in Messina, Italy.

11.1. Introduction Its main goal is to provide a simple testbed of a smart city, mainly focusing on smart environment application scenarios. To this purpose, 6 nodes have been equipped and made available to students for practising in these contexts. These nodes can be framed into the MCU (Arduino) + MPU (Raspberry Pi) category: 5 out of 6 combine an Arduino Uno with a Raspberry Pi 3 b+, the last node is a combo board developed by a spinoff company (SmartMe.io), Arancino, which combines in the same board an Arduino-like MCU (based on an ARM Cortex M0+ @48MHz) and a Raspberry Pi 3 compute module. In this section, we will focus on the 5 pure Arduino nodes and their sensors and actuators.

11.2. Prerequisites To approach this laboratory, the student should grasp: ▪

basic MQTT concepts like topics, broker, subscribing and publishing;



quantities and metrics related to the physical quantities that can be detected using DHT and PMS sensors: temperature (°C and F), relative humidity (%), air quality (PMx concentration).

11.3. Technical details 4 Arduino nodes are Internet-connected by a router through ETH, while the 5th is reachable only by the IoT gateway (RaspPi). The Lab configuration is shown in the figure below

99

11. SmartMe Network Laboratory: Arduino Nodes 1-5

11.3.1. Node schematic All Arduino nodes are configured as reported in the following schematic

100

11.3. Technical details

101

11. SmartMe Network Laboratory: Arduino Nodes 1-5

11.4. Sensors Each node is equipped with either a DHT11 or DHT22 sensor and a PMS7003 sensor. The DHT sensors allow measuring temperature and relative humidity, while the PMS7003 sensor allows measuring the air quality through the PMx concentration. Parameter

DHT11

DHT22

Operating Voltage 3 to 5V

3 to 5V

0.3mA (measuring) 60uA Operating Current (standby)

0.3mA (measuring) 60uA (standby)

Humidity Range

20-80% / 5%

0-100% / 2-5%

Temperature Range

0-50°C / ± 2°C

-40 to 80°C / ± 0.5°C

Sampling Rate

1 Hz (reading every second)

0.5 Hz (reading every 2 seconds)

Body size

15.5mm x 12mm x 5.5mm

15.1mm x 25mm x 7.7mm

Advantage

Ultra low cost

Resolution

16-bit Humidity

Accuracy

±1°C and ±1%

±0.5°C and ±1%

Sampling period

1 second

2 second

Price

$1 to $5

$4 to $10

Temperature

More Accurate and 16-bit Humidity

Temperature

and

Some nodes of the lab are equipped with “MIKROE-2818 DHT22 2 click” sensors. This sensor feature ultra-small size, low-power consumption, data signal transmission distance up to 20mts, and good measuring accuracy [1]. The sensing part is the CM2322, which uses a capacitive humidity sensor and a thermistor to measure the surrounding air. Typical temperature accuracy is ±0.3°C, while relative humidity accuracy is 2% RH. The humidity and temperature measurement are compensated by some calibration coefficient, which is saved in the OTP memory of an integrated MCU. The integrated MCU also provides I2C or 1Wire interface, selectable by the onboard SMD jumper selectors. The operating voltage can also be selected by the onboard SMD jumper [2]. As shown in the previous figure, the 1Wire mode was chosen while the operating voltage is 5V. The sensor is connected to pin 8 of Arduino Uno. The PMS7003 consists of a digital and universal particle concentration sensor, which can be used to obtain the number of suspended particles in the air, i.e. the concentration of particles, and output them in the form of a digital interface. The working principle of such a sensor consists into produce scattering by using a laser to radiate suspending particles in the air, then collect scattering light to a certain degree, and finally obtain the curve of scattering light change with time. In the end, the equivalent particle diameter and the number of particles with different diameters per unit volume can be calculated [3]. So, the values of PM1.0, PM2.5, and PM10, will be available for our scopes. In order to physically interface the 10 bus lines of the sensor with Arduino Uno, the PMS7003 connector shown in the previous figure was employed [4]. By supplying the adapter at 5V, the particle sensor will operate correctly and the data will be available at RX and

102

11.5. Actuators TX pins. However, the serial voltage level is 3.3V typical, while Arduino Uno needs 5V. For this reason, a bi-directional level converter was introduced [5]: by supplying the HV (High Voltage) side at 5V and the LV (Low Voltage) side at 3.3V, the serial levels will be correct on both sides (Arduino at 5V, PMS7003 at 3.3V). Since is not possible to deploy the code by using, at the same time, the default RX, TX pins (0,1) of Arduino Uno, the PMS7003 is connected to pins 9 and 10: by using the <SoftwareSerial.h> library, such pins can be used as RX and TX of Arduino Uno, respectively. [1]https://www.mouser.it/new/mikroelektronika/mikroelektronikamikroe-2818-dht22-2-click/ [2]http://www.farnell.com/datasheets/2618831.pdf [3]https://download.kamami.com/ p564008-p564008-PMS7003%20series%20data%20manua_English_V2.5.pdf [4]https://kamami.com/others/564553-adapter-from-127mm-pitch-to-254mm-forpms7003.html [5]https://kamami.com/voltage-level-converters/234535-logic-level-converter-bidirectional.html

11.5. Actuators There are no mechanical actuators in this laboratory. Each node is equipped with a 2×16 LCD screen and with an RGB led, but it is possible to use only the green light component. The green led of the RGB is connected to the Arduino pin 3. Since such a pin supports the PWM, the led brilliance can be set. Moreover, the led can be used for blinking or to indicate when a threshold is reached. The 2×16 LCD is a Displaytech 162B based on the HD44780 standard. Such standard means that the display supports almost all characters of the ASCII character table. Therefore, it is possible to display the most important characters. The display controller, which is integrated into the display, can generate these characters and send them to the matrix. In addition to the already 208 known characters, it is also possible to draw any other characters and signs. The display controller handles most of the operations, so the code for the microcontroller is very short [6]. Both 8 bit or 4-bit mode can be used to drive the display. The library supports the 4 bit communication. As shown in the figure, the Arduino Uno pins 5, 4, 13, 2 are used for the 4 bit communication (display pins 13, 14, 15, 16), while the Arduino Uno pins 7, 6 are used for the RS (Register Select) and for the E (Enable) (display pins 8, 6). The not used display data pins (9, 10, 11, 12) are simply not connected. The other display pins are used for the power supply (1,2) and to control the display light via the potentiometer (3,4). The display R/W pin (7) is simply connected to GND since only the write operation is required. [6] https://www.aeq-web.com/atmega328-4bit-16x2-lcd-display-amtel-studioc/?lang=en

Power supply Each node is equipped with a Breadboard Power Supply Module MB120. The MB102 is able to provide up to 700 mA, with a voltage of 3.3V and/or 5V. It can be supplied with an external DC power supply, in the range of 6.5 - 12V. The required voltage can be selected by properly choice the onboard jumper position. Both 3.3V and 5V are required

103

11. SmartMe Network Laboratory: Arduino Nodes 1-5 in the project.

11.6. Software, libraries and externals The following libraries are required to run the example proposed below for the hands-on labs: ▪

Liquid Crystal



DHT sensor Library (mandatory version 1.3.0)



Adafruit Unified Sensor



PMS



Ethernet



MQTT

LCD display requires a dedicated library. Of course, you can control it on the low-level programming, but we suggest using a library first. As there are many universal libraries, and many of them are incompatible with this display, we strongly recommend using "Liquid Crystal Library for Arduino". The LCD control library can be imported to the source code via: #include

Then configure your LCD controller: // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2);

DHT11 and DHT22 sensors require some dedicated library. We strongly recommend using the “DHT sensor library” version 1.3.0, which is not the last version available on the repository. DHT sensor library depends on the “Adafruit Unified Sensor”, so it is mandatory to include this library. The DHT sensor library can be imported to the source code via: #include

Configure your DHT sensor: #define DHTPIN 8 // Digital pin connected to the DHT sensor // Uncomment whatever type you're using! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // Initialize DHT sensor. DHT dht(DHTPIN, DHTTYPE);

PMS sensor requires a dedicated library. The Arduino library for Plantower PMS sensors, also “PMS” library, supports PMS x003 sensors (1003, 3003, 5003, 6003, 7003). The PMS sensor library can be imported to the source code via: #include "PMS.h"

104

11.7. Communication The PMS sensor is connected to pins 9 and 10: by using the <SoftwareSerial.h> library, such pins can be used as rx and tx of Arduino Uno, respectively. #include <SoftwareSerial.h> SoftwareSerial mySerial(9,10); // Arduino Rx and Tx ports

Arduino Ethernet Shield requires a dedicated library. With the Arduino Ethernet Shield, the Ethernet.h library allows an Arduino board to connect to the Internet. The Arduino Ethernet Shield library can be imported to the source code via: #include <Ethernet.h>

Then configure your Ethernet Shield: // Enter a MAC address and IP address for your controller below. byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; byte ip[] = {192, 168, 0, 99}; // <- change to match your network

MQTT connectivity protocol requires a dedicated library. The MQTT.h library uses the Arduino Ethernet Client API for interacting with the underlying network hardware. This library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT. The Arduino Ethernet Shield library can be imported to the source code via: #include <MQTT.h>

“platformio.ini” (Project Configuration File) The Project configuration file is named platformio.ini. [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] [email protected] [email protected] [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

11.7. Communication The user can connect and program the controller of each node by using the Distancelab environment by booking it for the time he needs. The user can use the MQTT protocol.

105

11. SmartMe Network Laboratory: Arduino Nodes 1-5 MQTT stands for Message Queuing Telemetry Transport. MQTT is a machine-to-machine (M2M) connectivity protocol usable for “Internet of Things” solutions. MQTT is a simple messaging protocol, designed for constrained devices with low-bandwidth. So, it’s the perfect solution for Internet of Things applications. This publish/subscribe messaging pattern requires a message broker. The broker is responsible for distributing messages to interested clients based on the topic of a message. So a client must connect to a broker in order to: ▪

publish messages specifying a topic so that other clients that have subscribed to that topic will be able to receive those messages;



receive messages subscribing to a specific topic.

11.8. Limits At the same time, only one user can program the controller. But all users connected to the Distancelab MQTT broker can read the values if they are being transmitted over MQTT.

11.9. Support [email protected], [email protected]

11.9.1. IB1: Basic operations on the 2x16 LCD screen Whatever you do, you expect to have some output of the system. Sometimes there is a blinking LED, sometimes information about connected/disconnected network and some other time simply trace algorithm progress. In laboratories where you have connected the MCU physically to your programming device (i.e., your laptop), you usually would like to choose the serial port to report about what is going on. However, here all you have at runtime is the access to the video stream. Perhaps those are the reasons why you will use the LCD display in every lab work you will do.

Target group This hands-on lab guide is intended for the Beginners but other target groups may benefit from it, treating it as basics for advanced projects.

Prerequisites There are no other prerequisites besides the Liquid Crystal library. All the nodes of

106

11.9. Support SmartME Network Laboratory are equipped with a 2×16 LCD Displaytech 162B based on the HD44780 standard. It is necessary to initialize the library by associating any pin of the LCD interface to the Arduino pin number to which it is connected (see Step 2).

The circuit: ▪

LCD pin 1 = 5v+ (220 ohm resistance)



LCD pin 2 = GND



LCD pin 3 = GND



LCD pin 4 = 5v



LCD pin 5 = center of potentiometer (potentiometer leg 1 goes to 5v and leg 3 goes to ground)



LCD pin 6 = Arduino pin 7



LCD pin 7 = GND



LCD pin 8 = Arduino pin 6



LCD pin 13 = Arduino pin 5



LCD pin 14 = Arduino pin 4



LCD pin 15 = Arduino pin 13



LCD pin 16 = Arduino pin 2

Scenario Initialize the LCD screen with the text “SmartMe Lab!”, then turn it off, then turn it on again, in a loop: each phase lasting half a second. Delays are expressed in ms (milliseconds) and not in s (seconds).

Result You should see the text “Smart lab!” appearing and disappearing every half second.

Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library: #include

Step 2 Instantiate the software controller component for the LCD display: // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2);

107

11. SmartMe Network Laboratory: Arduino Nodes 1-5 Step 3 Initialize display - we suggest to do it in the setup() function: void setup() { // set up the LCD's number of columns and rows lcd.begin(16, 2); // print a message to the LCD lcd.print("SmartMe lab!"); }

Step 4 Implement loop() to turn off and on the LCD display, for 500 ms each: void loop() { // turn off the display lcd.noDisplay(); delay(500); // turn on the display lcd.display(); delay(500); }

Result validation Observe the text appearing and disappearing every half second.

Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

IB1.cpp #include // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); void setup() { // set up the LCD's number of columns and rows lcd.begin(16, 2); // print a message to the LCD lcd.print("SmartMe Lab!"); }

108

11.9. Support void loop() { // turn off the display lcd.noDisplay(); delay(500); // turn on the display lcd.display(); delay(500); }

11.9.2. IB2: Presenting temperature and humidity values on the LCD Target group This hands-on lab guide is intended for the Beginners but other target groups may benefit from it, treating it as basics for advanced projects.

Prerequisites Liquid Crystal For this library, you may refer to the B1 exercise.

DHT sensors The nodes of SmartME Network Laboratory are equipped with different versions of DHT sensors: DHT11 and DHT22. The sensors look a bit similar and have the same pinout, but have different characteristics. Below you can find the DHT technical specifications:

DHT11 ▪

Ultra-low-cost



3 to 5V power and I/O



2.5mA max current use during conversion (while requesting data)



Good for 20-80% humidity readings with 5% accuracy



Good for 0-50°C temperature readings ±2°C accuracy



No more than 1 Hz sampling rate (once every second)



Body size 15.5mm x 12mm x 5.5mm



4 pins with 0.1“ spacing

DHT22 ▪

Low cost



3 to 5V power and I/O



2.5mA max current use during conversion (while requesting data)



Good for 0-100% humidity readings with 2-5% accuracy



Good for -40 to 80°C temperature readings ±0.5°C accuracy

109

11. SmartMe Network Laboratory: Arduino Nodes 1-5 ▪

No more than 0.5 Hz sampling rate (once every 2 seconds)



Body size 15.1mm x 25mm x 7.7mm



4 pins with 0.1” spacing

DHT sensors are able to detect temperature and relative humidity. Relative humidity consists of the amount of water vapour in air vs. the saturation point of water vapour in the air. At the saturation point, water vapour starts to condense and accumulate on surfaces forming dew. The saturation point changes with air temperature. Cold air can hold less water vapour before it becomes saturated, and hot air can hold more water vapour before it becomes saturated. Temperature and relative humidity can be used to determine the apparent temperature or the human perceived equivalent temperature, also called “heat index”. The heat index was developed in 1978 by George Winterling and was adopted next year. It is also known as humiture, according to Wikipedia contributors.

Scenario First, initialize LCD screen with the labels of temperature and relative humidity. Then, after the sensor detection, next to the labels, the sensor values will be displayed, one per line, every 3 seconds. Note, the function readTemperature() reads temperature as Celsius (the default). If you want to read the temperature as Farenight, you have to set the true value as a parameter of the signature in the readTemperature(true) function. The relative humidity is expressed as a percentage. That means that at 100% RH the condensation occurs, while at 0% RH the air is completely dry. More, but not used in the proposed exercise, it is possible to compute the heat index in Fahrenheit (the default) by using the function computeHeatIndex(temp_value_farenight, humidity_value), or if you want in Celsius (isFahreheit = false) by using the function computeHeatIndex(temp_value_celsius, humidity_value, false). Result You should see the values of temperature and relative humidity, that is sampled and displayed every 3 seconds (3000 ms). Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library and DHT library: #include #include "DHT.h"

Step 2 Instantiate the software controller component for the LCD display. Then set up: 1.

the DHTPIN (which refers to the digital pin we use to get the signal);

2.

the DHT sensor type in use (DHT11 or DHT22, it depends on the node of the lab you are using).

Then initialize the DHT sensor. // initialize the library with the numbers of the interface pins

110

11.9. Support LiquidCrystal lcd(7, 6, 5, 4, 13, 2); #define DHTPIN 8 // what pin we are connected to // Uncomment whatever type you're using! #define DHTTYPE DHT11 //#define DHTTYPE DHT22 // Initialize DHT sensor DHT dht(DHTPIN, DHTTYPE);

Step 3 Initialize display and Initialize the DHT sensor - we suggest to do it in the setup() function: void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print Temperature label to the LCD. lcd.print("Temp. *C"); lcd.setCursor(0,1); // Print the Humidity label to the LCD. lcd.print("Hum. %"); dht.begin(); }

Step 4 Implement loop() to sample and display the values of temperature and relative humidity on the LCD display, every 3 seconds: void loop() { // Wait three seconds between measurements. delay(3000); // read relative humidity float h = dht.readHumidity(); // read temperature as Celsius float t = dht.readTemperature(); // read temperature as Fahrenheit //float f = dht.readTemperature(true); // compute heat index in Fahrenheit (the default) float hif = dht.computeHeatIndex(f, h); // compute heat index in Celsius (isFahreheit = false) float hic = dht.computeHeatIndex(t, h, false); // print Temperature value to the LCD lcd.setCursor(14, 0); lcd.print(t); // print the Humidity value to the LCD lcd.setCursor(14, 1); lcd.print(h); }

Result validation Observe the temperature and relative humidity values shown in the LCD display. The display will refresh values every 3 seconds.

111

11. SmartMe Network Laboratory: Arduino Nodes 1-5 Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

IB2.cpp #include #include "DHT.h" // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); #define DHTPIN 8 // what pin we are connected to // uncomment whatever type you're using #define DHTTYPE DHT22 //#define DHTTYPE DHT22 // initialize DHT sensor DHT dht(DHTPIN, DHTTYPE); void setup() { // set up the LCD's number of columns and rows lcd.begin(16, 2); // Print Temperature label to the LCD lcd.print("Temp. C"); lcd.setCursor(0,1); // Print the Humidity label to the LCD lcd.print("Hum. %"); dht.begin(); } void loop() { // wait three seconds between measurements delay(3000); // read humidity float h = dht.readHumidity(); // read temperature as Celsius float t = dht.readTemperature(); // read temperature as Fahrenheit //float f = dht.readTemperature(true); //

// compute heat index in Fahrenheit (the default) float hif = dht.computeHeatIndex(f, h);

112

11.9. Support // compute heat index in Celsius (isFahreheit = false); float hic = dht.computeHeatIndex(t, h, false); // print Temperature value to the LCD lcd.setCursor(14, 0); lcd.print(t); // print the Humidity value to the LCD lcd.setCursor(14, 1); lcd.print(h); }

11.9.3. IB3: PWM mode (~) of digital pins, programming threshold values Target group This hands-on lab guide is intended for the Beginners but other target groups may benefit from it, treating it as a tool for advanced projects.

Prerequisites Liquid Crystal For this library, you may refer to the B1 exercise.

RGB LED The SmartME Network Laboratory Arduino nodes 1-5 are equipped with an RGB LED. To connect other devices, however, only the green light component is available, exposed as a separate LED. To turn on the green LED, you have to follow three steps: 1.

first, you have to define a variable with the number of the pin where the LED is connected to (int greenPin = 3;);

2.

second, you need to configure this variable in output mode (OUTPUT) by invoking the pinMode(pin, mode) function, inside the setup() function.

3.

finally, you need to send to this variable a HIGH signal by using the digitalWrite(pin, value) function, inside the loop() function.

To turn off the LED, you need to send a LOW signal value to this pin. You can make the LED flashing by tuning the delay of HIGH and LOW states. The digital pins either give you 5V (when turned HIGH) or 0V (when turned LOW) and the output is a square wave signal. PWM stands for Pulse Width Modulation and it is a technique used in controlling the brightness of the LED. The PWM pins are labelled with ~ sign. The function analogWrite() can be used to generate a PWM signal in those digital pins that are labelled with ~ sign. The frequency of this generated signal for most pins will be about 490Hz and you can give the value from 0-255 using this function ▪

analogWrite(0) means a signal of 0% duty cycle.



analogWrite(127) means a signal of 50% duty cycle.



analogWrite(255) means a signal of 100% duty cycle.

The function random() generates pseudo-random numbers. The syntax is random(max)

113

11. SmartMe Network Laboratory: Arduino Nodes 1-5 or random(min, max), where min represents the lower bound of the random value, inclusive (optional); and max represents the upper bound of the random value, exclusive. The function returns a long random number between min and max-1.

The circuit: RGB GREEN pin = Arduino pin 3 (~)

Scenario Initialize the LCD screen with the label “rand value”, then calculates a random value. If randomValue is lower than lowThreshold, turn on the LED. If randomValue is upper than highThreshold, turn off the LED. After 1 second, print the random value to the LCD. Then, turn on the LED for 3 seconds, assigning it a value of brightness which corresponds to the random value previously calculated. Note, you can set the two values of the threshold as you prefer. You can modify the brightness of the LED because, although it is connected to a digital pin, the Arduino pin number 3 is labeled with ~ sign (PWM).

Result You should see the LED on or off for 1 second, a second if the value is greater or less than the predefined threshold values. Next, you should see the randomly calculated value between 0 and 255 on the LCD, at that point, the LED should assign a brightness associated with that value, and keep it for 3 seconds.

Start There are no special steps to be performed.

Steps Step 1 Include the LCD driver library: #include

Step 2 Instantiate the software controller component for the LCD display. Initialize the LED pin. Declare the threshold values. // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); // initializing LED Pin int greenPin = 3; // declaring the threshold values int lowThreshold = 127; int highTreshold = 128;

Step 3 Initialize the display and declare the LED pin as OUTPUT - preferably in the setup()

114

11.9. Support function: void setup(){ pinMode(greenPin, OUTPUT); lcd.begin(16, 2); lcd.print("rand value"); }

// declaring LED pin as output // set up the LCD's number of columns and rows // print the random value label to the LCD

Step 4 Implement loop() to do in the order: calculate a random value between 0 and 255; compare the random value with the lower threshold and with the upper threshold in order to decide whether to switch the LED on or off for 1 second; display the random value on the screen, and use it to assign a specific brightness value to the LED, which must be held for 3 seconds. void loop() { // calculate a randomValue in the range 0-255 int randomValue = random(255); if (randomValue < lowThreshold){ digitalWrite(greenPin, HIGH); } if (randomValue > highTreshold){ digitalWrite(greenPin, LOW); } delay(1000); // print the random value of light to the LCD lcd.setCursor(14, 0); lcd.print(randomValue); analogWrite(greenPin, randomValue); delay(3000); }

Result validation The state of the LED will depend on the random number calculated and on the threshold values that have been set. The random value will be shown by the display monitor. It also will affect the LED brightness for 3 seconds.

Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

115

11. SmartMe Network Laboratory: Arduino Nodes 1-5 IB3.cpp #include #include "DHT.h" // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); // initializing LED Pin int greenPin = 3; // declaring of threshold values int lowThreshold = 500; int highTreshold = 600; void setup(){ // declaring LED pin as output pinMode(greenPin, OUTPUT); // set up the LCD's number of columns and rows lcd.begin(16, 2); // print the random value label to the LCD lcd.print("rand value"); } void loop() { int randomValue = random(255); if (randomValue < lowThreshold){ digitalWrite(greenPin, HIGH); } if (randomValue > highTreshold){ digitalWrite(greenPin, LOW); } delay(1000); // print the random value of light to the LCD lcd.setCursor(14, 0); lcd.print(randomValue); analogWrite(greenPin, randomValue); delay(3000); }

11.9.4. IU1: Showing temperature, humidity and dust values on the 2x16 LCD screen Target group This hands-on lab guide is intended for the Undergraduate but other target groups may benefit from it, treating it as basics for advanced projects.

Prerequisites Liquid Crystal For this library, you may refer to the B1 exercise.

DHT For this library, you may refer to the B2 exercise.

116

11.9. Support PMS7003 All the SmartME Network Laboratory Arduino nodes are equipped with a PMS7003 sensor. This sensor allows measuring the air quality by taking into account the PMx concentration. The working principle of such a sensor is based on producing scattering by using a laser to radiate suspending particles in the air, then collecting scattering light to a certain degree, and finally obtaining the curve of scattering light change with time. In the end, the equivalent particle diameter and the number of particles with different diameters per unit volume can be calculated [1]. So, the values of PM1.0, PM2.5, and PM10, will be available for our scopes. In order to physically interface the 10 bus lines of the dust sensor with Arduino Uno, we used the PMS7003 connector [2]. By supplying the adapter at 5V, the particle sensor will operate correctly and the data will be available at RX and TX pins. However, the serial voltage level is 3.3V typical, while Arduino Uno needs 5V. For this reason, to supply the HV (High Voltage) side at 5V and the LV (Low Voltage), we introduced a bidirectional level converter [3] which allows correcting the serial levels of Arduino (5V) and of PMS7003 (3.3V). [1]https://download.kamami.com/ p564008-p564008-PMS7003%20series%20data%20manua_English_V2.5.pdf [2]https://kamami.com/others/564553-adapter-from-127mm-pitch-to-254mm-forpms7003.html [3]https://kamami.com/voltage-level-converters/234535-logic-level-converter-bidirectional.html

Arduino Serial This function is used for communication between the Arduino board and a computer or other devices. All Arduino boards have at least one serial port. On Uno pins 0 and 1 are used for communication with the computer. Serial communication on pins TX/RX uses TTL logic levels (5V or 3.3V depending on the board) [4]. Since is not possible to deploy the code by using, at the same time, the default RX, TX pins (0,1) of Arduino Uno, the PMS7003 is connected to pins 9 and 10: by using the <SoftwareSerial.h> library [5], such pins can be used as RX and TX of Arduino Uno, respectively. [4]https://www.arduino.cc/reference/en/language/functions/communication/serial/ [5] https://www.arduino.cc/en/Reference/softwareSerial

Scenario First, initialize LCD screen with the labels of temperature (“T”), relative humidity (“H”), and dust particles (“PM10”). Then, after the sensor detection, next to the labels, the sensor values will be displayed, every 1 second. Notice that, by enabling the serial print section, data will be available to the serial monitor too. The sensor is able to measure three types of dust particles: PM1.0, PM2.5, and PM10. It may take several seconds to have more precious values about these values. Such values are represented by two bytes: the MSB and the LSB one, as shown in [6] (appendix I). Only the MSB byte

117

11. SmartMe Network Laboratory: Arduino Nodes 1-5 can be shown or, alternatively, both values, separated by a point, as for the display management in this example. Various options and combinations are possible for you. For example, the PM2.5 value can be shown on the display, instead of the temperature one. Similarly, for the serial monitor. [6]https://download.kamami.com/ p564008-p564008-PMS7003%20series%20data%20manua_English_V2.5.pdf

Result You should see the values of temperature, relative humidity and dust that are sampled and displayed every 1 second (1000 ms).

Start There are no special steps to be performed.

Steps Step 1 Include LCD driver library, DHT library and Software Serial library: #include #include <SoftwareSerial.h> #include "DHT.h"

Step 2 Instantiate the software controller component for the LCD display. Then set up: 1.

1) the DHTPIN (which refers to the digital pin we use to get the signal);

2.

2) the DHT sensor type in use (DHT11 or DHT22, it depends on the node of the lab you are using).

Set the RX and TX pin of Arduino in the object of the SoftwareSerial library. #define DHTPIN 8 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal lcd(7, 6, 5, 4, 13, 2); // Arduino Uno port RX, TX SoftwareSerial mySerial(9,10);

Step 3 Initialize display. Initialize the DHT sensor. Sets the data rate in bits per second (baud) for serial data transmissions, both for debugging (115200) and for communication (9600). We suggest to do it in the setup() function: void setup() {

118

11.9. Support lcd.begin(16, 2); // Print Temperature label to the LCD lcd.print("T"); lcd.setCursor(9,0); // Print the Humidity label to the LCD lcd.print("H"); dht.begin(); lcd.setCursor(0,1); lcd.print("PM10"); // for debugging Serial.begin(115200); // Use software serial mySerial.begin(9600); }

Step 4 Implement loop() to sample and display the values of the temperature, relative humidity and dust on the LCD display, every 1 second: void loop() { float h = dht.readHumidity(); // read temperature in Celsius float t = dht.readTemperature(); // compute heat index in Celsius (isFahreheit = false); float hic = dht.computeHeatIndex(t, h, false); // in Fahrenheit //float f = dht.readTemperature(true); // float hif = dht.computeHeatIndex(f, h); // print Temperature value to the LCD lcd.setCursor(2, 0); lcd.print(t); lcd.setCursor(6,0); lcd.print("C"); // print the Humidity value to the LCD lcd.setCursor(11, 0); lcd.print(h); lcd.setCursor(15,0); lcd.print("%"); int chksum=0; byte pms[32]={0,}; if(mySerial.available()>=32){ for(int j=0; j<32 ; j++){ pms[j]=mySerial.read(); if(j<30) chksum+=pms[j]; } if(pms[30] != (byte)(chksum>>8) || pms[31] != (byte)(chksum) ){ } } delay(1000); lcd.setCursor(5, 1); lcd.print(pms[14]);

119

11. SmartMe Network Laboratory: Arduino Nodes 1-5 lcd.print("."); lcd.print(pms[15]); lcd.print("ug/m3

");

}

Result validation Observe the temperature, relative humidity and dust values shown in the LCD display. The display will refresh values every 1 second.

Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

IU1.cpp #include #include <SoftwareSerial.h> #include "DHT.h" #define DHTPIN 8 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal lcd(7, 6, 5, 4, 13, 2); SoftwareSerial mySerial(9,10); // Arduino Uno port RX, TX void setup() { lcd.begin(16, 2); // Print Temperature label to the LCD lcd.print("T"); lcd.setCursor(9,0); // Print the Humidity label to the LCD lcd.print("H"); dht.begin(); lcd.setCursor(0,1); lcd.print("PM10"); // for debuging Serial.begin(115200); // Use software serial

120

11.9. Support mySerial.begin(9600); } void loop() { float h = dht.readHumidity(); // read temperature as Celsius float t = dht.readTemperature(); // read temperature as Fahrenheit // float f = dht.readTemperature(true); // compute heat index in Fahrenheit (the default) // float hif = dht.computeHeatIndex(f, h); // compute heat index in Celsius (isFahreheit = false); float hic = dht.computeHeatIndex(t, h, false); // print Temperature value to the LCD lcd.setCursor(2, 0); lcd.print(t); lcd.setCursor(6,0); lcd.print("C"); // print the Humidity value to the LCD lcd.setCursor(11, 0); lcd.print(h); lcd.setCursor(15,0); lcd.print("%"); int chksum=0; byte pms[32]={0,}; if(mySerial.available()>=32){ for(int j=0; j<32 ; j++){ pms[j]=mySerial.read(); if(j<30) chksum+=pms[j]; } if(pms[30] != (byte)(chksum>>8) || pms[31] != (byte)(chksum) ){ } } delay(1000); lcd.setCursor(5,1); lcd.print(pms[14]); lcd.print("."); lcd.print(pms[15]); lcd.print("ug/m3 "); }

11.9.5. IM1: MQTT to publish a message with a topic MQTT is one of the most commonly used protocols in IoT projects. It stands for Message Queuing Telemetry Transport. In addition, it is designed as a lightweight messaging protocol that provides publish/subscribe operations to exchange data between parties. This exercise is to be considered as closely related to the M2 exercise. Both are part of the same scenario. This exercise shows how to publish a message as a client.

Target group This hands-on lab guide is intended for master students. Other target groups may benefit

121

11. SmartMe Network Laboratory: Arduino Nodes 1-5 from it only if they follow it after having dealt with all the exercises proposed which belong to lower levels of difficulty.

Prerequisites Liquid Crystal For this library, you may refer to the B1 exercise.

DHT For this library, you may refer to the B2 exercise.

Understand what Arduino Ethernet Shield is, and how it works The Arduino Ethernet Shield V1 allows an Arduino board to connect to the internet. It is based on the Wiznet W5100 [1] ethernet chip (datasheet [2]). The Wiznet W5100 provides a network (IP) stack capable of both TCP and UDP-based communication. It supports up to four simultaneous socket connections. Use the Ethernet library [3] to write sketches that connect to the Internet using the shield. The ethernet shield connects to an Arduino board using long wire-wrap headers which extend through the shield. This keeps the pin layout intact and allows another shield to be stacked on top. [1] http://www.wiznet.co.kr/Sub_Modules/en/product/ Product_Detail.asp?cate1=5&cate2=7&cate3=26&pid=1011 [2] http://www.wiznet.co.kr/UpLoad_Files/ReferenceFiles/W5100_Datasheet_v1.2.2.pdf [3] https://www.arduino.cc/en/Reference/Ethernet

Understand what MQTT is and how it works. MQTT (Message Queue Telemetry Transport) is a standard (SO/IEC PRF 20922) machineto-machine (M2M) communication protocol for the Internet of Things smart objects and devices. MQTT is a simple messaging protocol, designed for constrained devices with lowbandwidth. So, it’s the perfect solution for Internet of Things applications. This publish/ subscribe messaging pattern requires a message broker. The broker is responsible for distributing messages to interested clients based on the topic of a message. So a client must connect to a broker in order to: publish messages specifying a topic so that other clients that have subscribed to that topic will be able to receive those messages; receive messages subscribing to a specific topic. This exercise uses shiftr.io [4]. Shiftr.io is a web-based visualization for messages going through an MQTT broker. It is possible to use broker.shiftr.io directly as a public broker. [4] https://shiftr.io

Scenario This node, which acts as a publisher, takes care of sampling the temperature value and sending it to other nodes, which serve as subscribers and were initialized as in exercise M2.

122

11.9. Support Result It will be possible to display the value of the temperature, measured from the sensors attached to this node of the lab, on the LCD display attached to another node of the lab, provided that in the latter node the M2 sketch has been previously launched. Start This exercise is to be considered as closely related to the M2 exercise. This means that if you want to reproduce a complete experiment, you have to book at least two nodes of the lab, and then you have to run both IM1 and IM2 sketches, one per node.

Steps Step 1 Include the following libraries: LCD driver, DHT, MQTT, and Ethernet. #include #include #include #include

<Ethernet.h> <MQTT.h>

Step 2 Instantiate the software controller component for the LCD display. Then assign to the ethernet interface a MAC and IP address, the latter valid for the internal laboratory network (192.168.0.0/24 in this case). Thus instantiate the EthernetClient and MQTTClient objects. Finally declare the connect() function. // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; byte ip[] = {192, 168, 0, 98}; EthernetClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("connecting..."); while (!client.connect("arduino", "try", "try")) { Serial.print("."); delay(1000); } Serial.println("\nconnected!"); }

Step 3 Initialize the display and the Ethernet connection with IP and MAC address. Then launch the connection() function and initialize the MQTT client with the shift.io broker. You can visualize your device stream, after a successful connection, here: https://shiftr.io/try. We suggest doing all of the above in the setup() function, as follows: void setup() { lcd.begin(16, 2);

123

11. SmartMe Network Laboratory: Arduino Nodes 1-5 lcd.print("Temp. *C"); lcd.setCursor(0,1); lcd.print("MQTT PUB"); Serial.begin(115200); Ethernet.begin(mac, ip); client.begin("broker.shiftr.io", net); connect(); }

Step 4 Implement the loop() function to detect the value of temperature from the DHT sensor and publish it as a message with the topic “iotopenume” every 1 second, as follows: void loop() { client.loop(); if (!client.connected()) { connect(); } int t = dht.readTemperature(); String payload = String(t); // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); Serial.println(payload); //publish to the iotopenume topic client.publish("/iotopenume", payload); lcd.setCursor(14, 1); lcd.print(payload); } }

Result validation It will be possible to display the value, sampled by the temperature sensor attached to this node, on the LCD display attached to the node you will use as a subscriber, as soon as you start the M2 sketch on the latter.

Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] [email protected]

124

11.9. Support [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

IM1_pub.cpp #include #include #include #include

<Ethernet.h> <MQTT.h>

#define DHTPIN 8 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal lcd(7, 6, 5, 4, 13, 2); byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; byte ip[] = {192, 168, 0, 98}; EthernetClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("connecting..."); while (!client.connect("arduino", "try", "try")) { Serial.print("."); delay(1000); } Serial.println("\nconnected!"); } void setup() { lcd.begin(16, 2); lcd.print("Temp. *C"); lcd.setCursor(0,1); lcd.print("MQTT PUB"); Serial.begin(115200); Ethernet.begin(mac, ip); client.begin("broker.shiftr.io", net); connect(); } void loop() { client.loop(); if (!client.connected()) { connect(); } int t = dht.readTemperature(); String payload = String(t); // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); Serial.println(payload); client.publish("/iotopenume", payload); lcd.setCursor(14, 1); lcd.print(payload);

125

11. SmartMe Network Laboratory: Arduino Nodes 1-5 } }

11.9.6. IM2: MQTT to subscribe to a topic to receive messages MQTT is one of the most commonly used protocols in IoT projects. It stands for Message Queuing Telemetry Transport. In addition, it is designed as a lightweight messaging protocol that provides publish/subscribe operations to exchange data between parties. This exercise is to be considered as closely related to the M1 exercise. Both are part of the same scenario. This exercise shows how to subscribe to a topic to receive messages belonging to it.

Target group This hands-on lab guide is intended for master students. Other target groups may benefit from it only if they follow it after having dealt with all the exercises proposed which belong to lower levels of difficulty.

Prerequisites Liquid Crystal For this library, you may refer to the B1 exercise.

DHT For this library, you may refer to the B2 exercise.

Understand what Arduino Ethernet Shield is and how it works The Arduino Ethernet Shield V1 allows an Arduino board to connect to the internet. It is based on the Wiznet W5100 [1] ethernet chip (datasheet [2]). The Wiznet W5100 provides a network (IP) stack capable of both TCP and UDP-based communication. It supports up to four simultaneous socket connections. Use the Ethernet library [3] to write sketches that connect to the Internet using the shield. The ethernet shield connects to an Arduino board using long wire-wrap headers which extend through the shield. This keeps the pin layout intact and allows another shield to be stacked on top. [1] http://www.wiznet.co.kr/Sub_Modules/en/product/ Product_Detail.asp?cate1=5&cate2=7&cate3=26&pid=1011 [2] http://www.wiznet.co.kr/UpLoad_Files/ReferenceFiles/W5100_Datasheet_v1.2.2.pdf [3] https://www.arduino.cc/en/Reference/Ethernet

Understand what MQTT is and how it works. MQTT (Message Queue Telemetry Transport) is a standard (SO/IEC PRF 20922) machineto-machine (M2M) communication protocol for the Internet of Things smart objects and devices. MQTT is a simple messaging protocol, designed for constrained devices with lowbandwidth. So, it’s the perfect solution for Internet of Things applications. This publish/ subscribe messaging pattern requires a message broker. The broker is responsible for distributing messages to interested clients based on the topic of a message. So a client

126

11.9. Support must connect to a broker in order to: publish messages specifying a topic so that other clients that have subscribed to that topic will be able to receive those messages; receive messages subscribing to a specific topic. This exercise uses shiftr.io [4]. Shiftr.io is a web-based visualization for messages going through an MQTT broker. It is possible to use broker.shiftr.io directly as a public broker. [4] https://shiftr.io

Scenario This node, which acts as a subscriber, shows the value of temperature received by the other node that was initialized with the exercise M1.

Result It will be possible to display the value of the temperature, measured from the sensors attached to the node where the M1 sketch had been previously launched, on the LCD attached to this node. Start This exercise is to be considered as closely related to the M1 exercise. This means that if you want to reproduce a complete experiment, you have to book at least two nodes of the lab, and then you have to run both IM1 and IM2 sketches, one per node.

Steps Step 1 Include the following libraries: LCD driver, MQTT, and Ethernet. #include #include <Ethernet.h> #include <MQTT.h>

Step 2 Instantiate the software controller component for the LCD display. Then assign to the ethernet interface a MAC and IP address, the latter valid for the internal laboratory network (192.168.0.0/24 in this case). Then instantiate the EthernetClient and MQTTClient objects. Then declare the connect() and messageReceived() functions. In particular, in the connect() body there is a call to the subscribe() function, in order to subscribe to a specific topic. In the messageReceived() body the payload of the message (the temperature value, in this case) is written in the LCD display of the node. // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 13, 2); byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; byte ip[] = {192, 168, 0, 99}; EthernetClient net; MQTTClient client; void connect() { Serial.print("connecting..."); while (!client.connect("arduino", "try", "try")) {

127

11. SmartMe Network Laboratory: Arduino Nodes 1-5 Serial.print("."); delay(1000); } Serial.println("\nconnected!"); // subscribe to the iotopenume topic client.subscribe("/iotopenume"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); lcd.setCursor(14, 1); lcd.print(payload); }

Step 3 Initialize the display and the Ethernet connection with IP and MAC address. Then launch the connection() function and initialize the MQTT client with the shift.io broker. You can visualize your device stream, after a successful connection, here: https://shiftr.io/try. We suggest doing all of the above in the setup() function, as follows: void setup() { lcd.begin(16, 2); lcd.print("Temp. *C"); lcd.setCursor(0,1); lcd.print("MQTT SUB"); Serial.begin(115200); Ethernet.begin(mac, ip); client.begin("broker.shiftr.io", net); client.onMessage(messageReceived); connect(); }

Step 4 Implement loop() to try connecting until success, as follows: void loop() { client.loop(); if (!client.connected()) { connect(); } }

Result validation Observe on your LCD display, its hosting node acting as a subscriber, the value sampled by the temperature sensor attached to the publisher, as soon as you start the M1 sketch on the latter.

128

11.9. Support Platformio.ini [env:uno] platform = atmelavr board = uno framework = arduino lib_ldf_mode=deep+ lib_compat_mode=strict lib_deps = DHT sensor [email protected] Adafruit Unified [email protected] [email protected] [email protected] lib_deps_external = https://github.com/arduino-libraries/LiquidCrystal.git#1.0.7

IM2_sub.cpp #include #include <Ethernet.h> #include <MQTT.h> LiquidCrystal lcd(7, 6, 5, 4, 13, 2); byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; byte ip[] = {192, 168, 0, 99}; EthernetClient net; MQTTClient client; void connect() { Serial.print("connecting..."); while (!client.connect("arduino", "try", "try")) { Serial.print("."); delay(1000); } Serial.println("\nconnected!"); client.subscribe("/iotopenume"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); lcd.setCursor(14, 1); lcd.print(payload); } void setup() { lcd.begin(16, 2); lcd.print("Temp. *C"); lcd.setCursor(0,1); lcd.print("MQTT SUB"); Serial.begin(115200); Ethernet.begin(mac, ip); client.begin("broker.shiftr.io", net); client.onMessage(messageReceived);

129

11. SmartMe Network Laboratory: Arduino Nodes 1-5 connect(); } void loop() { client.loop(); if (!client.connected()) { connect(); } }

130

Related Documents


More Documents from "ChRis dE Leon"