Pārlūkot izejas kodu

Improve sleep & debugging

- Update debug statements to do a check for `Serial`
  - For some reason, when not plugged into a computer, the serial interface is
    never initialized, so the program waits forever on it being created.
- Sleep based on number of milliseconds since waking, to reduce skew over time
  - It's not perfect, especially when wifi times out and forces a reboot, but
    it's better than ignoring the overall time taken otherwise.
Jason Tarka 4 gadi atpakaļ
vecāks
revīzija
25e6e8b701
7 mainītis faili ar 90 papildinājumiem un 67 dzēšanām
  1. 2 3
      01_humidity.ino
  2. 5 8
      01_pressure.ino
  3. 8 3
      02_sleep.ino
  4. 15 9
      02_wifi.ino
  5. 13 20
      03_log_data.ino
  6. 17 12
      99_main.ino
  7. 30 12
      outdoor-weather-station.ino

+ 2 - 3
01_humidity.ino

@@ -9,14 +9,13 @@ public:
 } HumTemp;
 
 void initHumidity() {
-	debugln("Initializing humidity sensor");
+	debug("Initializing humidity sensor");
 	
 	if (!aht.begin()) {
 		Serial.println("Could not initialize humidity sensor");
-		// TODO: Turn on the LED or screen or something
 		ERR;
 	}
-	debugln("Initialized humidity sensor");
+	debug("Initialized humidity sensor");
 }
 
 void updateHumidity() {

+ 5 - 8
01_pressure.ino

@@ -10,7 +10,7 @@ struct {
 } PressTemp;
 
 void initPressure() {
-	debugln("Initializing pressure sensor");
+	debug("Initializing pressure sensor");
 
 	if (!dps.begin_I2C()) {
 		Serial.println("Failed to initialize pressure sensor!");
@@ -21,23 +21,20 @@ void initPressure() {
 	dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
 	dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);
 
-//	dps_temp->printSensorDetails();
-//	dps_pressure->printSensorDetails();
-
-	debugln("Initialized pressure sensor");
+	debug("Initialized pressure sensor");
 }
 
 void updatePressure() {
 	sensors_event_t temp,
 		pressure;
 
-	debugln("Reading pressure & temperature");
+	debug("Reading pressure & temperature");
 
 	// Wait until both are available, as reading temperature
 	// resets pressure availability, but both are still OK
 	// to read.
 	while (!dps.temperatureAvailable() || !dps.pressureAvailable()) {
-		debugln("Waiting...");
+		debug("Waiting...");
 		delay(1);
 	}
 	
@@ -50,5 +47,5 @@ void updatePressure() {
 	dps_pressure->getEvent(&pressure);
 	PressTemp.pressure = pressure.pressure;
 
-	debugln("Got temperature & pressure");
+	debug("Got temperature & pressure");
 }

+ 8 - 3
02_sleep.ino

@@ -1,8 +1,13 @@
 void deepSleep() {
 	hideProgress(); // Make sure the LEDs are turned off
+
+	debug("Milliseconds awake: %d", millis() - wakeTime);
+	int64_t sleepTimeMillis = SLEEP_TIME_MS - (millis() - wakeTime);
 	
-	debuglog("Going to sleep for: ", SLEEP_TIME_US);
-	esp_sleep_enable_timer_wakeup(SLEEP_TIME_US);
-	Serial.flush();
+	debug("Going to sleep for: %d milliseconds", sleepTimeMillis);
+
+	// Do it again to account for the time the serial printing might take.
+	sleepTimeMillis = SLEEP_TIME_MS - (millis() - wakeTime);
+	esp_sleep_enable_timer_wakeup(sleepTimeMillis * 1000);
 	esp_deep_sleep_start();
 }

+ 15 - 9
02_wifi.ino

@@ -7,19 +7,25 @@
 void connectWifi() {
 	WiFi.begin(NETWORK, PASSWORD);
 
-	debug("Connecting to wifi ..");
+	debugNoLn("Connecting to wifi ..");
+	int64_t startTime = millis();
 	while (WiFi.status() != WL_CONNECTED) {
-		debug('.');
+		if(millis() - startTime > WIFI_TIMEOUT_SECONDS * 1000) {
+			debug("Could not connect to wifi.");
+			ERR;
+		}
+		debugNoLn(".");
 		showProgress(PROGRESS_BLUE);
 		delay(500);
 	}
-
-	debugln();
-	debugln("Connected!");
-	debuglog("IP: 		", WiFi.localIP());
-	debuglog("Strength: ", WiFi.RSSI());
-	debuglog("DNS:		", WiFi.dnsIP());
-	debuglog("Gateway:	", WiFi.gatewayIP());
+	debug("");
+
+	debug("=====");
+	debug("Connected!");
+	debugln("IP: 	   ", WiFi.localIP());
+	debugln("Strength: ", WiFi.RSSI());
+	debugln("DNS:      ", WiFi.dnsIP());
+	debugln("Gateway:  ", WiFi.gatewayIP());
 }
 
 

+ 13 - 20
03_log_data.ino

@@ -1,14 +1,7 @@
 #include <WiFi.h>
 #include <WiFiClientSecure.h>
 
-#define PROJECT "weather-station-58080"
-#define AUTH_TOKEN "aud8LdW1IeTWqcv77Ka1LJn5xSqambsJ9jYx5OEh"
-#define DATABASE_URL "https://weather-station-58080-default-rtdb.firebaseio.com"
-#define DATABASE_PATH "outdoor.json"
-
 #define PORT 443
-#define HOST "weather-station-58080-default-rtdb.firebaseio.com"
-const String WRITE_URL = String("https://") + HOST + "/" + DATABASE_PATH + "?auth=" + AUTH_TOKEN;
 
 void getSomething() {
 	showProgress(PROGRESS_GREEN);
@@ -19,15 +12,15 @@ void getSomething() {
 
 	WiFiClientSecure client;
 	client.setInsecure();
-	debugln("Connectiong to: example.com");
+	debug("Connectiong to: example.com");
 	showProgress(PROGRESS_GREEN);
 
 	if(!client.connect("example.com", 443)) {
-		debugln("Connection failed!");
+		debug("Connection failed!");
 		ERR;
 	}
 
-	debugln("Connection established. Sending headers & body.");
+	debug("Connection established. Sending headers & body.");
 	showProgress(PROGRESS_GREEN);
 	client.print(content);
 
@@ -38,10 +31,10 @@ void getSomething() {
 	while(client.available()) {
 		showProgress(PROGRESS_GREEN);
 		String line = client.readStringUntil('\n');
-		debuglog("Read line: ", line);
+		debug("Read line: %s", line);
 	}
 	hideProgress();
-	debugln("===== Done =====");
+	debug("===== Done =====");
 }
 
 boolean uploadData(
@@ -58,7 +51,7 @@ boolean uploadData(
 				+ "\t\"light\": " + light + ",\n"
 				+ "\t\"time\": { \".sv\": \"timestamp\" }\n"
 				+ "}";
-	debuglog("Content body: ", data);
+	debugln("Content body: ", data);
 
 	String content = String("POST ") + RTDB_URL + " HTTP/1.1\r\n"
 				+ "Host: " + RTDB_HOST + "\r\n"
@@ -70,20 +63,20 @@ boolean uploadData(
 				+ "\r\n"
 				+ data;
 
-	debuglog("HTTP request: ", content);
+	debugln("HTTP request: ", content);
 
 	WiFiClientSecure client;
 	client.setInsecure();
 	showProgress(PROGRESS_GREEN);
-	debuglog("Connectiong to: ", RTDB_HOST);
+	debugln("Connectiong to: ", RTDB_HOST);
 
-	if(!client.connect(RTDB_HOST, PORT)) {
-		debugln("Connection failed!");
+	if(!client.connect(RTDB_HOST.c_str(), PORT)) {
+		debug("Connection failed!");
 		showError();
 		return false;
 	}
 
-	debugln("Connection established. Sending headers & body.");
+	debug("Connection established. Sending headers & body.");
 	showProgress(PROGRESS_GREEN);
 	client.print(content);
 
@@ -94,9 +87,9 @@ boolean uploadData(
 	while(client.available()) {
 		showProgress(PROGRESS_GREEN);
 		String line = client.readStringUntil('\n');
-		debuglog("Read line: ", line);
+		debugln("Read line: ", line);
 	}
-	debugln("===== Done =====");
+	debug("===== Done =====");
 
 	hideProgress();
 	return true;

+ 17 - 12
99_main.ino

@@ -1,31 +1,35 @@
 void setup() {
+#ifdef USE_SERIAL
 	Serial.begin(115200);
-	while(!Serial) delay(10);
+	delay(500);
+#endif
+
+	wakeTime = millis();
+	debug("Wake time: %d", wakeTime);
 
 	initLeds(); // Shows errors, so needs to be first
+	
 	initHumidity();
 	initPressure();
 }
 
 void loop() {
-	debugln("----------------------");
+	debug("----------------------");
 	updateHumidity();
 	updatePressure();
 	
 	uint16_t light = analogRead(LIGHT_PIN);
 
-	debugln();
-
-	debuglog("Light value:            ", light);
-	debuglog("Humidity - Humidity:    ", HumTemp.humidity);
-	debuglog("Humidity - Temperature: ", HumTemp.temperature);
-	debuglog("Pressure - Temperature: ", PressTemp.temperature);
-	debuglog("Pressure - Pressure:    ", PressTemp.pressure);
+	debug("Light value:            %d", light);
+	debug("Humidity - Humidity:    %f", HumTemp.humidity);
+	debug("Humidity - Temperature: %f", HumTemp.temperature);
+	debug("Pressure - Temperature: %f", PressTemp.temperature);
+	debug("Pressure - Pressure:    %f", PressTemp.pressure);
 
 	float averageTemperature = (HumTemp.temperature + PressTemp.temperature) / 2;
-	debuglog("Average - Temperature:  ", averageTemperature);
+	debug("Average - Temperature:  %f", averageTemperature);
 
-	debugln();
+	debug("=====");
 	
 	initWifi();
 
@@ -33,11 +37,12 @@ void loop() {
 	getSomething();
 	hideProgress();
 	delay(5000);
+	deepSleep();
 #else
 	boolean complete = false;
 	while(!complete) {
 		delay(500);
-		debugln("Uploading data");
+		debug("Uploading data");
 		complete = uploadData(
 				averageTemperature,
 				PressTemp.pressure,

+ 30 - 12
outdoor-weather-station.ino

@@ -1,32 +1,50 @@
 //#define TEST_MODE
+#define USE_SERIAL
 
 #define LIGHT_PIN A3
 
 #define ERR reboot()
 
-#define SLEEP_TIME_S 30
-#define SLEEP_TIME_MS SLEEP_TIME_S * 1000
-#define SLEEP_TIME_US SLEEP_TIME_MS * 1000
+#ifndef TEST_MODE
+#define SLEEP_TIME_MIN 5
+#define SLEEP_TIME_SEC 60 * SLEEP_TIME_MIN
+#define SLEEP_TIME_MS 1000 * SLEEP_TIME_SEC
+#else
+#define SLEEP_TIME_MS 10 * 1000 // 10 second sleep in test mode
+#endif
 
-#define debug(X) Serial.print(X)
-#define debugln(...) Serial.println(__VA_ARGS__)
-#define debuglog(A, B) debug(A); debugln(B)
+#define WIFI_TIMEOUT_SECONDS 30 // How long to wait before giving up on wifi connection
 
+#ifdef USE_SERIAL
 char log_buff[200];
-#define dout(...) sprintf(log_buff, __VA_ARGS__); Serial.println(log_buff); 
+#define debug(...) if(Serial) { sprintf(log_buff, __VA_ARGS__); Serial.println(log_buff); Serial.flush(); }
+#define debugln(X, Y) if(Serial) { Serial.print(X); Serial.println(Y); } // For things that can't be represented as a normal % formatter 
+#define debugNoLn(...) if(Serial) { sprintf(log_buff, __VA_ARGS__); Serial.print(log_buff); }
+#else
+#define debug(...)
+#define debugln(X, Y)
+#define debugNoLn(...)
+#endif
 
 #define RTDB_AUTH_TOKEN "abc123"
-#define RTDB_PROJECT "weather-station-xxxxx"
+#define RTDB_PROJECT "weather-project"
 #define RTDB_PATH "outdoor"
 
-#define RTDB_HOST RTDB_PROJECT "-default-rtdb.firebaseio.com"
-#define RTDB_URL "https://" RTDB_HOST "/" RTDB_PATH ".json?auth=" RTDB_AUTH_TOKEN
+const String RTDB_HOST = String(RTDB_PROJECT) + "-default-rtdb.firebaseio.com";
+const String RTDB_URL = String("https://") + RTDB_HOST + "/" + RTDB_PATH + ".json?auth=" + RTDB_AUTH_TOKEN;
 
-// Reboot on error
+// Used in various places to get the sleep time to be as close to SLEEP_TIME_MIN as possible.
+int64_t wakeTime;
+
+// Defined later, but declare it now.
+void showError();
+
+// Turn LEDs on to red, then go into deep sleep, restarting after 5 seconds.
+// Effectively doing a reboot, while visually displaying an error state.
 void reboot() {
 	showError();
 	const int64_t reboot_sleep_time = 5 * 1000 * 1000;
-	debuglog("Rebooting by going to sleep for: ", reboot_sleep_time);
+	debug("Rebooting by going to sleep for: %d", reboot_sleep_time);
 	esp_sleep_enable_timer_wakeup(reboot_sleep_time);
 	Serial.flush();
 	esp_deep_sleep_start();