#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <LittleFS.h>
#include <SimpleFTPServer.h>
#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;
}
}
}