Table of Contents

U9: A CoAP client

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

Target group

Undergraduate / Bachelor / Engineering Students

Prerequisites

We assume you already know how to:

NodeRED CoAP server is present in the internal.IOT network and it is also visible under public address. Refer to the node documentation for the latest information.

Note - information present in source code samples can be not up-to-date - remember to refer to the VREL node documentation for the latest information on IPs, users and passwords for both internal.IOT network access and for the NodeRED access.

CoAP server data is:

Scenario

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

Result

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

Start

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

Steps

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

Step 1

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

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "coap_client.h"
#include <LiquidCrystal_I2C.h>
...

Declare some identifiers and variables/class instances to let you easier handle necessary modifications and keep code clear:

#define wifi_ssid "internal.IOT"
#define wifi_password "IoTlab32768"
 
IPAddress ip(192,168,90,5);//take NodeRed Address 
int port = 5683;
 
...
Step 2

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

...
 
coapClient coap;
 
...
Step 3

Prepare CoAP client response asynchronous handler.

CoAP uses UDP for communication, so you will be informed asynchronously, when response to your request appears. That is fully handled by asynchronous response handler and mechanism is implemented by the library.
As messages may come quickly in the queue (many replies) due to the heavy use or UDP nature, you are required to make a copy of the payload ASAP, best using memcpy, as first operation in your asynchronous response handler.
void callback_response(coapPacket &packet, IPAddress ip, int port);
...
// coap client response callback
void callback_response(coapPacket &packet, IPAddress ip, int port) {
    char p[packet.payloadlen + 1];                 //declare local buffer for the payload
    memcpy(p, packet.payload, packet.payloadlen);  //quickly copy payload contents
    p[packet.payloadlen] = NULL;
 
    //response from coap server - check if this is regular one (response to your request), or is it a ping request?
    if(packet.type==3 && packet.code==0){
      //that means you've obtained a ping request so handle it (i.e. show on LCD)
      ...
    }
    ... //handle payload.
}
...
Step 4

Start your CoAP client in the setup() function:

... // remember to initialise it AFTER you make a WiFi connection, not before
  coap.respinse(callback_response); // add response handler
  coap.start(); //start coap client
Step 5

Your loop() function should include call to the CoAP client methods. Here we use only CoAP GET, as this is the only one implemented by the NodeRED server, we provide to you:

void loop()
{
  ...
  int msgid = coap.get(ip,port,"");
  bool state = coap.loop();
  ...
  delay(10000);
}
Mind to keep a delay(…), not to saturate NodeRED server with issuing dozens of UDP requests. Minimum reasonable delay between issuing consecutive requests is about 500ms.

Result validation

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

FAQ

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