Differences

This shows you the differences between two versions of the page.

Link to this comparison view

en:book [2019/10/12 12:07]
en:book [2019/10/14 08:38] (current)
Line 1: Line 1:
 +====== 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!**
 +====== 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 [[https://​en.wikipedia.org/​wiki/​Creative_Commons_license|Creative Commons Licence]], free for Non-Commercial use. 
 +<figure label>
 +{{en:​iot-open:​ccbync.png?​100|CC BY-NC}}
 +</​figure>​
 +In case of commercial use, please contact IOT-OPEN.EU consortium representative.
 +====== VREL - Remote Distant Laboratories ======
 +
 +Laboratories can be accessed via the uniform model using web platform available here: [[http://​distance.roboticlab.eu/​|link]]. 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 them. 
 +
 +<note important>​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.</​note>​
 +
 +Each document has subchapters with hands-on labs to launch your experience with the device. You can extend it than yourself!
 +
 +List of laboratories:​
 +
 +**ITT Group, laboratories location: Tallinn, Estonia**
 +  * Node 1 [[en:​iot-open:​remotelab:​itt:​remotelights|Remote lights]]
 +  * Node 2 [[en:​iot-open:​remotelab:​itt:​thermohygro|Temperature/​Humidity controlled rooms]]
 +  * Node 3 [[en:​iot-open:​remotelab:​itt:​efficiency|Production efficiency]]
 +**SUT The Silesian University of Technology, laboratories location: ​ Gliwice, Poland**
 +  * Node 1 and Node 3 [[en:​iot-open:​remotelab:​sut:​generalpurpose2]] - air RX
 +  * Node 2 and Node 4 [[en:​iot-open:​remotelab:​sut:​generalpurpose]] - air TX 
 +  * Node 5 [[en:​iot-open:​remotelab:​sut:​roboarm]]
 +  * Node 6 [[en:​iot-open:​remotelab:​sut:​color]]
 +  * Node 7 [[en:​iot-open:​remotelab:​sut:​rooftop]]
 +**UME University di Messina, laboratory location: Messina, Sicilia, Italy**
 +  * Node 1-5 [[en:​iot-open:​remotelab:​ume:​smartme|SmartME Network Laboratory Arduino]].
 +  * Node 6 [[en:​iot-open:​remotelab:​ume:​arancino|SmartME Network Laboratory Arancino]].
 +
 +
 +===== VREL #1 and #3: General Purpose IoT Laboratory, air receiving nodes 1 and 3 =====
 +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.
 +
 +
 +==== 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 photoelectric proximity sensor. The signal from the sensor is sent to the AD converter and additionally is displayed on needle gauge.
 +
 +==== Prerequisites ====
 +The user needs to know:
 +  * physical effect of the airflow,
 +  * elementary rules od light propagation,​
 +  * work of unbalanced bridge.
 +
 +=== Sensors ===
 +The sensor of flap position is made which photoresistors. For reference, next to the flap there is immovable surface made with the same material like the flap. Like in case of flaps, here is 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. ​
 +==== 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.
 +
 +{{:​en:​iot-open:​remotelab:​sut:​iotrx.jpg?​500|}}
 +
 +Independent,​ in the lab there is a sensor of temperature and humidity, DHT22, connected to the D4/GPIO2.
 +
 +{{:​en:​iot-open:​remotelab:​sut:​iotrx_sch.jpg?​300|}}
 +
 +
 +=== Actuators ===
 +There are no mechanical actuators in this laboratory.\\
 +LCD Display is 4x20 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).
 +<note important>​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.</​note>​
 +<note tip>​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.</​note>​
 +
 +=== 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 [[https://​github.com/​tonykambo/​LiquidCrystal_I2C|''​LiquidCrystal_I2C by Tony Kambourakis''​]].
 +The LCD I2C control library can be imported to the source code via:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +Then configure your LCD controller:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +</​code>​
 +
 +=== 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.
 +
 +__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
 +
 +The same MQTT server/​broker is visible under public IP: 157.158.56.54 port 1883 (non-secure) and 8883 (secure) to let you exchange data with the world and control your devices remotely.
 +
 +=== 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.
 +
 +==== Hands-on labs ====
 +          * Beginners
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​b1]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​b2]].
 +          * Undergraduates
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​u1]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​u2]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​u3]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​u4]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​u8]].
 +          * Masters
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​m1|registering temperature,​ humidity and flap position, period long time, and display these (as graph) on the dashboard along with its analysis]],
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​m2|check correlation between data from the neighbour Tx laboratory]],​
 +            * [[en:​iot-open:​remotelab:​sut:​generalpurpose2:​m3|Using a closed loop with MQTT based communication,​ drive the neighbour node fan (TX node) to ensure assumed flap position, possibly with the use of PID controller implementation]]
 +
 +==== Support ====
 +gabriel.drabik@polsl.pl
 +==== B1: Basic operations on the 4x20 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 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 important>​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!</​note>​
 +
 +=== 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 and the I2C bus is connected to the pins D1 and D2 (D1 is SCL and D2 is SDA).
 +
 +=== 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:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +== Step 2 ==
 +Instantiate software controler component for the LCD display:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +</​code>​
 +== Step 3 ==
 +Declare some variables: counter ''​i'',​ its length ''​n''​ and ''​buffer''​ for the into to string conversion:
 +<code c>
 +int i = 0;
 +char buffer [50];
 +int n;
 +</​code>​
 +We will use them in further part of the code.
 +== Step 3 ==
 +Initialize display - we suggest to do it in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.init(D2,​D1); ​                // initialize the lcd I2C
 +  lcd.backlight(); ​                // switch on the backlight
 +...
 +</​code>​
 +== Step 4 ==
 +Clear the contents, set cursor and draw static text - still in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.home();
 +  lcd.print("​Hello IOT!"​);​
 +  lcd.setCursor(0,​ 1);
 +  lcd.print("​James Bond here"​);​
 +  lcd.setCursor(0,​2);​
 +  lcd.print("​London"​);​
 +...
 +</​code>​
 +== Step 5 ==
 +Implement ''​loop()''​ to draw number of loop executions:
 +<code c>
 +...
 +  i++;
 +  n=sprintf(buffer,"​%d",​i);​
 +  lcd.setCursor(20-n,​3);​
 +  lcd.print(i);​
 +  delay(1000);​
 +...
 +</​code>​
 +<note tip>''​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.</​note>​
 +
 +=== Result validation ===
 +Observe text, its position and counter ticking in lower, right corner.
 +
 +
 +==== 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:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +The temperature and humidity sensor is all-in-one, DHT22 sensor, connected to the pin D3.
 +To read data you may use a dedicated library (libraries):​
 +<code c>
 +#include <​Adafruit_Sensor.h>​
 +#include <​DHT.h>​
 +</​code>​
 +=== 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.
 +<note warning>​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.</​note>​
 +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://"​\\
 +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 ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +Include LCD driver library:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​Adafruit_Sensor.h>​
 +#include <​DHT.h>​
 +</​code>​
 +
 +== Step 2 ==
 +Instantiate software controler component for the LCD display:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +DHT dht(DHTpin,​DHT22,​50);​
 +</​code>​
 +== Step 3 ==
 +Declare a buffer for ''​sprintf''​ function:
 +<code c>
 +char buffer [10];
 +</​code>​
 +
 +== Step 4 ==
 +Initialize LCD and dht sensor:
 +<code c>
 +...
 +  lcd.init(D2,​D1); ​                     // initialize the lcd 
 +  lcd.backlight();​
 +  lcd.home();
 +...
 +  dht.begin();​
 +  delay(1000); ​                         // give it a second to let the sensor initialize
 +...
 +</​code>​
 +
 +== Step 5 ==
 +Read in the loop:
 +<code c>
 +...
 +  float hum = dht.readHumidity();​
 +  float temp = dht.readTemperature();​
 +...
 +</​code>​
 +To convert float into the string with formatting use ''​sprintf''​ function:
 +<code c>
 +...
 +  sprintf(buffer,"​%2.1f C",​temp);​
 +...
 +  sprintf(buffer,"​%2.1f%%Rh",​hum);​
 +...
 +  delay(5000);​
 +...
 +</​code>​
 +<note tip>''​sprintf''​ uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on ''​sprintf''​. Here <code c>​%2.1f</​code>​ 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. <code c>​%%</​code>​ is an escape character to print a <code c>​%</​code>​ (percent) symbol.\\''​delay(time)''​ is measured in milliseconds.</​note>​
 +
 +=== Result validation ===
 +Observe temperature and humidity readings on the LCD. Temperature ranges between 20-30C while humidity between 35-60%Rh.
 +
 +==== 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 4x20 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +</​code>​
 +<note important>​Always refer to the node documentation to ensure you know current SSID and passphrase. They may differ to those in the code above!</​note>​
 +
 +== 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:
 +<code c>
 +  delay(10);
 +  WiFi.mode(WIFI_STA);​
 +  WiFi.begin(wifi_ssid,​ wifi_password);​
 +  n=0;
 +</​code>​
 +<note important>''​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.</​note>​
 +<note tip>''​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 check your SSID and passphrase.</​note>​
 +<note warning>​Please,​ explicitly use interface mode setting: ''​WiFi.mode(WIFI_STA);''​. See FAQ section for details.</​note>​
 +
 +== Step 4 ==
 +Check if connected, if not, give it next attempt:
 +<code c>
 +while (WiFi.status() != WL_CONNECTED) {
 +    lcd.setCursor(0,​1);​
 +    n++;
 +    sprintf(buffer,"​Attempt %d",​n);​
 +    lcd.print(buffer);​
 +    delay(1000);​
 +</​code>​
 +
 +== Step 5 ==
 +When connected, show details to the camera:
 +<code c>
 +  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());​
 +</​code>​
 +<note tip>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.</​note>​
 +== 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. 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!
 +
 +==== 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.\\ <fc #​ff0000>​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!</​fc>​
 +<note warning>​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!</​note>​
 +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. <note tip>​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.</​note>​
 +
 +=== 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code, remember to change ssid name to yours!
 +<code c>
 +#define wifi_ssid_ap put_your_unique_id_here //give it some unique name - change here!!
 +#define wifi_password_ap "​1234567890"​
 +</​code>​
 +<note warning>​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!</​note>​
 +
 +== Step 3 ==
 +Print some information about starting software WiFi AP, configure network interface as a WiFi AP and give it a try to start:
 +<code c>
 +...
 +  delay(10);
 +...
 +  WiFi.mode(WIFI_AP);​
 +  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
 +  }
 +...
 +</​code>​
 +
 +== Step 4 ==
 +Implement in the ''​loop()''​ an information about number of connected clients, i.e. like this:
 +<code c>
 +...
 +void loop()
 +{
 +  lcd.setCursor(0,​3);​
 +  sprintf(buffer,​ "​Stations:​ %d", WiFi.softAPgetStationNum());​
 +  lcd.print(buffer);​
 +  delay(3000);​
 +}
 +...
 +</​code>​
 +
 +=== 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!
 +==== 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
 +
 +=== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +
 +=== 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.
 +<note important>​In this scenario, you do not subscribe your device to any messages, you only publish them.</​note>​
 +
 +=== 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 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​DHT.h>​
 +...
 +</​code>​
 +Declare some identifiers to let you easier handle necessary modifications and keep code clear:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topics, MQTT client ID and payloads for the status notification (on / off).
 +<note important>​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.</​note>​
 +<code c>
 +#define MQTTClientName ...<your client name>...
 +#define tempTopic ​ ...<some topic for temperature>​... // give it some unique topic i.e. including your name
 +#define humTopic ​  ​...<​come topic for humidity>​... ​   // 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"​
 +</​code>​
 +
 +== 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:
 +<code c>
 +// WiFi & MQTT
 +WiFiClient espClient;
 +PubSubClient client(espClient);​
 +</​code>​
 +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:​
 +<code c>
 +client.setServer(mqtt_server,​ 1883);
 +</​code>​
 +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 configurd 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:
 +<code c>
 +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);​
 +    }
 +  }
 +  lcd.setCursor(0,​1);​
 +  lcd.print("​MQTT Connected!"​);​
 +}
 +</​code>​
 +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:
 +<code c>
 +...
 +if (!client.connected()) {
 +    reconnect();​ //reconnect MQTT
 +  }
 +...
 +</​code>​
 +== 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:
 +<code c>
 +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);
 +    }
 +  }
 +}
 +</​code>​
 +<note warning>​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.</​note>​
 +
 +Finally your ''​loop()''​ may look like this:
 +<code c>
 +void loop()
 +{
 +  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);  ​
 +}
 +</​code>​
 +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.
 +==== 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.
 +=== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +=== 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.
 +<note important>​Subscribing to ''#''​ is a really bad idea in production, live system. You will get a flood of messages! </​note>​
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​DHT.h>​
 +...
 +</​code>​
 +Declare some identifiers to let you easier handle necessary modifications and keep code clear:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topic (one with wildcard, for four LCD lines) and MQTT client ID.
 +<note important>​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.</​note>​
 +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:
 +<code c>
 +// MQTT messages
 +#define MQTTClientName "​thisissomeuniqueclientname"​
 +#define lcdTopicWithWildcard "/​sut/​mydevice/​LCD/​+"​
 +</​code>​
 +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):
 +<code c>
 +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]);​
 +    }
 +  }
 +}
 +</​code>​
 +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:
 +<code c>
 +// WiFi & MQTT
 +WiFiClient espClient;
 +PubSubClient client(espClient);​
 +</​code>​
 +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'':​
 +<code c>
 +client.setServer(mqtt_server,​ 1883);
 +client.setCallback(mqttCallback);​
 +</​code>​
 +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:
 +<code c>
 +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!"​);​
 +}
 +</​code>​
 +== Step 6 ==
 +Finally your ''​loop()''​ may look like this:
 +<code c>
 +void loop()
 +{
 +  if (!client.connected()) {
 +    reconnect();​
 +  }
 +  client.loop();​
 +}
 +</​code>​
 +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. 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.
 +//
 +
 +==== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +
 +<note important>​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.</​note>​
 +
 +=== 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 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 tip>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.</​note> ​
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +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:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topics, MQTT client ID and payloads for the status notification (on / off).
 +
 +<note important>​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.</​note>​
 +
 +<code c>
 +// MQTT messages
 +#define MQTTClientName ...<your client name>​... ​        
 +#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   // give it some unique topic i.e. including your name
 +#define lastWillMessage "​off"​
 +#define mqttWelcomeMessage "​on"​
 +</​code>​
 +
 +== 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:
 +<code c>
 +void mqttPublish()
 +{
 +  flap = analogRead(A0);​
 +  ​
 +  if(client.connected())
 +  {
 +    client.publish(analogOutTopic,​ String(flap).c_str(),​ false); ​ // Do not retain messages
 +  }
 +}
 +</​code>​
 +<note important>​Reading analogue input is pretty easy: all you need to do is to use ''​analogRead(A0)''​. Note, ESP8266 has only one analogue input A0.</​note>​
 +
 +== Step 5 ==
 +Your ''​loop()''​ function should include call to the aforementioned ''​mqttPublish''​ and printing on the LCD screen once every 5 seconds.
 +<code c>
 +void loop()
 +{
 +  if (!client.connected()) {
 +    reconnect();​
 +  }
 +  client.loop();​
 +  mqttPublish();​
 +  sprintf(buffer,"​Flap is %d ",​flap);​
 +  lcd.setCursor(0,​2);​
 +  lcd.print(buffer);​
 +  delay(1000);​
 +}
 +</​code>​
 +<note warning>​Mind to keep a ''​delay(...)'',​ not to saturate MQTT broker and communication channel. Minimum reasonable delay between issuing consecutive MQTT messages is about 200ms.</​note>​
 +<note tip>The ''​flap''​ variable is a global one, set in the ''​mqttPublish''​ using ''​analogRead(A0)''​. This way you have it set for ''​sprintf''​ formating function.</​note>​
 +
 +=== 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.
 +//
 +==== M1: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== M2: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +
 +===== VREL #2 and #4: General Purpose IoT Laboratory, air pushing nodes 2 and 4 =====
 +The laboratory is located at Silesian Technical University, Poland, Gliwice Akademicka 16, room 310.
 +
 +==== 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.
 +
 +==== Prerequisites ====
 +The user needs to know:
 +  * physical effect of the airflow,
 +  * PWM control method,
 +  * working od servo-motors and its control.
 +
 +==== 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.
 +
 +{{:​en:​iot-open:​remotelab:​sut:​iottx.jpg?​500|}}
 +
 +
 +=== Sensors ===
 +There is temperature and humidity sensor in the lab node: DHT22, connected to the GPIO0 (D3).
 +
 +=== 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
 +
 +{{:​en:​iot-open:​remotelab:​sut:​iottx_sch.jpg?​500|}}
 +
 +=== Software, libraries and externals ===
 +//Provide a list of software, software libraries and external resources (i.e. files) necessary during code development. Please note, write here only common for all hands-on-labs scenarios (there is a relevant section in scenario template. Remove this section if empty.//
 +
 +=== 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 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).
 +
 +==== Hands-on labs ====
 +Generally, this node provides airflow to the neighbour receiving (Rx) node: node 2 sends air to node 1, node 4 sends air to node 2. For simple scenarios it is enough to book just one node while to simulate complex scenarios, it is essential to book and solve complex problems using two nodes.
 +  * Beginners:
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​b1]]
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​b2]]
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​b3]]
 +  * Undergraduates: ​
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​u1]]
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​u2]]
 +  * Masters:
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​m1]]
 +    * [[en:​iot-open:​remotelab:​sut:​generalpurpose:​m2]] ​
 +
 +==== Support ====
 +gabriel.drabik@polsl.pl
 +
 +==== B1: Basic operations on the 4x20 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 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 important>​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!</​note>​
 +
 +=== 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 and the I2C bus is connected to the pins D1 and D2 (D1 is SCL and D2 is SDA).
 +
 +=== 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:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +== Step 2 ==
 +Instantiate software controler component for the LCD display:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +</​code>​
 +== Step 3 ==
 +Declare some variables: counter ''​i'',​ its length ''​n''​ and ''​buffer''​ for the into to string conversion:
 +<code c>
 +int i = 0;
 +char buffer [50];
 +int n;
 +</​code>​
 +We will use them in further part of the code.
 +== Step 3 ==
 +Initialize display - we suggest to do it in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.init(D2,​D1); ​                // initialize the lcd I2C
 +  lcd.backlight(); ​                // switch on the backlight
 +...
 +</​code>​
 +== Step 4 ==
 +Clear the contents, set cursor and draw static text - still in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.home();
 +  lcd.print("​Hello IOT!"​);​
 +  lcd.setCursor(0,​ 1);
 +  lcd.print("​James Bond here"​);​
 +  lcd.setCursor(0,​2);​
 +  lcd.print("​London"​);​
 +...
 +</​code>​
 +== Step 5 ==
 +Implement ''​loop()''​ to draw number of loop executions:
 +<code c>
 +...
 +  i++;
 +  n=sprintf(buffer,"​%d",​i);​
 +  lcd.setCursor(20-n,​3);​
 +  lcd.print(i);​
 +  delay(1000);​
 +...
 +</​code>​
 +<note tip>''​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.</​note>​
 +
 +=== Result validation ===
 +Observe text, its position and counter ticking in lower, right corner.
 +
 +
 +==== 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:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +The temperature and humidity sensor is all-in-one, DHT22 sensor, connected to the pin D3.
 +To read data you may use a dedicated library (libraries):​
 +<code c>
 +#include <​Adafruit_Sensor.h>​
 +#include <​DHT.h>​
 +</​code>​
 +=== 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.
 +<note warning>​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.</​note>​
 +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://"​\\
 +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 ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +Include LCD driver library:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​Adafruit_Sensor.h>​
 +#include <​DHT.h>​
 +</​code>​
 +
 +== Step 2 ==
 +Instantiate software controler component for the LCD display:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +DHT dht(DHTpin,​DHT22,​50);​
 +</​code>​
 +== Step 3 ==
 +Declare a buffer for ''​sprintf''​ function:
 +<code c>
 +char buffer [10];
 +</​code>​
 +
 +== Step 4 ==
 +Initialize LCD and dht sensor:
 +<code c>
 +...
 +  lcd.init(D2,​D1); ​                     // initialize the lcd 
 +  lcd.backlight();​
 +  lcd.home();
 +...
 +  dht.begin();​
 +  delay(1000); ​                         // give it a second to let the sensor initialize
 +...
 +</​code>​
 +
 +== Step 5 ==
 +Read in the loop:
 +<code c>
 +...
 +  float hum = dht.readHumidity();​
 +  float temp = dht.readTemperature();​
 +...
 +</​code>​
 +To convert float into the string with formatting use ''​sprintf''​ function:
 +<code c>
 +...
 +  sprintf(buffer,"​%2.1f C",​temp);​
 +...
 +  sprintf(buffer,"​%2.1f%%Rh",​hum);​
 +...
 +  delay(5000);​
 +...
 +</​code>​
 +<note tip>''​sprintf''​ uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on ''​sprintf''​. Here <code c>​%2.1f</​code>​ 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. <code c>​%%</​code>​ is an escape character to print a <code c>​%</​code>​ (percent) symbol.\\''​delay(time)''​ is measured in milliseconds.</​note>​
 +
 +=== Result validation ===
 +Observe temperature and humidity readings on the LCD. Temperature ranges between 20-30C while humidity between 35-60%Rh.
 +
 +==== 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 4x20 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +</​code>​
 +<note important>​Always refer to the node documentation to ensure you know current SSID and passphrase. They may differ to those in the code above!</​note>​
 +
 +== 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:
 +<code c>
 +  delay(10);
 +  WiFi.mode(WIFI_STA);​
 +  WiFi.begin(wifi_ssid,​ wifi_password);​
 +  n=0;
 +</​code>​
 +<note important>''​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.</​note>​
 +<note tip>''​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 check your SSID and passphrase.</​note>​
 +<note warning>​Please,​ explicitly use interface mode setting: ''​WiFi.mode(WIFI_STA);''​. See FAQ section for details.</​note>​
 +
 +== Step 4 ==
 +Check if connected, if not, give it next attempt:
 +<code c>
 +while (WiFi.status() != WL_CONNECTED) {
 +    lcd.setCursor(0,​1);​
 +    n++;
 +    sprintf(buffer,"​Attempt %d",​n);​
 +    lcd.print(buffer);​
 +    delay(1000);​
 +</​code>​
 +
 +== Step 5 ==
 +When connected, show details to the camera:
 +<code c>
 +  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());​
 +</​code>​
 +<note tip>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.</​note>​
 +== 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. 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!
 +
 +==== 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.\\ <fc #​ff0000>​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!</​fc>​
 +<note warning>​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!</​note>​
 +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. <note tip>​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.</​note>​
 +
 +=== 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code, remember to change ssid name to yours!
 +<code c>
 +#define wifi_ssid_ap put_your_unique_id_here //give it some unique name - change here!!
 +#define wifi_password_ap "​1234567890"​
 +</​code>​
 +<note warning>​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!</​note>​
 +
 +== Step 3 ==
 +Print some information about starting software WiFi AP, configure network interface as a WiFi AP and give it a try to start:
 +<code c>
 +...
 +  delay(10);
 +...
 +  WiFi.mode(WIFI_AP);​
 +  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
 +  }
 +...
 +</​code>​
 +
 +== Step 4 ==
 +Implement in the ''​loop()''​ an information about number of connected clients, i.e. like this:
 +<code c>
 +...
 +void loop()
 +{
 +  lcd.setCursor(0,​3);​
 +  sprintf(buffer,​ "​Stations:​ %d", WiFi.softAPgetStationNum());​
 +  lcd.print(buffer);​
 +  delay(3000);​
 +}
 +...
 +</​code>​
 +
 +=== 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!
 +==== 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
 +
 +=== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +
 +=== 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.
 +<note important>​In this scenario, you do not subscribe your device to any messages, you only publish them.</​note>​
 +
 +=== 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 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​DHT.h>​
 +...
 +</​code>​
 +Declare some identifiers to let you easier handle necessary modifications and keep code clear:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topics, MQTT client ID and payloads for the status notification (on / off).
 +<note important>​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.</​note>​
 +<code c>
 +#define MQTTClientName ...<your client name>...
 +#define tempTopic ​ ...<some topic for temperature>​... // give it some unique topic i.e. including your name
 +#define humTopic ​  ​...<​come topic for humidity>​... ​   // 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"​
 +</​code>​
 +
 +== 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:
 +<code c>
 +// WiFi & MQTT
 +WiFiClient espClient;
 +PubSubClient client(espClient);​
 +</​code>​
 +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:​
 +<code c>
 +client.setServer(mqtt_server,​ 1883);
 +</​code>​
 +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 configurd 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:
 +<code c>
 +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);​
 +    }
 +  }
 +  lcd.setCursor(0,​1);​
 +  lcd.print("​MQTT Connected!"​);​
 +}
 +</​code>​
 +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:
 +<code c>
 +...
 +if (!client.connected()) {
 +    reconnect();​ //reconnect MQTT
 +  }
 +...
 +</​code>​
 +== 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:
 +<code c>
 +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);
 +    }
 +  }
 +}
 +</​code>​
 +<note warning>​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.</​note>​
 +
 +Finally your ''​loop()''​ may look like this:
 +<code c>
 +void loop()
 +{
 +  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);  ​
 +}
 +</​code>​
 +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.
 +==== 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.
 +=== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +=== 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.
 +<note important>​Subscribing to ''#''​ is a really bad idea in production, live system. You will get a flood of messages! </​note>​
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​DHT.h>​
 +...
 +</​code>​
 +Declare some identifiers to let you easier handle necessary modifications and keep code clear:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topic (one with wildcard, for four LCD lines) and MQTT client ID.
 +<note important>​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.</​note>​
 +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:
 +<code c>
 +// MQTT messages
 +#define MQTTClientName "​thisissomeuniqueclientname"​
 +#define lcdTopicWithWildcard "/​sut/​mydevice/​LCD/​+"​
 +</​code>​
 +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):
 +<code c>
 +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]);​
 +    }
 +  }
 +}
 +</​code>​
 +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:
 +<code c>
 +// WiFi & MQTT
 +WiFiClient espClient;
 +PubSubClient client(espClient);​
 +</​code>​
 +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'':​
 +<code c>
 +client.setServer(mqtt_server,​ 1883);
 +client.setCallback(mqttCallback);​
 +</​code>​
 +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:
 +<code c>
 +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!"​);​
 +}
 +</​code>​
 +== Step 6 ==
 +Finally your ''​loop()''​ may look like this:
 +<code c>
 +void loop()
 +{
 +  if (!client.connected()) {
 +    reconnect();​
 +  }
 +  client.loop();​
 +}
 +</​code>​
 +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. 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.
 +//
 +
 +==== 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 the node documentation for the latest information.
 +<note important>​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>​
 +
 +<note warning>​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!</​note>​
 +
 +
 +
 +=== 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.
 +
 +<note warning>​Legal range for the servo is 0...90 degree! Exceeding over 90 degrees may break the construction!</​note>​
 +<note tip>​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.</​note>​
 +
 +=== 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 minimum set here is:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​Servo.h>​
 +...
 +</​code>​
 +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:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topics, MQTT client ID and payloads for the status notification (on / off).
 +<note important>​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.</​note>​
 +<code c>
 +// MQTT messages
 +#define MQTTClientName "​myVREL2clientname"​
 +#define servoTopic ...<some topic for servo>​... // give it some unique topic i.e. including your name
 +#define fanTopic ​  ​...<​some topic for fan>... // 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   // give it some unique topic i.e. including your name
 +#define lastWillMessage "​off"​
 +#define mqttWelcomeMessage "​on"​
 +</​code>​
 +Finally, declare GPIOs pin numbers connecting to the servo and fan:
 +<code c>
 +//Hardware
 +#define PWMFanPin D8 
 +#define servoPin D5
 +</​code>​
 +
 +== 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:
 +<code c>
 +...
 +Servo servo;
 +...
 +</​code>​
 +
 +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):
 +<code c>
 +...
 +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
 +...
 +</​code>​
 +
 +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:
 +<code c>
 +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];​
 +      }
 +    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);​
 +  }
 +}
 +</​code>​
 +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:
 +<code c>
 +...
 +client.setCallback(mqttCallback);​
 +...
 +</​code>​
 +
 +=== 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 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!
 +==== M1: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== M2: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== B1: Basic operations on the 4x20 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 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 important>​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!</​note>​
 +
 +=== 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 and the I2C bus is connected to the pins D1 and D2 (D1 is SCL and D2 is SDA).
 +
 +=== 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:
 +<code c>
 +#include <​LiquidCrystal_I2C.h>​
 +</​code>​
 +== Step 2 ==
 +Instantiate software controler component for the LCD display:
 +<code c>
 +LiquidCrystal_I2C lcd(0x3F,​20,​4); ​ // set the LCD address to 0x3F for a 20 chars and 4 line display
 +</​code>​
 +== Step 3 ==
 +Declare some variables: counter ''​i'',​ its length ''​n''​ and ''​buffer''​ for the into to string conversion:
 +<code c>
 +int i = 0;
 +char buffer [50];
 +int n;
 +</​code>​
 +We will use them in further part of the code.
 +== Step 3 ==
 +Initialize display - we suggest to do it in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.init(D2,​D1); ​                // initialize the lcd I2C
 +  lcd.backlight(); ​                // switch on the backlight
 +...
 +</​code>​
 +== Step 4 ==
 +Clear the contents, set cursor and draw static text - still in ''​setup()''​ function:
 +<code c>
 +...
 +  lcd.home();
 +  lcd.print("​Hello IOT!"​);​
 +  lcd.setCursor(0,​ 1);
 +  lcd.print("​James Bond here"​);​
 +  lcd.setCursor(0,​2);​
 +  lcd.print("​London"​);​
 +...
 +</​code>​
 +== Step 5 ==
 +Implement ''​loop()''​ to draw number of loop executions:
 +<code c>
 +...
 +  i++;
 +  n=sprintf(buffer,"​%d",​i);​
 +  lcd.setCursor(20-n,​3);​
 +  lcd.print(i);​
 +  delay(1000);​
 +...
 +</​code>​
 +<note tip>''​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.</​note>​
 +
 +=== Result validation ===
 +Observe text, its position and counter ticking in lower, right corner.
 +
 +
 +==== 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 4x20 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +</​code>​
 +<note important>​Always refer to the node documentation to ensure you know current SSID and passphrase. They may differ to those in the code above!</​note>​
 +
 +== 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:
 +<code c>
 +  delay(10);
 +  WiFi.mode(WIFI_STA);​
 +  WiFi.begin(wifi_ssid,​ wifi_password);​
 +  n=0;
 +</​code>​
 +<note important>''​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.</​note>​
 +<note tip>''​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 check your SSID and passphrase.</​note>​
 +<note warning>​Please,​ explicitly use interface mode setting: ''​WiFi.mode(WIFI_STA);''​. See FAQ section for details.</​note>​
 +
 +== Step 4 ==
 +Check if connected, if not, give it next attempt:
 +<code c>
 +while (WiFi.status() != WL_CONNECTED) {
 +    lcd.setCursor(0,​1);​
 +    n++;
 +    sprintf(buffer,"​Attempt %d",​n);​
 +    lcd.print(buffer);​
 +    delay(1000);​
 +</​code>​
 +
 +== Step 5 ==
 +When connected, show details to the camera:
 +<code c>
 +  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());​
 +</​code>​
 +<note tip>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.</​note>​
 +== 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. 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!
 +
 +==== 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.\\ <fc #​ff0000>​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!</​fc>​
 +<note warning>​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!</​note>​
 +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. <note tip>​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.</​note>​
 +
 +=== 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code, remember to change ssid name to yours!
 +<code c>
 +#define wifi_ssid_ap put_your_unique_id_here //give it some unique name - change here!!
 +#define wifi_password_ap "​1234567890"​
 +</​code>​
 +<note warning>​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!</​note>​
 +
 +== Step 3 ==
 +Print some information about starting software WiFi AP, configure network interface as a WiFi AP and give it a try to start:
 +<code c>
 +...
 +  delay(10);
 +...
 +  WiFi.mode(WIFI_AP);​
 +  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
 +  }
 +...
 +</​code>​
 +
 +== Step 4 ==
 +Implement in the ''​loop()''​ an information about number of connected clients, i.e. like this:
 +<code c>
 +...
 +void loop()
 +{
 +  lcd.setCursor(0,​3);​
 +  sprintf(buffer,​ "​Stations:​ %d", WiFi.softAPgetStationNum());​
 +  lcd.print(buffer);​
 +  delay(3000);​
 +}
 +...
 +</​code>​
 +
 +=== 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!
 +==== 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.
 +=== 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 [[https://​github.com/​eclipse/​paho.mqtt-spy/​releases|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 important>​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>​
 +=== 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.
 +<note important>​Subscribing to ''#''​ is a really bad idea in production, live system. You will get a flood of messages! </​note>​
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​PubSubClient.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +#include <​DHT.h>​
 +...
 +</​code>​
 +Declare some identifiers to let you easier handle necessary modifications and keep code clear:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +#define mqtt_server "​192.168.90.5"​
 +#define mqtt_user "​vrel"​
 +#define mqtt_password "​vrel2018"​
 +...
 +</​code>​
 +
 +== Step 2 ==
 +Declare some identifiers,​ here MQTT messages'​ topic (one with wildcard, for four LCD lines) and MQTT client ID.
 +<note important>​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.</​note>​
 +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:
 +<code c>
 +// MQTT messages
 +#define MQTTClientName "​thisissomeuniqueclientname"​
 +#define lcdTopicWithWildcard "/​sut/​mydevice/​LCD/​+"​
 +</​code>​
 +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):
 +<code c>
 +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]);​
 +    }
 +  }
 +}
 +</​code>​
 +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:
 +<code c>
 +// WiFi & MQTT
 +WiFiClient espClient;
 +PubSubClient client(espClient);​
 +</​code>​
 +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'':​
 +<code c>
 +client.setServer(mqtt_server,​ 1883);
 +client.setCallback(mqttCallback);​
 +</​code>​
 +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:
 +<code c>
 +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!"​);​
 +}
 +</​code>​
 +== Step 6 ==
 +Finally your ''​loop()''​ may look like this:
 +<code c>
 +void loop()
 +{
 +  if (!client.connected()) {
 +    reconnect();​
 +  }
 +  client.loop();​
 +}
 +</​code>​
 +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. 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.
 +//
 +
 +==== U9: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== M3: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +
 +===== VREL #6: Color Temperature and Brightness Compensation Laboratory=====
 +
 +The laboratory is located at Silesian Technical University, Poland, Gliwice Akademicka 16, room 319.
 +
 +
 +====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.
 +
 +
 +<figure Tower_diagram>​
 +{{ :​en:​iot-open:​remotelab:​sut:​image002.jpg?​nolink |}}
 +<​caption>​General view of laboratory stand.</​caption>​
 +</​figure>​
 +
 +
 +====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,​
 +
 +====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 {{ref>​Sensor_diagram}},​ and diagram of LEDs connection is in figure {{ref>​LEDs_diagram}}
 +
 +<figure Sensor_diagram>​
 +{{ :​en:​iot-open:​remotelab:​sut:​vrel2b_bb.png?​nolink%900 |}}
 +<​caption>​Microcontroller with PWM and sensors.</​caption>​
 +</​figure>​
 +
 +<figure LEDs_diagram>​
 +{{ :​en:​iot-open:​remotelab:​sut:​vrel2a_bb.png?​nolink&​900 |}}
 +<​caption>​LEDs connections</​caption>​
 +</​figure>​
 +
 +
 +===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.
 +<note important>​ Remember to always select the appropriate multiplexer channel before referring to the correct light sensor </​note>​
 +^TCA9548A I2C channel^Sensors ^I2C Address^Position^Input/​output^Remarks^
 +
 +|Channel 0|Sensor TCS34725 RGB - Main|0x29h|Bottom of brightside|Output|Main sensor of mixed light|
 +|Channel 1|Sensor TCS34725 RGB - DarkSide|0x29h|Bottom of darkside|Output|Sensor of only LED light |
 +|Channel 2|Sensor TCS34725 RGB - Ambient |0x29h|Top of Tower|Output|Ambient light sensor|
 +|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| 
 +
 +===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 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|
 +| Channel 9 |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|
 +
 +====Software,​ libraries and externals ====
 +
 +=== 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. ​
 +
 +__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 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 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.
 +
 +
 +==== Hands-on labs ====
 +Generally, this node provides ...
 +
 +  * Beginners:
 +    * [[en:​iot-open:​remotelab:​sut:​color:​b3]]
 +    * [[en:​iot-open:​remotelab:​sut:​color:​b4]]
 +  * Undergraduates: ​
 +    * [[en:​iot-open:​remotelab:​sut:​color:​u5]]
 +    * [[en:​iot-open:​remotelab:​sut:​color:​b5]]
 +  * Masters:
 +    * [[en:​iot-open:​remotelab:​sut:​color:​m4]]
 +    * [[en:​iot-open:​remotelab:​sut:​color:​m5]] ​
 +
 +==== Support ====
 +
 +In case of problems write: jaroslaw.paduch@polsl.pl
 +
 +==== B3: epaper display operations ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== B4: 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 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: ​
 +<​code>​
 +#include <​Wire.h>​
 +#include <​PCA9685.h>​
 +</​code> ​
 +
 +===Step 2===
 +Instantiate PWM controler component: ​
 +<​code>​
 +#define PCA9685_ADDRESS ​    0x40
 +PCA9685 ledDriver; ​
 +</​code>​
 +or 
 +<​code>​
 +#define PCA9685_ADDRESS ​    0x40
 +PCA9685 ledDriver(PCA9685_ADDRESS); ​
 +</​code>​
 +
 +===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:
 +<​code>​
 +  ...
 +  Wire.begin(D1,​ D2); /* join i2c bus with SDA=D5 and SCL=D4 of NodeMCU */
 +  ...
 +</​code>​
 +
 +and then enable PWM controller ( pin /EN of PCA9685 is connected to pin D0 of NodeMCU):
 +<​code>​
 +  ...
 +  pinMode( D0, OUTPUT );  // define pin D0 as output ​
 +  digitalWrite( D0, LOW); // enable PWM
 +  ...
 +</​code>​
 +
 +===Step 4===
 +Turn the desired led to any PWM level from 0 to 4095:
 +<note tip>
 +  The diodes are numbered from 0 to 3
 +</​note>​
 +<note tip>
 +  PWM level 0 means that LED isswitch off and level value 4095 means that diode is full-on.
 +</​note>  ​
 +
 +<​code>​
 +    ...
 +    ledDriver.setLEDDimmed( number , level);
 +    ...
 +</​code>​
 +   
 +<note important>​
 +  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.
 +</​note> ​
 +
 +===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.
 +
 +==== U5: Measuring RGB light components using I2C extender/​gpio multiplexer ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== B5: Controlling light colour (cold/warm) ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== M4: Light balancing between two rooms ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== M5: Keeping constant light conditions including ambient light ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== 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 4x20 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.
 +
 +=== 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:
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ESP8266WiFi.h>​
 +#include <​LiquidCrystal_I2C.h>​
 +...
 +</​code>​
 +== Step 2 ==
 +Give it some definitions as identifiers for cleaner code:
 +<code c>
 +#define wifi_ssid "​internal.IOT"​
 +#define wifi_password "​IoTlab32768"​
 +</​code>​
 +<note important>​Always refer to the node documentation to ensure you know current SSID and passphrase. They may differ to those in the code above!</​note>​
 +
 +== 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:
 +<code c>
 +  delay(10);
 +  WiFi.mode(WIFI_STA);​
 +  WiFi.begin(wifi_ssid,​ wifi_password);​
 +  n=0;
 +</​code>​
 +<note important>''​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.</​note>​
 +<note tip>''​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 check your SSID and passphrase.</​note>​
 +<note warning>​Please,​ explicitly use interface mode setting: ''​WiFi.mode(WIFI_STA);''​. See FAQ section for details.</​note>​
 +
 +== Step 4 ==
 +Check if connected, if not, give it next attempt:
 +<code c>
 +while (WiFi.status() != WL_CONNECTED) {
 +    lcd.setCursor(0,​1);​
 +    n++;
 +    sprintf(buffer,"​Attempt %d",​n);​
 +    lcd.print(buffer);​
 +    delay(1000);​
 +</​code>​
 +
 +== Step 5 ==
 +When connected, show details to the camera:
 +<code c>
 +  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());​
 +</​code>​
 +<note tip>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.</​note>​
 +== 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. 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!
 +
 +==== U6: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== U10: ====
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. MQTT library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +===== Controller module basics=====
 +
 +
 +==== Introduction ​ ====
 +This chapter describes the IOT ITT controller module. Controller module is necessary for for any other module to work. 
 +
 +{{:​en:​iot_homelab_kit:​hardware:​controller.png?​200|}}
 +
 +==== Prerequisites ====
 +General knowledge of MQTT protocol: topics, brokers, subscribe, publish.
 +General knowledge on microcontrollers and Arduino IDE.
 +
 +==== Technical details ====
 +
 +The ITT IoT controller module is based on the Wemos D1 Mini controller. Its pinout can be seen in the following schematic.
 +
 +{{:​en:​iot_homelab_kit:​hardware:​d1mini_pinout.png?​300|}}
 +
 +===== Specifications=====
 +  * 11 digital input/​output pins
 +  * Micro USB connector
 +  * Compatible with ArduinoIDE
 +  * Compatible with  nodemc
 +  * 4 MB flash-memory
 +
 +===== 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
 +
 +=== Actuators ===
 +As this is the controller module, no actuators or sensors are installed to it.
 +
 +=== Software, libraries and externals ===
 +To program the controller module ITTIoT libary is used. This is a custom libary made specifically for ITT IoT kits. It aims to make the board easier to use with simple but yet effective methods.
 +
 +<table Ref.Tab.1.1>​
 +<​caption>​List of ITTIoT methods</​caption>​
 +^ 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 primarly used to subscribe into 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 topic, String msg) | User defined method that is called when the controller receives a message from one 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 topic, String msg, bool retain) | Publishes the message "​msg"​ to the topic "​topic"​. Boolean retain informs the broker if the message should be saved into the memory of the broker.|
 +</​table>​
 +
 +=== Communication ===
 +The user can connect to and program 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 subscribe to and publish messages to the topics.
 +
 +===== RGB LED module =====
 +This laboratory is located in the office of ITT Group in Tallinn, Estonia.
 +
 +==== Introduction ​ ====
 +This laboratory consists of a 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 signaling part of other more complicated systems.
 +
 +{{:​en:​iot_homelab_kit:​hardware:​led2.png?​200 |}}
 +
 +==== Prerequisites ====
 +General knowledge of MQTT protocol: topics, brokers, subscribe, publish.
 +
 +==== 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 libaries 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.
 +
 +==== Hands-on labs ====
 +
 +=== Example code ===
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ittiot.h>​
 +#include <​Adafruit_NeoPixel.h>​
 +
 +#define PIN            D2
 +
 +// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
 +// 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);​
 +
 +  pixels.setPixelColor(0,​ r.toInt(), g.toInt(), b.toInt()); // Moderately bright green color.
 +
 +  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!"​);​
 +}
 +
 +void setup()
 +{
 +  Serial.begin(115200);​
 +  Serial.println("​Booting"​);​
 +
 +  iot.printConfig();​ // print json config to serial //Peale Serial.begin ja enne iot.setup
 +  iot.setup();​
 +
 +  pixels.begin();​ // This initializes the NeoPixel library.
 +}
 +
 +void loop()
 +{
 +  iot.handle();​
 +  delay(200);
 +}
 +</​code>​
 +
 +=== Study scenarios ===
 +
 +//List study scenarios (hands-on labs), linking to the Dokuwiki pages with hands-on labs descriptions (there should be a separate page for each scenario). Classify each scenario and refer to the target group using starting keywords:
 +  * Beginners
 +  * Undergraduates
 +  * Masters
 +  * Professionals
 +Note, assume that more professional group automatically contains less professional ones. Note - use language and as appropriate to the target group, i.e.://
 +<​code>​
 +  * Beginners: Elementary operations on the Arduino 2x16 LCD screen.
 +  * Undergraduates:​ Visualizing temperature and humidity on the remote screen.
 +  * Masters: Using power saving states to limit power consumption.
 +</​code>​
 +==== Support ====
 +//Give some information on how to access help, how to get support in case of the trouble etc.//
 +
 +==== RGB LED module: Remote lights ====
 +This is a simple example of programming the LED module to show different colors.
 +
 +=== Target group ===
 +This hands-on lab guide is intended for the Beginners.
 +
 +=== Prerequisites ===
 +Understanding how a RGB LED works.
 +
 +=== Scenario ===
 +In this scenario, the user will program a IoT controller connected to a RGB LED module to display different colors. The commands to show and switch colors will be given over MQTT network.
 +
 +=== Result ===
 +As a result the user can control the RGB LED with MQTT commands.
 +
 +=== Start ===
 +In the beginning make sure you are connected to the IoT controller with RGB LED module.
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +The user can check from the webcam feed if the commands are working.
 +
 +=== 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.
 +//
 +
 +===== Temperature and humidity sensor module =====
 +This laboratory is located in the office of ITT Group in Tallinn, Estonia.
 +
 +==== 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.
 +
 +{{:​en:​iot_homelab_kit:​hardware:​hum2.png?​200|}}
 +
 +==== Prerequisites ====
 +For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing.
 +
 +==== 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 analog 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 ===
 +
 +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.
 +
 +==== Hands-on labs ====
 +
 +=== Example code ===
 +
 +<code c>
 +#include <​Arduino.h>​
 +#include <​ittiot.h>​
 +
 +#include <​DHT.h>​
 +#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 //Peale Serial.begin ja enne iot.setup
 +  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);​
 +}
 +</​code>​
 +
 +=== Study scenarios ===
 +
 +//List study scenarios (hands-on labs), linking to the Dokuwiki pages with hands-on labs descriptions (there should be a separate page for each scenario). Classify each scenario and refer to the target group using starting keywords:
 +  * Beginners
 +  * Undergraduates
 +  * Masters
 +  * Professionals
 +Note, assume that more professional group automatically contains less professional ones. Note - use language and as appropriate to the target group, i.e.://
 +<​code>​
 +  * Beginners: Elementary operations on the Arduino 2x16 LCD screen.
 +  * Undergraduates:​ Visualizing temperature and humidity on the remote screen.
 +  * Masters: Using power saving states to limit power consumption.
 +</​code>​
 +==== Support ====
 +//Give some information on how to access help, how to get support in case of the trouble etc.//
 +
 +==== Smart climate system (with relay module) ====
 +
 +The aim of this scenario is to create a smart climate system that consists of two nodes: a sensor node that measures the temperature and humidity and a relay node that controls the ventilator that can be used to stabilize the temperature.
 +
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +===== Servo module =====
 +This laboratory is located in the office of ITT Group in Tallinn, Estonia.
 +
 +==== Introduction ​ ====
 +This laboratory can be used to practice controlling the servo motor attached to the controller.
 +
 +{{:​en:​iot:​examples:​servopicture2.jpg?​300|}}
 +
 +==== Prerequisites ====
 +For this laboratory, the student should understand basic MQTT concepts like topics, broker, subscribing and publishing.
 +
 +==== 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 Ref.Tab.1.1>​
 +<​caption>​Servo specifications</​caption>​
 +^ 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 |
 +</​table>​
 +
 +=== 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.
 +
 +==== Hands-on labs ====
 +
 +=== Example code ===
 +
 +<code c>
 +/*
 + * 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 <​Arduino.h>​
 +#include <​Servo.h>​
 +#include <​ittiot.h>​
 +
 +//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)
 +{
 +  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);
 +}
 +
 +</​code>​
 +
 +=== Study scenarios ===
 +//List study scenarios (hands-on labs), linking to the Dokuwiki pages with hands-on labs descriptions (there should be a separate page for each scenario). Classify each scenario and refer to the target group using starting keywords:
 +  * Beginners
 +  * Undergraduates
 +  * Masters
 +  * Professionals
 +Note, assume that more professional group automatically contains less professional ones. Note - use language and as appropriate to the target group, i.e.://
 +<​code>​
 +  * Beginners: Elementary operations on the Arduino 2x16 LCD screen.
 +  * Undergraduates:​ Visualizing temperature and humidity on the remote screen.
 +  * Masters: Using power saving states to limit power consumption.
 +</​code>​
 +==== Support ====
 +//Give some information on how to access help, how to get support in case of the trouble etc.//
 +
 +==== Servo module: Waving servo ====
 +In this scenario, the user will program the servo to perform a predefined set of actions (like waving).
 +
 +
 +
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +==== Servo lock (with RGB LED module) ====
 +
 +In this scenario the user will program a controller module connected to a servo module to open the "​latch"​ (servo) when a correct password has been inserted. The RGB LED will provide status information (Green for open, red for closed, blinking red for wrong password inserted)
 +
 +//Give few words about this scenario. Provide some objectives and impact on the students.//
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +===== Relay module =====
 +This laboratory is located in the office of ITT Group in Tallinn, Estonia.
 +
 +==== Introduction ​ ====
 +This laboratory can be used to practice controlling the relay module attached to the controller.
 +
 +{{:​en:​iot_homelab_kit:​hardware:​relee.png?​300|}}
 +
 +==== 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.
 +
 +==== Technical details ====
 +This laboratory consists of a relay module attached to the ITT IoT controller module. Relay module is an electrically operated switch of 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.
 +
 +=== 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.
 +
 +==== Hands-on labs ====
 +
 +=== Example code ===
 +
 +<code c>
 +
 +#include <​Arduino.h>​
 +#include <​ittiot.h>​
 +
 +#define RELAY_PIN 5
 +
 +// If 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 //Peale Serial.begin ja enne iot.setup
 +  iot.setup();​
 +  pinMode(RELAY_PIN,​ OUTPUT);
 +}
 +
 +void loop()
 +{
 +  iot.handle();  ​
 +  delay(200);
 +}
 +
 +
 +</​code>​
 +
 +=== Study scenarios ===
 +
 +//List study scenarios (hands-on labs), linking to the Dokuwiki pages with hands-on labs descriptions (there should be a separate page for each scenario). Classify each scenario and refer to the target group using starting keywords:
 +  * Beginners
 +  * Undergraduates
 +  * Masters
 +  * Professionals
 +Note, assume that more professional group automatically contains less professional ones. Note - use language and as appropriate to the target group, i.e.://
 +<​code>​
 +  * Beginners: Elementary operations on the Arduino 2x16 LCD screen.
 +  * Undergraduates:​ Visualizing temperature and humidity on the remote screen.
 +  * Masters: Using power saving states to limit power consumption.
 +</​code>​
 +==== Support ====
 +//Give some information on how to access help, how to get support in case of the trouble etc.//
 +
 +==== Relay module: Switching the relay ====
 +In this scenario, student will program the controller connected to the relay module, so that it switches when a command is given over MQTT.
 +
 +=== Target group ===
 +//This hands-on lab guide is intended for the Beginners/​Undergraduates/​Masters/​Professionals. Choose appropriate.//​
 +
 +=== Prerequisites ===
 +//Provide prerequisite readings/​hardware/​software/​software libraries/​skills if other than stated in the Laboratory Description. If none, remove along with the header. Please note some of those may be common for all scenarios (i.e. mqtt library), so provide it in the laboratory description level, not in the scenario level.//
 +
 +=== Scenario ===
 +//Describe scenario to let the user understand its idea and process. Write information about the approach, algorithm, etc. (depends on the lab). Provide useful information about protocols, assumptions,​ addresses (i.e. communication servers), credentials,​ etc.//
 +
 +=== Result ===
 +//Describe expected result when scenario is finished.//
 +
 +=== Start ===
 +//Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like,  etc.//
 +
 +=== Steps ===
 +// Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).//
 +== Step 1 ==
 +//Describe activities done in Step 1.//
 +
 +...
 +
 +== Step n ==
 +//Describe activities done in Step n.//
 +
 +=== Result validation ===
 +//Provide some result validation methods, for self assesment.//​
 +
 +=== 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.
 +//
 +
 +/​home/​www/​roboticlab/​homelab_data/​pages/​en/​iot-open/​remotelab/​itt/​OLEDscreen.txt---
 + ​MISSING PAGE ---
 +/​home/​www/​roboticlab/​homelab_data/​pages/​en/​iot-open/​remotelab/​itt/​OLEDscreen/​b1.txt---
 + ​MISSING PAGE ---
 +/​home/​www/​roboticlab/​homelab_data/​pages/​en/​iot-open/​remotelab/​itt/​OLEDscreen/​m1.txt---
 + ​MISSING PAGE ---
 +===== SmartMe Network Laboratory: Arduino Nodes 1-5 =====
 +/* //Give an information,​ where laboratory is located (partner name) and very short description (like one sentence).//​ */
 +
 +The SmartMe lab is located at the Engineering building of the University of Messina, in Messina, Italy. ​
 +
 +==== Introduction ​ ====
 +/* //Here provide some general idea of the laboratory. Do not use very complicated phrases. It is to be understood by people with limited understanding of the technology. Photos, schematics, and drawings may be attached as well.//
 +//Write objectives for the laboratory i.e. "its purpose is to model ...." or "​simulate",​ or simply to "​practice"​. Write some objectives. Provide a link to the live video stream (if any).// */
 +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 practicing 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 Raspbery 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.
 +
 +==== Prerequisites ====
 +/* //Describe prerequisite readings, software, hardware (if any) - note - only those that apply to ALL scenarios, knowledge necessary to understand. I case single scenario requires some extra knowledge/​prerequisites,​ provide it with the scenario document, not here.// */
 +
 +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).
 +
 +
 +==== Technical details ====
 +/* //Provide technical details on the construction of the laboratory, both hardware, and software. Use technical words and sentences. It is to be understood by technology-related people. Consider it as a kind of laboratory hardware and eventually software implementation. Sections below (remove section if not present) present details. Provide circuit, essential mechanical schema, if necessary to use the laboratory and understand its physics/​mechanics,​ etc.// */
 +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 
 +
 +{{ :​en:​iot-open:​remotelab:​ume:​umelab.png?​500 |UME Distance Lab Nodes 1-5}}
 +
 +
 +=== Node schematic ===
 +All Arduino nodes are configured as reported in the following schematic
 +{{ :​en:​iot-open:​remotelab:​ume:​nodo.png?​850 | Nodes 1-5 schematic}}
 +
 +
 +=== Sensors ===
 +/* //Describe sensors (if any). Provide details on measured values, connection details, accuracy, protocols, its relation to the physical/​mechanical part of the laboratory (if any). Add photos and schematics, where the sensor is located. In case the sensor is virtual, do not expose it - present as physical until it is essential to know it regarding study (i.e. code implementation,​ timings, etc.). Provide links to external resources regarding i.e. necessary libraries, protocol definition, etc.// */
 +
 +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.
 +
 +/​*{{tablelayout?​colwidth="​20px,​30px"&​rowsHeaderSource=1&​rowsVisible=2&​float=right}}*/​
 +^ Parameter ^ DHT11 ^ DHT22 ^
 +|Operating Voltage | 3 to 5V| 3 to 5V |
 +|Operating Current | 0.3mA (measuring) 60uA (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 |More Accurate |
 +|Resolution | 16-bit ​ Temperature and Humidity|16-bit Temperature and Humidity|
 +|Accuracy| ±1°C and ±1% |±0.5°C and ±1%|
 +|Sampling period|1 second|2 second |
 +|Price|$1 to $5|$4 to $10 |
 +
 +
 +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 on 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 digital interface. The working principle of such sensor consists into produce scattering by using a laser to radiate suspending particles in the air, then collect scattering light in 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 diameter 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 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/​mikroelektronika-mikroe-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-for-pms7003.html
 +
 +[5]https://​kamami.com/​voltage-level-converters/​234535-logic-level-converter-bi-directional.html
 +
 +=== Actuators ===
 +/* //Describe actuators, their impact on the physical/​mechanical part of the laboratory device, limits, connections,​ etc. Add photos and schematics, where the actuator is located. In case the actuator is virtual, do not expose it - present as physical until it is essential to know it regarding study (i.e. code implementation,​ timings, etc.). Provide links to external resources regarding i.e. necessary libraries, protocol definition, etc.// */
 +There are no mechanical actuators in this laboratory. ​
 +Each node is equipped with a 2x16 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 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 2x16 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 <​LiquidCrystal.h>​ 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-studio-c/?​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 in the project.
 +
 +
 +=== Software, libraries and externals ===
 +/* //Provide a list of software, software libraries and external resources (i.e. files) necessary during code development. Please note, write here only common for all hands-on-labs scenarios (there is a relevant section in scenario template. Remove this section if empty.// */
 +
 +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 [[https://​github.com/​arduino-libraries/​LiquidCrystal|"​Liquid Crystal Library for Arduino"​]]. ​
 +The LCD control library can be imported to the source code via:
 +<code c>
 +#include <​LiquidCrystal.h>​
 +</​code>​
 +
 + Then configure your LCD controller:
 +
 +<code c>
 +// initialize the library with the numbers of the interface pins
 +LiquidCrystal lcd(7, 6, 5, 4, 13, 2);
 +</​code>​
 + 
 + 
 +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:
 +<code c>
 +#include <​DHT.h>​
 +</​code>​
 + 
 +  Then configure your DHT sensor:
 +<code c>
 +#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);
 +</​code>​
 +
 +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:
 +<code c>
 +#include "​PMS.h"​
 +</​code>​
 + 
 +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. ​
 +<code c>
 +#include <​SoftwareSerial.h>​
 +SoftwareSerial mySerial(9,​10);​ // Arduino Rx and Tx ports
 +</​code>​
 + 
 + 
 +Arduino Ethernet Shield requires a dedicated library. With the Arduino Ethernet Shield, the library “Ethernet” allows an Arduino board to connect to the Internet.
 +The Arduino Ethernet Shield library can be imported to the source code via:
 +<code c>
 +#include <​Ethernet.h>​
 +</​code>​
 + 
 +   Then configure your Ethernet Shield:
 +<code c>
 +// 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
 +</​code>​
 + 
 +MQTT connectivity protocol requires a dedicated library. The “MQTT” 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:
 +<code c>
 +#include <​MQTT.h>​
 +</​code>​
 + 
 +“platformio.ini” (Project Configuration File) 
 +The Project configuration file is named platformio.ini. ​
 +<​code>​
 +[env:uno]
 +platform = atmelavr
 +board = uno
 +framework = arduino
 + 
 +lib_ldf_mode=deep+
 +lib_compat_mode=strict
 + 
 +lib_deps =
 + DHT sensor library@1.3.0
 + ​Adafruit Unified Sensor@1.0.3
 + ​Ethernet@2.0.0
 + ​MQTT@2.4.3
 + ​PMS@1.1.0
 + 
 +lib_deps_external =
 + ​https://​github.com/​arduino-libraries/​LiquidCrystal.git#​1.0.7
 +</​code>​
 +
 +
 +
 +
 +=== Communication ===
 +/​*//​Describe communication if it is implemented and sealed (not intended to be implemented by students, or provided i.e. as default code). Present data flow. Describe protocols and details i.e. key-value pairs, etc. Provide how exceptions are handled.//​*/​
 +
 +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. 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.
 +
 +{{ :​en:​iot-open:​remotelab:​ume:​mqtt_-publish_and_subscribe_system_.png?​500 |}}
 +
 +
 +=== Limits ===
 +/*//Provide information about limits on usage, i.e. need for maintenance/​service break, access mode (parallel, booking, etc.), manual mechanical reset, etc.//*/
 +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. 
 +
 +
 +==== Hands-on labs ====
 +/*//List study scenarios (hands-on labs), linking to the Dokuwiki pages with hands-on labs descriptions (there should be a separate page for each scenario). Classify each scenario and refer to the target group using starting keywords:
 +  * Beginners
 +  * Undergraduates
 +  * Masters
 +  * Professionals
 +Note, assume that more professional group automatically contains less professional ones. Note - use language and as appropriate to the target group, i.e.://*/
 +
 +  * Beginners: ​
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​b1|B1:​ Basic operations on the 2x16 LCD screen.]]
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​b2|B2:​ Showing temperature and humidity values on the LCD.]]
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​b3|B3:​ PWM mode (~) of digital pins, programming threshold values.]]
 +  * Undergraduates: ​
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​u1|U1:​ Showing temperature,​ humidity and dust values on the 2x16 LCD screen]]
 +  * Masters:
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​m1|M1:​ MQTT to publish a message]]
 +     * [[en:​iot-open:​remotelab:​ume:​smartme:​m2|M2:​ MQTT to subscribe to a topic to receive messages]] ​
 +
 +==== Support ====
 +/*//Give some information about how to access help, how to get support in case of the trouble etc.//*/
 +gmerlino@unime.it,​ rdipietro@unime.it ​
 +
 +
 +====== Project ideas on IoT ======
 +Following chapter present some ideas of the IoT project, one may implement starting from scratch and developing as presented or introducing own customisation. As IoT is a wide idea applying to many different areas we present only a selected number of proposals.
 +
 +
 +
 +    * [[en:​iot-open:​project:​project1]][*]
 +    * [[en:​iot-open:​project:​project2]][*]
 +    * [[en:​iot-open:​getting_familiar_with_your_hardware_rtu_itmo_sut:​raspberrypi_rpi:​applciation_example_projects]][*]
 +    * [[en:​iot-open:​project:​project3]][**]
 +
 +===== Distributed sensor network =====
 +
 +==== Introduction ====
 +
 +The distributed sensor network is a classic example of the Internet of Things application. Information is gathered from different locations and based on the data controller system makes decisions and controls actuators which can also be in different places. The classical distributed sensor network is a weather station all over the world or traffic monitoring systems in transportations. ​
 +In this project, we will develop and implement a simple distributed sensor network solution to illustrate the concept and logic of the system.
 +Although the real-life distributed sensor network is expected to have hundreds of sensors, the minimum number of sensors is still at least 2 items. For simplification and cost efficiency in this task, we will have minimal setup and simple operation.
 +
 +==== Task ====
 +
 +You need to create a simple sensor system which monitors the temperature and humidity in the different locations of the room. Based on sensor data you need to set ventilation fan on and off. If the combination of temperature and humidity in the different places of the room is exceeding a certain limit, run the fan on the window. Stopping the fan must be defined again by the input from the sensors but triggering values must be different than starting the fan. Temperature and humidity values, which trigger fan, can be selected by the student, according to the present condition and the experiment room.
 +
 +
 +==== Hardware description ====
 +
 +
 +==== Remote lab instructions ====
 +
 +  - Log into your account at [[http://​distance.roboticlab.eu|distance.roboticlab.eu]].
 +  - From under "My site" go to "My devices"​.
 +  - If you already have something booked then click on the "​Book"​ link or icon.
 +  - Choose available IoT device.
 +  - Click on the "​Book"​ link or icon.
 +  - Choose your preferred end date by clicking on the empty field and then clicking on a date. Press save when you are done.
 +  - Go back to "My devices"​ and choose the IoT device.
 +  - In the code editor window click on the "​Select Files" and under "​Example Files" choose "​IoT_DHT_Example.cpp"​ and "​IoT_Relay_Example.cpp"​.
 +  - Start coding.
 +
 +Running your code:
 +  - While having the code you want to run open click on "​Compile"​.
 +  - Wait for the compiler to finish and check for errors.
 +  - If the compiler was successful, then click on "​Execute"​.
 +
 +Saving your code:
 +  - While having the code you want to save open click on "Save file as..".
 +  - Enter a name for your code and press "​Ok"​.
 +  - To open your code, you can choose it from under "User files"​.
 +
 +==== Steps to solve the problem ====
 +
 +  - Study temperature and humidity sensor working principles and the output signal
 +  - Study control hardware and messaging logic
 +  - Develop a distributed sensor network concept
 +  - Connect hardware and interface them with remote programming lab
 +  - Make a software code for all nodes in the system
 +  - Run the code and validate the results
 +===== Controlling the GPIO pins on Raspberry Pi board =====
 +The aim of this exercise is to prepare software written in the C# language under Windows 10 Core system for Raspberry Pi 3 board. The software application blinks LEDS connected to the appropriate Raspberry Pi GPIO pin ports in specific order. The hardware module contains 4 red LEDS which can be turned on/off using Windows 10 GPIO SDK functions.
 +
 +==Step 1==
 +Hardware preparation. Mount the LEDs module into 40-pin Raspberry Pi connector.
 +<figure label>
 +{{ :​en:​iot-open:​getting_familiar_with_your_hardware_rtu_itmo_sut:​raspberrypi_rpi:​sft1.png?​300 |}}<​caption>//​Electronic schematic of the LEDs module//</​caption>​
 +</​figure>​
 +<figure label>
 +{{ :​en:​iot-open:​getting_familiar_with_your_hardware_rtu_itmo_sut:​raspberrypi_rpi:​sft3.png?​300 |}}<​caption>//​Electronic board of the LEDs module//</​caption>​
 +</​figure>​
 +
 +==Step 2==
 +To control selected GPIO pins in C# language available for UWP platform create the UWP solution as it was described in the //Hello World!// application. In the MainPage.cs file add the source code:
 +<code c>
 +/​********************************************************************************************************************************
 + *
 + ​* ​                                             SAMPLE GPIO CONTROL PROGRAM
 + *
 + ​* ​ Sample LED control program for students laboratory purposes. ​
 + ​* ​ Presents the Raspberry Pi 2/3 IoT ability to control
 + ​* ​ GPIO output pins blinking LEDs.
 + *
 + *
 + ​* ​       Raspberry Pi GPIO Layout - Model B+
 + ​* ​ 1 - 3V3     ​Power ​                     2 - 5V Power
 + ​* ​ 3 - GPIO2   SDA1 I2C                   4 - 5V Power
 + ​* ​ 5 - GPIO3   SCL1 I2C                   6 - GND
 + ​* ​ 7 - GPIO4                              8 - GPIO14 ​  ​UART0_TXD
 + ​* ​ 9 - GND                               10 - GPIO15 ​  ​UART0_RXD
 + * 11 - GPIO17 ​                           12 - GPIO18 ​  ​PCM_CLK
 + * 13 - GPIO27 ​                           14 - GND
 + * 15 - GPIO22 ​                           16 - GPIO23
 + * 17 - 3V3     ​Power ​                    18 - GPIO24
 + * 19 - GPIO10 ​ SPI0_MOSI ​                20 - GND
 + * 21 - GPIO9   ​SPI0_SCLK ​                22 - GPIO25
 + * 23 - GPIO11 ​                           24 - GPIO8    SPI0_CE0_N
 + * 25 - GND                               26 - GPIO7    SPI0_CE1_N ​
 + * 27 - ID_SD   I2C ID EEPROM ​            28 - ID_SC    I2C ID EEPROM
 + * 29 - GPIO5                             30 - GND
 + * 31 - GPIO6                             32 - GPIO12
 + * 33 - GPIO13 ​                           34 - GND
 + * 35 - GPIO19 ​                           36 - GPIO16
 + * 37 - GPIO26 ​                           38 - GPIO20
 + * 39 - GND                               40 - GPIO21
 + *
 + ​********************************************************************************************************************************/​
 +
 +using System;
 +using Windows.Devices.Gpio;​
 +using Windows.UI.Xaml;​
 +using Windows.UI.Xaml.Controls;​
 +using Windows.UI.Xaml.Media;​
 +
 +namespace LEDTest
 +{
 +  public sealed partial class MainPage : Page
 +  {
 +    // Raspberry Pi GPIO pins used for LEDs coontrol ​
 +    private const int LED_PIN1 = 4;   // GPIO04
 +    private const int LED_PIN2 = 23;  // GPIO23
 +    private const int LED_PIN3 = 24;  // GPIO24
 +    private const int LED_PIN4 = 12;  // GPIO12
 +
 +    private GpioPin pin1;
 +    private GpioPin pin2;
 +    private GpioPin pin3;
 +    private GpioPin pin4;
 +
 +    // Raspberry Pi GPIO Pin variables for blinking effect
 +    private GpioPinValue[] pinValue1 = new GpioPinValue[8];​
 +    private GpioPinValue[] pinValue2 = new GpioPinValue[8];​
 +    private GpioPinValue[] pinValue3 = new GpioPinValue[8];​
 +    private GpioPinValue[] pinValue4 = new GpioPinValue[8];​
 +
 +    private DispatcherTimer timer;
 +    private SolidColorBrush redBrush ​ = new SolidColorBrush(Windows.UI.Colors.Red);​
 +    private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray);​
 +    private int Counter = 0;
 +
 +    public MainPage() {
 +      InitLEDs(); ​                                          // Initialize LEDs blinking procedure
 +      InitializeComponent(); ​                               // Initialize XAML Display view
 +
 +      timer = new DispatcherTimer(); ​                       // define the timer
 +      timer.Interval = TimeSpan.FromMilliseconds(500); ​     // set callback timer to execute each 500 ms
 +      timer.Tick += Timer_Tick; ​                            // register callback procedure
 +      InitGPIO(); ​                                          // Initialze GPIO pins
 +
 +      if ((pin1 != null) && (pin2 != null) && (pin3 != null) && (pin4 != null)) {
 +        timer.Start(); ​                                     // start the timer
 +      }        ​
 +    }
 +    // Initial LEDs state 8 stages
 +    void InitLEDs()
 +    {
 +      pinValue1[0] = GpioPinValue.High; ​                    // pins value state 0
 +      pinValue2[0] = GpioPinValue.Low;​
 +      pinValue3[0] = GpioPinValue.Low;​
 +      pinValue4[0] = GpioPinValue.Low;​
 +
 +      pinValue1[1] = GpioPinValue.High; ​                    // pins value state 1
 +      pinValue2[1] = GpioPinValue.High;​
 +      pinValue3[1] = GpioPinValue.Low;​
 +      pinValue4[1] = GpioPinValue.Low;​
 +
 +      pinValue1[2] = GpioPinValue.High; ​                    // pins value state 2
 +      pinValue2[2] = GpioPinValue.High;​
 +      pinValue3[2] = GpioPinValue.High;​
 +      pinValue4[2] = GpioPinValue.Low;​
 +
 +      pinValue1[3] = GpioPinValue.High; ​                    // pins value state 3
 +      pinValue2[3] = GpioPinValue.High;​
 +      pinValue3[3] = GpioPinValue.High;​
 +      pinValue4[3] = GpioPinValue.High;​
 +
 +      pinValue1[4] = GpioPinValue.Low; ​                     // pins value state 4
 +      pinValue2[4] = GpioPinValue.High;​
 +      pinValue3[4] = GpioPinValue.High;​
 +      pinValue4[4] = GpioPinValue.High;​
 +
 +      pinValue1[5] = GpioPinValue.Low; ​                     // pins value state 5
 +      pinValue2[5] = GpioPinValue.Low;​
 +      pinValue3[5] = GpioPinValue.High;​
 +      pinValue4[5] = GpioPinValue.High;​
 +
 +      pinValue1[6] = GpioPinValue.Low; ​                     // pins value state 6
 +      pinValue2[6] = GpioPinValue.Low;​
 +      pinValue3[6] = GpioPinValue.Low;​
 +      pinValue4[6] = GpioPinValue.High;​
 +
 +      pinValue1[7] = GpioPinValue.Low; ​                     // pins value state 7
 +      pinValue2[7] = GpioPinValue.Low;​
 +      pinValue3[7] = GpioPinValue.Low;​
 +      pinValue4[7] = GpioPinValue.Low;​
 +    }
 +    // Initialize device GPIO. All LEDs control pins set to the output state
 +    private void InitGPIO()
 +    {
 +      var GPIO = GpioController.GetDefault();​
 +
 +      // Show an error if there is no GPIO controller
 +      if (GPIO == null) {
 +        pin1 = null;
 +        pin2 = null;
 +        pin3 = null;
 +        pin4 = null;
 +
 +        Time.Text = "There is no GPIO controller on this device.";​
 +        return;
 +      }
 +      pin1 = GPIO.OpenPin(LED_PIN1);​
 +      pin2 = GPIO.OpenPin(LED_PIN2);​
 +      pin3 = GPIO.OpenPin(LED_PIN3);​
 +      pin4 = GPIO.OpenPin(LED_PIN4);​
 +
 +      pin1.Write(pinValue1[0]); ​                    // set pin1 state LOW/HIGH
 +      pin1.SetDriveMode(GpioPinDriveMode.Output);​
 +      pin2.Write(pinValue2[0]); ​                    // set pin2 state LOW/HIGH
 +      pin2.SetDriveMode(GpioPinDriveMode.Output);​
 +      pin3.Write(pinValue3[0]); ​                    // set pin3 state LOW/HIGH
 +      pin3.SetDriveMode(GpioPinDriveMode.Output);​
 +      pin4.Write(pinValue4[0]); ​                    // set pin4 state LOW/HIGH
 +      pin4.SetDriveMode(GpioPinDriveMode.Output);​
 +
 +      Time.Text = "GPIO pins initialized correctly.";​
 +    }
 +    // XAML Timer callback function set to be executed each 500 ms
 +    private void Timer_Tick(object sender, object e) {
 +      LED1.Fill = pinValue1[Counter] == GpioPinValue.High ? redBrush : grayBrush; ​  // Draw LED1 elipse Red/Gray = High/Low
 +      pin1.Write(pinValue1[Counter]); ​                                              // Set pin1 value High/Low
 +      LED2.Fill = pinValue2[Counter] == GpioPinValue.High ? redBrush : grayBrush; ​  // Draw LED2 elipse Red/Gray = High/Low
 +      pin2.Write(pinValue2[Counter]); ​                                              // Set pin2 value High/Low
 +      LED3.Fill = pinValue3[Counter] == GpioPinValue.High ? redBrush : grayBrush; ​  // Draw LED3 elipse Red/Gray = High/Low
 +      pin3.Write(pinValue3[Counter]); ​                                              // Set pin3 value High/Low
 +      LED4.Fill = pinValue4[Counter] == GpioPinValue.High ? redBrush : grayBrush; ​  // Draw LED4 elipse Red/Gray = High/Low
 +      pin4.Write(pinValue4[Counter]); ​                                              // Set pin4 value High/Low
 +      Counter++;
 +      if (Counter > 7)
 +        Counter = 0;
 +    }
 +  }
 +}
 +</​code>​
 +The code defines GPIO pins 4, 23, 24 and 12 as output. GPIO pins can be set as input/​output. ​ Because the board contains already resistors connected to the powers supply and LEDs (see the LEDs module schematic) the GPIO pins are set to turn off the internal //pullup// resistors. Line code 143: ''​pin1.SetDriveMode(GpioPinDriveMode.Output);''​. The program simply loads the state of the LEDs from the Array[8] defined in the InitLEDs void. In the Main void the timer callback function ''​Timer_Tick''​ is registered to change LEDs state each 500ms. Callback function Timer_Tick each 500ms changes the state of the LEDs from ''​GpioPinValue.High''​ to ''​GpioPinValue.Low''​ (line 156). On the display, according to the LEDs state, the 4 circles change colour from red to brush synchronously.
 +
 +==Step 3==
 +In the MainPage.xaml the code looks like:
 +<code c>
 +<Page
 +    x:​Class="​LEDTest.MainPage"​
 +    xmlns="​http://​schemas.microsoft.com/​winfx/​2006/​xaml/​presentation"​
 +    xmlns:​x="​http://​schemas.microsoft.com/​winfx/​2006/​xaml"​
 +    xmlns:​local="​using:​LEDTest"​
 +    xmlns:​d="​http://​schemas.microsoft.com/​expression/​blend/​2008"​
 +    xmlns:​mc="​http://​schemas.openxmlformats.org/​markup-compatibility/​2006"​
 +    mc:​Ignorable="​d">​
 +  <​Grid>​
 +    <​Grid.Background>​
 +      <​ImageBrush x:​Name="​Theme"​ ImageSource="​Assets/​AEI.jpg"​ Stretch="​UniformToFill"/>​
 +    </​Grid.Background>​
 +    <​TextBlock x:​Name="​ZMiTAC"​ HorizontalAlignment="​Center"​ Height="​35"​ Margin="​0,​5,​0,​0"​ TextAlignment="​Center"​ Text="​ZMiTAC IoT Laboratory"​ FontSize="​24"​ VerticalAlignment="​Top"​ Width="​360"​ Foreground="#​FFD02BF5"​ RenderTransformOrigin="​0.489,​2.571"​ FontWeight="​Bold"/>​
 +    <​TextBlock x:​Name="​Time"​ TextAlignment="​Center"​ Margin="​0,​55,​0,​0"​ TextWrapping="​Wrap"​ Text="​500 msec" VerticalAlignment="​Top"​ Foreground="#​FF89F99D"​ FontWeight="​Bold"​ FontSize="​18.667"​ RenderTransformOrigin="​0.5,​1.8"/>​
 +    <Ellipse x:​Name="​LED1"​ Fill="#​FFF4F4F5"​ HorizontalAlignment="​Center"​ Height="​40"​ Margin="​-150,​145,​0,​0"​ Stroke="​Black"​ VerticalAlignment="​Top"​ Width="​40"/>​
 +    <Ellipse x:​Name="​LED2"​ Fill="#​FFF4F4F5"​ HorizontalAlignment="​Center"​ Height="​40"​ Margin="​-50,​145,​0,​0"​ Stroke="​Black"​ VerticalAlignment="​Top"​ Width="​40"​ RenderTransformOrigin="​1.75,​0.714"/>​
 +    <Ellipse x:​Name="​LED3"​ Fill="#​FFF4F4F5"​ HorizontalAlignment="​Center"​ Height="​40"​ Margin="​50,​145,​0,​0"​ Stroke="​Black"​ VerticalAlignment="​Top"​ Width="​40"/>​
 +    <Ellipse x:​Name="​LED4"​ Fill="#​FFF4F4F5"​ HorizontalAlignment="​Center"​ Height="​40"​ Margin="​150,​145,​0,​0"​ Stroke="​Black"​ VerticalAlignment="​Top"​ Width="​40"/>​
 +  </​Grid>​
 +</​Page>​
 +</​code>​
 +
 +==Step 4==
 +Start debugging application and after deploy application package to the board SD card it will be displayed on the monitor.
 +<figure label>
 +{{ :​en:​iot-open:​getting_familiar_with_your_hardware_rtu_itmo_sut:​raspberrypi_rpi:​sft9.png?​300 |}}<​caption>//​LEDsApplication on the Raspberry Pi display//</​caption>​
 +</​figure>​
 +
 +===== Industrial IoT =====
 +
 +==== Introduction ====
 +
 +Industry 4.0 is a concept to digitalise industrial systems and factories. Internet of Things is one of the critical components to be successful in digitalisation. System monitoring, data collection, predictive maintenance,​ energy efficiency and many others are central topics of IoT.
 +
 +In this project, an industrial production line efficiency monitoring system will be developed and demonstrated.
 +
 +==== Task ====
 +
 +{{ :​en:​iot-open:​project:​flexiblemanufactoring.jpg?​300|}}
 +
 +This is the Festo flexible manufacturing line. You need to create a proper sensor system which monitors the machine usage of a particular unit. There will be 3 different workstations which need to be controlled. Current values will be transferred to the operator. The operator must be able to set warning setpoints on which he/she will be notified by a buzzer. For example, when the current rises above the allowed value, the alarm will be sound. ​
 +In this task you need to set up:
 +  *  An encoder that is monitoring the workload of the conveyor belt. The controller will send information about how much the belt has moved.
 +  * A current sensor that is following the electrical power consumed by the machine. The controller will send the current amperage.
 +  * A PIR (Passive infrared) sensor that will monitor human movement in the working area. The controller will send a notification if it detects movement.
 +  *An HMI (Human-Machine Interface) that the operator can use to check the beforementioned data. It must be possible to check the values and the warning setpoints of each of the sensors.
 +
 +{{:​en:​iot-open:​project:​system_diagram_s.png?​700|}}
 +
 +==== Hardware description ====
 + 
 +^ Module ^ Description ^  ​
 +|{{:​en:​iot_homelab_kit:​hardware:​controller.png?​100|}}|**Controller module.** The controller module is a low-cost Wi-Fi chip with full TCP/IP stack and MCU (microcontroller unit) capability. This small module allows microcontrollers to connect to a Wi-Fi network and make simple TCP/IP connections using Hayes-style commands. The controller can be connected with Micro USB connection or with WIFI connection.|
 +|  {{:​en:​iot_homelab_kit:​hardware:​controller2.png?​100}} | **Sensor module.** Sensor module interfaces different sensors and also small actuators like RC servo motor. In this task, the sensor module will be used with the rotary encoder and AC sensor.|
 +|{{:​en:​iot_homelab_kit:​hardware:​pirmodule.png?​100}}|**PIR module.** PIR sensors allow you to sense motion of warm objects; it is almost always used to detect whether a human has moved in or out of the sensors range.|
 +|{{:​en:​iot_homelab_kit:​hardware:​soundmodule.png?​100|}}| **Buzzer module.** Buzzer module purpose is to signal the user when an event occurs. In this task, the buzzer will be sound if measured values go over the warning limits. |
 +|{{:​en:​iot_homelab_kit:​hardware:​buttonshield.png?​100|}}|**Button module.** Button module will be used to interact with the HMI. For example to switch pages.|
 +|{{:​en:​iot_homelab_kit:​hardware:​oled3.png?​100|}}|**OLED module.**OLED module will be used for HMI display.|
 +
 +
 +The current sensor will be attached to the power cables of the machine.
 +
 +{{ :​en:​iot-open:​project:​cursensorassembly.png?​300 |}}
 +
 +The PIR sensor will be positioned above the working area of the machine.
 +
 +{{ :​en:​iot-open:​project:​pirassembly.png?​300 |}}
 +
 +The encoder will be attached to the conveyor belt.
 +
 +{{ :​en:​iot-open:​project:​encassembly.png?​300 |}}
 +
 +And the button module with the HMI module will be on the operator'​s work desk.
 +
 +{{ :​en:​iot-open:​project:​buttonhmiassembly.png?​300 |}}
 +
 +
 +==== Remote lab instructions ====
 +
 +  - Log into your account at [[http://​distance.roboticlab.eu|distance.roboticlab.eu]].
 +  - From under "My site" go to "My devices"​.
 +  - If you already have something booked then click on the "​Book"​ link or icon.
 +  - Choose available IoT device.
 +  - Click on the "​Book"​ link or icon.
 +  - Choose your preferred end date by clicking on the empty field and then clicking on a date. Press save when you are done.
 +  - Go back to "My devices"​ and choose the IoT device.
 +  - In the code editor window click on the "​Select Files" and under "​Example Files" choose the example programs for the modules used in this project.
 +  - Start coding.
 +
 +Running your code:
 +  - While having the code you want to run open click on "​Compile"​.
 +  - Wait for the compiler to finish and check for errors.
 +  - If the compiler was successful, then click on "​Execute"​.
 +
 +Saving your code:
 +  - While having the code you want to save open click on "Save file as..".
 +  - Enter a name for your code and press "​Ok"​.
 +  - To open your code, you can choose it from under "User files"​.
 +
 +==== Steps to solve the problem ====
 +
 +  - Study current sensor and encoder working principles and output signals
 +  - Study control hardware and messaging logic
 +  - Develop a factory monitoring system network concept
 +  - Connect hardware and interface them with remote programming lab
 +  - Make a software code for all nodes in the system
 +  - Run the code and validate the results
  
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0