#include <WiFi.h>
#include <PubSubClient.h>
//#include "UbidotsESPMQTT.h"
//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>
//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define WIFISSID "ZyXEL_KEENETIC_620" // Put your WifiSSID here
#define PASSWORD "09101939" // Put your wifi password here
#define TOKEN "BBFF-LamC2X9MfgFypdT0UohUiTCoT1iGHh" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "ESP32_BME680_Station" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
#define PORT 1883
#define VARIABLE_LABEL1 "Temperature" // Assing the variable label
#define DEVICE_LABEL "esp32"
//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 433E6
//OLED pins
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Replace with your network credentials
// Variables to save date and time
// Initialize variables to get and save LoRa data
int rssi;
String loRaMessage;
String temperature;
String readingID;
char mqttBroker[] = "industrial.api.ubidots.com";
char payload[1000];
char topic1[150];
char topic2[150];
// Space to store values to send
char str_Temperature[10];
WiFiClient ubidots;
PubSubClient client(ubidots);
void callback(char* topic, byte* payload, unsigned int length)
{
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
Serial.write(payload, length);
Serial.println(topic);
}
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.println("Attempting MQTT connection...");
// Attemp to connect
if (client.connect(MQTT_CLIENT_NAME, TOKEN, ""))
{
Serial.println("Connected");
} else
{
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 2 seconds");
// Wait 2 seconds before retrying
delay(2000);
}
}
}
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);
// Replaces placeholder with DHT values
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATURE"){
return temperature;
}
else if (var == "RRSI"){
return String(rssi);
}
return String();
}
//------------------Initialize OLED Module-------------------------------------------//
void initOLED(){
//reset OLED display via software
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
//initialize OLED
Wire.begin(OLED_SDA, OLED_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.print("LORA RECEIVER");
}
//----------------------Initialize LoRa Module-----------------------------------------//
void initLoRA(){
int counter;
//SPI LoRa pins
SPI.begin(SCK, MISO, MOSI, SS);
//setup LoRa transceiver module
LoRa.setPins(SS, RST, DIO0);
while (!LoRa.begin(BAND) && counter < 10) {
Serial.print(".");
counter++;
delay(500);
}
if (counter == 10) {
// Increment readingID on every new reading
Serial.println("Starting LoRa failed!");
}
Serial.println("LoRa Initialization OK!");
display.setCursor(0,10);
display.clearDisplay();
display.print("LoRa Initializing OK!");
display.display();
delay(2000);
}
//----------------------Connect to WiFi Function-----------------------------------------//
//-----------------Read LoRa packet and get the sensor readings-----------------------//
void getLoRaData() {
Serial.print("Lora packet received: ");
// Read packet
while (LoRa.available()) {
String LoRaData = LoRa.readString();
// LoRaData format: readingID/temperature&soilMoisture#batterylevel
// String example: 1/27.43&654#95.34
Serial.print(LoRaData);
// Get readingID, temperature and soil moisture
int pos1 = LoRaData.indexOf('/');
int pos2 = LoRaData.indexOf('&');
int pos3 = LoRaData.indexOf('#');
readingID = LoRaData.substring(0, pos1);
temperature = LoRaData.substring(pos1 +1, pos2);
}
// Get RSSI
rssi = LoRa.packetRssi();
Serial.print(" with RSSI ");
Serial.println(rssi);
}
//-----------------------Function to get date and time from NTPClient------------------//
//-------------------------Display Readings on OLED-------------------------------------//
void displayReadings()
{
display.clearDisplay();
display.setCursor(0,0);
display.println("LoRa RECEIVER 1- Pune");
display.setCursor(0,20);
display.setTextSize(1);
display.print("TEMPERATURE");
display.setCursor(70,20);
display.print(":");
display.setCursor(80,20);
display.print(temperature);
display.drawCircle(116,20,1, WHITE);
display.setCursor(121,20);
display.print("C");
display.display();
delay(500);
}
void setup(){
// serial.begin(115200);
Serial.begin(115200);
WiFi.begin(WIFISSID, PASSWORD);
Serial.println();
Serial.print("Waiting for WiFi Connection ..............");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setServer(mqttBroker, 1883);
client.setCallback(callback);
// Initialize Serial Monitor
initOLED();
initLoRA();
}
void loop() {
if (!client.connected()) {
reconnect();
}
// Check if there are LoRa packets available
int packetSize = LoRa.parsePacket();
if (packetSize) {
getLoRaData();
displayReadings();
//dtostrf(temperature, 4, 2, str_Temperature);
sprintf(topic1, "%s%s", "/v1.6/devices/,esp32");
sprintf(payload, "%s", "");
sprintf(payload, "{\"%s\":", VARIABLE_LABEL1);
sscanf(payload, "%s {\"value\": %s}}", payload, temperature);
Serial.println("Publishing temperature to Ubidots Cloud");
client.publish(topic1, payload);
Serial.println();
client.loop();
}
}
Hello @Ahmed,
I hope everything is going well.
Overall, your code seems correct, at least from the Ubidots MQTT data sending perspective, although it’s hard to predict what other issues might be there as I can’t test locally. The only thing I saw was this line:
Instead of what you have, it should be:
sprintf(topic1, "%s%s", "/v1.6/devices/","esp32");
You were missing one closing and one opening quotation marks.
In addition to this, I saw that your code imports the Ubidots’ MQTT library for the ESP32, but you don’t use it. Instead, you manage all the MQTT communication with PubSubClient. I recommend actually using the library as it abstracts many of the hurdles of sending data over MQTT to Ubidots; for example, connecting to WiFi, managing the connection to the broker, building a correct payload, and sending it.
You can follow the below article which describes how to use the library:
Best Regards,
–Leo