I've written an Arduino sketch to read temperature and humidity from both a DHT20 sensor and SHT35 sensor attached to MKR 1010 and send the two sets of temperature readings and one of the humidity readings over WiFi to the IoT cloud along with RSSI. Temperature, humidity and RSSI are displayed using Dashboard widgets. All outputs also sent out the serial port.
Temperature and humidity from the DHT20 sensor (temperature1 & humidity1) and RSSI are received in the cloud correctly. Temperature from the SHT35 Sensor (temperature2) has correct value when sent to serial but always registers as 0 in the cloud. It shows in the Things tab as being updated at the same time as the other variables but is always 0.
/*
Arduino sketch to read temperature and humidity from both a DHT20 sensor and SHT35 sensor attached to MKR 1010 and send the two sets of temperature readings
and one of the humidity readings over WiFi to the IoT cloud. Display temperature and humidity using Dashboard widgets. Sensor outputs also sent out the serial port.
Control1 still TBD.
Sketch generated by the Arduino IoT Cloud Thing "MKRIoTEnv"
https://create.arduino.cc/cloud/things/fa8b93f5-90e6-4f4b-888c-3e0904e9a621
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
float humidity1;
float temp;
float temperature1;
int rssiInt;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include <DFRobot_DHT20.h>
#include "Seeed_SHT35.h"
DFRobot_DHT20 dht20;
//Define SHT35 variables for *SAMD core*
#define SDAPIN 20
#define SCLPIN 21
#define RSTPIN 7
SHT35 sensor(SCLPIN);
int period = 1000;
unsigned long time_now = 0;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
time_now = millis();
{
//Get temperature1 and humidity1
float tempread = dht20.getTemperature();
float humidread = dht20.getHumidity()*100;
//Round to 1 decimal place
temperature1=round(tempread*10)/10;
humidity1=round(humidread*10)/10;
//Print out to serial
Serial.print("temperature1: "); Serial.print(temperature1);Serial.println("C");
Serial.print("humidity1: "); Serial.print(humidity1);Serial.println(" %");
}
//Get temperature2 and humidity2
{ u16 value=0;
u8 data[6]={0};
float temp,hum;
if(NO_ERROR!=sensor.read_meas_data_single_shot(HIGH_REP_WITH_STRCH,&temp,&hum))
{
Serial.println("read temp SHT35 failed!!");
Serial.println(" ");
}
else
Serial.print("temperature2: "); Serial.print(temp);Serial.println("C");
Serial.print("humidity2: "); Serial.print(hum);Serial.println(" %");
}
//Delay
while(millis() < time_now + period){
//wait approx. [period] ms
}
// read the WiFi RSSI value and convert it to an integer
{
long rssiValue = WiFi.RSSI(); // get the RSSI value
rssiInt = (int)rssiValue; // convert the RSSI value to an integer
Serial.print("RSSI: "); Serial.print(rssiInt);Serial.println(" dbm");
Serial.println(" ");
Serial.println(" ");
}
/*
Since Control1 is READ_WRITE variable, onControl1Change() is
executed every time a new value is received from IoT Cloud.
void onControl1Change(); {
// Add your code here to act upon Control1 change
}
*/
delay(1000);
}
// Code generated by Arduino IoT Cloud, DO NOT EDIT.
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
const char SSID[] = SECRET_SSID; // Network SSID (name)
const char PASS[] = SECRET_OPTIONAL_PASS; // Network password (use for WPA, or use as key for WEP)
float humidity1;
float temp;
float temperature1;
int rssiInt;
void initProperties(){
ArduinoCloud.addProperty(humidity1, READ, 2 * SECONDS, NULL);
ArduinoCloud.addProperty(temp, READ, 2 * SECONDS, NULL);
ArduinoCloud.addProperty(temperature1, READ, 2 * SECONDS, NULL);
ArduinoCloud.addProperty(rssiInt, READ, 2 * SECONDS, NULL);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
I don't understand how the variable "temp" going to the cloud changes from it's correct value as shown in the serial printout to 0 when sent to the cloud.
Before digging further into any other code issues, I would start highlighting that you shouldn't use delays inside the loop() when used along the IoT Cloud. This is because ArduinoCloud.update() tries to synchronise with the IoT Cloud frequently and you might be disrupting that flow.
So, I would suggest changing your code this way:
unsigned long time_next = 0;
void loop() {
ArduinoCloud.update();
time_now = millis();
if (time_now > time_next)
{
time_next = time_now + period;
{
//Get temperature1 and humidity1
float tempread = dht20.getTemperature();
float humidread = dht20.getHumidity()*100;
//Round to 1 decimal place
temperature1=round(tempread*10)/10;
humidity1=round(humidread*10)/10;
//Print out to serial
Serial.print("temperature1: "); Serial.print(temperature1);Serial.println("C");
Serial.print("humidity1: "); Serial.print(humidity1);Serial.println(" %");
}
//Get temperature2 and humidity2
{
u16 value=0;
u8 data[6]={0};
float temp,hum;
if(NO_ERROR!=sensor.read_meas_data_single_shot(HIGH_REP_WITH_STRCH,&temp,&hum))
{
Serial.println("read temp SHT35 failed!!");
Serial.println(" ");
}
else {
Serial.print("temperature2: "); Serial.print(temp);Serial.println("C");
Serial.print("humidity2: "); Serial.print(hum);Serial.println(" %");
}
}
// read the WiFi RSSI value and convert it to an integer
{
long rssiValue = WiFi.RSSI(); // get the RSSI value
rssiInt = (int)rssiValue; // convert the RSSI value to an integer
Serial.print("RSSI: "); Serial.print(rssiInt);Serial.println(" dbm");
Serial.println(" ");
Serial.println(" ");
}
}
}
I deleted the delay function and added the timer function to my sketch as suggested. It certainly helped speed up the time it takes for my Arduino to sync to the IoT Cloud, however, the SHT35 temperature still isn't making to the Cloud even though it's being printed out to the serial monitor. The Cloud is reporting DHT20 sensor and RSSI correctly.
So I tried removing the DHT20 sensor from my sketch including library function call, variables, printout to serial, etc. and also removed the DHT20 sensor variables from the Cloud. That didn't fix it either. The SHT35 temperature still isn't making to the Cloud even though it's being printed out to the serial monitor.
I don't know what else to try. I'm considering getting an Ethernet Tap, connecting it to my WiFi Router and to a PC running Wireshark to determine where the SHT35 sensor data is getting lost.
Sketch with latest revisions. SHT35 values still reported as 0:
Sketch generated by the Arduino IoT Cloud Thing "MKRIoTEnv"
https://create.arduino.cc/cloud/things/fa8b93f5-90e6-4f4b-888c-3e0904e9a621
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
float hum;
float humidity1;
float temp;
float temperature1;
int rssiInt;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include "Seeed_SHT35.h"
#include <DFRobot_DHT20.h>
DFRobot_DHT20 dht20;
//Define SHT35 variables for *SAMD core*
#define SDAPIN 20
#define SCLPIN 21
#define RSTPIN 7
SHT35 sensor(SCLPIN);
int period = 10000;
unsigned long time_now = 0;
unsigned long time_next = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
time_now = millis();
if (time_now > time_next)
{
time_next = time_now + period;
{
//Get temperature1 and humidity1
float tempread = dht20.getTemperature();
float humidread = dht20.getHumidity()*100;
//Round to 1 decimal place
temperature1=round(tempread*10)/10;
humidity1=round(humidread*10)/10;
//Print out to serial
Serial.print("temperature1: "); Serial.print(temperature1);Serial.println("C");
Serial.print("humidity1: "); Serial.print(humidity1);Serial.println(" %");
}
//Get temperature2 and humidity2
{ u16 value=0;
u8 data[6]={0};
float temp,hum;
if(NO_ERROR!=sensor.read_meas_data_single_shot(HIGH_REP_WITH_STRCH,&temp,&hum))
{
Serial.println("read temp SHT35 failed!!");
Serial.println(" ");
}
else
Serial.print("temperature2: "); Serial.print(temp);Serial.println("C");
Serial.print("humidity2: "); Serial.print(hum);Serial.println(" %");
}
// read the WiFi RSSI value and convert it to an integer
{
long rssiValue = WiFi.RSSI(); // get the RSSI value
rssiInt = (int)rssiValue; // convert the RSSI value to an integer
Serial.print("RSSI: "); Serial.print(rssiInt);Serial.println(" dbm");
Serial.println(" ");
Serial.println(" ");
}
/*
Since Control1 is READ_WRITE variable, onControl1Change() is
executed every time a new value is received from IoT Cloud.
void onControl1Change(); {
// Add your code here to act upon Control1 change
}
*/
}
}
// Code generated by Arduino IoT Cloud, DO NOT EDIT.
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
const char SSID[] = SECRET_SSID; // Network SSID (name)
const char PASS[] = SECRET_OPTIONAL_PASS; // Network password (use for WPA, or use as key for WEP)
float hum;
float humidity1;
float temp;
float temperature1;
int rssiInt;
void initProperties(){
ArduinoCloud.addProperty(hum, READ, 10 * SECONDS, NULL);
ArduinoCloud.addProperty(humidity1, READ, 10 * SECONDS, NULL);
ArduinoCloud.addProperty(temp, READ, 10 * SECONDS, NULL);
ArduinoCloud.addProperty(temperature1, READ, 10 * SECONDS, NULL);
ArduinoCloud.addProperty(rssiInt, READ, 10 * SECONDS, NULL);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
But I got it to work by adding variables temperature2 & humidity2, making temperature2=temp & humidity2=hum. (temp and hum are the SHT35 library variables). I changed Thing variables from temp>temperature2 & hum>humidity2. First time I got it to work, I uploaded the code over-the-air (as I had the Arduino deployed in my cold frame doing what it was supposed to be doing). Not really sure why adding these variables or OTA programming (vs. serial) was the solution but it's working now. Is there an explanation? Working code as follows:
Sketch generated by the Arduino IoT Cloud Thing "MKRIoTEnv"
https://create.arduino.cc/cloud/things/fa8b93f5-90e6-4f4b-888c-3e0904e9a621
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
float humidity1;
float humidity2;
float temperature1;
float temperature2;
int rssiInt;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include "Seeed_SHT35.h"
#include <DFRobot_DHT20.h>
DFRobot_DHT20 dht20;
//Define SHT35 variables for *SAMD core*
#define SDAPIN 20
#define SCLPIN 21
#define RSTPIN 7
SHT35 sensor(SCLPIN);
int period = 10000;
unsigned long time_now = 0;
unsigned long time_next = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
time_now = millis();
if (time_now > time_next)
{
time_next = time_now + period;
//Get temperature1 and humidity1
{
float tempread = dht20.getTemperature();
float humidread = dht20.getHumidity()*100;
//Round to 1/0 decimal place
temperature1=round(tempread*10)/10;
humidity1=round(humidread);
//Print out to serial
Serial.print("temperature1: "); Serial.print(temperature1);Serial.println("C");
Serial.print("humidity1: "); Serial.print(humidity1);Serial.println(" %");
}
//Get temperature2 and humidity2
{ u16 value=0;
u8 data[6]={0};
float temp,hum;
if(NO_ERROR!=sensor.read_meas_data_single_shot(HIGH_REP_WITH_STRCH,&temp,&hum))
{
Serial.println("read temp SHT35 failed!!");
Serial.println(" ");
}
else
temperature2=temp;
humidity2=hum;
//Round to 1/0 decimal place
temperature2=round(temperature2*10)/10;
humidity2=round(humidity2);
Serial.print("temperature2: "); Serial.print(temperature2);Serial.println("C");
Serial.print("humidity2: "); Serial.print(humidity2);Serial.println(" %");
}
// read the WiFi RSSI value and convert it to an integer
{
long rssiValue = WiFi.RSSI(); // get the RSSI value
rssiInt = (int)rssiValue; // convert the RSSI value to an integer
Serial.print("RSSI: "); Serial.print(rssiInt);Serial.println(" dbm");
Serial.println(" ");
Serial.println(" ");
}
/*
Since Control1 is READ_WRITE variable, onControl1Change() is
executed every time a new value is received from IoT Cloud.
void onControl1Change(); {
// Add your code here to act upon Control1 change
}
*/
}
}