summaryrefslogblamecommitdiffstats
path: root/prog/tehtnica/tehtnica.ino
blob: 15af6a26d6a7dffa10c7cd2599f6d0e320a3f666 (plain) (tree)







































































































































































































































                                                                                                                                                          
#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;
    }
  }
}