# How to integrate an Arduino device via MQTT on akenza

[**MQTT**](https://mqtt.org/) is an OASIS standard messaging protocol for the Internet of Things (IoT) and one of the protocols supported by akenza.&#x20;

It is designed as an extremely lightweight **publish/subscribe messaging protocol** that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth. **MQTT** is used in a wide variety of industries.\
By using a combination of MQTT and API functionalities, akenza enables you to automatically create **Digital Twins** for your devices.\
Akenza runs an open-source **MQTT broker** from [Eclipse Mosquitto](https://mosquitto.org/).

\
In order to proceed in this tutorial, you need an **Arduino Board** capable to connect to the Internet. In our example, we use an **Arduino Uno WiFi Rev2.** To directly connect your device via MQTT with akenza, you can easily implement it with a **Python script**. Find out more about MQTT connectivity [here](https://docs.akenza.io/api-reference/mqtt).

![](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMKXTFIN5ZlLOjBlfC4%2F-MkMeQo-ejVbijMYfNK1%2F-MkMfKKojhBxEDKILXvh%2Fimage.png?alt=media\&token=2083423f-7845-4159-81b7-967ff8efe829)

### 1. Connect the Arduino device via MQTT on akenza

#### 1.1 Creating a secret

In order to safely communicate with akenza, a secret needs to be generated that has to be provided in the topic structure of the uplink request.

This step has to be performed for all devices with the same connection parameters, which you want to connect. Each device will be uniquely identified by a **specific ID** accordingly.\
A secret will be generated after the creation of the **MQTT device connector** on the **Data Flow**.

#### **1.1.1 Setting up an MQTT Device Connector on akenza**

Go to **Data Flow** in the menu and select *Create Data Flow*.&#x20;

Choose MQTT as a device connector. As Device Type, select *Passthrough*, in order to receive data in the same format as sent from your MQTT device.

Choose one or multiple **Output Connectors** of your choice. There are several options to choose from. In this tutorial, we choose the **Akenza DB**. Find out more about [Output Connectors](https://docs.akenza.io/get-started/connectors).

![MQTT Data Flow](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MMKXTFIN5ZlLOjBlfC4%2Fuploads%2FGKegozGFvUVWvCH22n4b%2Fimage.png?alt=media\&token=4a2254b6-1ecd-4695-b698-334d9f369a68)

#### **1.2 Create an MQTT device on akenza**&#x20;

To create a new MQTT device, select *Create Device* within the menu of the **Asset Inventory**. Add a device name and optionally a description, Asset Tags, and Custom Fields. Select *Next* and choose your created MQTT- Data Flow. Select *Proceed*.

![Create new device](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MMKXTFIN5ZlLOjBlfC4%2Fuploads%2FWUvKa7RQEHbDLU1wPmyy%2Fscreely-1640816236580%20tags%20device%20create.png?alt=media\&token=8bc99b3f-08c4-4154-8d3e-094457da50c6)

Generate a **random** **ID** for this device by clicking *Generate ID*. Finish the process by clicking on the button *Create Device*. Your device will be now displayed on the **Asset Inventory Overview**.

#### 1.3 Set up the Arduino device

As a next step, the Arduino device has to be now configured to send data to the **MQTT Broker** of akenza.\
Go to **Asset Inventory** and use the filter to search for your device. Open the device detail page by selecting your device. Within *API-Configuration*, all the required information is available to set up the device as an MQTT- client.

![API configuration on device detail page](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMKXTFIN5ZlLOjBlfC4%2F-MkMgtkGtjnosTotivzV%2F-MkMhVEcS2WHg3pkafih%2Fimage.png?alt=media\&token=6b8e8147-80ff-4bf9-aa87-b97f50a4f011)

### 2. Configure the Arduino device

#### 2.1 Set up the WiFi Connection

To have the Arduino Uno Wifi able to connect to WiFi we used the WiFiNINA library, available in the Library Manager of Arduino IDE.

#### 2.1.1 Manage Username and Password

In order to manage Username and Password, we have created an additional header file called *arduino\_secrets.h*

```python
#define SECRET_SSID "<your username>"
#define SECRET_PASS "<your password>"
```

#### 2.1.2 WiFi connection code

The code to connect Arduino to WiFi is reported as below:

```python
#include <WiFiNINA.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;     // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

WiFiClient wifiClient;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    // failed, retry
    Serial.print(".");
    delay(5000);
  }

  Serial.println("You're connected to the network");
  Serial.println();
}

void loop()
{}
```

#### 2.2 Set up the MQTT Connection to akenza

For security reasons akenza only supports **authenticated connections via MQTT**. For this, we have chosen as library **PubSubClient** to manage our MQTT connection. This enables us to use *username* and *password* in our connection string.

```python
#include <PubSubClient.h>

//MQTTClient mqttClient(WiFiClient);

char host[] = "mqtt.akenza.io";
char clientid[] = "Arduino";
char username[] = "<copy from Akenza Device Api configuration>";
char password[] = "<copy from Akenza Device Api configuration>";
char outTopic[] = "<copy from Akenza Device Api configuration>";

PubSubClient client(host, 1883, callback, wifiClient);

void setup() {
  if (client.connect(host, username, password)) {
    Serial.print("Connected to ");
    Serial.println(host);
    Serial.println();
    
    boolean r = client.subscribe(outTopic);
    Serial.print("Subscribed to ");
    Serial.println(outTopic);
    Serial.println();
    } 
    else {
      // connection failed
      // mqttClient.state() will provide more information
      // on why it failed.
      Serial.print("Connection failed: ");
      Serial.println(client.state());
      Serial.println();
  }
}
```

#### 2.3 Create a JSON message

Akenza accepts messages in **JSON format for MQTT connections**. To build up a well-formed JSON object, we make use of the [ArduinoJson library](https://arduinojson.org/).

```python
#include <ArduinoJson.h>

void loop()
{
  StaticJsonDocument<256> doc;
  doc["Temperature"] = 22;
  doc["Humidity"] = 68;
  doc["Light"] = 96;

  // Add an array
  JsonArray data = doc.createNestedArray("data");
  data.add(48);
  data.add(2.3);
  
  char out[128];
  int b =serializeJson(doc, out);
  Serial.print("publishing bytes = ");
  Serial.println(b,DEC);
  
  boolean rc = client.publish(outTopic, out);
  
  // The above line prints:
  // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
  delay(5000);
  client.loop();
}
```

#### **2.4 Final result**

Now you have all the elements needed to set up your code on Arduino and stream data via MQTT to akenza.

The final code is reported as below:

```python
#include <SPI.h>
#include <PubSubClient.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>

#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;     // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

char host[] = "mqtt.akenza.io";
char clientid[] = "Arduino";
char username[] = "0783ddd64683f579";
char password[] = "bd604gmgit0x7kilc8puok3g2rxsldl2";
char outTopic[] = "/up/bd604gmgit0x7kilc8puok3g2rxsldl2/id/99E77F4ECC728656";

//set interval for sending messages (milliseconds)
const long interval = 8000;
unsigned long previousMillis = 0;

int count = 0;

//receive data
void callback(char* topic, byte* payload, unsigned int length) {

  char str[length+1];
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  int i=0;
  
  for (i=0;i<length;i++) {
    Serial.print((char)payload[i]);
    str[i]=(char)payload[i];
  }

  str[i] = 0; // Null termination
  Serial.println();
  
  StaticJsonDocument <256> doc;
  deserializeJson(doc,payload);

  // deserializeJson(doc,str); can use string instead of payload
  const char* sensor = doc["sensor"];
  long time          = doc["time"];
  float latitude    = doc["data"][0];
  float longitude   = doc["data"][1];

  Serial.println("latitude =");
  Serial.println(latitude,2);
  Serial.println(sensor);
  
}

WiFiClient wifiClient;
PubSubClient client(host, 1883, callback, wifiClient);

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    // failed, retry
    Serial.print(".");
    delay(5000);
  }

  Serial.println("You're connected to the network");
  Serial.println();

  if (client.connect(host, username, password)) {
    Serial.print("Connected to ");
    Serial.println(host);
    Serial.println();
    
    boolean r = client.subscribe(outTopic);
    Serial.print("Subscribed to ");
    Serial.println(outTopic);
    Serial.println();
    } 
    else {
      // connection failed
      Serial.println("Connection failed ");
      Serial.println(client.state());
      Serial.println();
  }
}

void loop()
{
  StaticJsonDocument<256> doc;
  doc["Temperature"] = 22;
  doc["Humidity"] = 68;
  doc["Light"] = 96;

  // Add an array
  JsonArray data = doc.createNestedArray("data");
  data.add(48);
  data.add(2.3);
  
  char out[128];
  int b =serializeJson(doc, out);
  Serial.print("publishing bytes = ");
  Serial.println(b,DEC);
  
  boolean rc = client.publish(outTopic, out);
  
  // The above line prints:
  // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
  delay(5000);
  client.loop();
}
```

### 3. Visualize and manage your data on akenza

Akenza automatically decodes the received JSON and visualizes data received from the Arduino device. Incoming data can be viewed on the **Device Detail Page** within *Message Logs*.

![Message Logs on Device Detail Page](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMKXTFIN5ZlLOjBlfC4%2F-MkMhexZkFYZdIu58wQn%2F-MkMieQm9AfTL0SpENdi%2Fimage.png?alt=media\&token=c2b32ec1-56a0-4796-a3d2-0c6e3d7e2270)

Incoming data are visualized on *Data Overview* as **Device Data KPIs** and also on the **History** chart.

![Device Data KPIs & History Chart on Device Detail Page](https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMKXTFIN5ZlLOjBlfC4%2F-MkMhexZkFYZdIu58wQn%2F-MkMiRO9rqUSEsaevx9d%2Fimage.png?alt=media\&token=391c9c73-58a0-4826-8884-9de86a76ceb1)

Further data processing and visualization options can now be applied to your individual use case. For example:

* [Apply business logic with the Rule Engine on akenza](https://docs.akenza.io/get-started/rule-engine)
* [Data processing & notification options with Output Connectors on akenza](https://docs.akenza.io/get-started/connectors)
* [Data visualization with Grafana](https://docs.akenza.io/api-reference/advanced-topics/grafana-data-source-plugin)
* [Advanced enterprise solutions with Azure](https://docs.akenza.io/tutorials/create-enterprise-solutions/how-to-send-data-to-the-azure-iot-hub)

### 4. Useful Links

{% embed url="<https://arduinojson.org/>" %}

{% embed url="<https://www.arduino.cc/reference/en/libraries/pubsubclient/>" %}

{% embed url="<https://www.arduino.cc/reference/en/libraries/wifinina/>" %}

{% embed url="<http://www.steves-internet-guide.com/arduino-sending-receiving-json-mqtt/>" %}

{% embed url="<https://www.arduino.cc/reference/en/libraries/arduinojson/>" %}
