summaryrefslogtreecommitdiffstats
path: root/prog/tehtnica/tehtnica.ino
blob: 15af6a26d6a7dffa10c7cd2599f6d0e320a3f666 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#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;
    }
  }
}