diff options
Diffstat (limited to 'fiz/naloga/vodnaraketa')
-rw-r--r-- | fiz/naloga/vodnaraketa/data/settings.json | 8 | ||||
-rw-r--r-- | fiz/naloga/vodnaraketa/platformio.ini | 18 | ||||
-rw-r--r-- | fiz/naloga/vodnaraketa/src/main.cpp | 226 | ||||
-rw-r--r-- | fiz/naloga/vodnaraketa/src/main.cpp.hx711 | 78 |
4 files changed, 256 insertions, 74 deletions
diff --git a/fiz/naloga/vodnaraketa/data/settings.json b/fiz/naloga/vodnaraketa/data/settings.json index 4ef4b59..e7ecd13 100644 --- a/fiz/naloga/vodnaraketa/data/settings.json +++ b/fiz/naloga/vodnaraketa/data/settings.json @@ -5,15 +5,15 @@ "ap_ch": 1, "ap_hidden": 0, "ap_ip": "10.82.66.1", - "ap_gw": "10.82.66.1", + "ap_gw": "10.82.66.2", "ap_nm": "255.255.255.0", "ap_dns1": "", "ap_dns2": "", "ap_host": "vodnaraketa", /* wifi station (client) configuration, leave ip settings empty to use DHCP obtained */ - "sta_ssid": "", - "sta_pass": "", + "sta_ssid": "Xiaomi_5F6D", + "sta_pass": "kitajska", "sta_ip": "", "sta_dns": "", "sta_gw": "", @@ -26,6 +26,8 @@ /* pin configuration */ "scale_dout": "D6", "scale_sck": "D5", + "scale_cal": 440000, + "scale_tar": -51100, /* username and password for FTP and HTTP authentication */ "ftp_user": "vodnaraketa", diff --git a/fiz/naloga/vodnaraketa/platformio.ini b/fiz/naloga/vodnaraketa/platformio.ini index 5977f35..0c7f25b 100644 --- a/fiz/naloga/vodnaraketa/platformio.ini +++ b/fiz/naloga/vodnaraketa/platformio.ini @@ -1,18 +1,14 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html +[s] +monitor_speed = 9600 +upload_speed = 921600 + [env:myboard] platform = espressif8266 +extends = s board = nodemcuv2 monitor_speed = 9600 -upload_speed = 921600 -build_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_PORT=Serial -DIP_FORWARD=1 +upload_speed = 460800 +build_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_PORT=Serial -DIP_FORWARD=1 -DMONITOR_SPEED=${s.monitor_speed} framework = arduino board_build.filesystem = littlefs board_build.ldscript = eagle.flash.4m2m.ld diff --git a/fiz/naloga/vodnaraketa/src/main.cpp b/fiz/naloga/vodnaraketa/src/main.cpp index 91280dd..f782cdb 100644 --- a/fiz/naloga/vodnaraketa/src/main.cpp +++ b/fiz/naloga/vodnaraketa/src/main.cpp @@ -13,7 +13,7 @@ #include <HX711.h> #include <FTPServer.h> -DynamicJsonDocument settings(2048); +DynamicJsonDocument settings(1024); #include <func.c> @@ -23,38 +23,77 @@ AsyncWebServer httpServer(80); HX711 scale; time_t measure = 0; +unsigned long measureStartMillis; File measureFile; +struct measure { + unsigned long millis; + float scale; + double pa; +}; +#define MEASURE_BUFFER_SIZE (1024) +struct measure measureBuffer[MEASURE_BUFFER_SIZE]; /* buffer to store measured stuff before writing to littlefs */ + +#define A2VOLT(ar) (ar*3.3/1023) +#define VOLT2A(vo) (vo*1023/3.3) +#define A2PA(ar) ((A2VOLT(ar)-0.5)*1200000/4.5) +#define TEXT_ENC "text/plain; charset=utf-8" + +int do_reload = 0; + void reload (bool w = 0) { /* stop services unless they were never started, indicate this by w in for example setup() */ + Serial.println("reload"); if (!w) { + Serial.println("stopping services: ftp"); ftpServer.stop(); + Serial.println("stopping services: http"); httpServer.reset(); + Serial.println("stopping services: dns"); dnsServer.stop(); } /* reload settings */ + Serial.println("loading settings"); load_settings(); + /* configure pin modes */ + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH /* LED IS ON when pulled LOW */); + + + long unsigned int mac; + uint8_t macar[6]; + /* bring up AP networking */ - IPAddress ap_ip(10, 82, 66, 1); - ap_ip.fromString(settings["ap_ip"].as<String>()); - IPAddress ap_gateway(10, 82, 66, 1); - ap_gateway.fromString(settings["ap_gw"].as<String>()); - IPAddress ap_subnet(255, 255, 255, 0); - ap_subnet.fromString(settings["ap_nm"].as<String>()); - WiFi.mode(WIFI_AP); - WiFi.softAPConfig(ap_ip, ap_gateway, ap_subnet); + /* // setting fancy settings does not work, FUCK ESPRESSIF AND THEIR BLOB RTOS!!! + IPAddress ap_ip(10, 82, 66, 1); + ap_ip.fromString(settings["ap_ip"].as<String>()); + IPAddress ap_gateway(10, 82, 66, 1); + ap_gateway.fromString(settings["ap_gw"].as<String>()); + IPAddress ap_subnet(255, 255, 255, 0); + ap_subnet.fromString(settings["ap_nm"].as<String>()); + WiFi.softAPdisconnect(true); + WiFi.softAPConfig(ap_ip, ap_gateway, ap_subnet); + mac = strtoul(settings["ap_mac"].as<String>().c_str(), NULL, 16); + memcpy(macar, (char *) &mac, 6); + if (strlen(settings["ap_mac"].as<String>().c_str()) == 12) + wifi_set_macaddr(SOFTAP_IF, macar); + */ + Serial.println("access point"); const char * ap_pass = settings["ap_pass"].as<String>().c_str(); if (ap_pass && strlen(ap_pass) < 8) ap_pass = NULL; - WiFi.softAP(settings["ap_ssid"].as<String>().c_str(), ap_pass, settings["cp_ch"].as<int>(), settings["ap_hidden"].as<int>()); + WiFi.mode(WIFI_AP); + WiFi.softAP(settings["ap_ssid"].as<String>().c_str(), ap_pass, settings["ap_ch"].as<int>(), settings["ap_hidden"].as<int>()); Serial.println("WiFi.softAPIP() = " + WiFi.softAPIP().toString()); /* bring up STA networking - if that's desired */ + Serial.println("station networking"); const char * sta_ssid = settings["sta_ssid"].as<String>().c_str(); - if (sta_ssid && strlen(sta_ssid) > 0) { + if (strlen(settings["sta_ssid"].as<String>().c_str())) { + Serial.println("setting up wifi station mode"); IPAddress sta_ip(10, 69, 69, 82); sta_ip.fromString(settings["sta_ip"].as<String>()); IPAddress sta_gw(10, 69, 69, 1); @@ -65,6 +104,12 @@ void reload (bool w = 0) { sta_dns1.fromString(settings["sta_dns1"].as<String>()); IPAddress sta_dns2(193, 2, 1, 66); sta_dns2.fromString(settings["sta_dns2"].as<String>()); + + mac = strtoul(settings["sta_mac"].as<String>().c_str(), NULL, 16); + memcpy(macar, (char *) &mac, 6); + if (strlen(settings["sta_mac"].as<String>().c_str()) == 12) + wifi_set_macaddr(STATION_IF, macar); + WiFi.disconnect(true); WiFi.hostname(settings["sta_host"].as<String>()); const char * sta_pass = settings["sta_pass"].as<String>().c_str(); @@ -74,98 +119,159 @@ void reload (bool w = 0) { if (settings["sta_static"].as<int>()) if (!WiFi.config(sta_ip, sta_gw, sta_nm, sta_dns1, sta_dns2)) Serial.println("failed to wifi config"); + Serial.println(String("wifi local ip: ")+WiFi.localIP().toString()); + } else { + WiFi.disconnect(); } /* start services */ dnsServer.start(53, settings["host"], WiFi.softAPIP()); ftpServer.begin(settings["ftp_user"], settings["ftp_pass"]); /* web server */ -#define ADD_AUTH(h) if (strlen(settings["http_user"].as<String>().c_str()) || strlen(settings["http_pass"].as<String>().c_str())) h.setAuthentication(settings["http_user"], settings["http_pass"]) - auto h = httpServer.serveStatic("/", LittleFS, "/") - .setDefaultFile("index.html") - .setAuthentication(settings["http_user"], settings["http_pass"]); - ADD_AUTH(h); - h = httpServer.on("/rst", [](AsyncWebServerRequest * r) { - r->send(201, "text/plain", "OK"); +#define ADD_AUTH(h) h.setAuthentication(settings["http_user"], settings["http_pass"]); + auto s = httpServer.serveStatic("/index.html", LittleFS, "/") + .setDefaultFile("index.html"); + ADD_AUTH(s); + auto h = httpServer.on("/s", [](AsyncWebServerRequest * r) { + r->send(201, TEXT_ENC, "OK"); ESP.restart(); }); ADD_AUTH(h); - h = httpServer.on("/rld", [](AsyncWebServerRequest * r) { - r->send(201, "text/plain", "OK"); - reload(); + h = httpServer.on("/l", [](AsyncWebServerRequest * r) { + r->send(201, TEXT_ENC, "OK"); + do_reload = 1; }); h = httpServer.on("/m", [](AsyncWebServerRequest * r) { if (!r->hasParam("n")) - r->send(400, "text/plain", "Manjka parameter n - število sekund meritve"); + r->send(400, TEXT_ENC, "Manjka parameter n - število sekund meritve"); else if (!measure) { - measure = time(NULL)+atoi(r->getParam("n")->value().c_str()); - r->send(201, "text/plain", "OK"); + measure = atoi(r->getParam("n")->value().c_str()); + r->send(201, TEXT_ENC, String("OK")+measure); } else { - r->send(400, "text/plain", "Meritev že poteka!"); + r->send(400, TEXT_ENC, "Meritev že poteka!"); } }); ADD_AUTH(h); /* specifični ukazi za meritve: začetek loadcella, kalibracija, tara */ + Serial.println(String("začenjam vago na pinih ")+str2pin(settings["scale_dout"].as<String>().c_str())+String(" in ")+ + str2pin(settings["scale_sck"].as<String>().c_str())); scale.begin(str2pin(settings["scale_dout"].as<String>().c_str()), str2pin(settings["scale_sck"].as<String>().c_str())); + Serial.println(String("kalibriram vago na vrednost ")+settings["scale_cal"].as<float>()); + scale.set_scale(settings["scale_cal"].as<float>()); + scale.set_offset(settings["scale_tar"].as<long>()); + if (scale.wait_ready_timeout(1000)) + Serial.println(String("skala meri surovo: ")+scale.read_average(10)); + else + Serial.println(String("ne morem se povezati na skalo")); + + /* specifični http ukazi */ h = httpServer.on("/c", [](AsyncWebServerRequest * r) { - if (!r->hasParam("t")) { - r->send(400, "text/plain", "Manjka parameter t - teža na tehtnici"); - } - if (scale.wait_ready_timeout(1000)) { - scale.set_scale(); - scale.tare(); - scale.set_scale(scale.get_units(10)/atof(r->getParam("t")->value().c_str())); - r->send(200, "text/plain", "OK"); - } else { - r->send(500, "text/plain", "Tehtnica ni najdena"); - } + if (!r->hasParam("t") && !r->hasParam("f")) { + r->send(400, TEXT_ENC, "Manjka parameter t - teža na tehtnici ali parameter f - kalibracijski faktor"); + } else + if (scale.wait_ready_timeout(1000)) { + float scaleCal; + if (!r->hasParam("f")) { + scale.set_scale(); + scale.tare(); + scaleCal = scale.get_units(10)/atof(r->getParam("t")->value().c_str()); + scale.set_scale(scaleCal); + r->send(200, TEXT_ENC, String("kalibracijski faktor: ")+String(scaleCal)); + } else { + scale.set_scale(atof(r->getParam("f")->value().c_str())); + r->send(200, TEXT_ENC, String("teža: "+String(scale.get_units(10)))); + } + } else { + r->send(500, TEXT_ENC, "Tehtnica ni najdena"); + } }); ADD_AUTH(h); h = httpServer.on("/t", [](AsyncWebServerRequest * r) { if (scale.wait_ready_timeout(1000)) { scale.tare(); - r->send(400, "text/plain", "OK"); + r->send(400, TEXT_ENC, String("razlika, ki jo odštejemo od surove vrednosti, je ")+scale.get_offset()); } else { - r->send(500, "text/plain", "Tehtnica ni najdena."); + r->send(500, TEXT_ENC, "Tehtnica ni najdena."); } }); ADD_AUTH(h); + h = httpServer.on("/g", [](AsyncWebServerRequest * r) { + float reading = -1; + long readingraw = -1; + if (scale.wait_ready_timeout(1000)) { + reading = scale.get_units(5); + readingraw = scale.read_average(5); + } else + Serial.println("/g: reading error"); + double pa = analogRead(A0); + pa = A2PA(pa); + r->send(200, "application/json", String("{\"p\":")+pa+String(",\"s\":")+reading+String(",\"r\":")+readingraw+String("}")); + }); + ADD_AUTH(h); + httpServer.begin(); } void handleMeasure() { - if (measure != 0) { - if (measure < time(NULL)) { - if (measureFile.isFile()) { - char filename[32]; - snprintf(filename, 32, "meritev%ldl.csv", time(NULL)); - measureFile = LittleFS.open(filename, "w"); - scale.power_up(); - } - if (scale.wait_ready_timeout(1000)) { - long reading = scale.get_units(10); - measureFile.print(millis()+""+"\n"); - } else { - Serial.println("HX711 ni najden."); - } - } else { - measure = 0; - measureFile.close(); - scale.power_down(); + /* ni časovno omejeno, zapiše se čim več meritev, recimo izvede se enkrat na 10 milisekund, to je idealno. */ + /* ob desetsekundni meritvi je to 1000 zajemov, kar znese ob 100 bajtih na zajem 100 kilobajtov na flash. */ + httpServer.end(); + Serial.println(String("meritev loop started at ")+millis()); + measure += time(NULL)+1; + int i = 0; + digitalWrite(LED_BUILTIN, LOW); /* glows in the dark1 */ + ESP.wdtDisable(); + while (measure >= time(NULL)) { + Serial.println("meritev ..."); + if (scale.wait_ready_timeout(1000)) { + measureBuffer[i].millis = millis(); + measureBuffer[i].scale = scale.get_units(1); + /* zaradi konstantnega branja analognih vrednosti je pričakovano, da ob meritvi crkne WiFi */ + measureBuffer[i].pa = analogRead(A0); + measureBuffer[i].pa = A2PA(measureBuffer[i].pa); + } else + Serial.println("HX711 ni najden."); + if (i >= MEASURE_BUFFER_SIZE) { + Serial.println("zapolnjen measure buffer, dovolj bo"); + break; } + i++; + } + ESP.wdtEnable(2000); + digitalWrite(LED_BUILTIN, HIGH); /* stops glowing */ + if (!measureFile.isFile()) { + char filename[32]; + snprintf(filename, 32, "meritev%ld.csv", time(NULL)); + Serial.println(String("starting measure into file ")+filename); + measureFile = LittleFS.open(filename, "w"); + scale.power_up(); + measureStartMillis = millis(); } + for (int j = 0; j < i; j++) + measureFile.print(measureBuffer[j].millis+String(",")+measureBuffer[j].scale+String(",")+measureBuffer[j].pa+String("\n")); + measure = 0; + measureFile.close(); + Serial.println(String("meritev loop done at ")+millis()); + httpServer.begin(); } void setup () { - Serial.begin(9600); + Serial.begin(MONITOR_SPEED); Serial.println("Živ sem!"); LittleFS.begin(); reload(1); } void loop () { - handleMeasure(); - ftpServer.handleFTP(); - dnsServer.processNextRequest(); + if (measure) + handleMeasure(); + else { + ftpServer.handleFTP(); + dnsServer.processNextRequest(); + if (do_reload) { + reload(); + do_reload = 0; + } + } } diff --git a/fiz/naloga/vodnaraketa/src/main.cpp.hx711 b/fiz/naloga/vodnaraketa/src/main.cpp.hx711 new file mode 100644 index 0000000..ebaf9a5 --- /dev/null +++ b/fiz/naloga/vodnaraketa/src/main.cpp.hx711 @@ -0,0 +1,78 @@ +/** + * + * HX711 library for Arduino - example file + * https://github.com/bogde/HX711 + * + * MIT License + * (c) 2018 Bogdan Necula + * +**/ +#include "HX711.h" + + +// HX711 circuit wiring +const int LOADCELL_DOUT_PIN = D6; +const int LOADCELL_SCK_PIN = D5; + + +HX711 scale; + +void setup() { + Serial.begin(9600); + Serial.println("HX711 Demo"); + + Serial.println("Initializing the scale"); + + // Initialize library with data output pin, clock input pin and gain factor. + // Channel selection is made by passing the appropriate gain: + // - With a gain factor of 64 or 128, channel A is selected + // - With a gain factor of 32, channel B is selected + // By omitting the gain factor parameter, the library + // default "128" (Channel A) is used here. + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); + + Serial.println("Before setting up the scale:"); + Serial.print("read: \t\t"); + Serial.println(scale.read()); // print a raw reading from the ADC + + Serial.print("read average: \t\t"); + Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC + + Serial.print("get value: \t\t"); + Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet) + + Serial.print("get units: \t\t"); + Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided + // by the SCALE parameter (not set yet) + + scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details + scale.tare(); // reset the scale to 0 + + Serial.println("After setting up the scale:"); + + Serial.print("read: \t\t"); + Serial.println(scale.read()); // print a raw reading from the ADC + + Serial.print("read average: \t\t"); + Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC + + Serial.print("get value: \t\t"); + Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare() + + Serial.print("get units: \t\t"); + Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided + // by the SCALE parameter set with set_scale + + Serial.println("Readings:"); +} + +void loop() { + Serial.print("one reading:\t"); + Serial.print(scale.get_units(), 1); + Serial.print("\t| average:\t"); + Serial.println(scale.get_units(10), 1); + + scale.power_down(); // put the ADC in sleep mode + delay(50); + scale.power_up(); +} |