No ACL setup yet! Denying access to everyone.
en:edu:zmitac:s2:iotn:lab3

Differences

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

Link to this comparison view

Next revision
Previous revision
en:edu:zmitac:s2:iotn:lab3 [2022/03/18 21:57] – created pczekalskien:edu:zmitac:s2:iotn:lab3 [2023/04/21 16:46] (current) – administrator
Line 1: Line 1:
-====== IoT Networks: Laboratory 2 - CoAP ======+====== IoT Networks: Laboratory 3 - CoAP ======
 Network programming for the IoT Devices using CoAP protocol. Network programming for the IoT Devices using CoAP protocol.
  
-Following manual assumes you're familiar with [[en:edu:zmitac:s2:iotn:lab1|InT Networks: Laboratory 1 - Introduction]]. In case you're not, please get yourself familiar with it and spend some time practising. You can start your project stub using hints and guidance in the [[en:edu:zmitac:s2:iotn:lab1|InT Networks: Laboratory 1 - Introduction]] manual and modify it / extend as guided below.+The following manual assumes you're familiar with [[en:edu:zmitac:s2:iotn:lab1|InT Networks: Laboratory 1 - Introduction]]. If you're not, please familiarize yourself with it and spend some time practicing. Start your project stub using hints and guidance in the [[en:edu:zmitac:s2:iotn:lab1|InT Networks: Laboratory 1 - Introduction]] manual and modify it / extend as guided below.
  
-<note important>This manual is not intended to be stand-alone. You need to follow Laboratory 1 manual to prepare basics for the project then continue here.</note>+<note important>This manual is not intended to be stand-alone. You need to follow the Laboratory 1 manual to prepare the basics for the project, then continue here.</note>
  
-<note important>Computers in laboratory rooms 320, 321 and 336 use freezing software which means that for every startup, computers are restored to their initial state.</note>+<note important>Computers in laboratory rooms 320, 321, and 336 use freezing software, which means that for every startup, computers are restored to their initial state.</note>
  
 ==== Hardware ==== ==== Hardware ====
-We do not use any specific hardware here other than an LCD screen to present visual information. If you intend to extend your project and i.e. use a temperature and humidity sensor, refer to the [[en:edu:zmitac:s2:iotn:lab2|IoT Networks: Laboratory 2 - MQTT]] documentation on necessary libraries and configuration.+We do not use any specific hardware here besides an LCD screen to present visual information. If you intend to extend your project and i.e., use a temperature and humidity sensor, refer to the [[en:edu:zmitac:s2:iotn:lab2|IoT Networks: Laboratory 2 - MQTT]] documentation on necessary libraries and configuration.
  
  
 === Hardware-software components and libraries === === Hardware-software components and libraries ===
-Interfacing hardware requires the use of particular GPIOs. Laboratory nodes and hardware used needs specific configuration. Following chunks of code will help to set up proper hardware-software configuration.+Interfacing hardware requires the use of particular GPIOs. Laboratory nodes and hardware used need specific configurations. The following chunks of code will help to set up proper hardware-software configuration.
  
 == LCD display == == LCD display ==
Line 30: Line 30:
 </code> </code>
  
-To initialise it and instantiate controller object, use following GPIO definition and initialisation:+To initialize it and instantiate the controller object, use the following GPIO definition and initialization:
 <code c> <code c>
 const int rs = 12, en = 13, d4 = 4, d5 = 0, d6 = 2, d7 = 14; const int rs = 12, en = 13, d4 = 4, d5 = 0, d6 = 2, d7 = 14;
Line 36: Line 36:
 </code> </code>
  
-It is also necessary to tell the library about the display organisation as there is a variety of configurations possible. Here, the organisation is 2 lines, 16 columns each, so in the code, you need to explicitly initialise it:+It is also necessary to tell the library about the display organization, as various configurations are possible. Here, the organization is 2 lines, 16 columns each, so in the code, you need to explicitly initialize it:
 <code c> <code c>
 ... ...
Line 45: Line 45:
  
 ==== Software ==== ==== Software ====
-String formatting may be a challenge. An easy approach is to allocate a character buffer of the size of the LCD or just one display's line, or any other size, large enough to handle your text.+String formatting may be a challenge. An easy approach is to allocate a character buffer of the size of the LCD or just one display's line, or any other size large enough to handle your text.
 <code c> <code c>
 ... ...
Line 52: Line 52:
 </code> </code>
  
-To convert float into the string with formatting use ''sprintf'' function:+To convert float into the string with formatting, use ''sprintf'' function:
 <code c> <code c>
 ... ...
Line 60: Line 60:
 ... ...
 </code> </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.+<note tip>''sprintf'' uses a number of wildcards rendered with data. Refer to the c/c++ documentation on ''sprintf''. Here <code c>%2.1f</code> means: having a float number render it to string using two digits before the decimal point and one after. The temperature in our lab is always above 10C. <code c>%%</code> is an escape character to print a <code c>%</code> (percent) symbol.
 <code c> <code c>
 delay(time) delay(time)
Line 66: Line 66:
  
 === Software libraries === === Software libraries ===
-Software libraries are needed to handle communication between your IoT device and network and services. In this laboratory, you will connect your device to the WiFi access point (see the Networking section below for credentials) and use UDP (opposite to the Lab2 where you have used TCP). Your device will be automatically given an IP address that you may show on the LCD screen. Once WiFi is connected and works (PHY+MAC+NET layer protocols) then you can instantiate a CoAP client and ask the laboratory server or any other service present in your network (i.e. other device acting as CoAP server) for data or activity.\\+Software libraries are needed to communicate between your IoT device, network, and services. In this laboratory, you will connect your device to the WiFi access point (see the Networking section below for credentials) and use UDP (opposite Lab2, where you have used TCP). Your device will be automatically given an IP address that you may show on the LCD screen. Once WiFi is connected and works (PHY+MAC+NET layer protocols), then you can instantiate a CoAP client and ask the laboratory server or any other service present in your network (i.e., other device acting as CoAP server) for data or activity.\\
  
-The great feature of the CoAP is, you do not need to take care of the instant connection to the service on the application-level protocol. Just reconnecting WiFi, if the connection is dropped, is quite enough. UDP is a "connectionless" protocol and acts more-less as "send and forget", at least on the single message level. Obviously, ACK messages are expected but this approach is so much different to the MQTT on TCP, where connection break is instantly detected and yielded if only happens.+The outstanding feature of the CoAP is you do not need to take care of the instant connection to the service on the application-level protocol. Just reconnecting WiFi, if the connection is dropped, is quite enough. UDP is a "connectionless" protocol and acts more-less as "send and forget", at least on the single message level. Obviously, ACK messages are expected, but this approach is very different from the MQTT on TCP, where a connection break is instantly detected and yielded if it only happens.
  
 == WIFI and UDP == == WIFI and UDP ==
-A WiFi library is already included in the ESP8266 framework for the Arduino programming model, so there is no need to use library manager to add it. All is necessary is to include a header to your C code:+A WiFi library is already included in the ESP8266 framework for the Arduino programming model, so there is no need to use a library manager to add it. All that is necessary is to have a header included to your C code:
 <code c> <code c>
 ... ...
Line 78: Line 78:
 </code> </code>
  
-Then create some constant variables with ''sSsid'' and ''sPassword'' (see Networking section for credentials) and instantiate WiFi communication object:+Then create some constant variables or declare token string identifiers (as below) with ''sSsid'' and ''sPassword'' (see Networking section for credentials) and instantiate the WiFi communication object:
 <code c> <code c>
 ... ...
Line 85: Line 85:
 ... ...
 </code> </code>
-The ''WiFi'' object is a singleton, static one. Try to connect to the AP, i.e. this way:+The ''WiFi'' object is a singleton, static one. Try to connect to the AP, i.e., this way:
 <code c> <code c>
 ... ...
Line 94: Line 94:
  
 Some useful code snippets are below.\\ Some useful code snippets are below.\\
-Checking if WiFi connection is successful:+Checking if the WiFi connection is successful:
 <code c> <code c>
 ... ...
Line 111: Line 111:
 </code> </code>
  
-Once WiFi is connected, it is necessary to use a ''WiFiClient'' object to pass the connection object to the application layer libraries.\\+Once WiFi is connected, it is necessary to use a ''WiFiUDP'' object to pass the connection object to the application layer libraries.\\
 The declaration can be as follows: The declaration can be as follows:
 <code c> <code c>
 ... ...
-  WiFiClient espClient;+  WiFiUDP Udp;
 ... ...
 </code> </code>
-Note, this object becomes automatically active and bound to the ''WiFi'' connection, when available. You do not need explicitly to initialise it or force connect it.+Note this object becomes automatically active and bound to the ''WiFi'' connection when available. You do not need explicitly to initialize it or force connect it. However, you must initialize an object with an appropriate port. The default port for the CoAP server is 5683 (UDP):
  
-== MQTT == 
-To ease and speed up implementation, you will use an MQTT library that implements acting both as a publisher and subscriber ''platformio.ini'' file:  
-<code> 
-lib_deps = ..., PubSubClient, ... 
-</code> 
- 
-<note important>Please note, on the NET protocol level, in this scenario, you're connecting to the WiFi AP (STA), not setting your device to be a WiFi server (AP), so you need to set appropriate WiFi mode, as it may be previously used in AP, not STA mode.</note> 
- 
-MQTT clients need to be instantiated using WiFi client connection, i.e. this way: 
 <code c> <code c>
 ... ...
-#define mqtt_server "<here is your MQTT broker IP or FQDN>" +int port = 5683; //Standard CoAP port 
-#define mqtt_user "<mqtt user>" +
-#define mqtt_password "<mqtt password>" +
-... +
-PubSubClient client(espClient); +
-...+
 </code> </code>
-and in the setup code, you need to initialise the ''client'' with MQTT address and port number. Do not use SSL / TLS encoding as this library is not able to support encrypted communication with MQTT broker: 
 <code c> <code c>
 ... ...
-client.setServer(mqtt_server, 1883);+  Udp.begin(port);
 ... ...
 </code> </code>
  
 +== CoAP ==
 +To ease and speed up implementation, you will use a CoAP library that implements acting both as a client and server. It is necessary to inform the library manager to download and include ''hirotakaster/CoAP simple library'' in the configuration section of the  ''platformio.ini'' file: 
 +<code>
 +lib_deps = ..., hirotakaster/CoAP simple library, ...
 +</code>
  
 +<note important>Please note, on the NET protocol level, in this scenario, you're connecting to the WiFi AP (STA), not setting your device to be a WiFi server (AP), so you need to set the appropriate WiFi mode, as it may be previously used in AP, not STA mode.</note>
  
-Consider encapsulating MQTT connecting process as a separate function, i.e. as below. Note, the code below publishes a hello world message to the broker to emphasize its successful presence in the network:+CoAP client or server both require to be instantiated using WiFi UDP connection (afore initialized ''Udp'' object), i.e., this way:
 <code c> <code c>
-void reconnect() { +... 
-  // Loop until we're reconnected +Coap coap(Udp); 
-  while (!client.connected()) { +...
-    Serial.print("Attempting MQTT connection..."); +
-    // Create a random client ID +
-    String clientId = "ESP8266Client-"; +
-    clientId += String(random(0xffff), HEX); +
-    // Attempt to connect +
-    if (client.connect(clientId.c_str(),mqtt_user,mqtt_password)) { +
-      Serial.println("connected"); +
-      // Once connected, publish an announcement... +
-      client.publish("outTopic", "hello world"); +
-      // ... and resubscribe +
-      client.subscribe("#"); +
-    } else { +
-      Serial.print("failed, rc="); +
-      Serial.print(client.state()); +
-      Serial.println(" try again in 5 seconds"); +
-      // Wait 5 seconds before retrying +
-      delay(5000); +
-    } +
-  } +
-}+
 </code> </code>
  
-Receiving MQTT message is done with the use of the asynchronously called callback function, i.e. like this one (it switches on and off the LED):+Because UDP is asynchronous due to its nature, each transaction (sending a request and waiting for the response) must be handled asynchronously. For this purpose, we need to use callbacks. 
 +The sample callback function may have the following parameters:
 <code c> <code c>
 ... ...
-void callback(char* topic, byte* payload, unsigned int length) { +void callback_response(CoapPacket &packet, IPAddress ip, int port); //this is only prototype 
-  Serial.print("Message arrived ["); +... 
-  Serial.print(topic); +</code>
-  Serial.print("] "); +
-  for (int i = 0; i < length; i++) { +
-    Serial.print((char)payload[i]); +
-  } +
-  Serial.println(); +
- +
-  // Switch on the LED if an 1 was received as first character +
-  if ((char)payload[0] == '1') { +
-    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level +
-    // but actually the LED is on; this is because +
-    // it is active low on the ESP-01) +
-  } else { +
-    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH +
-  }+
  
 +As code runs asynchronously and many messages may come one by one, you should not process the ''packet'' itself but instead make a copy as quickly as possible to release resources for handling another request (if any):
 +<code c>
 +...
 +void callback_response(CoapPacket &packet, IPAddress ip, int port) {
 +    char p[packet.payloadlen + 1];
 +    memcpy(p, packet.payload, packet.payloadlen);
 +    p[packet.payloadlen] = NULL;
 +    //and then process "p" here
 +    ...
 } }
 ... ...
 </code> </code>
-You also need to bind the callback function with the MQTT client:+ 
 +<note tip>You may have a variety of frames received, but the common is to "ping" someone. If you detect ''packet.type==3 && packet.code==0'', then you were pinged. The following code snippet may help to identify ping and distinguish it from the data packets:
 <code c> <code c>
 ... ...
-  client.setCallback(callback);+    if(packet.type==3 && packet.code==0){ 
 +      Serial.println("COAP ping ok"); 
 +    }
 ... ...
 </code> </code>
-And then periodically execute the communication routine for the handling of the incoming messages, usually in the ''loop()'' function of your code (unless using FreeRTOS tasks asynchronous model):+</note> 
 + 
 +Once your callback function is ready, send a request and wait for the callback function to be triggered when the response comes. 
 +<note warning>Warning! You MUST configure and bind all response callback functions PRIOR to starting a CoAP communication, as below:</note>
 <code c> <code c>
 ... ...
-  client.loop();+  coap.response(callback_response); 
 +  coap.start();
 ... ...
 </code> </code>
 +
 +
 +Once the infrastructure is ready, you can send a request and observe a response, i.e., in a ''void loop()'' function:
 +<code c>
 +  int msgid = coap.get(ip,port,"");
 +  bool state = coap.loop();
 +</code>
 +Note, in the code above, ''coap.get(...)'' has three parameters:
 +  - IP address of the server you want to connect to (''IPAddress'' object);
 +  - port number (''int'');
 +  - URL, or actually, its part coming AFTER the IP section of the URL.
 +Regarding the last parameter, ''""'' denotes root, so in fact, the resulting request URI in this example is: ''%%coap://<IP>:<port>/<URL>%%''
 +
 ==== Networking ==== ==== Networking ====
-There is a WiFi 2.4GHz, IPv4 network available to the students. This is a PRIVATE network. This network is separated from the Internet but all connected devices to it can talk to another. There is a DHCP server with networking addressing scope 192.168.90.10-192.168.90.254. +There is a WiFi 2.4GHz, IPv4 network available to the students. This is a PRIVATE network. This network is separated from the Internet, but all connected devices can talk to one another. There is a DHCP server with networking addressing scope 192.168.90.10-192.168.90.254. In this laboratory scenario, you work ONLY on the PRIVATE network.
  
-<note warning>Do not use static IP! Some services present in the network have fixed IP addresses, overlapping it causes unavailability of your solution and this service, also to other teams! Use the only DHCP for obtaining a network address.</note>+<note warning>Do not use static IP! Some services in the network have fixed IP addresses; overlapping causes the unavailability of your solution and this service, also to other teams! Use only DHCP for obtaining a network address.</note>
  
 To connect to the wireless network, use the following credentials: To connect to the wireless network, use the following credentials:
Line 222: Line 210:
 ==== Network services ==== ==== Network services ====
  
-=== MQTT === +=== CoAP === 
-There is an MQTT Broker, binding WiFi PRIVATE network and the PUBLIC Internet. This way you can route MQTT messages from your end node devices connected to the ''internal.IOT'' network to the external tools i.e. cloud-based dashboard or storage via i.e. publishing from your end node IoT device through the PRIVATE network to MQTT Broker and subscribing to those messages from the cloud using PUBLIC Internet. \\+There is a CoAP server awaiting you.
  
-You can access it from the Internet PUBLIC network, using the following configuration and credentials: +You can also access it from the aforementioned PRIVATE network using the following configuration and credentials:
-  * Address: 157.158.56.54 +
-  * Port: 1883 for plain text, 8883 for secure communication +
-  * User: vrel +
-  * Password: vrel2018 +
- +
-You can also access it from the aforementioned PRIVATE network, using the following configuration and credentials:+
   * Address: 192.168.90.5   * Address: 192.168.90.5
-  * Port: 1883 for plain text, 8883 for secure communication +  * Port: 5683, coaps is not implemented 
-  * User: vrel +  * There are 2 URIs you can use to test your CoAP client (IoT device): 
-  * Password: vrel2018+    * ''%%coap://192.168.90.5:5683/hello%%'' returns a Hello World style message to you; 
 +    * ''%%coap://192.168.90.5:5683/%%'' returns a magic code 
  
  
 ==== Laboratory scenarios ==== ==== Laboratory scenarios ====
-All teams share the same scenario yet please note that in particular, MQTT messages exchanged between devices shall be coordinated among team members not to overlay one another.\\ +You will implement two scenarios that you can bind into one code (or implement it as separate solutions)
-You can implement 3 separate codes or bind them into one, solid solution. +
-<note tip>Mind keeping your code between meetings. It is regular that every next laboratory meeting you will extend your code by something extra.</note> +
-<pagebreak>+
  
 === Scenario 1 === === Scenario 1 ===
-** Connecting to the WiFi **\\ +** Connecting to the WiFi and getting a Hello World message via CoAP **\\ 
-Make your IoT device connect to the Internal.IOT network and present MAC of the device and IP address on the LCD screen.+Connect to the CoAP server for the hello world URI and display returned text messages in the Serial console.
  
 Report: Report:
-  * Describe your approach to the WiFi re-connection and document IP and MAC with screenshot. +  * Document your code and present an approach towards including CoAP communication protocol into the code.
-<pagebreak>+
  
 === Scenario 2 === === Scenario 2 ===
-** Sending MQTT message **\\ +** Get a magic code via CoAP and present it in the LCD **\\ 
-Read temperature and humidity and send it as two separate MQTT messages (as payloads). +Get a secret code and present it on the LCD screen. You can assume the code is no longer than 16 characters.
-<note warning>Warning! Agree with other sections to use UNIQUE MQTT client names and MQTT topics. Otherwise, you will interfere with one another on the broker level.</note> +
-Observe your messages and their changing over time using any software-based MQTT client (i.e. MQTT Explorer or MQTT Spy apps). +
- +
-Report: +
-  * Describe your interface and include client name, MQTT topics, publishing frequency, etc.  +
-<pagebreak> +
- +
-=== Scenario 3 === +
-** Receiving MQTT message **\\ +
-Prepare a solution where your IoT device subscribes to the selected message that will be received and the payload will be present on the LCD screen. You can assume, the maximum payload size is 16 characters, to fit a single line of the LCD display. You should be able then to send any text to your LCD, remotely. Use 2 separate messages to control the text in line 0 and line 1 (first and second) of the LCD screen.\\ +
-Use MQTT Spy or MQTT Explorer app to send a message with payload.+
  
 Report: Report:
-  * Document your interface (topic, payload format). Present your approach to buffer the message. +  * Present results, including a photo of the LCD with a message (code).
-<pagebreak>+
  
  
  
en/edu/zmitac/s2/iotn/lab3.1647637071.txt.gz · Last modified: by pczekalski