Hello,
I am building a network of sensors for my home that will communicate with a MQTT broker that then sends the sensor feedback to a web app. As a result, I want my devices to send their payloads as JSON packets. I am working on a temperature sensor right now and I am having a problem sending over the JSON packet. The code compiles but the message does not get to the broker and my device notifies me that client.publish was not successful. I think it may be due to how I am loading the buffer and issues with lack of memory due to the size of the packet. Below is my source code, and I would appreciate feedback on how to fix this issue. Thank you!
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_Si7021.h>
#include <ArduinoJson.h>
// Update these with values suitable for your network.
const char* ssid = "********";
const char* password = "*****";
//const char* mqtt_server = "*********";
const char* mqtt_server = "broker.hivemq.com";
const char* clientID = "Device1";
const char* outTopic = "test";
const char* inTopic = "Request";
float humidity, temp_c,temp_f; // Values read from sensor
unsigned long previousMillis = 0; // will store last temp was read
const long interval = 2000; // interval at which to read sensor
Adafruit_Si7021 sensor;
WiFiClient espClient;
PubSubClient client(espClient);
char msg[50];
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
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 callback(char* topic, byte* payload, unsigned int length) {
// Conver the incoming byte array to a string
payload[length] = '\0'; // Null terminator used to terminate the char array
String message = (char*)payload;
Serial.print("Message arrived on topic: [");
Serial.print(topic);
Serial.print("], ");
Serial.println(message);
if(message == "send"){
gettemperature();
Serial.print("Sending temperature:");
Serial.println(temp_f);
dtostrf(temp_f , 2, 2, msg);
StaticJsonBuffer<1000> JSONbuffer;
JsonObject& root = JSONbuffer.createObject();
root["clientId"] = "Android-Autobahn";
root["eventType"] = "TEMPERATURE";
root["alertId"] = "12345";
root["timestamp"] = "1524151676676";
JsonObject& location = root.createNestedObject("location");
JsonObject& gps = location.createNestedObject("gps");
JsonObject& geometry = gps.createNestedObject("geometry");
JsonArray& coordinates = geometry.createNestedArray("coordinates");
coordinates.add(10.1);
coordinates.add(11);
geometry["type"] = "Point";
gps["type"] = "Feature";
JsonObject& sensorEvents = root.createNestedObject("sensorEvent");
sensorEvents["type"]= "THERMOMETER";
sensorEvents["subtype"]="highTemp";
sensorEvents["value"]=msg;
sensorEvents["threshold"]="72";
char JSONmessageBuffer[1000];
root.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
Serial.println("Sending message to MQTT topic..");
Serial.println(JSONmessageBuffer);
if (client.publish("test", JSONmessageBuffer) == true) { //update when server is changed
Serial.println("Success sending message");
} else {
Serial.println("Error sending message");
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientID)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, clientID);
// ... and resubscribe
client.subscribe(inTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
sensor = Adafruit_Si7021();
if (sensor.begin()) {
Serial.println('Sensor ready');
} else {
// TODO: We should probably reset the device if this happens
Serial.println('SENSOR FAILED TO START');
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void gettemperature() {
if(currentMillis - previousMillis >= interval) {
// save the last time you read the sensor
previousMillis = currentMillis;
temp_c = sensor.readTemperature(); // Read temperature as Celcius
temp_f = temp_c*1.8+32;
}
}