Connect STMicroelectronics boards to thethings.iO

Today, we’re gonna show you how to connect your STMicroelectronics board with thethings.iO. At this post we are going to connect exactly STMicroelectronics Discovery-F746NG board to take advantage of the mbed platform.

STMicroelectronics & thethings.iO

STMicroelectronics & thethings.iO

The STMicroelectronics Discovery-F746NG is a development kit board of the ST32F7 series of microcontrollers based on ARM Cortex-M7 processor. The board brings a microcontroller with 1MB of flash memory and 340KB of RAM connected with a 4.3 inches 480×272 TFT with capacitive touch screen. It brings Ethernet connectivity for Internet and for example Arduino UNO connectors. One of the most interesting part for this demo is that this board support mbed IDE.

thethings.iO-stm32f746ng

We decided to connect it to the Internet with thethings.iO to build a functional pilot for a customer.

How to connect STMicroelectronics Discovery-F746NG to thethings.iO

In order to connect with thethings.iO IoT platform, we’re going to need a thingToken to identify our board with the IoT platform and the business logic on the top. Find here the instructions to make it happen:

    1. Login or Register to thethings.iO (or quickly register here).
    2. If you already have a thing to work with, skip two steps. Navigate to Things (third row on the left)  and click on “Create new IoT product”. Insert a name, choose 8266 as the board and JSON as the format.

thethingsio-things-manager

  1. Click on the created product and click on “Get activation codes”. If you don’t have enough activation codes, generate more using “Genereate Activation Codes”. Now press on the “+” below “Activate” Row and copy the thing Token.

Making the firmware at the mbed platform

One of the interesting parts of this board is the use of the mbed platform that simplifies a lot the way to deploy new firmware on the board.

    1. Navigate to mbed developers site and login (or signup if you don’t have an account).

thethings.iO-mbed-login

    1. Click the  “Compiler” button. This link will redirect you to the mbed online compiler.thethings.iO-mbed-compiler
    2. A floating window will emerge, asking for a platform to work with. Select your board (DISCO-F746NG).
    3. On the top part of the mbed online compiler, click on Import.

 

  1. Press “Click here to import from URL”.

thethingsio-mbedcompiler-import

  1. Insert the following link: 
    1. For the HTTP version https://developer.mbed.org/users/charlyo/code/thethingsiO-DISCO_F746NG-http/
    2. For the MQTT version https://developer.mbed.org/users/charlyo/code/thethingsiO-DISCO_F746NG-mqtt/
  • The program is going to be imported into your workspace. Remember to change the TOKEN define with your thing token.
  • Connect the board to the computer: Connect both ST-LINK (mini USB) and FS (micro USB) to the computer. A new drive unit is going to appear in your computer:

thethings-usb-disco_f746ng

  • Click on compile. After compile is done, download the file into the USB disk that appeared when you connected the board to the computer.
  • The code is going to be flashed into the board and executed afterwards on the board.

thethings-io-stm-demo-crop

thethings.iO STMicroelectronics library

Once we know how to program the STMicroelectronics board with ARM mbed platform. It’s time to build a code that send the sensors’ data to thethings.iO. Find thethings.iO IoT platform STMicroelectronics library at our github account for HTTP and MQTT, with an example for each.

This is the library that connects the STMicroelectronics board to thethings.iO with HTTP. It have 4 basic calls to thethings.iO API: activate, read, readAll and write.



#include "ThethingsiO_DISCO_F746NG.h"

ThethingsiO_DISCO_F746NG::ThethingsiO_DISCO_F746NG()
{
    this->interface.init();
    this->interface.connect();
    this->buffer = network::Buffer(1024);
}

ThethingsiO_DISCO_F746NG::ThethingsiO_DISCO_F746NG(string token)
{
    this->interface.init();
    this->interface.connect();
    this->thingToken = token;
    this->buffer = network::Buffer(1024);
}

ThethingsiO_DISCO_F746NG::~ThethingsiO_DISCO_F746NG()
{

}

string ThethingsiO_DISCO_F746NG::thingReadAll(int limit)
{
    std::string request("GET /v2/things/");
    request.append(thingToken);
    request.append("/all_resources?limit=");
    stringstream convert;
    convert << limit;
    request.append(convert.str());
    request.append(" HTTP/1.1\r\nHost: %s\r\nUser-Agent: curl/7.43.0\r\nAccept: application/json\r\n\r\n");
    if (socket.open() < 0) {
        printf("Failed to open TCP Socket\n\r");
        return "Failed to open TCP Socket\n\r";
    }
    if (socket.connect("api.devices.thethings.io", 80) < 0) {
        printf("Failed to connect with thethings.iO\n\r");
        return "Failed to connect with thethings.iO\n\r";
    }
    if (socket.write((void *)request.data(), request.size()) < 0) { printf("Failed to write HTTP request\n\r"); return "Failed to write HTTP request\n\r"; } int result = this->socket.read(buffer);
    //printf("Received %d bytes:\n\r%s\n\r", string string string string string string string int result, (char *)buffer.data());
    string response = string((char*)buffer.data()).substr(string((char*)buffer.data()).find("\r\n\r\n"));
    buffer.flush();
    socket.close();
    return response;
}

string ThethingsiO_DISCO_F746NG::thingRead(string resource, int limit)
{
    std::string request("GET /v2/things/");
    request.append(thingToken);
    request.append("/resources/");
    request.append(resource);
    request.append("?limit=");
    stringstream convert;
    convert << limit;
    request.append(convert.str());
    request.append(" HTTP/1.1\r\nHost: %s\r\nUser-Agent: curl/7.43.0\r\nAccept: application/json\r\n\r\n");
    if (socket.open() < 0) {
        printf("Failed to open TCP Socket\n\r");
        return "Failed to open TCP Socket\n\r";
    }

    if (socket.connect("api.devices.thethings.io", 80) < 0) {
        printf("Failed to connect with thethings.iO\n\r");
        return "Failed to connect with thethings.iO\n\r";
    }

    if (socket.write((void *)request.data(), request.size()) < 0) { printf("Failed to write HTTP request\n\r"); return "Failed to write HTTP request\n\r"; } int result = this->socket.read(this->buffer);
    //printf("Received %d bytes:\n\r%s\n\r", string string string string string string string int result, (char *)buffer.data());
    string response = string((char*)this->buffer.data()).substr(string((char*)this->buffer.data()).find("\r\n\r\n"));
    this->buffer.flush();
    socket.close();
    return response;
}

int ThethingsiO_DISCO_F746NG::thingWrite(string resource, string value)
{
    string body;
    body.append("{\"values\":[{\"key\":\"");
    body.append(resource);
    body.append("\",\"value\":\"");
    body.append(value);
    body.append("\"}]}");
    std::string writerequest("POST /v2/things/");
    writerequest.append(thingToken);
    writerequest.append(" HTTP/1.1\r\nHost: %s\r\nUser-Agent: curl/7.43.0\r\nAccept: application/json\r\nContent-Type: application/json\r\nContent-Length: ");
    stringstream convert;
    convert << body.length();
    writerequest.append(convert.str());
    writerequest.append("\r\n\r\n");
    writerequest.append(body);
    writerequest.append("\r\n");
    if (socket.open() < 0) {
        printf("Failed to open TCP Socket\n\r");
        return -1;
    }
    if (socket.connect("api.devices.thethings.io", 80) < 0) {
        printf("Failed to connect with thethings.iO\n\r");
        return -1;
    }
    if (socket.write((void *)writerequest.data(), writerequest.size()) < 0) { printf("Failed to connect with thethings.iO\n\r"); return -1; } int result = socket.read(buffer); //printf("Received %d bytes:\n\r%s\n\r", string string string string string string string int result, (char *)buffer.data()); string response = string((char *) buffer.data()); //printf("%s\n", (char *) buffer.data()); int ret = response.find("status:created"); buffer.flush(); socket.close(); if (ret >= 0) return 0;
    else return -1;
}

string ThethingsiO_DISCO_F746NG::thingActivate(string activationCode)
{
    string body;
    body.append("{\"activationCode\":\"");
    body.append(activationCode);
    body.append("\"}");
    std::string writerequest("POST /v2/things/");
    writerequest.append(" HTTP/1.1\r\nHost: %s\r\nUser-Agent: curl/7.43.0\r\nAccept: application/json\r\nContent-Type: application/json\r\nContent-Length: ");
    stringstream convert;
    convert << body.length();
    writerequest.append(convert.str());
    writerequest.append("\r\n\r\n");
    writerequest.append(body);
    writerequest.append("\r\n");
    if (socket.open() < 0) {
        printf("Failed to open TCP Socket\n\r");
        return "Failed to open TCP Socket\n\r";
    }
    if (socket.connect("api.devices.thethings.io", 80) < 0) {
        printf("Failed to connect with thethings.iO\n\r");
        return "Failed to connect with thethings.iO\n\r";
    }
    if (socket.write((void *)writerequest.data(), writerequest.size()) < 0) { printf("Failed to write HTTP request\n\r"); return "Failed to write HTTP request\n\r"; } int result = socket.read(buffer); //printf("Received %d bytes:\n\r%s\n\r", string string string string string string string int result, (char *)buffer.data()); string response = string((char *) buffer.data()); response = response.substr(response.find("\r\n\r\n")); buffer.flush(); socket.close(); //string string string int result = "{\"status\":\"created\",\"message\":\"thing activated\",\"thingToken\":\"5RWZ6xFogVSJEla3b2gbToHGF1Ko-R8vTNoS3FMl8mM\"}" return response; } string ThethingsiO_DISCO_F746NG::getToken() { return this->thingToken;
}

void ThethingsiO_DISCO_F746NG::setToken(string token)
{
    this->thingToken = token;
}

Try it and let us know how do you connect your STMicroelectronics board to thethings.iO. We are going to publish your example at our github and at thethings.iO blog.