#include #include #include #include #include #include #include #include #include #include #include #include "HX711.h" HX711 scale; unsigned long wake = 0; long wake_mass = 0; #define WAKE_MASS 10 #define TIMEOUT 30e3 // go to sleep after 30 seconds #define POWER_DEVICES 14 #define HX711_CLOCK 12 #define HX711_DATA 13 #define SCL 5 #define SDA 4 #define GUMB_CAL 0 #define DELAY 3e3 Adafruit_SSD1306 display(128, 32, &Wire, -1); FtpServer ftpSrv; int stanje = 0; #define GLAVNO 0 #define CENA 1 #define KALIBRACIJA 2 #define WIFI 3 #define DOLŽINA 4 unsigned long nazadnje_gumb = 0; bool gumb = false; void ICACHE_RAM_ATTR isr() { if (millis() - nazadnje_gumb > 100) { nazadnje_gumb = millis(); gumb = true; } } String readFile(const char * path) { String r; File file = LittleFS.open(path, "r"); if (!file) return ""; while (file.available()) r += (char) file.read(); file.close(); Serial.println(String("readFile(\"") + path + "\") = \"" + r + "\""); return r; } bool writeFile (const char * path, String data) { File file = LittleFS.open(path, "w"); if (!file) return false; bool r = false; if (file.print(data)) r = true; file.close(); Serial.println(String("writeFile(\"") + path + "\", \"" + data + "\")"); return r; } void render (int siz, String text) { display.clearDisplay(); display.cp437(true); display.setTextSize(siz); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.print(text); display.display(); } void wifi_update () { if (readFile("wifi").toInt()) { WiFi.mode(WIFI_AP_STA); WiFi.begin(readFile("wifi_ssid"), readFile("wifi_password")); WiFi.softAP(readFile("ap_ssid"), readFile("ap_password")); } else WiFi.mode(WIFI_OFF); Serial.println("wifi_update();"); } float cena = 0; void setup() { pinMode(GUMB_CAL, INPUT); attachInterrupt(GUMB_CAL, isr, RISING); pinMode(POWER_DEVICES, OUTPUT); digitalWrite(POWER_DEVICES, HIGH); Wire.begin(SDA, SCL); Serial.begin(115200); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("SSD1306 allocation failed"); for (;;); } ArduinoOTA.onStart([]() { render(1, "Posodabljanje \n" "programske opreme \n" "se bo izvedlo v \n" "kratkem. "); }); ArduinoOTA.onEnd([]() { render(1, "Prenos posodobitve \n" "uspel. Sedaj kopiram \n" "posodobitev v shrambo\n" "za zagon. Ne izklopi!"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { render(1, String("Posodabljam ... \n") + "Potek: " + progress*100/total + " %\n" + progress + " od " + total + "\n" + "Prosim za potrpljenje\n"); }); ArduinoOTA.onError([](ota_error_t error) { const char * desc = "neznana napaka"; if (error == OTA_AUTH_ERROR) desc = "avtentikacija spodl. "; else if (error == OTA_BEGIN_ERROR) desc = "'begin' spodletel "; else if (error == OTA_CONNECT_ERROR) desc = "povezava spodletela "; else if (error == OTA_RECEIVE_ERROR) desc = "prejem spodletel "; else if (error == OTA_END_ERROR) desc = "'end' spodletel "; render(1, String("Napaka[") + error + "]: \n" + desc + "\nOprostite."); delay(DELAY); }); ArduinoOTA.begin(); render(1, "~NASTAVLJAM TEHTNICO~\n" "V kolikor ta tekst \n" "dolgo ostane, je \n" "tehtnica pokvarjena. \n"); scale.begin(HX711_DATA, HX711_CLOCK); Serial.println("scale.begin(SDA, SCL);"); scale.tare(20); Serial.println("scale.tare(20);"); if (!LittleFS.begin()) { render(1, "LittleFS.begin() \n" "spodletel! \n" "Ni trajne shrambe! \n" "Nesite na popravilo. "); delay(DELAY); } if (readFile("wifi_ssid") == "") writeFile("wifi_ssid", "b"); if (readFile("wifi_password") == "") writeFile("wifi_password", ""); if (readFile("ap_ssid") == "") writeFile("ap_ssid", "tehtnica"); if (readFile("ap_password") == "") writeFile("ap_password", ""); if (readFile("wifi") == "") writeFile("wifi", "1"); if (readFile("cena") == "") writeFile("cena", "7.0"); wifi_update(); ftpSrv.begin("Pozdravljeni, to je tehtnica!"); scale.set_scale(readFile("faktor").toFloat()); cena = readFile("cena").toFloat(); wake = millis(); } void loop() { ftpSrv.handleFTP(); ArduinoOTA.handle(); if (millis() - wake > TIMEOUT) { digitalWrite(POWER_DEVICES, LOW); pinMode(POWER_DEVICES, INPUT); ESP.deepSleep(0); } if (stanje % DOLŽINA == GLAVNO || stanje % DOLŽINA == CENA) { float teža = scale.get_units(); if (!wake_mass) wake_mass = teža; if (abs(wake_mass - teža) > WAKE_MASS) { wake_mass = teža; wake = millis(); } char teža_str[16]; char cena_str[16]; if (stanje % DOLŽINA == CENA) { wake = millis(); sprintf(teža_str, "% 6.1f", teža); sprintf(cena_str, "% 6.1f", cena*strtof(teža_str, NULL)); render(2, String(teža_str) + " g\n" + String(cena_str) + " eur"); } else { sprintf(teža_str, "% 6.1f", teža); render(3, String(teža_str)); } } if (millis() - nazadnje_gumb > DELAY) switch (stanje % DOLŽINA) { case KALIBRACIJA: render(2, "KALIBRIRAM\n100 g"); scale.calibrate_scale(100, 20); writeFile("faktor", String(scale.get_scale())); render(1, String(" ~ KALIBRACIJA ~ \n") + "Faktor: " + scale.get_scale() + "\nFaktor sem shranil\n" "v trajni spomin."); delay(DELAY); stanje = GLAVNO; break; case WIFI: writeFile("wifi", String(!(readFile("wifi").toInt()))); wifi_update(); render(1, String( " ~ ~ ~ WIFI ~ ~ ~ \n") + "Operacija uspela. \n" + "WiFi je sedaj \n" + String(readFile("wifi").toInt() ? "vklopljen" : "izklopljen") + "."); delay(DELAY); stanje = GLAVNO; break; } if (gumb) { wake = millis(); gumb = false; switch (++stanje % DOLŽINA) { case GLAVNO: break; case KALIBRACIJA: render(1, String( " ~ KALIBRACIJA ~ \n") + String("Faktor: ") + scale.get_scale() + "\n100g naj bo na tehtn.\n" + "Kmalu bom kalibriral."); break; case WIFI: String sta = "Nisem povezan."; if (WiFi.waitForConnectResult() == WL_CONNECTED) sta = WiFi.localIP().toString(); render(1, String( " ~ ~ ~ WIFI ~ ~ ~ \n") + sta + "\nKmalu bom wifi\n" + (readFile("wifi").toInt() ? String("izklopil") : String("vklopil")) + " ..."); break; } } }