Display data on oled 1.3 inch screen after 5 seconds but update data on google sheet after every 15 minutes - sensors

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');
}

Related

sending data from max30100 sensor using esp8266 to thingspeak

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.

sensor esp8266 with arduino wont loop anymore

Do forgive me as i am new to programming.
I used a sample code I found online for dht22 and have added other sensors in my esp8266. However, when i added the code necessary for the latest sensor (waterproof temp sensor), it doesn't activate the loop. the serial monitor prints out one sensor reading but it stops there
12:03:50.208 -> WiFi connected - ESP IP address: ****
12:03:50.208 -> Attempting MQTT connection...connected
12:03:55.499 -> { "temperature": " 23.72", "humidity" : " 56.70", "soilmoisture" : "99", "soiltemperature" : " 22.00"}
I looked around and deleted the code for the temp sensor one by one and i have discovered that when i changed the
char data[80] to char data[100]
the code starts working again but now it is looping every milisecond or something instead of 10s that i have assigned
// Loading the ESP8266WiFi library and the PubSubClient library
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
// Uncomment one of the lines bellow for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//For capacitive soil sensor
const int AirValue = 865; //you need to replace this value with Value_1
const int WaterValue = 590; //you need to replace this value with Value_2
int soilMoistureValue = 0;
int soilmoisturepercent= 0;
// GPIO where the DS18B20 (soil temperature) is connected to
const int oneWireBus = D3;
// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "****";
const char* password = "****";
// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "****";
// Initializes the espClient
WiFiClient espClient;
PubSubClient client(espClient);
// DHT Sensor
const int DHTPin = 5;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;
char data[100];
// Don't change the function below. This functions connects your ESP8266 to your router
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.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}
// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
}
// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a unique name to the ESP8266.
Here's how it looks like now:
if (client.connect("ESP8266Client")) {
If you want more devices connected to the MQTT broker, you can do it like this:
if (client.connect("ESPOffice")) {
Then, for the other ESP:
if (client.connect("ESPGarage")) {
That should solve your MQTT multiple connections problem
THE SECTION IN loop() function should match your device name
*/
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Subscribe or resubscribe to a topic
// You can subscribe to more topics (to control more LEDs in this example)
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// The setup function sets your DHT sensor, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
dht.begin();
// Start the DS18B20 sensor
sensors.begin();
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// For this project, you don't need to change anything in the loop function.
// Basically it ensures that you ESP is connected to your broker
void loop() {
if (!client.connected()) {
reconnect();
}
if(!client.loop())
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a unique name to the ESP8266.
Here's how it looks like now:
client.connect("ESP8266Client");
If you want more devices connected to the MQTT broker, you can do it like this:
client.connect("ESPOffice");
Then, for the other ESP:
client.connect("ESPGarage");
That should solve your MQTT multiple connections problem
THE SECTION IN recionnect() function should match your device name
*/
client.connect("ESP8266Client");
now = millis();
// Publishes new temperature and humidity every 30 seconds
if (now - lastMeasure > 10000)
{
lastMeasure = now;
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
//put Sensor insert into soil
float sensorValue = analogRead(A0);
soilmoisturepercent = map(sensorValue, AirValue, WaterValue, 0, 100);
float s = soilmoisturepercent;
//sensor soil temperature code
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
//float temperatureF = sensors.getTempFByIndex(0);
// Check if any reads failed and exit early (to try again).
//
if (isnan(h) || isnan(t) || isnan(f) || isnan(soilmoisturepercent) || isnan(temperatureC))
{
Serial.println("Failed to read from sensors!");
return;
}
// Computes temperature values in Celsius
float hic = dht.computeHeatIndex(t, h, false);
static char temperatureTemp[7];
dtostrf(hic, 6, 2, temperatureTemp);
static char humidityTemp[7];
dtostrf(h, 6, 2, humidityTemp);
static char soilmoist[7];
dtostrf(soilmoisturepercent, 6, 2, soilmoist);
static char soiltemp[7];
dtostrf(temperatureC, 6, 2, soiltemp);
String dhtReadings = "{ \"temperature\": \"" + String(temperatureTemp) + "\", \"humidity\" : \"" + String(humidityTemp) + "\", \"soilmoisture\" : \"" + String(soilmoisturepercent) + "\", \"soiltemperature\" : \"" + String(soiltemp) + "\"}";
dhtReadings.toCharArray(data, (dhtReadings.length() + 1));
client.publish("room/temperature", temperatureTemp);
client.publish("room/humidity", humidityTemp);
client.publish("room/soilmoisture", soilmoist);
client.publish("room/soiltemperature", soiltemp);
// Publishes Temperature and Humidity values
client.publish("/esp8266/dhtreadings", data);
Serial.println(data);
}
}

Unable to subscribe to Azure Device Twins using MQTT and ESP8266

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");
}
}

Sending Sensor Data from Nodemcu ESP32 and Firebase

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);
}

How to send a text file and append it using Arduino

I'm working on a GPS logger project. I have an Arduino Mega set up with a transmitter and receiver and GPS and GSM modules. I also have an Arduino Uno with a transmitter, receiver and buzzer.
When the two devices go too far from each other, the GPS data is pulled and sent to my web server using the GSM module. When I send my file to the server it creates a text file and when I move to another location it overwrites the previous location.
I'm trying to figure out how to append the text file instead of overwriting it. I found a lot of stuff using an SD card shield but nothing without it.
#define GPS_PIN_1 9 // GPS serial pin RX
#define GPS_PIN_2 8 // GPS serial pin TX
#define CHECKPIN 13 // Pin that lights up when things are checked
#define GPSRATE 4800 // GPS baud rate
#include <SoftwareSerial.h>
#include <Flash.h>
#include <Streaming.h>
// How many bytes of input to buffer from the GPS?
#define BUFFERSIZE 100
#define ENDLN
int rx1Pin=31;
int txPin=30;
int tx1Pin=11;
int onModulePin = 2;
int rxPin=12;
SoftwareSerial mySerial = SoftwareSerial(GPS_PIN_1, GPS_PIN_2); //(rx,tx)
SoftwareSerial txSerial = SoftwareSerial(rxPin, txPin);
SoftwareSerial rxSerial = SoftwareSerial(rx1Pin, tx1Pin);
char sendChar ='H';
char incomingChar = 0;
int counter=0;
//GPS variables
int numSats = 0;
int fixType = 0;
int time[] = {
0, 0, 0};
double latitude = 0.0;
double longitude = 0.0;
long altitude = 0;
long maxAlt = 0;
int speed = 0;
int txCount = 0;
int ExOnce = 0;
int FalcomCheck = 0;
int LogCheck =0;
unsigned long GpsOffTime = 0;
unsigned long SmsStart = 0; // SMS-time
char buffer[BUFFERSIZE];
void switchModule(){ // Function to switch the module ON;
digitalWrite(onModulePin,HIGH);
delay(2000);
digitalWrite(onModulePin,LOW);
delay(2000);
}
void setup(){
pinMode(rxPin, INPUT);
pinMode(txPin,OUTPUT);
pinMode(rx1Pin, INPUT);
pinMode(tx1Pin,OUTPUT);
pinMode(GPS_PIN_1, INPUT);
pinMode(GPS_PIN_2, OUTPUT);
pinMode(7, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(7, HIGH);
pinMode(onModulePin, OUTPUT);
txSerial.begin(4800);
rxSerial.begin(4800);
mySerial.begin(4800);
Serial.begin(19200); // The GPRS baud rate
switchModule(); // Switch the module ON
for (int i=0;i<2;i++){ // Wait 20 sec for connection
delay(10000);
}
}
void loop(){
txSerial.println(sendChar);
Serial.println(sendChar);
for(int i=0; i<6; i++) {
incomingChar = rxSerial.read(); //Read incoming message from TX.
if (incomingChar =='L') {
GPS();//Serial.println("It Works");
}
}
}
void GPS(){
Serial.flush();
// Get a GGA string from the GPS, and
// check if it's a valid fix, and extract the data.
getNMEA("$GPGGA");
delay(100);
numSats = getSats();
fixType = getFixType();
// Make sure we have a valid fix
if (fixType != 0) {
getTime(time);
latitude = getLat();
longitude = getLong();
altitude = getAlt();
// Keep track of the maximum altitude
}
// Convert latitude and longitude into strings.
char latString[12];
char longString[12];
doubleToString(latitude, 4, latString);
doubleToString(longitude, 4, longString);
sprintf(buffer, "%02d:%02d:%02d,%s,%s,%ld",
time[0], time[1], time[2], latString, longString, altitude);
Serial.println(buffer);
if (fixType > 0) {
if (ExOnce==0){
digitalWrite(13, HIGH);
//ExOnce=1;
sendsms();
logftp();
// for (int i=0; i<3; i++) { // Wait 30 sec for a connection.
// delay(10000);
// }
}
}
delay(200);
}
void sendsms(){
Serial.println("AT+CMGF=1"); // Set the SMS mode to text.
delay(500);
Serial.print("AT+CMGS="); // Send the SMS the number.
Serial.print(34,BYTE); // Send the " char.
Serial.print("**********"); // Send the number change *********
// by the actual number.
Serial.println(34,BYTE); // Send the " char.
delay(1500);
Serial.print("Hi this is the General text testing."); // The SMS body
delay(500);
Serial.print(0x1A,BYTE); // End of message command 1A (hex)
delay(20000);
}
void logftp(){
Serial.println("AT&k3"); // Flow activate
delay(1000);
Serial.print("AT+KCNXCFG=0,"); // Connect to GPRS
Serial.print(34,BYTE);
Serial.print("GPRS");
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
//Serial.print("wap.cingular");
Serial.print("epc.tmobile.com");
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
Serial.println(34,BYTE);
delay(1000);
Serial.println("AT+KCNXTIMER=0,60,2,70"); // Set timers
delay(1000);
Serial.println("AT+CGATT=1"); // Network check
delay(1000);
Serial.print("AT+KFTPCFG=0,"); //FTP configuration/connect
Serial.print(34,BYTE);
Serial.print("ftp.insertaddress.com"); //FTP address
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
Serial.print("username"); //Username
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
Serial.print("password"); //Password
Serial.print(34,BYTE);
Serial.println(",21,0"); //Port
delay(500);
Serial.print("AT+KPATTERN=");
Serial.print(34,BYTE);
Serial.print("--EOF--Pattern--");
Serial.println(34,BYTE);
delay(500);
Serial.print("AT+KFTPSND=0,,");
Serial.print(34,BYTE);
Serial.print("log"); //Directory folder of FTP
Serial.print(34,BYTE);
Serial.print(",");
Serial.print(34,BYTE);
Serial.print("pol.txt"); //Text file
Serial.print(34,BYTE);
Serial.println(",0");
delay(12000);
Serial.print(buffer);
Serial.println("--EOF--Pattern--");
delay(12000);
Serial.println("AT+KTCPCLOSE=1,1");
delay(1000);
}
// ------- GPS Parsing ----------
// Reads a line from the GPS NMEA serial output
// Give up after trying to read 1000 bytes (~2 seconds)
int readLine(void) {
char c;
byte bufferIndex = 0;
boolean startLine = 0;
byte retries = 0;
while (retries < 20) {
c = mySerial.read();
if (c == -1) {
delay(2);
continue;
}
if (c == '\n') continue;
if (c == '$') startLine = 1;
if ((bufferIndex == BUFFERSIZE-1) || (c == '\r')) {
if (startLine) {
buffer[bufferIndex] = 0;
return 1;
}
}
if (startLine)
buffer[bufferIndex++] = c;
//}
else {
retries++;
delay(50);
}
}
return 0;
}
// Returns a specific field from the buffer
void getField(int getId, char *field, int maxLen) {
byte bufferIndex = 0;
byte fieldId = 0;
byte i = 0;
while (bufferIndex < sizeof(buffer)) {
if (fieldId == getId) {
// End of string, or string overflow
if (buffer[bufferIndex] == ',' || i > (maxLen - 2)) {
field[i] = 0; // Null terminate
return;
}
// Buffer chars to field
field[i++] = buffer[bufferIndex++];
}
else {
// Advance field on comma
if (buffer[bufferIndex] == ',') {
bufferIndex++; //Advance in buffer
fieldId++; // Increase field position counter
}
else {
bufferIndex++; // Advance in buffer
}
}
}
// Null terminate incase we didn't already..
field[i] = 0;
}
// Polls for an NMEA sentence of type requested
// Validates checksum, silently retries on failed checksums
int getNMEA(char *getType) {
char type[7];
byte retries = 0;
while (retries < 2) {
if (readLine() && validateChecksum()) {
;
getField(0, type, sizeof(type));
if (strcmp(type, getType) == 0) {
return 1;
}
}
else {
retries++;
}
}
Serial.println("Failed to read GPS");
return 0;
}
// Validates the checksum on an NMEA string
// Returns 1 on valid checksum, 0 otherwise
int validateChecksum(void) {
char gotSum[2];
gotSum[0] = buffer[strlen(buffer) - 2];
gotSum[1] = buffer[strlen(buffer) - 1];
// Check that the checksums match up
if ((16 * atoh(gotSum[0])) + atoh(gotSum[1]) == getCheckSum(buffer))
return 1;
else
return 0;
}
// Calculates the checksum for a given string
// returns as integer
int getCheckSum(char *string) {
int i;
int XOR;
int c;
// Calculate checksum ignoring any $'s in the string
for (XOR = 0, i = 0; i < strlen(string); i++) {
c = (unsigned char)string[i];
if (c == '*') break;
if (c != '$') XOR ^= c;
}
return XOR;
}
// Returns the groundspeed in km/h
int getSpeed(void) {
char field[10];
getField(7, field, sizeof(field));
int speed = atoi(field);
return speed;
}
// Return the fix type from a GGA string
int getFixType(void) {
char field[5];
getField(6, field, sizeof(field));
int fixType = atoi(field);
return fixType;
}
// Return the altitude in meters from a GGA string
long getAlt(void) {
char field[10];
getField(9, field, sizeof(field));
long altitude = atol(field);
return altitude;
}
// Returns the number of satellites being tracked from a GGA string
int getSats(void) {
char field[3];
getField(7, field, sizeof(field));
int numSats = atoi(field);
return numSats;
}
// Read the latitude in decimal format from a GGA string
double getLat(void) {
char field[12];
getField(2, field, sizeof(field)); // read the latitude
double latitude = atof(field); // convert to a double (precise)
int deg = (int) latitude / 100; // extract the number of degrees
double min = latitude - (100 * deg); // work out the number of minutes
latitude = deg + (double) min/60.0; // convert to decimal format
getField(3, field, sizeof(field)); // get the hemisphere (N/S)
// sign the decimal latitude correctly
if (strcmp(field, "S") == 0)
latitude *= -1;
return latitude;
}
// Read the longitude in decimal format from a GGA string
double getLong(void) {
char field[12];
getField(4, field, sizeof(field)); // read the longitude
double longitude = atof(field); // convert to a double
int deg = (int) longitude / 100; // extract the number of degrees
double min = longitude - (100 * deg); // work out the number of minutes
longitude = deg + (double) min/60.00; // convert to decimal format
getField(5, field, sizeof(field)); // get the E/W status
// sign decimal latitude correctly
if (strcmp(field, "W") == 0)
longitude *= -1;
return longitude;
}
// Converts UTC time to the correct timezone
void convertTime(int *time) {
// How many hours off GMT are we?
float offset = -5;
long sectime = ((long)(time[0]) * 3600) + (time[1] * 60) + time[2];
sectime += (offset * 3600.0);
// Did we wrap around?
if (sectime < 0) sectime += 86400;
if (sectime > 86400) sectime -= 86400;
// Convert back to time
time[0] = (int)(sectime / 3600);
time[1] = (int)((sectime % 3600) / 60);
time[2] = (int)((sectime % 3600) % 60);
}
// Parses a time field from a GGA string
void parseTime(char *field, int *time) {
char tmp[3];
tmp[2] = 0; // Init tmp and null terminate
tmp[0] = field[0];
tmp[1] = field[1];
time[0] = atoi(tmp); // Hours
tmp[0] = field[2];
tmp[1] = field[3];
time[1] = atoi(tmp); // Minutes
tmp[0] = field[4];
tmp[1] = field[5];
time[2] = atoi(tmp); // Seconds
}
// Gets the hours, minutes and seconds from a GGA string
void getTime(int *time) {
char field[12];
getField(1, field, sizeof(field));
parseTime(field, time);
convertTime(time);
}
// ------ MISC ----------
// Returns a string with a textual representation of a float
void doubleToString(double val, int precision, char *string){
// Print the int part
sprintf(string, "%d", (int)(val));
if(precision > 0) {
// Print the decimal point
strcat(string, ".");
unsigned long frac;
unsigned long mult = 1;
int padding = precision -1;
while (precision--) {
mult *=10;
}
if (val >= 0)
frac = (val - (int)(val)) * mult;
else
frac = ((int)(val)- val ) * mult;
unsigned long frac1 = frac;
while (frac1 /= 10) {
padding--;
}
while (padding--) {
strcat(string, "0");
}
// Convert and print the fraction part
sprintf(string+strlen(string), "%d", (int)(frac));
}
}
// Converts a HEX string to an int
int atoh(char c) {
if (c >= 'A' && c <= 'F')
return c - 55;
else if (c >= 'a' && c <= 'f')
return c - 87;
else
return c - 48;
}
If the server is where the text file is received via SMS/GSM, that server program controls how the file is written or appended. Your posted Arduino code would not need to be changed. On the server, where you now open the file - first check if the file exists and if it does, change the open function to add append mode. Exactly how depends on the OS/language of your server program. But you should be able to figure it out from reading the documentation on the open call.

Resources