Hi everyone,
I’m totaly new in the “hobby” so my code might affraid some of you…
I’m using the Wemos D1 Mini V3.0.0 (ESP8266) to build my own weather station (largely inspire by this Solar Powered WiFi Weather Station V1.0 : 19 Steps (with Pictures) - Instructables) + I’ve added a oled screen so I can read the temp direclty on the device.
My problem is that when my wifi connection is lost (don’t know why), the device freezes (I guess loop “brokes”) and I have to go outside to restart the device to make it reworks properly.
I have read somewehere that Cayenne Team is working on an “offline” feature, but I’m not sure if this is related to my issue. I guess the issue is more on my side, so I hope you’ll be able to helps me to fixe this and improve my code
#include <Adafruit_GFX.h> // Icons and lines
#include <Adafruit_SSD1306.h> // Oled display
#include <Adafruit_BME280.h> // Sensor
#include <math.h> // isnan()
//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>
// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "xxxxxxxxxxxxxxxxx";
char password[] = "xxxxxxxxxxxxxxxxxx";
char clientID[] = "xxxxxxxxxxxxxxxxxxxxxxx";
// WiFi network info.
char ssid[] = "xxxxxxxxxx";
char wifiPassword[] = "xxxxxxxxxxx";
Adafruit_BME280 bme; //I2C
Adafruit_SSD1306 display(-1); //I2C
const unsigned long UPDATE_PERIOD_MS = 5000;
unsigned long lastMillis = 0;
//Oled on/off
bool oledState = true;
// I2C wiring
#define BME_MOSI D2
#define BME_SCK D1
// Temp calibration
const float tempOffset = -1.75;
// Battery voltage
const float VoltageMultiplier = ( 1 / 210.447761 ); //calculed with voltmeter
const float BatteryPercentage = 0;
const float BattMin = 3.3;
const float BattMax = 4.2;
unsigned long lastUpdate = 0;
char buf[64];
//wifi icon size: 20W*15H px
const unsigned char wifi_icon [] PROGMEM = {
0x07, 0xc0, 0x1f, 0xf0, 0x7c, 0x7c, 0x70, 0x1c,
0xc0, 0x06, 0xc3, 0x86, 0x0f, 0xe0, 0x1c, 0x70,
0x18, 0x30, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80
};
void setup() {
Serial.begin(9600);
if (bme.begin()) {
Serial.println("BME280 sensor connected");
}
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.dim(true);
display.display(); // show splashscreen
delay(1000);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
display.clearDisplay(); // clears the screen and buffer
}
void loop() {
Cayenne.loop();
if (millis() - lastUpdate >= UPDATE_PERIOD_MS) {
lastUpdate = millis();
float volt = analogRead(A0)*VoltageMultiplier; // battery voltage
// Prevent power consumption if voltage it too low
if( volt < 3.3 ){
//Do not read neither send an data
//Erase all screen pixels
display.clearDisplay(); // clears the screen and buffer
display.fillRect(0, 0, 124, 68, BLACK );
display.display();
} else {
Serial.println("____________________________________");
Cayenne.virtualWrite(1, volt, "voltage", "v");
Serial.print("Voltage = ");
Serial.print(volt);
Serial.println(" V");
float bat = (volt - BattMin)/(BattMax - BattMin) * 100;
if(bat > 100){
bat = 100;
}
Cayenne.virtualWrite(2, bat, "batt", "p");
Serial.print("Battery = ");
Serial.print(bat);
Serial.println("%");
float temp = bme.readTemperature() + tempOffset; // degrees C
Cayenne.virtualWrite(3, temp, "temp", "c");
Serial.print("Temperature = ");
Serial.print(temp);
Serial.println(" °C");
float humidity = bme.readHumidity(); // %
Cayenne.virtualWrite(4, humidity, "rel_hum", "p");
Serial.print("Humidity = ");
Serial.print(humidity);
Serial.println(" %");
float pressure = (bme.readPressure() / 100.0F); // hPa
Cayenne.virtualWrite(5, pressure, "bp", "c");
Serial.print("Pressure = ");
Serial.print(pressure);
Serial.println(" hPa");
if( oledState == true ){
// Update button status on Cayenne
Cayenne.virtualWrite(6, 1, "digital_actuator", "d");
if (!isnan(temp) && !isnan(humidity) ) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
if( bat == 100){
display.fillRect(0, 0, 27, 12, 1 );
display.setTextColor(BLACK);
display.setCursor(2,2);
snprintf(buf, sizeof(buf), "%.1fv", volt);
display.print(buf);
display.setTextColor(WHITE);
} else {
display.setCursor(5,2);
snprintf(buf, sizeof(buf), "%.0f%%", bat);
display.print(buf);
}
//Battery logo
display.drawLine(27, 3, 27, 8, 1);
display.drawLine(28, 3, 28, 8, 1);
display.drawLine(29, 4, 29, 7, 1);
display.drawRect(0, 0, 27, 12, 1 );
display.setCursor(0,16);
display.setTextSize(2);
snprintf(buf, sizeof(buf), "%.2f ", temp);
display.print(buf);
display.print((char)247);
display.println("C");
snprintf(buf, sizeof(buf), "%.2f %%", humidity);
display.println(buf);
snprintf(buf, sizeof(buf), "%.1f hPa", pressure);
display.println(buf);
}
if( WiFi.status() == WL_CONNECTED ){
// Wifi logo
display.drawBitmap(113, 0, wifi_icon, 15, 12, 1);
} else {
// Remove wifi icone and draw a cross
display.fillRect(113, 0, 15, 12, BLACK );
display.drawLine(116, 1, 128, 12, 1);
display.drawLine(116, 11, 128, 0, 1);
}
} else {
// Update button status on Cayenne
Cayenne.virtualWrite(6, 0, "digital_actuator", "d");
//Erase all screen pixels
display.clearDisplay(); // clears the screen and buffer
display.fillRect(0, 0, 124, 68, BLACK );
}
display.display();
}
}
}
// Virtual button to power on/off the oled display
CAYENNE_IN(6){
// get value sent from dashboard
int currentValue = getValue.asInt();
if (currentValue ==1){
Serial.println("Oled on");
oledState = true;
} else {
Serial.println("Oled off");
oledState = false;
}
}
I’ve added a feature to “shutdown” the oled screen (actually just make it black) to prevent over battery discharge + a virtual button to manually turn it on/off.
My if/else statement to update the wifi logo with WiFi.status() == WL_CONNECTED does not work neither, I guess because of when there is no wifi, the conditional test is not called because the loop breaks.
Thanks for your help !
Brice