diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..c70bc3b --- /dev/null +++ b/main.cpp @@ -0,0 +1,417 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCK 17 +#define SDA 16 +#define SUMMER 18 +#define BATT A1 +#define BUTTON 14 + +U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); + +const char* ssid = "Limbo"; +const char* password = "95H2O862U235@#"; + +bool lpmode, debugmode; + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, "gr.pool.ntp.org", 0, 1296000000); +Adafruit_BME280 bme; + +void serialDebugInfo(float firmwareVersion, float batteryVoltage, float batteryPrecentage, int wifiRSSI, int wifiStatus, const char* day, bool brightness, float temperature, float humidity, float pressure, bool disconnected) +{ + Serial1.print("Firmware Version: "); + Serial1.println(firmwareVersion, 1); + Serial1.print("Battery Voltage: "); + Serial1.println(batteryVoltage, 1); + Serial1.print("Battery Precentage: "); + Serial1.println(batteryPrecentage, 0); + Serial1.print("WiFi RSSI: "); + Serial1.println(wifiRSSI); + Serial1.print("WiFi Status: "); + Serial1.println(wifiStatus); + Serial1.print("Day: "); + Serial1.println(day); + Serial1.print("Brightness: "); + if (brightness == true) + { + Serial1.println("LOW"); + } + else + { + Serial1.println("HIGH"); + } + Serial1.print("Manually Disconnected WiFi: "); + if (disconnected == false) + { + Serial1.println("NO"); + } + else + { + Serial1.println("YES"); + } + Serial1.print("Low Power Mode: "); + if (lpmode == false) + { + Serial1.println("INACTIVE"); + } + else + { + Serial1.println("ACTIVE"); + } + Serial1.print("Temperature: "); + Serial1.print(temperature, 1); + Serial1.println(" C"); + Serial1.print("Humidity: "); + Serial1.print(humidity, 1); + Serial1.println(" %"); + Serial1.print("Pressure: "); + Serial1.print((pressure * 0.01), 1); + Serial1.println(" hPa"); + Serial1.println(""); +} + +int batteryReader() +{ + static int battery, readings, batterya; + int batteryv = analogRead(BATT); + batterya = batterya + batteryv; + readings++; + if (readings >= 10) + { + battery = batterya / 10; + batterya = 0; + readings = 0; + } + return battery; +} + +float getBatteryVoltage(int battery) +{ + float battv = (battery * 3.3 / 4095) * 2; + return battv; +} + +float getBatteryPrecentage(float battv) +{ + float battp = (battv - 2.5) / (4.2 - 2.5) * 100; + if (battp <= 0) + { + battp = 1; + } + if (battp > 99) + { + lpmode = false; + } + else + { + lpmode = true; + } + return battp; +} + +int getWifiRSSI() +{ + static int RSSI, RSSIavg, readings; + int rssir = WiFi.RSSI(); + RSSIavg = RSSIavg + rssir; + readings++; + if (readings >= 10) + { + RSSI = RSSIavg / 10; + RSSIavg = 0; + readings = 0; + } + return RSSI; +} + +int getWifiStatus(int RSSI){ + int wifiStatus; + if (RSSI >= -55 && WiFi.status() == WL_CONNECTED) + { + wifiStatus = 0; + } + else if (RSSI >= -67 && WiFi.status() == WL_CONNECTED) + { + wifiStatus = 1; + } + else if (RSSI >= -90 && WiFi.status() == WL_CONNECTED) + { + wifiStatus = 2; + } + else if (WiFi.status() != WL_CONNECTED && lpmode == true) + { + wifiStatus = 3; + } + else + { + wifiStatus = 4; + WiFi.begin(ssid, password); + } + return wifiStatus; +} + +const char* getDay(int dayInt) +{ + const char* day; + switch (dayInt) + { + case 0: + day = "Sun"; + break; + case 1: + day = "Mon"; + break; + case 2: + day = "Tue"; + break; + case 3: + day = "Wed"; + break; + case 4: + day = "Thu"; + break; + case 5: + day = "Fri"; + break; + case 6: + day = "Sat"; + break; + } + return day; +} + +bool checkBrightness() +{ + static bool brightness = lpmode; + if (digitalRead(BUTTON) == true) + { + brightness = !brightness; + } + return brightness; +} + +float readTemperature() +{ + static int counter; + float temp = bme.readTemperature(); + static float tempAvg, returnTempAvg; + tempAvg = tempAvg + temp; + counter++; + if (counter >= 10) + { + returnTempAvg = tempAvg / 10; + tempAvg = 0; + counter = 0; + } + return returnTempAvg; +} + +float readHumidity() +{ + static int counter; + float hum = bme.readHumidity(); + static float humAvg, returnHumAvg; + humAvg = humAvg + hum; + counter++; + if (counter >= 10) + { + returnHumAvg = humAvg / 10; + humAvg = 0; + counter = 0; + } + return returnHumAvg; +} + +void displayClock(const char *day, float battp, int wifiStatus, int hour, int minute, bool brightness, float temp, float hum) +{ + static bool blink; + + u8g2.clearBuffer(); + + u8g2.setFont(u8g2_font_spleen16x32_mn); + if (hour < 10) + { + u8g2.setCursor(24, 41); + u8g2.print("0"); + u8g2.setCursor(40, 41); + u8g2.print(hour); + } + else + { + u8g2.setCursor(24, 41); + u8g2.print(hour); + } + u8g2.setCursor(56, 41); + switch (blink) + { + case true: + u8g2.print(":"); + break; + case false: + u8g2.print(""); + break; + } + if (minute < 10) + { + u8g2.setCursor(72, 41); + u8g2.print("0"); + u8g2.setCursor(88, 41); + u8g2.print(minute); + } + else + { + u8g2.setCursor(72, 41); + u8g2.print(minute); + } + + u8g2.setFont(u8g2_font_7x14_mf); + u8g2.setCursor(0, 60); + u8g2.print(day); + + u8g2.setFont(u8g2_font_siji_t_6x10); + switch (wifiStatus) + { + case 0: + u8g2.drawGlyph(0, 10, 57882); + break; + case 1: + u8g2.drawGlyph(0, 10, 57881); + break; + case 2: + u8g2.drawGlyph(0, 10, 57880); + break; + case 3: + u8g2.drawGlyph(0, 10, 57907); + break; + case 4: + u8g2.drawGlyph(0, 10, 57879); + break; + } + + if (battp < 99) + { + if (battp >= 70) + { + u8g2.drawGlyph(92, 10, 57487); + } + else if (battp >= 30) + { + u8g2.drawGlyph(92, 10, 57486); + } + else + { + u8g2.drawGlyph(92, 10, 57485); + } + u8g2.setCursor(104, 10); + u8g2.print(battp, 0); + u8g2.drawStr(116, 10, "%"); + } + else + { + u8g2.drawGlyph(116, 10, 57409); + } + + u8g2.drawGlyph(44, 10, 57550); + u8g2.setCursor(56, 10); + u8g2.print(temp, 1); + u8g2.drawGlyph(44, 60, 57549); + u8g2.setCursor(56, 60); + u8g2.print(hum, 1); + + switch (brightness) + { + case false: + u8g2.setContrast(255); + u8g2.drawGlyph(114, 60, 57794); + break; + case true: + u8g2.setContrast(50); + u8g2.drawGlyph(114, 60, 57795); + break; + } + + blink = !blink; + u8g2.sendBuffer(); +} + +void setup() +{ + pinMode(SUMMER, INPUT_PULLDOWN); + pinMode(BUTTON, INPUT_PULLDOWN); + analogReadResolution(12); + Wire.setSCL(SCK); + Wire.setSDA(SDA); + WiFi.mode(WIFI_STA); + WiFi.hostname("pico-clock"); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + } + Wire.begin(); + u8g2.begin(); + timeClient.begin(); + bme.begin(0x76); + if (digitalRead(SUMMER) == 1) + { + timeClient.setTimeOffset(10800); //UTC+3 + } + else + { + timeClient.setTimeOffset(7200); //UTC+2 + } + for (int i = 0; i < 10; i++) + { + getBatteryPrecentage(getBatteryVoltage(batteryReader())); + getWifiRSSI(); + } + if (digitalRead(BUTTON) == true) + { + Serial1.setTX(0); + Serial1.setRX(1); + Serial1.begin(115200); + debugmode = true; + } +} + +void loop() +{ + static bool disconnected = false; + static int counter = 29; + timeClient.update(); + + const char* day = getDay(timeClient.getDay()); + float batteryVoltage = getBatteryVoltage(batteryReader()); + float batteryPrecentage = getBatteryPrecentage(batteryVoltage); + int wifiRSSI = getWifiRSSI(); + int wifiStatus = getWifiStatus(wifiRSSI); + int hours = timeClient.getHours(); + int minutes = timeClient.getMinutes(); + bool brightness = checkBrightness(); + float temperature = readTemperature(); + float humidity = readHumidity(); + + displayClock(day, batteryPrecentage, wifiStatus, hours, minutes, brightness, temperature, humidity); + if (debugmode == true && counter >= 30) + { + float pressure = bme.readPressure(); + serialDebugInfo(2.2 ,batteryVoltage, batteryPrecentage, wifiRSSI, wifiStatus, day, brightness, temperature, humidity, pressure, disconnected); + counter = 0; + } + counter++; + sleep_ms(1000); + if (lpmode == true && disconnected == false) + { + WiFi.disconnect(); + set_sys_clock_khz(20000, true); + disconnected = true; + } +} diff --git a/updates.md b/updates.md index 158aca3..c7fdab5 100644 --- a/updates.md +++ b/updates.md @@ -1,5 +1,9 @@ **CHANGELOG:** +2.2: +* Changed baudrate to standard 115200 baud +* Added a firmware version printout to serial + 2.1: * Added a serial debugging mode. This mode is activated if the BUTTON is held at bootup. Serial debugging info (variables) are output on GPIO0(TX) at 9600 baud every 30 seconds. * All functions are now called seperately and their return values placed in variables to be given to displayClocl() and serialDebugInfo() @@ -59,4 +63,4 @@ 1.0: * Updated battery precentage calculator math to original (measurement - min) / (max - min) * 100 -* Created this updates.md file \ No newline at end of file +* Created this updates.md file