Fix LCD Display, Add OTA
This commit is contained in:
parent
3a6c1ca884
commit
222feef353
|
@ -1,3 +1,5 @@
|
|||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/launch.json
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
!<arch>
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
!<arch>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -59,7 +59,7 @@
|
|||
<span id="voltage"></span> V
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
<span id="shuntvoltage_V_min"></span> / <span id="shuntvoltage_V_max"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-active">
|
||||
|
@ -73,7 +73,7 @@
|
|||
<span id="current"></span> A
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
<span id="current_A_min"></span> / <span id="current_A_max"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -87,7 +87,7 @@
|
|||
<span id="power"></span> W
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
<span id="power_W_min"></span> / <span id="power_W_max"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-active">
|
||||
|
@ -115,6 +115,7 @@
|
|||
<span id="Wh"></span> Wh
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -141,7 +142,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>Build by Carsten Schmiemann (2018), Akku <span id="battery"></span> V, Status: <span id="run"></span></div>
|
||||
<div><center>Build by Carsten Schmiemann (2018), Akku <span id="battery"></span> V, Status: <span id="run"></span></center></div>
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<script src="js/scripts.js"></script>
|
||||
|
|
|
@ -11,7 +11,13 @@
|
|||
document.getElementById("Ah").innerHTML = values.Ah;
|
||||
document.getElementById("Wh").innerHTML = values.Wh;
|
||||
document.getElementById("battery").innerHTML = values.battery;
|
||||
document.getElementById("run").innerHTML = values.run;
|
||||
document.getElementById("run").innerHTML = values.run;
|
||||
document.getElementById("shuntvoltage_V_max").innerHTML = values.shuntvoltage_V_max;
|
||||
document.getElementById("shuntvoltage_V_min").innerHTML = values.shuntvoltage_V_min;
|
||||
document.getElementById("current_A_max").innerHTML = values.current_A_max;
|
||||
document.getElementById("current_A_min").innerHTML = values.current_A_min;
|
||||
document.getElementById("power_W_max").innerHTML = values.power_W_max;
|
||||
document.getElementById("power_W_min").innerHTML = values.power_W_min;
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "/meas/values", true);
|
||||
|
|
|
@ -16,3 +16,5 @@ lib_deps = ArduinoINA219, Wire, EEPROM, TaskScheduler, LiquidCrystal_I2C, ESPAsy
|
|||
board_build.partitions = partitions.csv
|
||||
monitor_port = COM6
|
||||
monitor_speed = 115200
|
||||
upload_port = 10.11.0.44
|
||||
upload_flags = "--port=1337 --auth=powerlyzer"
|
|
@ -12,13 +12,15 @@
|
|||
#include <ESPAsyncWiFiManager.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <ESP8266FtpServer.h>
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
//Library Config
|
||||
LiquidCrystal_I2C lcd(0x27,20,4);
|
||||
INA219 ina219;
|
||||
AsyncWebServer server(80);
|
||||
DNSServer dns;
|
||||
FtpServer ftpSrv;
|
||||
FtpServer ftpSrv;
|
||||
Scheduler task;
|
||||
|
||||
//Konstanten
|
||||
#define R_SHUNT 0.001
|
||||
|
@ -49,6 +51,14 @@ void web_measuring_reset(AsyncWebServerRequest *request);
|
|||
void web_get_values(AsyncWebServerRequest *request);
|
||||
void data_logging();
|
||||
|
||||
//Task Scheduler
|
||||
Task t1(500, TASK_FOREVER, &lcd_print);
|
||||
Task t2(1750, TASK_FOREVER, &lcd_header);
|
||||
Task t3(10000, TASK_FOREVER, &read_bat);
|
||||
Task t4(300, TASK_FOREVER, &read_button);
|
||||
Task t5(30000, TASK_FOREVER, &data_logging);
|
||||
//Task t3(60000, TASK_FOREVER, &eeprom_save);
|
||||
|
||||
//Globale Variablen
|
||||
float shuntvoltage_V = 0, shuntvoltage_mV = 0, busvoltage_V = 0, busvoltage_mV = 0, current_A = 0, current_mA = 0, power_W = 0, power_mW = 0;
|
||||
float shuntvoltage_V_max = 0, current_A_max = 0, power_W_max = 0, shuntvoltage_V_min = 0, current_A_min = 0, power_W_min = 0;
|
||||
|
@ -56,8 +66,8 @@ float Ah = 0, mAh = 0, Wh = 0, mWh = 0;
|
|||
float battery_voltage, battery_average;
|
||||
int i_header = 0;
|
||||
bool button1, button2, button3;
|
||||
bool lcd_light = true, wifi_enabled = true;
|
||||
bool measuring_run = false, reset_actual = false, reset_minmax =false, battery_low = false;
|
||||
bool lcd_light = true, wifi_enabled = true, test_mode = false;
|
||||
bool measuring_run = false, measuring_init = false, reset_actual = false, reset_minmax =false, battery_low = false;
|
||||
unsigned long lastread = 0;
|
||||
unsigned long tick;
|
||||
unsigned long previousMillisReadData = 0;
|
||||
|
@ -99,16 +109,6 @@ byte batterie[8] = {
|
|||
0b11111
|
||||
};
|
||||
|
||||
//Task Scheduler
|
||||
Task t1(500, TASK_FOREVER, &lcd_print);
|
||||
Task t2(1750, TASK_FOREVER, &lcd_header);
|
||||
Task t3(10000, TASK_FOREVER, &read_bat);
|
||||
Task t4(300, TASK_FOREVER, &read_button);
|
||||
Task t5(30000, TASK_FOREVER, &data_logging);
|
||||
//Task t3(60000, TASK_FOREVER, &eeprom_save);
|
||||
Scheduler task;
|
||||
|
||||
|
||||
void setup() {
|
||||
//Setup GPIO
|
||||
pinMode(led_lowbat_pin, OUTPUT);
|
||||
|
@ -122,6 +122,46 @@ void setup() {
|
|||
Serial.begin(115200);
|
||||
Serial.println("Power Analyzer by Carsten Schmiemann (C) 2018");
|
||||
|
||||
//Setup Over The Air - Update
|
||||
ArduinoOTA
|
||||
.onStart([]() {
|
||||
//Disable Tasks
|
||||
t1.disable();
|
||||
t2.disable();
|
||||
t3.disable();
|
||||
t4.disable();
|
||||
t5.disable();
|
||||
SPIFFS.end();
|
||||
String type;
|
||||
lcd.clear();
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("OTA Firmware Update");
|
||||
lcd.setCursor(7,1);
|
||||
lcd.print("Init");
|
||||
})
|
||||
.onEnd([]() {
|
||||
lcd.setCursor(7,2);
|
||||
lcd.print("Done.");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
})
|
||||
.onProgress([](unsigned int progress, unsigned int total) {
|
||||
lcd.setCursor(3,1);
|
||||
lcd.print(progress / (total / 100)); lcd.print("% Complete");
|
||||
})
|
||||
.onError([](ota_error_t error) {
|
||||
lcd.setCursor(3,3);
|
||||
lcd.print("Done.");
|
||||
if (error == OTA_AUTH_ERROR) lcd.print("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) lcd.print("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) lcd.print("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) lcd.print("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) lcd.print("End Failed");
|
||||
});
|
||||
ArduinoOTA.setPort(1337);
|
||||
ArduinoOTA.setPassword("powerlyzer");
|
||||
ArduinoOTA.begin();
|
||||
|
||||
//Init LCD and Custom Chars
|
||||
lcd.init();
|
||||
lcd.backlight();
|
||||
|
@ -138,7 +178,7 @@ void setup() {
|
|||
lcd.print("Power Analyzer");
|
||||
lcd.setCursor(7,1);
|
||||
//lcd.print("Tracker");
|
||||
lcd.setCursor(5,2);
|
||||
lcd.setCursor(6,2);
|
||||
lcd.print("V0.29 Beta");
|
||||
lcd.setCursor(7,3);
|
||||
lcd.print("CS,2018");
|
||||
|
@ -178,17 +218,66 @@ void setup() {
|
|||
wifi_enabled = false;
|
||||
}
|
||||
|
||||
//Setup Over The Air - Update
|
||||
ArduinoOTA
|
||||
.onStart([]() {
|
||||
//Disable Tasks
|
||||
t1.disable();
|
||||
t2.disable();
|
||||
t3.disable();
|
||||
t4.disable();
|
||||
t5.disable();
|
||||
SPIFFS.end();
|
||||
String type;
|
||||
lcd.clear();
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("OTA Firmware Update");
|
||||
lcd.setCursor(7,1);
|
||||
lcd.print("Init");
|
||||
})
|
||||
.onEnd([]() {
|
||||
lcd.setCursor(7,2);
|
||||
lcd.print("Done.");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
})
|
||||
.onProgress([](unsigned int progress, unsigned int total) {
|
||||
lcd.setCursor(3,1);
|
||||
lcd.print(progress / (total / 100)); lcd.print("% Complete");
|
||||
})
|
||||
.onError([](ota_error_t error) {
|
||||
lcd.setCursor(3,3);
|
||||
lcd.print("Done.");
|
||||
if (error == OTA_AUTH_ERROR) lcd.print("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) lcd.print("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) lcd.print("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) lcd.print("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) lcd.print("End Failed");
|
||||
});
|
||||
if (wifi_enabled) {
|
||||
ArduinoOTA.setPort(1337);
|
||||
ArduinoOTA.setPassword("powerlyzer");
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
|
||||
//Init ina219s
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("Init Sensors...");
|
||||
ina219.begin();
|
||||
ina219.configure(INA219::RANGE_16V, INA219::GAIN_2_80MV, INA219::ADC_16SAMP, INA219::ADC_16SAMP, INA219::CONT_SH_BUS);
|
||||
lastread = millis();
|
||||
ina219.calibrate(R_SHUNT, V_SHUNT_MAX, V_BUS_MAX, I_MAX_EXPECTED);
|
||||
delay(300);
|
||||
lcd.setCursor(16,1);
|
||||
lcd.print("Done");
|
||||
delay(200);
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("Init Sensors...");
|
||||
if (digitalRead(button1_pin)) {
|
||||
ina219.begin();
|
||||
ina219.configure(INA219::RANGE_16V, INA219::GAIN_2_80MV, INA219::ADC_16SAMP, INA219::ADC_16SAMP, INA219::CONT_SH_BUS);
|
||||
lastread = millis();
|
||||
ina219.calibrate(R_SHUNT, V_SHUNT_MAX, V_BUS_MAX, I_MAX_EXPECTED);
|
||||
delay(300);
|
||||
lcd.setCursor(16,1);
|
||||
lcd.print("Done");
|
||||
delay(200);
|
||||
} else {
|
||||
lcd.setCursor(16,1);
|
||||
lcd.print("Test");
|
||||
test_mode = true;
|
||||
delay(500);
|
||||
}
|
||||
|
||||
//Init Task Scheduler
|
||||
lcd.setCursor(0,2);
|
||||
|
@ -199,10 +288,6 @@ void setup() {
|
|||
task.addTask(t3);
|
||||
task.addTask(t4);
|
||||
task.addTask(t5);
|
||||
t2.enable();
|
||||
t3.enable();
|
||||
t4.enable();
|
||||
t5.enable();
|
||||
//Init Filesystem and Webserver
|
||||
SPIFFS.begin();
|
||||
server.on("/meas/run", HTTP_GET, web_measuring_run);
|
||||
|
@ -229,39 +314,75 @@ void setup() {
|
|||
lcd.clear();
|
||||
lcd.setCursor(6,1);
|
||||
lcd.print("IP address");
|
||||
lcd.setCursor(5,2);
|
||||
lcd.setCursor(6,2);
|
||||
lcd.print(WiFi.localIP());
|
||||
delay(1500);
|
||||
}
|
||||
//Load Default Screen
|
||||
lcd_init();
|
||||
|
||||
//Enable Tasks
|
||||
t1.enable();
|
||||
t2.enable();
|
||||
t3.enable();
|
||||
t4.enable();
|
||||
t5.enable();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Exec TaskScheduler
|
||||
task.execute();
|
||||
ftpSrv.handleFTP();
|
||||
ArduinoOTA.handle();
|
||||
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
if ((unsigned long)(currentMillis - previousMillisReadData) >= 250) {
|
||||
previousMillisReadData = millis();
|
||||
if (test_mode) {
|
||||
if (digitalRead(button1_pin)) {
|
||||
shuntvoltage_V += 1;
|
||||
power_W += 1;
|
||||
current_A += 1;
|
||||
Ah += 1;
|
||||
Wh += 1;
|
||||
}
|
||||
if (digitalRead(button2_pin)) {
|
||||
shuntvoltage_V -= 1;
|
||||
power_W -= 1;
|
||||
current_A -= 1;
|
||||
Ah -= 1;
|
||||
Wh -= 1;
|
||||
}
|
||||
} else {
|
||||
readCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_print() {
|
||||
if (busvoltage_V > 10) {lcd.setCursor(1,3);} else if (busvoltage_V < 0) {lcd.setCursor(1,3);} else {lcd.setCursor(1,3); lcd.print(" ");}
|
||||
lcd.print(busvoltage_V);
|
||||
if (current_A > 10) {lcd.setCursor(1,1);} else if (current_A < 0) {lcd.setCursor(1,1);} else {lcd.setCursor(1,1); lcd.print(" ");}
|
||||
lcd.setCursor(0,1);
|
||||
if (current_A < 100 && current_A >= 10) {lcd.print(" ");} else if (current_A < 10 && current_A >= 0) {lcd.print(" ");};
|
||||
if (current_A > -100 && current_A <= -10) {lcd.print(" ");} else if (current_A > -10 && current_A < 0) {lcd.print(" ");};
|
||||
lcd.print(current_A);
|
||||
|
||||
lcd.setCursor(0,2);
|
||||
if (power_W < 100 && power_W > 10) {lcd.print(" ")}; else if (power_W < 10) {lcd.print(" ")};
|
||||
if (power_W < 1000 && power_W > 100) {lcd.print(" ");} else if (power_W < 100 && power_W >= 10) {lcd.print(" ");} else if (power_W < 10) {lcd.print(" ");};
|
||||
lcd.print(power_W);
|
||||
if (Ah > 10) {lcd.setCursor(13,1);} else if (Ah < 0){lcd.setCursor(11,1);} else {lcd.setCursor(11,1); lcd.print(" ");}
|
||||
|
||||
lcd.setCursor(0,3);
|
||||
if (busvoltage_V < 100 && busvoltage_V >= 10) {lcd.print(" ");} else if (busvoltage_V < 10) {lcd.print(" ");};
|
||||
lcd.print(busvoltage_V);
|
||||
|
||||
lcd.setCursor(11,1);
|
||||
if (Ah < 1000 && Ah > 100) {lcd.print(" ");} else if (Ah < 100 && Ah >= 10) {lcd.print(" ");} else if (Ah < 10) {lcd.print(" ");};
|
||||
lcd.print(Ah);
|
||||
if (Wh > 10) {lcd.setCursor(13,2);} else if (Wh < 0){lcd.setCursor(11,2);} else {lcd.setCursor(11,2); lcd.print(" ");}
|
||||
|
||||
lcd.setCursor(11,2);
|
||||
if (Wh < 1000 && Wh > 100) {lcd.print(" ");} else if (Wh < 100 && Wh >= 10) {lcd.print(" ");} else if (Wh < 10) {lcd.print(" ");};
|
||||
lcd.print(Wh);
|
||||
lcd.setCursor(15,3);
|
||||
|
||||
lcd.setCursor(14,3);
|
||||
if (battery_voltage > 3.4) {lcd.print(battery_voltage);} else {lcd.print("LOW ");}
|
||||
}
|
||||
|
||||
|
@ -275,13 +396,13 @@ void lcd_init() {
|
|||
lcd.print("W");
|
||||
lcd.setCursor(7,3);
|
||||
lcd.print("V");
|
||||
lcd.setCursor(17,1);
|
||||
lcd.setCursor(18,1);
|
||||
lcd.print("Ah");
|
||||
lcd.setCursor(17,2);
|
||||
lcd.setCursor(18,2);
|
||||
lcd.print("Wh");
|
||||
lcd.setCursor(14,3);
|
||||
lcd.setCursor(13,3);
|
||||
lcd.write((uint8_t)2);
|
||||
lcd.setCursor(19,3);
|
||||
lcd.setCursor(18,3);
|
||||
lcd.print("V");
|
||||
delay(300);
|
||||
}
|
||||
|
@ -420,13 +541,22 @@ void readCurrent() {
|
|||
current_A_min = 0;
|
||||
power_W_min = 0;
|
||||
}
|
||||
if (measuring_run && measuring_init == false) {
|
||||
shuntvoltage_V_max = 0;
|
||||
current_A_max = 0;
|
||||
power_W_max = 0;
|
||||
shuntvoltage_V_min = shuntvoltage_V;
|
||||
current_A_min = current_A;
|
||||
power_W_min = power_W;
|
||||
measuring_init = true;
|
||||
}
|
||||
lastread = newtime;
|
||||
ina219.recalibrate();
|
||||
ina219.reconfig();
|
||||
}
|
||||
|
||||
void read_bat() {
|
||||
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.1;
|
||||
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.3;
|
||||
battery_voltage = map(battery_average,0,4096,0,450)/100.0;
|
||||
if (battery_voltage < 3.3 && battery_low == false) {
|
||||
battery_low = true;
|
||||
|
@ -458,10 +588,10 @@ void read_button() {
|
|||
else {
|
||||
button3 = true;
|
||||
}
|
||||
if (button1) {
|
||||
if (button1 && test_mode == false) {
|
||||
reset_actual = true;
|
||||
}
|
||||
if (button2 && measuring_run) {
|
||||
if (button2 && measuring_run && test_mode == false) {
|
||||
measuring_run = false;
|
||||
} else if (button2 && measuring_run == false) {
|
||||
measuring_run = true;
|
||||
|
@ -496,17 +626,24 @@ void web_measuring_reset(AsyncWebServerRequest *request) {
|
|||
}
|
||||
|
||||
void web_get_values(AsyncWebServerRequest *request) {
|
||||
request->send( 200, "application/json", "{\"voltage\":" + String(busvoltage_V) + ", \"current\":" + String(current_A) + ", \"power\":" + String(power_W) + ", \"Ah\":" + String(Ah) + ", \"Wh\":" + String(Wh) + ", \"battery\":" + String(battery_voltage) + ", \"run\":" + String(measuring_run) + ", \"run\":" + String(shuntvoltage_V_max) + ", \"run\":" + String(shuntvoltage_V_min) + ", \"run\":" + String(current_A_max) + ", \"run\":" + String(current_A_min) + ", \"run\":" + String(power_W_max) + ", \"run\":" + String(power_W_min) + "}");
|
||||
String web_status;
|
||||
if (measuring_run) {
|
||||
web_status = "Running";
|
||||
}
|
||||
else {
|
||||
web_status = "Stopped";
|
||||
}
|
||||
request->send( 200, "application/json", "{\"voltage\":" + String(busvoltage_V) + ", \"current\":" + String(current_A) + ", \"power\":" + String(power_W) + ", \"Ah\":" + String(Ah) + ", \"Wh\":" + String(Wh) + ", \"battery\": " + String(battery_voltage) + ", \"run\":\"" + String(web_status) + "\", \"shuntvoltage_V_max\":" + String(shuntvoltage_V_max) + ", \"shuntvoltage_V_min\":" + String(shuntvoltage_V_min) + ", \"current_A_max\":" + String(current_A_max) + ", \"current_A_min\":" + String(current_A_min) + ", \"power_W_max\":" + String(power_W_max) + ", \"power_W_min\":" + String(power_W_min) + "}");
|
||||
}
|
||||
|
||||
void data_logging() {
|
||||
if (measuring_run) {
|
||||
if (measuring_run && test_mode == false) {
|
||||
File datalog = SPIFFS.open("/datalog.csv", "a");
|
||||
datalog.print(data_timestamp); datalog.print(',');
|
||||
datalog.print(busvoltage_V); datalog.print(',');
|
||||
datalog.print(current_A); datalog.print(',');
|
||||
datalog.println(power_W); datalog.print(',');
|
||||
datalog.println(Ah); datalog.print(',');
|
||||
datalog.print(power_W); datalog.print(',');
|
||||
datalog.print(Ah); datalog.print(',');
|
||||
datalog.println(Wh);
|
||||
datalog.close();
|
||||
data_timestamp++;
|
||||
|
|
Loading…
Reference in New Issue