ESP32-WROOM-32 callback function and memory issue - esp32

We are currently testing a library related to the IoT Platform with ESP32-WROOM-32 now.
_token is defined in .h file.
In one file HttpDownstream.cpp:
void HttpDownstreamClient::tokenCreate(char* URL, char* Subname, char* Suber, int expiretime) {
Serial.print("The subscription is associated with the Subscripter: ");
Serial.println(Suber);
StaticJsonDocument<200> root;
root["subscriber"] = Suber;
root["subscription"] = Subname;
root["expiresInMinutes"] = expiretime;
String body2send = "";
serializeJsonPretty(root, body2send);
if (_networkClient->connect(URL, 443)) {
Serial.println("Connected to the server to request token!");
// Make a HTTP request:
_networkClient->println("POST /notification2/token HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->print("Authorization: Basic ");
_networkClient->println(_base64);
_networkClient->println("Content-Type: application/json");
_networkClient->print("Content-Length: ");
_networkClient->println(body2send.length());
_networkClient->println("Accept: application/json");
_networkClient->println();
_networkClient->println(body2send);
}
//Start to handle incoming message sent from server
while (_token.length() == 0) {
String msg = "";
while (_networkClient->available()) {
char c = _networkClient->read();
msg += c;
}
Serial.println("debug!!!");
Serial.println(msg);
int start_init = msg.indexOf("\"token\"");
int start = msg.indexOf(":",start_init);
int until_n = msg.indexOf("\"", start + 3);
Serial.println(until_n);
if (start != -1 && until_n != -1 ) {
_token = msg.substring(start + 2, until_n);
Serial.print("Token is: ");
Serial.println(_token);
}
}
}
In test.io we have:
void setup(){
//WiFi setting is not showed here
c8yclient.tokenCreate(host, SubscriptionName, SubscriberName, expiretime);
}
void loop()
{
while (wifisecure.available()) {
char c = wifisecure.read();
Serial.print(c);
}
}
What I get is something like this:
21:31:57.993 -> The subscription is associated with the Subscripter: Test2Sub1
21:31:58.033 -> Connected to the server to request token!
21:31:58.073 -> debug!!!
21:31:58.073 -> ⸮
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
21:31:58.073 ->
21:31:58.073 -> -1
21:31:58.073 -> debug!!!
What I can make sure now is that the https request has been sent out. However, the incoming message from the server is not "well" processed. IMO there must be something wrong in memory since we have a "⸮" printed.
We tried this library with MKR wifi 1010, Arduino Uno rev 2 and nano 33 IoT. None of these boards has this issue. What has happened to ESP32? How can I fix this?
Many thanks in advance!
We think it might be a memory allocation issue since we have seen "⸮" printed. We need more inputs from your side. Thanks!
.h file
#ifndef HttpDownstream_h
#define HttpDownstream_h
#include "Arduino.h"
#include <Base64.h>
#include <ArduinoJson.h>
#include <string.h>
#include <Client.h>
class HttpDownstreamClient{
private:
String _token;
char* _base64;
//String _deviceID;
//Base64 encoder
void base64(char* username, char* password);
public:
Client* _networkClient;
HttpDownstreamClient(Client& networkClient);
//Delete the already existed subscription
void subscriptionDelete(char* user, char* password,char* URL, char* context,char* source);
//Create subscription
void subscriptionCreate(char* user, char* password, char* URL, char* device_ID,char* context ,char* SubName, char* API,char* typeFilter, char* fragmentsToCopy);
//Create token
void tokenCreate(char* URL, char* Subname, char* Suber, int expiretime);
//Create token by giving password
void tokenCreatePassword(char* user, char* password, char* URL, char* Subname, char* Suber, int expiretime);
//Open WSS
void connectWSS(char* URL,char* Suber);
};
#endif
.cpp file
#include "HttpDownstream.h"
HttpDownstreamClient::HttpDownstreamClient(Client& networkClient) {
_networkClient = &networkClient;
}
//Base64 encoder
void HttpDownstreamClient::base64(char* username, char* password) {
char temp[100];
strcpy(temp , username);
strcat(temp, ":");
strcat(temp, password);
Serial.println();
//For debugging
Serial.print("Information needs to be coded is:");
Serial.println(temp);
int inputStringLength = strlen(temp);
int encodedLength = Base64.encodedLength(inputStringLength);
char encodedString[encodedLength];
Base64.encode(encodedString, temp, inputStringLength);
//Serial.print("Encoded string is: ");
//Serial.println(encodedString);
//Memory allocation
if (_base64) free (_base64);
_base64 = (char*) malloc(sizeof(char) * strlen(encodedString));
strcpy(_base64, encodedString);
Serial.print("Stored Based64 string is: ");
Serial.println(_base64);
}
void HttpDownstreamClient::subscriptionDelete(char* user, char* password,char* URL,char* context,char* source){
base64(user, password);
//Serial.println(_base64);
if (_networkClient->connect(URL, 443)){
Serial.println("Start to clear the subscription");
// Make a HTTP request:
_networkClient->print("DELETE /notification2/subscriptions?context=");
_networkClient->print(context);
_networkClient->print("&");
_networkClient->print("source=");
_networkClient->print(source);
_networkClient->println(" HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->println("Accept: application/vnd.com.nsn.cumulocity.error+json");
_networkClient->print("Authorization: Basic ");
_networkClient->println(_base64);
}
}
void HttpDownstreamClient::subscriptionCreate(char* user, char* password, char* URL, char* device_ID, char* context , char* SubName, char* API, char* type_Filter, char* fragments_To_Copy) {
//Serial.print("The subscription is associated with the device: ");
//Serial.println(device_ID);
base64(user, password);
Serial.println(_base64);
StaticJsonDocument<400> root;
root["context"] = context;
if(context == "mo"){
if(device_ID != NULL){
JsonObject source = root.createNestedObject("source");
source["id"] = device_ID;
}else{
Serial.println("Please enter the device ID");
}
}
//JsonObject source = root.createNestedObject("source");
//source["id"] = device_ID;
root["subscription"] = SubName;
JsonObject subFilter = root.createNestedObject("subscriptionFilter");
if (*type_Filter != NULL) {
subFilter["typeFilter"] = type_Filter;
} else {}
JsonArray apis = subFilter.createNestedArray("apis");
apis.add(API);
if (*fragments_To_Copy != NULL) {
JsonArray fragtocopy = root.createNestedArray("fragmentsToCopy");
fragtocopy.add(fragments_To_Copy);
} else {}
String body2send = "";
serializeJsonPretty(root, body2send);
Serial.println(body2send);
if (_networkClient->connect(URL, 443)) {
Serial.println("Connected to the server");
// Make a HTTP request:
_networkClient->println("POST /notification2/subscriptions HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->println("Content-Type: application/json");
_networkClient->print("Content-Length: ");
_networkClient->println(body2send.length());
_networkClient->println("Accept: application/json");
_networkClient->print("Authorization: Basic ");
_networkClient->print(_base64);
_networkClient->println();
_networkClient->println();
_networkClient->println(body2send);
} else {
Serial.println("Connection fail!");
}
}
void HttpDownstreamClient::tokenCreate(char* URL, char* Subname, char* Suber, int expiretime) {
Serial.print("The subscription is associated with the Subscripter: ");
Serial.println(Suber);
StaticJsonDocument<150> root;
root["subscriber"] = Suber;
root["subscription"] = Subname;
root["expiresInMinutes"] = expiretime;
String body2send = "";
serializeJsonPretty(root, body2send);
//Serial.println(body2send);
Serial.println("Start to connect to the server!");
if (_networkClient->connect(URL, 443)) {
Serial.println("Connected to the server");
// Make a HTTP request:
_networkClient->println("POST /notification2/token HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->print("Authorization: Basic ");
_networkClient->println(_base64);
_networkClient->println("Content-Type: application/json");
_networkClient->print("Content-Length: ");
_networkClient->println(body2send.length());
_networkClient->println("Accept: application/json");
_networkClient->println();
_networkClient->println(body2send);
}
while (_token.length() == 0) {
String msg = "";
while (_networkClient->available()) {
char c = _networkClient->read();
msg += c;
}
Serial.println("debug!!!");
Serial.println(msg);
int start_init = msg.indexOf("\"token\"");
int start = msg.indexOf(":",start_init);
int until_n = msg.indexOf("\"", start + 3);
Serial.println(until_n);
if (start != -1 && until_n != -1 ) {
_token = msg.substring(start + 2, until_n);
Serial.print("Token is: ");
Serial.println(_token);
}
}
}
void HttpDownstreamClient::tokenCreatePassword(char* user, char* password, char* URL, char* Subname, char* Suber, int expiretime) {
base64(user, password);
Serial.println(_base64);
Serial.print("The subscription is associated with the Subscripter: ");
Serial.println(Suber);
StaticJsonDocument<150> root;
root["subscriber"] = Suber;
root["subscription"] = Subname;
root["expiresInMinutes"] = expiretime;
String body2send = "";
serializeJsonPretty(root, body2send);
//Serial.println(body2send);
if (_networkClient->connect(URL, 443)) {
Serial.println("Connected to the server");
// Make a HTTP request:
_networkClient->println("POST /notification2/token HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->print("Authorization: Basic ");
_networkClient->println(_base64);
_networkClient->println("Content-Type: application/json");
_networkClient->print("Content-Length: ");
_networkClient->println(body2send.length());
_networkClient->println("Accept: application/json");
_networkClient->println();
_networkClient->println(body2send);
}
while (_token.length() == 0) {
String msg = "";
while (_networkClient->available()) {
char c = _networkClient->read();
msg += c;
}
Serial.println(msg);
int start_init = msg.indexOf("\"token\"");
int start = msg.indexOf(":",start_init);
int until_n = msg.indexOf("\"", start + 3);
Serial.println(until_n);
if (start != -1 && until_n != -1 ) {
_token = msg.substring(start + 2, until_n);
Serial.print("Token is: ");
Serial.println(_token);
}
}
}
void HttpDownstreamClient::connectWSS(char* URL, char* Suber) {
if (_token.length() != 0) {
if (_networkClient->connect(URL, 443)) {
Serial.println("Websocket port is opened");
// Make a HTTP request:
_networkClient->print("GET ");
_networkClient->print("/notification2/consumer/?token=");
_networkClient->print(_token);
_networkClient->print("&consumer=");
_networkClient->print(Suber);
_networkClient->println(" HTTP/1.1");
_networkClient->print("Host: ");
_networkClient->println(URL);
_networkClient->println("Sec-WebSocket-Key: q4xkcO32u266gldTkKaSOw==");
_networkClient->println("Upgrade: websocket");
_networkClient->println("Connection: Upgrade");
_networkClient->println("Sec-WebSocket-Version: 13");
_networkClient->println();
}
}
}
.ino file
#include <HttpDownstream.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
WiFiClientSecure wifisecure;
HttpDownstreamClient c8yclient(wifisecure); //initiate the HttpDownstreamClient
char* host = "tenant.cumulocity.com";
char* username = "tenant";
char* password = "tenant";
char* device_id = "13225";
//Subscription Test
char* SubscriptionName = "NotificationV2Test12";
char* SubscriberName = "Test2Sub1";
char* APIs = "measurements";
char* typeFilter= "";
char* fragmentsToCopy= "";
int expiretime = 1100;
char ssid[] = "**********"; // your network SSID (name)
char pass[] = "**********"; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;
void setup()
{
Serial.begin(115200);
delay(10);
wifisecure.setInsecure();
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 5 seconds for connection:
delay(5000);
}
Serial.println("Connected to WiFi");
c8yclient.subscriptionCreate(username,password,host, device_id,"mo" ,SubscriptionName, APIs,typeFilter,fragmentsToCopy);
delay(6000);
c8yclient.tokenCreate(host, SubscriptionName, SubscriberName, expiretime);
delay(6000);
//c8yclient.connectWSS(host,SubscriberName);
//delay(5000);
}
void loop()
{
while (wifisecure.available()) {
char c = wifisecure.read();
Serial.print(c);
}
}

You have an off-by-one issue when you allocate memory for _base64.
Your code currently reads:
if (_base64) free (_base64);
_base64 = (char*) malloc(sizeof(char) * strlen(encodedString));
strcpy(_base64, encodedString);
strlen() returns the number of characters in the string, not including the null terminator. You need to allocate 1 more character than the length. Even better, just use strdup(), which takes care of it for you.
So either
if (_base64) free (_base64);
_base64 = (char*) malloc((sizeof(char) * (strlen(encodedString)+1));
strcpy(_base64, encodedString);
or
if (_base64) free (_base64);
_base64 = strdup(_encodedString);
You really should check if malloc() or strdup() fails and do something appropriate in that case, too.

Related

How to recieve a Direct Method on the ESP32 with azure-sdk-for-c-arduino

For a school project I am using IoT Hub to connect between different devices (ESP32), The intention is to use a web application to retrieve data from a device. I want to do this by using a Direct Method.
Now I have seen in the past some direct methods using python and how I can use this in Azure Functions but not yet on an ESP32. By the way, I am programming in C on the ESP32.
Does anyone have an example code for this? I am not finding really much info about direct methods in C with the library "azure-sdk-for-c-arduino".
Thanks in advance
My code at the moment (This is test code):
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/*
This is an Arduino-based Azure IoT Hub sample for ESPRESSIF ESP32 boards.
It uses our Azure Embedded SDK for C to help interact with Azure IoT.
For reference, please visit https://github.com/azure/azure-sdk-for-c.
To connect and work with Azure IoT Hub you need an MQTT client, connecting, subscribing
and publishing to specific topics to use the messaging features of the hub.
Our azure-sdk-for-c is an MQTT client support library, helping composing and parsing the
MQTT topic names and messages exchanged with the Azure IoT Hub.
This sample performs the following tasks:
- Synchronize the device clock with a NTP server;
- Initialize our "az_iot_hub_client" (struct for data, part of our azure-sdk-for-c);
- Initialize the MQTT client (here we use ESPRESSIF's esp_mqtt_client, which also handle the tcp connection and TLS);
- Connect the MQTT client (using server-certificate validation, SAS-tokens for client authentication);
- Periodically send telemetry data to the Azure IoT Hub.
To properly connect to your Azure IoT Hub, please fill the information in the `iot_configs.h` file.
*/
//Variabeles for drukknop
const int PushButton = 35;
//Variables for weight sensor;
double weight = 5.0;
// C99 libraries
#include <cstdlib>
#include <string.h>
#include <time.h>
// Libraries for MQTT client and WiFi connection
#include <WiFi.h>
#include <mqtt_client.h>
// Azure IoT SDK for C includes
#include <az_core.h>
#include <az_iot.h>
#include <azure_ca.h>
// Libraries for SendingJson
#include <ArduinoJson.h>
// Additional sample headers
#include "AzIoTSasToken.h"
#include "SerialLogger.h"
#include "iot_configs.h"
// When developing for your own Arduino-based platform,
// please follow the format '(ard;<platform>)'.
#define AZURE_SDK_CLIENT_USER_AGENT "c/" AZ_SDK_VERSION_STRING "(ard;esp32)"
// Utility macros and defines
#define sizeofarray(a) (sizeof(a) / sizeof(a[0]))
#define NTP_SERVERS "pool.ntp.org", "time.nist.gov"
#define MQTT_QOS1 1
#define DO_NOT_RETAIN_MSG 0
#define SAS_TOKEN_DURATION_IN_MINUTES 60
#define UNIX_TIME_NOV_13_2017 1510592825
#define PST_TIME_ZONE -8
#define PST_TIME_ZONE_DAYLIGHT_SAVINGS_DIFF 1
#define GMT_OFFSET_SECS (PST_TIME_ZONE * 3600)
#define GMT_OFFSET_SECS_DST ((PST_TIME_ZONE + PST_TIME_ZONE_DAYLIGHT_SAVINGS_DIFF) * 3600)
// Translate iot_configs.h defines into variables used by the sample
static const char* ssid = IOT_CONFIG_WIFI_SSID;
static const char* password = IOT_CONFIG_WIFI_PASSWORD;
static const char* host = IOT_CONFIG_IOTHUB_FQDN;
static const char* mqtt_broker_uri = "mqtts://" IOT_CONFIG_IOTHUB_FQDN;
static const char* device_id = IOT_CONFIG_DEVICE_ID;
static const int mqtt_port = AZ_IOT_DEFAULT_MQTT_CONNECT_PORT;
// Memory allocated for the sample's variables and structures.
static esp_mqtt_client_handle_t mqtt_client;
static az_iot_hub_client client;
static char mqtt_client_id[128];
static char mqtt_username[128];
static char mqtt_password[200];
static uint8_t sas_signature_buffer[256];
static unsigned long next_telemetry_send_time_ms = 0;
static char telemetry_topic[128];
static uint8_t telemetry_payload[100];
static uint32_t telemetry_send_count = 0;
#define INCOMING_DATA_BUFFER_SIZE 128
static char incoming_data[INCOMING_DATA_BUFFER_SIZE];
// Auxiliary functions
#ifndef IOT_CONFIG_USE_X509_CERT
static AzIoTSasToken sasToken(
&client,
AZ_SPAN_FROM_STR(IOT_CONFIG_DEVICE_KEY),
AZ_SPAN_FROM_BUFFER(sas_signature_buffer),
AZ_SPAN_FROM_BUFFER(mqtt_password));
#endif // IOT_CONFIG_USE_X509_CERT
static void connectToWiFi()
{
Logger.Info("Connecting to WIFI SSID " + String(ssid));
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Logger.Info("WiFi connected, IP address: " + WiFi.localIP().toString());
}
static void initializeTime()
{
Logger.Info("Setting time using SNTP");
configTime(GMT_OFFSET_SECS, GMT_OFFSET_SECS_DST, NTP_SERVERS);
time_t now = time(NULL);
while (now < UNIX_TIME_NOV_13_2017)
{
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("");
Logger.Info("Time initialized!");
}
void receivedCallback(char* topic, byte* payload, unsigned int length)
{
Logger.Info("Received [");
Logger.Info(topic);
Logger.Info("]: ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println("");
}
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
switch (event->event_id)
{
int i, r;
case MQTT_EVENT_ERROR:
Logger.Info("MQTT event MQTT_EVENT_ERROR");
break;
case MQTT_EVENT_CONNECTED:
Logger.Info("MQTT event MQTT_EVENT_CONNECTED");
r = esp_mqtt_client_subscribe(mqtt_client, AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC, 1);
if (r == -1)
{
Logger.Error("Could not subscribe for cloud-to-device messages.");
}
else
{
Logger.Info("Subscribed for cloud-to-device messages; message id:" + String(r));
}
break;
case MQTT_EVENT_DISCONNECTED:
Logger.Info("MQTT event MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
Logger.Info("MQTT event MQTT_EVENT_SUBSCRIBED");
break;
case MQTT_EVENT_UNSUBSCRIBED:
Logger.Info("MQTT event MQTT_EVENT_UNSUBSCRIBED");
break;
case MQTT_EVENT_PUBLISHED:
Logger.Info("MQTT event MQTT_EVENT_PUBLISHED");
break;
case MQTT_EVENT_DATA:
Logger.Info("MQTT event MQTT_EVENT_DATA");
for (i = 0; i < (INCOMING_DATA_BUFFER_SIZE - 1) && i < event->topic_len; i++)
{
incoming_data[i] = event->topic[i];
}
incoming_data[i] = '\0';
Logger.Info("Topic: " + String(incoming_data));
for (i = 0; i < (INCOMING_DATA_BUFFER_SIZE - 1) && i < event->data_len; i++)
{
incoming_data[i] = event->data[i];
}
incoming_data[i] = '\0';
if (String(incoming_data) == "GETWEIGHT")
{
Logger.Info("Send Data To The Cloud ");
sendTelemetry();
}
else
{
Logger.Info("Data: " + String(incoming_data));
}
break;
case MQTT_EVENT_BEFORE_CONNECT:
Logger.Info("MQTT event MQTT_EVENT_BEFORE_CONNECT");
break;
default:
Logger.Error("MQTT event UNKNOWN");
break;
}
return ESP_OK;
}
static void initializeIoTHubClient()
{
az_iot_hub_client_options options = az_iot_hub_client_options_default();
options.user_agent = AZ_SPAN_FROM_STR(AZURE_SDK_CLIENT_USER_AGENT);
if (az_result_failed(az_iot_hub_client_init(
&client,
az_span_create((uint8_t*)host, strlen(host)),
az_span_create((uint8_t*)device_id, strlen(device_id)),
&options)))
{
Logger.Error("Failed initializing Azure IoT Hub client");
return;
}
size_t client_id_length;
if (az_result_failed(az_iot_hub_client_get_client_id(
&client, mqtt_client_id, sizeof(mqtt_client_id) - 1, &client_id_length)))
{
Logger.Error("Failed getting client id");
return;
}
if (az_result_failed(az_iot_hub_client_get_user_name(
&client, mqtt_username, sizeofarray(mqtt_username), NULL)))
{
Logger.Error("Failed to get MQTT clientId, return code");
return;
}
Logger.Info("Client ID: " + String(mqtt_client_id));
Logger.Info("Username: " + String(mqtt_username));
}
static int initializeMqttClient()
{
#ifndef IOT_CONFIG_USE_X509_CERT
if (sasToken.Generate(SAS_TOKEN_DURATION_IN_MINUTES) != 0)
{
Logger.Error("Failed generating SAS token");
return 1;
}
#endif
esp_mqtt_client_config_t mqtt_config;
memset(&mqtt_config, 0, sizeof(mqtt_config));
mqtt_config.uri = mqtt_broker_uri;
mqtt_config.port = mqtt_port;
mqtt_config.client_id = mqtt_client_id;
mqtt_config.username = mqtt_username;
#ifdef IOT_CONFIG_USE_X509_CERT
Logger.Info("MQTT client using X509 Certificate authentication");
mqtt_config.client_cert_pem = IOT_CONFIG_DEVICE_CERT;
mqtt_config.client_key_pem = IOT_CONFIG_DEVICE_CERT_PRIVATE_KEY;
#else // Using SAS key
mqtt_config.password = (const char*)az_span_ptr(sasToken.Get());
#endif
mqtt_config.keepalive = 30;
mqtt_config.disable_clean_session = 0;
mqtt_config.disable_auto_reconnect = false;
mqtt_config.event_handle = mqtt_event_handler;
mqtt_config.user_context = NULL;
mqtt_config.cert_pem = (const char*)ca_pem;
mqtt_client = esp_mqtt_client_init(&mqtt_config);
if (mqtt_client == NULL)
{
Logger.Error("Failed creating mqtt client");
return 1;
}
esp_err_t start_result = esp_mqtt_client_start(mqtt_client);
if (start_result != ESP_OK)
{
Logger.Error("Could not start mqtt client; error code:" + start_result);
return 1;
}
else
{
Logger.Info("MQTT client started");
return 0;
}
}
/*
#brief Gets the number of seconds since UNIX epoch until now.
#return uint32_t Number of seconds.
*/
static uint32_t getEpochTimeInSecs()
{
return (uint32_t)time(NULL);
}
static void establishConnection()
{
connectToWiFi();
initializeTime();
initializeIoTHubClient();
(void)initializeMqttClient();
}
static void getTelemetryPayload(az_span payload, az_span* out_payload)
{
az_span original_payload = payload;
payload = az_span_copy(
payload, AZ_SPAN_FROM_STR("{ \"deviceId\": "));
payload = az_span_copy(payload, AZ_SPAN_FROM_STR( IOT_CONFIG_DEVICE_ID ));
payload = az_span_copy(payload, AZ_SPAN_FROM_STR( "," ));
payload = az_span_copy(payload, AZ_SPAN_FROM_STR( "\" weight\": "));
(void)az_span_u32toa(payload, weight , &payload);
payload = az_span_copy(payload, AZ_SPAN_FROM_STR(" }"));
payload = az_span_copy_u8(payload, '\0');
*out_payload = az_span_slice(original_payload, 0, az_span_size(original_payload) - az_span_size(payload) - 1);
}
static void sendTelemetry()
{
az_span telemetry = AZ_SPAN_FROM_BUFFER(telemetry_payload);
Logger.Info("Sending telemetry ...");
// The topic could be obtained just once during setup,
// however if properties are used the topic need to be generated again to reflect the
// current values of the properties.
if (az_result_failed(az_iot_hub_client_telemetry_get_publish_topic(
&client, NULL, telemetry_topic, sizeof(telemetry_topic), NULL)))
{
Logger.Error("Failed az_iot_hub_client_telemetry_get_publish_topic");
return;
}
getTelemetryPayload(telemetry, &telemetry);
if (esp_mqtt_client_publish(
mqtt_client,
telemetry_topic,
(const char*)az_span_ptr(telemetry),
az_span_size(telemetry),
MQTT_QOS1,
DO_NOT_RETAIN_MSG)
== 0)
{
Logger.Error("Failed publishing");
}
else
{
Logger.Info("Message published successfully");
}
}
// Arduino setup and loop main functions.
void setup()
{
establishConnection();
pinMode(PushButton, INPUT);
}
void loop()
{
if (WiFi.status() != WL_CONNECTED)
{
connectToWiFi();
}
#ifndef IOT_CONFIG_USE_X509_CERT
else if (sasToken.IsExpired())
{
Logger.Info("SAS token expired; reconnecting with a new one.");
(void)esp_mqtt_client_destroy(mqtt_client);
initializeMqttClient();
}
#endif
int Push_button_state = digitalRead(PushButton);
// if condition checks if push button is pressed
if ( Push_button_state == HIGH )
{
Serial.println("De Button Is ingedrukt");
sendTelemetry();
delay(500);
}
}
The idea is that when I send a Direct Method "GETWEIGHT" I get a json value back.
In your initializeMqttClient method, you can add the following line.
mqtt_client.setCallback(receivedCallback);
Your receivedCallback method can have the following definition (code from a Microsoft sample)
void receivedCallback(char* topic, byte* payload, unsigned int length)
{
Logger.Info("Received [");
Logger.Info(topic);
Logger.Info("]: ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println("");
}
You mentioned you want to retrieve data from the device, so you probably want to respond to the message. This is done by sending a message on the right topic. You need to include the status (for instance a 200 indicating 'OK') and the ID of the direct method. This id is included when you receive the direct method. For instance, if you receive a direct method with ID 42, you can respond to it by publishing:
void RespondToDirectMethod()
{
mqtt_client.publish("$iothub/methods/res/200/?$rid=42", "", false);
}

Arduino How to POST a request to a HTTPS with ArduinoHttpClient

I'm pretty new on Arduino. I'm using ArduinoHttpClient and need to POST a request in secure way (https://).
I'm not able to define the https:// on the serverName passed to HttpClient(ethernetClient, serverName, webServerPort).
When I use serverName = url (ssl9083.websiteseguro.com or 179.188.19.74) with port 443 the board hangs and after sometime returns -3 on httpClient.responseStatusCode().
I'm using Arduino Uno R3 with Ethernet Shield W5100.
I'd appreciate any help. Below the code.
Thank you in advance.
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <ArduinoHttpClient.h>
//UDP Variables
#define UDP_PACKET_SIZE 80 //UDP size
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress localIp(192, 168, 1, 9);
unsigned int localPort = 8888; // local port to listen on
char packetBuffer[UDP_PACKET_SIZE]; // buffer to hold incoming packet,
EthernetUDP Udp; // An EthernetUDP instance to let us send and receive packets over UDP
//Http Variables
// Environment = P, H, D
char ENV[1] = {'H'};
const char* devServerName = "192.168.1.105";
const char* homServerName = "179.188.19.74";
//const char* homServerName = "https://ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "https://ssl9083.websiteseguro.com"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com"; Port 80 - OK conectou e retornou 404
//const char* homServerName = "179.188.19.74"; Port 80 OK conectou e retornou 404 - Port 443 retornou -3
const char* prdServerName = "ssl9083.websiteseguro.com/cfbinformatica";
String measurementServiceInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String postInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String serverName;
int webServerPort;
EthernetClient ethernetClient;
String authUserUid;
String userValidationUidCredentials;
void setup() {
setupSerial();
setupEthernetUDP();
setupHttp();
}
void setupSerial() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
}
void setupEthernetUDP() {
// start the Ethernet
Ethernet.begin(mac, localIp);
Serial.print("IP: ");
Serial.println(Ethernet.localIP());
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Etn shield notFnd");
while (1);
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Cable notConn");
while (1);
}
// start UDP
Udp.begin(localPort);
Serial.println("UDP init OK");
delay(5000);
}
void setupHttp() {
// Your Domain name with URL path or IP address with path
switch(ENV[0]) {
case 'P' :
serverName = prdServerName;
webServerPort = 443;
postInsertMeasurement = "/housemeterprd" + measurementServiceInsertMeasurement;
break;
case 'H' :
serverName = homServerName;
webServerPort = 443;
postInsertMeasurement = "/cfbinformatica/housemeterhom" + measurementServiceInsertMeasurement;
break;
default :
serverName = devServerName;
webServerPort = 80;
postInsertMeasurement = "/housemeterdev" + measurementServiceInsertMeasurement;
}
authUserUid = "Mg==";
userValidationUidCredentials = "PlUfGKwdXKmcF7HEoEPFu5QqGA3w52ukaUsIp5gOOlOXX928fermbxvGNsfbVr4Q";
Serial.println("HTTP init OK");
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i=0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
readPackage();
processPackage();
}
delay(10);
}
void readPackage() {
// read the packet into packetBufffer
Udp.read(packetBuffer, UDP_PACKET_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
}
void processPackage() {
switch(packetBuffer[0]) {
case 'A' :
handleAckMsg();
break;
case 'E' :
handleErrorMsg();
break;
default :
handleDataMsg();
}
}
void handleAckMsg() {
}
void handleErrorMsg() {
}
void handleDataMsg() {
String meterMAC;
meterMAC = convertToString(packetBuffer+35, 12);
String measurementValue;
measurementValue = convertToString(packetBuffer+20, 15);
String postData = "{\"meterMAC\":\"" + meterMAC + "\",\"measurementValue\":" + measurementValue +"}";
sendHttpPostDataMsg(&postData);
replyBack();
}
void sendHttpPostDataMsg(String *postData) {
Serial.print(serverName);
Serial.println(" Server ");
Serial.print(webServerPort);
Serial.println(" port ");
Serial.print(postInsertMeasurement);
Serial.println(" Url");
String data = *postData;
Serial.print(data);
Serial.println(" data ");
Serial.print(data.length());
Serial.println(" data length ");
HttpClient httpClient = HttpClient(ethernetClient, serverName, webServerPort);
httpClient.beginRequest();
httpClient.post(postInsertMeasurement);
httpClient.sendHeader("Content-Type", "application/json;charset=utf-8");
httpClient.sendHeader("Content-Length", data.length());
httpClient.sendHeader("Accept", "application/json");
httpClient.sendHeader("AuthUserUid", authUserUid);
httpClient.sendHeader("AuthUserValidationUid", userValidationUidCredentials);
httpClient.sendHeader("DeviceLanguage", "English");
httpClient.sendHeader("AuthUserProfile", "user");
httpClient.beginBody();
httpClient.print(data);
httpClient.endRequest();
int statusCode = httpClient.responseStatusCode();
String response = httpClient.responseBody();
httpClient.flush();
httpClient.stop();
Serial.print(statusCode);
Serial.println(" Http ret code");
Serial.print("Response: ");
Serial.println(response);
}
void replyBack() {
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(packetBuffer);
Udp.endPacket();
}
String convertToString(char* arr, int size)
{
int i;
String s = "";
for (i = 0; i < size; i++) {
s = s + arr[i];
}
return s;
}
here the results of the http call:
21:30:49.179 -> IP: 192.168.1.9
21:30:49.179 -> UDP init OK
21:30:54.226 -> HTTP init OK
21:31:05.891 -> Received packet of size 47
21:31:05.891 -> From 192.168.1.32, port 58412
21:31:05.937 -> Contents:
21:31:05.937 -> 000000000000000010330000000017.9090DEADBEEFFEED
21:31:05.985 -> 179.188.19.74 Server
21:31:06.031 -> 443 port
21:31:06.031 -> /cfbinformatica/housemeterhom/MeasurementService.svc/InsertMeasurement Url
21:31:06.125 -> {"meterMAC":"DEADBEEFFEED","measurementValue":0000000017.9090} data
21:31:06.172 -> 62 data length
21:32:07.214 -> -3 Http ret code
21:32:07.214 -> Response:

Why have I connection failed when I try to connect to my localhost?

I have an esp32 with one sensor(BMP280) connected and one database where I want to storage three parameters: temperature, atmospheric pressure and altitude. The database is on localhost with 8080 port. I cannot to connect at my localhost and I have connection failed. I have tried to put at host the ip address 0.0.0.0 or localhost:8080 and it doesn't work. What is the problem?
I attach my code below:
#include <BMP280_DEV.h>
#include <WiFi.h>
float temperature, pressure, altitude;
BMP280_DEV bmp280;
const char * ssid = "*******";
const char * password = "*********";
const char * host = "127.0.0.1";
const int port = 8080;
const int watchdog = 5000;
unsigned long previousMillis = millis();
void init_wifi() {
//We start by connecting to a Wi-Fi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
bmp280.begin(BMP280_I2C_ALT_ADDR);
//bmp280.setPresOversampling(OVERSAMPLING_X4);
//bmp280.setTempOversampling(OVERSAMPLING_X1);
//bmp280.setIIRFilter(IIR_FILTER_4);
bmp280.setTimeStandby(TIME_STANDBY_2000MS);
bmp280.startNormalConversion();
init_wifi();
}
void loop() {
if (bmp280.getMeasurements(temperature, pressure, altitude)) {
Serial.print(temperature);
Serial.print(F("*C "));
Serial.print(pressure);
Serial.print(F("hPa "));
Serial.print(altitude);
Serial.println(F("m"));
delay(20000);
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > watchdog) {
previousMillis = currentMillis;
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("Connection Failed");
return;
}
String url = "/test_bmp280/index.php?temp=";
url += temperature;
url += "&pres=";
url += pressure;
url += "&alt=";
url += altitude;
client.print(String("GET ") + url + "HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>>Client Timeout !");
client.stop();
return;
}
}
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
}
}
}

How do I make an HTTPS request with SIM900 (Arduino)

I try to make an HTTPS GET request and make an HTTPS POST request with the data recieved... I am using an arduino UNO with the library GSM_GPRS_GPS_Shield_GSMSHIELD and the GSM GPRS shield SIM900. Here is my current code below:
//include libs
#include "SIM900.h"
#include "inetGSM.h"
#include <SoftwareSerial.h>
InetGSM inet;
//data holder
int par1 = -1;
int par2 = -1;
void setup() {
Serial.begin(9600);
Serial.println("BEGIN");
boolean started = false;
SIM900power();
//initialize the SIM900
if (gsm.begin(2400)){
Serial.println("READY");
started=true;
}else Serial.println("IDLE");
//connect it to the network
if(started){
if (inet.attachGPRS("free", "", ""))
Serial.println("ATTACHED");
else Serial.println("ERROR");
delay(1000);
gsm.SimpleWriteln("AT+CIFSR");
delay(3000);
gsm.WhileSimpleRead();
//GET request
char * json = "";
while(strlen(json) < 4){
delay(2000);
char msg[200] = "";
Serial.println(inet.httpGET("my.site.com", 80, "/somethingToGet?param=1", msg, 200));
//interpret Json
char * msg_tmp = msg;
json = strstr (msg_tmp, "[{");
}
if(json != ""){
const byte posPar1 = (int)(strstr(json, "par1") - json) + 7;
const byte posPar2 = (int)(strstr(json, "par2") - json) + 7;
if(json[posPar1] != 'u')
par1 = extractNum(json, posPar1);
if(json[posPar2] != 'u')
par2 = extractNum(json, posPar2);
}
if(json == "" || par1 == -1 || par2 == -1){
SIM900power();
Serial.println("A JSON ERROR OCCURED");
while(1){}}
}
};
void loop() {
aPostRequest();
while(1){}
};
void SIM900power()
{
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(9, LOW);
delay(8000);
}
//extract the data from the Json string
int extractPar(char * json, byte pos){
int num = 0;
while (json[pos] != '"'){
num = json[pos]-'0' + num * 10;
pos++;
}
return num;
}
//POST request
void aPostRequest(){
if( par1 != -1 && par2 != -1){
boolean dataFound = true;
while(dataFound){
delay(2000);
char params[100];
snprintf(params, 100, "par1=%d&par2=%d", par1,par2);
char msg[200] = "";
dataFound = (inet.httpPOST("my.site.com ", 80, "/something", params , msg, 200) == 0);
}
}
}
I have two web sites, an HTTP one for my tests and the other one in HTTPS. As you can imagine, it's working on my HTTP one.
I don't know how to solve this problem but I think I need to do some tricky things with certificates in the library... can somebody help?
PS: if you want to test the code, you need to uncomment the HTTPPOST() function in the file inetGSM.h of the library. You can edit the functions httpGET() and HTTPPOST() in the file inetGSM.cpp.
UPDATE
There is the library code for the GET function below (httpPOST() works the same) :
int InetGSM::httpGET(const char* server, int port, const char* path, char* result, int resultlength)
{
boolean connected=false;
int n_of_at=0;
int length_write;
char end_c[2];
end_c[0]=0x1a;
end_c[1]='\0';
/*
Status = ATTACHED.
if(gsm.getStatus()!=GSM::ATTACHED)
return 0;
*/
while(n_of_at<3) {
if(!connectTCP(server, port)) {
#ifdef DEBUG_ON
Serial.println("DB:NOT CONN");
#endif
n_of_at++;
} else {
connected=true;
n_of_at=3;
}
}
if(!connected) return 0;
gsm.SimpleWrite("GET ");
gsm.SimpleWrite(path);
gsm.SimpleWrite(" HTTP/1.0\r\nHost: ");
gsm.SimpleWrite(server);
gsm.SimpleWrite("\r\n");
gsm.SimpleWrite("User-Agent: Arduino");
gsm.SimpleWrite("\r\n\r\n");
gsm.SimpleWrite(end_c);
switch(gsm.WaitResp(10000, 10, "SEND OK")) {
case RX_TMOUT_ERR:
return 0;
break;
case RX_FINISHED_STR_NOT_RECV:
return 0;
break;
}
delay(50);
#ifdef DEBUG_ON
Serial.println("DB:SENT");
#endif
int res = gsm.read(result, resultlength);
//gsm.disconnectTCP();
//int res=1;
return res;
}
I have already tried to change the HTTP/1.0 for HTTPS/1.0, but nothing appends.
UPDATE 2
I redirected my request through my HTTP server because I still have not found an answer, if someone could answer for those who could be blocked!
I was trying to make a HTTPS request to a Lambda function that i coded in AWS. The function had to send a json body from a WEMOS D1 mini via a POST to AWS. TBH, I don't know, if this will solve your Issue on your Controller, but it might be worth trying :)
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#ifndef STASSID
#define STASSID "<yourWiFiSSID>"
#define STAPSK "<yourWifiPW>"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "<the host link here (has to look like **google.com** important, dont add the route here) >";
const int httpsPort = 443;
const String data = "<Json Object here e.g -> **{\"temperature\": 20.5, \"humidity\": 60}**>";
// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char fingerprint[] PROGMEM = "5F F1 60 31 09 04 3E F2 90 D2 B0 8A 50 38 04 E8 37 9F BC 76";
void setup() {
Serial.begin(115200);
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Use WiFiClientSecure class to create TLS connection
WiFiClientSecure client;
Serial.print("connecting to ");
Serial.println(host);
Serial.printf("Using fingerprint '%s'\n", fingerprint);
client.setFingerprint(fingerprint);
client.setInsecure();
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
String url = "<your route here e.g **/photos/test**> ";
Serial.print("requesting URL: ");
Serial.println(url);
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n"+
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/json;charset=UTF-8\r\n\r\n"+
data +"\r\n");
Serial.println("request sent");
//READ INCOMING HTML
uint8_t * _buffer = new uint8_t[128];
String line = "";
if (client.connected()) {
int actualLength = client.read(_buffer, 128);
// If it fails for whatever reason
if(actualLength <= 0)
{
return;
}
// Concatenate the buffer content to the final response string
// I used an arduino String for convenience
// but you can use strcat or whatever you see fit
//TRANSFORM EVERY CHAR FROM INCOMING HTML
line += String((char*)_buffer).substring(0, actualLength);
if (line == "\r") {
Serial.println("headers received");
}
}
Serial.print("Line: ");
Serial.println(line);
if (line.startsWith("{\"state\":\"success\"")) {
Serial.println("esp8266/Arduino CI successfull!");
} else {
Serial.println("esp8266/Arduino CI has failed");
}
Serial.println("reply was:");
Serial.println("==========");
Serial.println(line);
Serial.println("==========");
Serial.println("closing connection");
}
void loop() {
}
I really hope this might have helped someone.

Whats the purpose of "num" in arduinoWebSockets?

Whats the purpose of num in webSocket.sendTXT(num, "Connected"); or at any other place its used in the code, what function does it serve? Because it doesn't ever get defined as anything anywhere, but it is required to
be passed as a function argument for it to work.
In void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) it's set as a function parameter.
Links2004/arduinoWebSockets Library
/*
* WebSocketServer_LEDcontrol.ino
*
* Created on: 26.11.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>
#define LED_RED 15
#define LED_GREEN 12
#define LED_BLUE 13
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED: {
IPAddress ip = webSocket.remoteIP(num);
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// send message to client
webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
if(payload[0] == '#') {
// we get RGB data
// decode rgb data
uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
analogWrite(LED_RED, ((rgb >> 16) & 0xFF));
analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF));
analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF));
}
break;
}
}
void setup() {
//USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
//USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_RED, 1);
digitalWrite(LED_GREEN, 1);
digitalWrite(LED_BLUE, 1);
WiFiMulti.addAP("SSID", "passpasspass");
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
// start webSocket server
webSocket.begin();
webSocket.onEvent(webSocketEvent);
if(MDNS.begin("esp8266")) {
USE_SERIAL.println("MDNS responder started");
}
// handle index
server.on("/", []() {
// send index.html
server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error);};connection.onmessage = function (e) { console.log('Server: ', e.data);};function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if(r.length < 2) { r = '0' + r; } if(g.length < 2) { g = '0' + g; } if(b.length < 2) { b = '0' + b; } var rgb = '#'+r+g+b; console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>");
});
server.begin();
// Add service to MDNS
MDNS.addService("http", "tcp", 80);
MDNS.addService("ws", "tcp", 81);
digitalWrite(LED_RED, 0);
digitalWrite(LED_GREEN, 0);
digitalWrite(LED_BLUE, 0);
}
void loop() {
webSocket.loop();
server.handleClient();
}
Looking at the library's source code, it reveals that it's a client id, so you can differentiate between multiple clients, that are connected at the same time.
/*
* send text data to client
* #param num uint8_t client id
* #param payload uint8_t *
* #param length size_t
* #param headerToPayload bool (see sendFrame for more details)
* #return true if ok
*/
bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
return false;
}
if(length == 0) {
length = strlen((const char *) payload);
}
WSclient_t * client = &_clients[num];
if(clientIsConnected(client)) {
return sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
}
return false;
}

Resources