I'm trying to send sensor data from nodemcu ESP32 to firebase.
When using the basic example shown below it worked fine, and also when viewing the sensor data without sending it to firebase.
https://github.com/mobizt/Firebase-ESP32/tree/master/examples/Basic
However when I tried to edit the code a bit and send my sensor's data, I get an error, I would appreciate any help, code, and error attached.
#include <WiFi.h>
#include <FirebaseESP32.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "WiFi.h"
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define FIREBASE_HOST "trial-2c3ea.firebaseio.com"
#define FIREBASE_AUTH "Eu706797Vy2zOEDp3Bc9e4T9GZVAVwTyoxshl9Am"
#define WIFI_SSID "saadon 1"
#define WIFI_PASSWORD "0547258525"
//Define FirebaseESP32 data object
FirebaseData firebaseData;
FirebaseJson json;
DHT dht(DHTPIN, DHTTYPE);
const int oneWireBus = 2;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const int Analog_channel_pin= 15;
double Soil_Moisture = 0;
double Soil_Moisture_analog = 0;
String path = "/Test";
void printResult(FirebaseData &data);
void setup()
{
Serial.begin(115200);
sensors.begin();
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
Soil_Moisture_analog = analogRead(Analog_channel_pin);
Soil_Moisture = (0.00531*exp(0.29*(Soil_Moisture_analog*0.006+1.0265)))*100;
if (Firebase.setFloat(firebaseData, path + "/Air Temp" + t))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Air Humidity" + h))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Soil Temperature" + temperatureC))
{
Serial.println("PASSED");
printResult(firebaseData);
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Soil Moisture" + Soil_Moisture))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
delay(5000);
}
Error:
firebasecode:74:65: error: no matching function for call to 'FirebaseESP32::setFloat(FirebaseData&, StringSumHelper&)'
The setFloat method takes three parameters:
bool setFloat(FirebaseData &dataObj, const String &path, float floatValue);
From https://github.com/mobizt/Firebase-ESP32/blob/master/src/FirebaseESP32.h#L1084
So the path and value are separate parameters. Change the calls to setFloat to look like:
if (Firebase.setFloat(firebaseData, path + "/Air Temp", t))
This is the new code which for some reason does not send the air humidity data, only air temp, the soil temp and moisture works fine.
#include <WiFi.h>
#include <FirebaseESP32.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "WiFi.h"
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define FIREBASE_HOST "trial-2c3ea.firebaseio.com"
#define FIREBASE_AUTH "Eu706797Vy2zOEDp3Bc9e4T9GZVAVwTyoxshl9Am"
#define WIFI_SSID "saadon 1"
#define WIFI_PASSWORD "0547258525"
FirebaseData firebaseData;
FirebaseJson json;
void printResult(FirebaseData &data);
//Define FirebaseESP32 data object
DHT dht(DHTPIN, DHTTYPE);
const int oneWireBus = 2;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const int Analog_channel_pin= 32;
double Soil_Moisture = 0;
double Soil_Moisture_analog = 0;
String path = "/Test";
void setup()
{
Serial.begin(115200);
sensors.begin();
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
Soil_Moisture_analog = analogRead(Analog_channel_pin);
Soil_Moisture = (0.00531*exp(0.29*(Soil_Moisture_analog*0.006+1.0265)))*100;
Firebase.setFloat(firebaseData, path + "/Air Humidity", h);
Firebase.setFloat(firebaseData, path + "/Air Temp", t);
Firebase.setFloat(firebaseData, path + "/Soil Temperature", temperatureC);
Firebase.setFloat(firebaseData, path + "/Soil Moisture", Soil_Moisture);
delay(5000);
}
Related
I am working with DHT22 sensor and NodeMCU to get temperature and humidity values. I want to store values on google sheet and also display values on 1.3 inch oled display. I have used millis() to do multitasking but still not able to do multitask. Both task (display on oled and update on google sheet) take place after 1 minute interval. Please suggest what modifications can be done to code.
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include "DHT.h"
#include <OneWire.h>
#include <SPI.h>
#define DHTTYPE DHT22 // type of the temperature sensor
#include "SH1106Wire.h"
SH1106Wire display (0x3C, D1, D2);
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 4000; // interval at which to blink (milliseconds)
const int DHTPin = 14; //--> The pin used for the DHT11 sensor is Pin D1 = GPIO5
DHT dht(DHTPin, DHTTYPE); //--> Initialize DHT sensor, DHT dht(Pin_used, Type_of_DHT_Sensor);
#define ON_Board_LED 2 //--> Defining an On Board LED, used for indicators when the process of connecting to a wifi router
const char* ssid = "OPPO F11 Pro"; //--> Your wifi name or SSID.
//const char* ssid = "SWE-SEEIT";
const char* host = "script.google.com";
const int httpsPort = 443;
WiFiClientSecure client; //--> Create a WiFiClientSecure object.
String GAS_ID = "AKfycbxoDW-7HxrMx90MH7ggsM_0DOTz3gIj-Z06kWTGOwOaoFoaUxW4xfGn_8L7WJh6LX3o"; //--> spreadsheet script ID
void setup() {
dht.begin();
delay(500);
display.init();
display.flipScreenVertically();
Serial.begin(115200);
WiFi.begin(ssid, NULL); //--> Connect to your WiFi router
pinMode(ON_Board_LED,OUTPUT); //--> On Board LED port Direction output
digitalWrite(ON_Board_LED, HIGH); //--> Turn off Led On Board
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(ON_Board_LED, LOW);
delay(250);
digitalWrite(ON_Board_LED, HIGH);
delay(250);
}
digitalWrite(ON_Board_LED, HIGH); //--> Turn off the On Board LED when it is connected to the wifi router.
client.setInsecure();
}
void loop() {
int h = dht.readHumidity();
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor !");
delay(500);
return;
}
String Temp = "Temperature : " + String(t) + " °C";
String Humi = "Humidity : " + String(h) + " %";
Serial.println(Temp);
Serial.println(Humi);
servosweep();
sendData(t, h);
delay(60000) ;
}
void servosweep(){
int h = dht.readHumidity();
float t = dht.readTemperature();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
display.setFont(ArialMT_Plain_16);
display.clear();
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString (60,0,"Temperature (°C)");
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(60,16,String(t));
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(60,32,"Humidity (%)");
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(60,48,String(h));
display.display();
}
}
// Subroutine for sending data to Google Sheets
void sendData(float tem, int hum) {
//Serial.println("==========");
//Serial.print("connecting to ");
//Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
//----------------------------------------Processing data and sending data
String string_temperature = String(tem);
String string_humidity = String(hum, DEC);
String url = "/macros/s/" + GAS_ID + "/exec?temperature=" + string_temperature + "&humidity=" + string_humidity;
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: BuildFailureDetectorESP8266\r\n" +
"Connection: close\r\n\r\n");
//----------------------------------------Checking whether the data was sent successfully or not
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line == "\r") {
//Serial.println("headers received");
break;
}
}
String line = client.readStringUntil('\n');
}
I want to use timer interrupter combined with BLE to transmit in esp32.
I found that an error occurs when the transmission cycle is too fast.
I don't know what caused this error.
Help me plz.............................................................................................
The error
This is my code
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
////////////////////////////////////////////////////////////
#include <BLE2902.h>
#define PERIOD_MS 5
#define BAUD_RATE 115200
#define BLE_WR_EN 0x5A
#define BLE_WR_DIS 0x55
#define SERVICE_UUID "0000ffe0-0000-1000-8000-00805f9b34fb"
#define CHARACTERISTIC_UUID_RX "0000ffe2-0000-1000-8000-00805f9b34fb"
#define CHARACTERISTIC_UUID_TX "0000ffe1-0000-1000-8000-00805f9b34fb"
int PERIOD_US=PERIOD_MS*1000;
/* create a hardware timer */
hw_timer_t * timer = NULL;
/* LED pin */
int led = 2;
/* LED state */
volatile byte state = LOW;
int i=0;
BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;
void IRAM_ATTR onTimer(){
//state = !state;
if(i<700){
i++;
}
else{
i=0;
}
//Serial.println(state);
char txString[8];
dtostrf(i, 1, 2, txString);
pCharacteristic->setValue(txString);
pCharacteristic->notify();
std::string txValue=pCharacteristic->getValue();
Serial.print("txValue:");
Serial.println(txValue.c_str());
//digitalWrite(led, state);
}
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("********************************");
Serial.println("Connected");
Serial.println("********************************");
timerAlarmEnable(timer);
};
void onDisconnect(BLEServer* pServer) {
Serial.println("********************************");
Serial.println("Disconnected");
Serial.println("********************************");
timerAlarmDisable(timer);
//delay(1000);
///*
// Start the service
//pService->start();
// Start advertising
//pServer->getAdvertising()->start();
pServer->startAdvertising();
//*/
//ESP.restart();
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
std::string EN="Z";
std::string DIS="U";
Serial.print("rxValue:");
Serial.println(rxValue.c_str());
/*
//Serial.println(getvalue);
if (rxValue==EN ) {
//g_Timer.enable(g_TimerId);
timerAlarmEnable(timer);
digitalWrite(LED, HIGH);
}
else if (rxValue==DIS) {
//g_Timer.disable(g_TimerId);
timerAlarmDisable(timer);
//data_count = 0;
digitalWrite(LED, LOW);
}
*/
}
};
void setup() {
Serial.begin(115200);
Serial.begin(BAUD_RATE);
////////////////////////////////////////
Serial.println("Starting BLE Server!");
BLEDevice::init("ESP32-INTERRUT-Server");
/////////////////////////////////////////////////////////////////////////////////////
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_READ|
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
////////////////////////////////////////////////////////////////////
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, PERIOD_US, true);
timerAlarmDisable(timer);
}
void loop() {
}
I have two sensors linked to my Arduino UNO: MAX30100(this is the problem) and LM35 Sensor.
These two sensors work without the ESP8266, their values are shown on the Serial port of arduino.
The problem is when I include the ESP8266 to send the values to ThingSpeak. The values for LM35 sensor are sent and they appear well on ThingSpeak.
The problem is with MAX30100. MAX30100 show just the value 0, that means that MAX30100 is not measuring nothing at all.
Does anybody has any ideea what to do to make the MAX30100 sensor to work while sending data to Thingspeak? I post my code below.
#define USE_ARDUINO_INTERRUPTS true
#define DEBUG true
#define SSID "Redmi" // "SSID-WiFiname"
#define PASS "wtfwtfwtf" // "password"
#define IP "184.106.153.149" // thingspeak.com ip
#define RX 10
#define TX 11
#include <Wire.h>
#include "Stdlib.h"
#include <SoftwareSerial.h>
#include "Timer.h"
#include <PulseSensorPlayground.h> // Includes the PulseSensorPlayground
Library.
Timer t;
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
String msg = "GET /update?key=T4RF5YWLJKOU9MVO";
SoftwareSerial esp8266(RX,TX);
//Variables
const int PulseWire = A0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
const int LED13 = 13; // The on-board Arduino LED, close to PIN 13.
int Threshold = 550; //for heart rate sensor
float myTemp;
int myBPM;
float mybpm;
float mySPO2;
String BPM;
String temp;
String SPO2;
int error;
int panic;
int raw_myTemp;
float Voltage;
float tempC;
void onBeatDetected()
{
Serial.println("Beat!");
}
void setup()
{
Serial.begin(9600);
esp8266.begin(115200);
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
}
else {
Serial.println("SUCCESS");
}
// Double-check the "pulseSensor" object was created and "began" seeing a signal.
//This prints one time at Arduino power-up, or on Arduino reset.
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
Serial.println("AT");
esp8266.println("AT");
delay(3000);
if(esp8266.find("OK"))
{
connectWiFi();
}
}
void loop()
{
panic_button();
start: //label
error=0;
t.update();
//Resend if transmission is not completed
if (error==1)
{
goto start; //go to label "start"
}
delay(1000);
panic_button();
delay(1000);
panic_button();
onBeatDetected();
delay(1000);
panic_button();
heart();
delay(1000);
panic_button();
oxygen();
delay(1000);
panic_button();
temp1();
}
boolean connectWiFi()
{
Serial.println("AT+CWMODE=1");
esp8266.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
esp8266.println(cmd);
delay(5000);
if(esp8266.find("OK"))
{
return true;
}
else
{
return false;
}
}
void temp1(){
raw_myTemp = analogRead(A1);
Voltage = (raw_myTemp / 1023.0) * 5000; // 5000 to get millivots.
myTemp = Voltage * 0.1;
Serial.print("Temperature = ");
Serial.print(myTemp);
Serial.print(" Degree Celsius\n");
delay(20);
char buffer3[10];
temp = dtostrf(myTemp, 4, 1, buffer3);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(10000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field3="; //field 1 for BPM
cmd += temp;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void heart(){
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.println("");
tsLastReport = millis();}
float mybpm = pox.getHeartRate();
delay(20);
char buffer1[10];
BPM = dtostrf(mybpm, 4, 1, buffer1);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(1000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field1="; //field 1 for BPM
cmd += mybpm;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void oxygen(){
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("bpm / SPO2::");
Serial.print(pox.getSpO2());
Serial.println("%");
tsLastReport = millis();}
/*int mySPO2 = pox.getSpO2();*/
delay(20);
char buffer2[10];
SPO2 = dtostrf(pox.getSpO2(), 4, 1, buffer2);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field2="; //field 1 for BPM
cmd +=SPO2;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void panic_button(){
panic = digitalRead(8);
if(panic == HIGH){
Serial.println(panic);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field4=";
cmd += panic;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
}
Expected Output: The values of MAX30100 and LM35 should be displayed on Serial monitor and uploaded to ThingSpeak platform.
I have been working on the Azure Device Twins for the past month. The main goal is to subscribe to three device twin paths so that any change of the desired property results in a notification shown on the serial monitor and the desired property is parsed and given as a reported property. I am running the code on a NodeMCU and the issue I am facing is that the device connects to the IoTHub and publishes data but any changes in the device twin are not shown or parsed. The Device Twin works when api-version=2016-11-14 is added to the MQTT Username, as soon as I add the api-version in the username it gives the error failed rc=-1. The code I am using is given below
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
const char mqtt_client[] = "test-device1";
const char mqtt_server[] = "HyperNet-IoTHub-Azure-Sphere.azure-devices.net";
const int mqtt_port = 8883;
const char mqtt_user[] = "HyperNet-IoTHub-Azure-Sphere.azure-devices.net/test-device1/api-version=2016-11-14";
void callback(char* topic, byte* payload, unsigned int length);
WiFiClientSecure WiFiclient;
PubSubClient client(WiFiclient);
void callback(char* topic, byte* payload, unsigned int length);
void parseDesiredProperties(byte* payload);
unsigned long previousMillis = 0;
long interval = 5000;
void reconnect();
void setup(){
Serial.begin(9600);
delay(250);
client.setServer(mqtt_server, 8883);
client.setCallback(callback);
WiFi.disconnect();
delay(100);
WiFi.mode(WIFI_STA);
Serial.println("Connecting To Wi-Fi: " + String(ssid));
WiFi.begin(ssid,pass);
while(WiFi.status() !=WL_CONNECTED){
delay(500);
Serial.print("..");
}
Serial.println(" ");
Serial.println("Wi-Fi Connected");
}
void loop(){
if(!client.connected()){
reconnect();
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
float value1 = 12.3;
float value2 = 13.6;
String postData = "{\"testvalue1\":" + String(value1) + ",\"testvalue2\":" + String(value2) +"}";
char postBuffer[postData.length()+1];
postData.toCharArray(postBuffer, postData.length()+1);
Serial.println(postBuffer);
client.publish("devices/test-device1/messages/events/", postBuffer);
}
client.loop();
}
void reconnect(){
WiFiclient.setInsecure();
while(!client.connected()){
Serial.println("Attempting MQTT Connection");
if (client.connect(mqtt_client, mqtt_user, mqtt_pass)) {
Serial.println("connected");
client.subscribe("devices/test-device1/messages/devicebound/#");
// subscribe to operation responses
client.subscribe("$iothub/twin/res/#");
// subscribe to desired property updates
client.subscribe("$iothub/twin/PATCH/properties/desired/#");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("MQTT message arrived on topic: ");
Serial.println(topic);
if (String(topic).startsWith("$iothub/twin/PATCH/properties/desired")) {
parseDesiredProperties(payload);
}
}
void parseDesiredProperties(byte* payload) {
JsonObject& root = jsonDesiredProperties.parseObject(payload);
if(root.success()) {
Serial.println("Parsed desired properties");
int newMillis=root["reportInterval"];
if(newMillis > 2999 && newMillis < 120001) {
interval = newMillis;
String postProperty = "{\"reportInterval\":" + String(newMillis) + "}";
char postBuffer[postProperty.length()+1];
postProperty.toCharArray(postBuffer, postProperty.length()+1);
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=1", postBuffer);
Serial.print("Set new interval to: ");
Serial.println(newMillis);
}
}
else {
Serial.println("Could not parse desired properties");
}
}
the code snippet you posted seems to be incomplete. It was missing the jsonDesiredProperties for instance. You might have left some other things out, but one important thing missing is the certificate fingerprint. IoT Hub only accepts secure MQTT connections, and to do that, you need to include the SHA1 fingerprint of Microsoft's CA cert.
You can download the certificate and put it in a file and retrieve the fingerprint with openssl:
openssl x509 -noout -fingerprint -sha1 -inform pem -in [certificate-file.crt]
Your setup method can then include the fingerprint:
static const char *fingerprint PROGMEM = "D4 DE 20 D0 5E 66 FC 53 FE 1A 50 88 2C 78 DB 28 52 CA E4 74";
void setup(){
Serial.begin(9600);
delay(250);
WiFiclient.setFingerprint(fingerprint);
client.setServer(mqtt_server, 8883);
client.setCallback(callback);
WiFi.disconnect();
delay(100);
WiFi.mode(WIFI_STA);
Serial.println("Connecting To Wi-Fi");
WiFi.begin("<REDACTED>","<REDACTED>");
while(WiFi.status() !=WL_CONNECTED){
delay(500);
Serial.print("..");
}
Serial.println(" ");
Serial.println("Wi-Fi Connected");
}
Another change I made is the API version you included in your MQTT username. You can use ?api-version=2018-06-30 rather than api-version=2016-11-14.
I tested these changes on my NodeMCU, and updating the reported twin properties is working just fine! Let me know if this works for you!
DynamicJsonBuffer jsonDesiredProperties;
char ssid[] = "Imran's Phone";
char pass[] = "1234567890";
int status = WL_IDLE_STATUS;
const char mqtt_client[] = "test-device1";
const char mqtt_server[] = "Hypernet-IOF.azure-devices.net";
const int mqtt_port = 8883;
const char mqtt_user[] = "HyperNet-IoF.azure-devices.net/test-device1/2018-06-30";
static const char *fingerprint PROGMEM = "D4 DE 20 D0 5E 66 FC 53 FE 1A 50 88 2C 78 DB
28 52 CA E4 74";
void callback(char* topic, byte* payload, unsigned int length);
WiFiClientSecure WiFiclient;
PubSubClient client(WiFiclient);
void callback(char* topic, byte* payload, unsigned int length);
void parseDesiredProperties(byte* payload);
unsigned long previousMillis = 0;
long interval = 5000;
void reconnect();
void setup(){
Serial.begin(9600);
delay(250);
WiFiclient.setFingerprint(fingerprint);
client.setServer(mqtt_server, 8883);
client.setCallback(callback);
WiFi.disconnect();
delay(100);
WiFi.mode(WIFI_STA);
Serial.println("Connecting To Wi-Fi: " + String(ssid));
WiFi.begin(ssid,pass);
while(WiFi.status() !=WL_CONNECTED){
delay(500);
Serial.print("..");
}
Serial.println(" ");
Serial.println("Wi-Fi Connected");
}
void loop(){
if(!client.connected()){
reconnect();
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
float value1 = 12.3;
float value2 = 13.6;
String postData = "{\"testvalue1\":" + String(value1) + ",\"testvalue2\":" +
String(value2) +"}";
char postBuffer[postData.length()+1];
postData.toCharArray(postBuffer, postData.length()+1);
Serial.println(postBuffer);
client.publish("devices/test-device1/messages/events/", postBuffer);
}
client.loop();
}
void reconnect(){
WiFiclient.setInsecure();
while(!client.connected()){
Serial.println("Attempting MQTT Connection");
if (client.connect(mqtt_client, mqtt_user, mqtt_pass)) {
Serial.println("connected");
client.subscribe("devices/test-device1/messages/devicebound/#");
// subscribe to operation responses
client.subscribe("$iothub/twin/res/#");
// subscribe to desired property updates
client.subscribe("$iothub/twin/PATCH/properties/desired/#");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("MQTT message arrived on topic: ");
Serial.println(topic);
if (String(topic).startsWith("$iothub/twin/PATCH/properties/desired")) {
parseDesiredProperties(payload);
}
}
void parseDesiredProperties(byte* payload) {
JsonObject& root = jsonDesiredProperties.parseObject(payload);
if(root.success()) {
Serial.println("Parsed desired properties");
int newMillis=root["reportInterval"];
if(newMillis > 2999 && newMillis < 120001) {
interval = newMillis;
String postProperty = "{\"reportInterval\":" + String(newMillis) + "}";
char postBuffer[postProperty.length()+1];
postProperty.toCharArray(postBuffer, postProperty.length()+1);
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=1", postBuffer);
Serial.print("Set new interval to: ");
Serial.println(newMillis);
}
}
else {
Serial.println("Could not parse desired properties");
}
}
I'm trying to make a GPS/GSM receiver with an Arduino Uno. My program is trying to ana]yse the incoming strings with a few ifs. Then I want to convert them to save them on an SD card, or send them as SMS.
This is the correct information from the GPS:
+GPSRD:
$GPGGA,151420.000,5222.61362,N,01658.51086,E,1,03,8.9,0.0,M,,M,,0000*44
$GPRMC,151420.000,A,5222.61362,N,01658.51086,E,0.46,160.58,201017,,,A*67
$GPVTG,160.58,T,,M,0.46,N,0.86,K,A*3B
The line I need is the third one, because there are coordinates. I want to save them. So I made some functions. I'm trying also to navigate the whole device by SMS commands. Everything is in the code. Here is the code:
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <string.h>
#define rxPin 7
#define txPin 8
String message="lalala", callingnumber="";
String response="";
String coords;
String data[13]={"","","","","","","","","","","","",""};
String thetime=(""), date=(""), latitude=(""), longitude=("");
SoftwareSerial mySerial(rxPin, txPin);
void setup() {
Serial.begin(115200);
mySerial.begin(19200);
while (!Serial) {
}
digitalWrite(3, HIGH);
delay(2000);
digitalWrite(3, LOW);
for(int i = 0; i < 8; i++) {
mySerial.println("AT");
Serial.println("AT");
delay(1000);
}
mySerial.println("");
delay(1000);
mySerial.println("Jestem gotowy!");
delay(1000);
mySerial.println("s - lokalizacja / g - wlacz gps / o - wylacz gps");
delay(1000);
Serial.println("AT+GPS=1");
delay(1000);
Serial.println("AT+CMGF=1");
delay(1000);
while (Serial.available()) {
mySerial.write(Serial.read());
}
}
void loop() {
RecData();
}
void RecData() {
int firstindex, lastindex;
Serial.setTimeout(1000);
response = Serial.readString();
firstindex = response.indexOf("$GPRMC");
lastindex = response.indexOf("$GPVTG");
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Start") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS("wlaczono");
OpenGPS();
}
}
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Stop") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS("zatrzymano");
CloseGPS();
}
}
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Sms") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS(message);
}
}
int a = 0;
for (int i=firstindex; i<lastindex; i++) {
mySerial.print(response[i]);
if(response[i] == ',') {
a++;
} else {
data[a] += response[i];
}
}
mySerial.print(firstindex);
mySerial.print("::");
mySerial.print(lastindex);
mySerial.println(" loop is working");
date = data[9];
thetime = data[1];
latitude = data[3] + data[4];
longitude = data[5] + data[6];
message = date.substring(0,2) + "." + date.substring(2,4) + "." + date.substring(4,6) + " " + thetime.substring(0,2) + ":" + thetime.substring(2,4) + ":" + thetime.substring(4,6) + " coords: " + latitude.substring(0,2) + "'" + latitude.substring(2,4) + "''" + latitude.substring(5,10) + "'''" + latitude.substring(10,11)+ " " + longitude.substring(1,3) + "'" + longitude.substring(3,5) + "''" + longitude.substring(6,11) + "'''" + longitude.substring(11,12);
for(int ii = 0; ii < 13; ii++) {
mySerial.print(data[ii]);
data[ii] = "";
//czyszczenie na szybko
}
if (firstindex < 0 && lastindex < 0) {
mySerial.write("test");
mySerial.print(response);
mySerial.print(response.length());
}
}
void OpenGPS() {
mySerial.println("wlaczam gps");
delay(500);
Serial.println("AT+GPSRD=1");
delay(500);
mySerial.println("Wlaczono");
}
void CloseGPS() {
mySerial.println("Wylaczam GPS");
delay(500);
Serial.println("AT+GPSRD=0");
}
void SignalQuality() {
mySerial.print("Jakosc sygnalu: ");
delay(1000);
Serial.println("AT+CSQ");
}
void SendSMS(String msg) {
mySerial.println("wysylam...");
delay(500);
Serial.println("AT+CMGS="+callingnumber);
delay(500);
Serial.print(msg);
delay(500);
Serial.println((char)26);
delay(500);
mySerial.println("wyslano");
}
I'm looking for some help, because it doesn't work well. Here is the screenshot of the executed program:
The response is not good. There was some text conversion to get 13 strings of message.
Please help, if I missed any information I can edit the post.
Thanks.