Dodanie folderów include i src

This commit is contained in:
2026-03-23 12:09:05 +01:00
commit 0985792a06
27 changed files with 3357 additions and 0 deletions

433
src/main.cpp Normal file
View File

@@ -0,0 +1,433 @@
#include <Logger.h>
#include "Watchdog.h"
#include <Arduino.h>
#include <Config.h>
#include <Pinout.h>
#include <Version.h>
#include <Display.h>
#include <SPI.h>
#include <SD.h>
#include "ADXL345FastSPI.h"
#include "RTClib.h"
#include <Wire.h>
#include <Network.h>
#include <Thread.h>
#include <Measure.h>
#include <Tool.h>
#include <Settings.h>
#include <Uploader.h> // Dodano moduł wysyłki
#define WDT_TIMEOUT 60 // Czas watchdoga do restartu
#define MAX_ADXL345_SENSORS 4 // Maksymalna ilość podłączanych sensorów
SPIClass SPI_ADXL(FSPI); // SPI2 (VSPI)
SPIClass SPI_SD(HSPI); // SPI3 (HSPI)
float x, y, z = 0; // Dane odczytane z akcelerometru
String name;
bool isRebootRequired = false;
bool isAccelExists = false; // Czy istnieje jakiś podłączony do SPI czujnik
bool testingNow = false; // Czy trwa test (gdy tak, trzeba wszystko inne wyłączyć)
bool runMeasure = false; // czy włączyć pomiar?
// Buttony: 5, 6, 7
// piny SPI CS dla ASXL345
const uint8_t csPins[MAX_ADXL345_SENSORS] = {9, 10, 14, 21};
long licznik = 0;
ConfigManager configManager;
RTC_DS3231 rtc;
ADXL345FastSPI adxl(csPins, MAX_ADXL345_SENSORS);
Display display(rtc, 0x27, 20, 4);
Settings settings(display, rtc); // obsługa przycisków
WiFiManager wifi;
DataCapture capture(adxl, display, rtc, SD, 8192); // NEW !!! MEASURE!!!
// Inicjalizacja Uploadera
Uploader uploader(display);
Thread wifiTestThread = Thread(); // Cykliczny test WiFi
Thread offlineThread = Thread(); // Jeśli offline
Thread measureThread = Thread(); // Pomiar i zapis na SD
Thread uploadThread = Thread(); // Wątek wysyłki SSL
//////// PROTOTYPY /////////////////
void setup();
void loop();
void reboot();
void resetBtnClick();
void checkWiFi();
void showOfflineScreen();
void measure();
void runUploader();
void toogleMode();
void settingsDevice();
void showError(String err);
/* ******************* SETUP() ************************* */
void setup() {
Serial.begin(115200);
delay(500);
// przy USB-CDC warto poczekać chwilę na enumerację (z timeoutem):
unsigned long t0 = millis();
while (!Serial && millis()-t0 < 2000) { delay(10); }
settings.begin();
esp_log_level_set("*", ESP_LOG_INFO); // _ERROR, _WARN, _INFO, _DEBUG, _VERBOSE
delay(500); // było 1000
ESP_LOGI(TAG_MAIN, "----------------------");
ESP_LOGI(TAG_MAIN, "WMT Stalowa Wola A.Chmielowiec & L.Klich");
ESP_LOGI(TAG_MAIN, "Rejestrator parametrow");
ESP_LOGI(TAG_MAIN, "Firmware: %s", VERSION);
ESP_LOGI(TAG_MAIN, "----------------------");
ESP_LOGI(TAG_MAIN, "ESP32 model: %s Rev %d", ESP.getChipModel(), ESP.getChipRevision());
ESP_LOGI(TAG_MAIN, "Chip cores: %d", ESP.getChipCores());
// Inicjalizacja Watchdoga na 5 sek, panic_on_trigger = true
if (Watchdog::init(25, true)) {
ESP_LOGI(TAG_MAIN, "Watchdog init ok.");
} else {
ESP_LOGE(TAG_MAIN, "Watchdog init error.");
}
Wire.begin(PIN_SDA, PIN_SCL, 100000);
scanI2C(); // Skanowanie magistrali I2C na UART (RTC-0x68, LCD-0x27)
configManager.begin(); // konfiguracja EEPROM urządzenia
// Test LCD I2C
if (!isI2CDevPresent(0x27)) {
ESP_LOGE(TAG_MAIN, "LCD 0x27 wire error!");
}
ESP_LOGI(TAG_MAIN, "Display init");
if (!display.begin()) {
ESP_LOGE(TAG_MAIN, "Display init failed");
while (true) delay(1000);
}
ESP_LOGI(TAG_MAIN, "Display OK");
display.welcomeScreen();
delay(1000);
// Przycisk reset w przypadku factory reset
if(settings.isBtnReset()) resetBtnClick();
// MCU Info
ESP_LOGI(TAG_MAIN, "MCU info");
display.textStatus(ESP.getChipModel());
delay(500);
char buf[20];
sprintf(buf, "Freq: %d MHz", ESP.getCpuFreqMHz());
display.textStatus(buf);
delay(500);
// Test PSRAM
display.textStatus("PSRAM:");
ESP_LOGI(TAG_MAIN, "PSRAM init");
if (!psramFound()) {
ESP_LOGE(TAG_MAIN, "PSRAM not found");
display.print("FAILED");
while (true) delay(1000);
}
display.print("OK");
delay(500);
// Test RTC
ESP_LOGI(TAG_MAIN, "RTC test");
if (!isI2CDevPresent(0x68)) {
ESP_LOGE(TAG_MAIN, "RTC 0x68 wire error!");
display.textStatus("RTC wire error!");
while (true) delay(1000);
}
display.textStatus("RTC:");
ESP_LOGI(TAG_MAIN, "RTC init");
if (!rtc.begin()) {
display.print("FAILED");
ESP_LOGE(TAG_MAIN, "Can't find RTC");
while (true) delay(1000);
} else {
display.print("OK");
ESP_LOGI(TAG_MAIN, "RTC OK");
if (rtc.lostPower()) {
ESP_LOGE(TAG_MAIN, "RTC power lost! Set clock");
display.textStatus("RTC: SET TIME");
delay(1000);
settings.setTimeRTC();
}
}
delay(500);
// Karta SD
ESP_LOGI(TAG_MAIN, "SD Card init");
ESP_LOGI(TAG_MAIN, "SPI2 SD SCK: %d, MISO: %d, MOSI: %d, CS: %d", SD_SCK, SD_MISO, SD_MOSI, SD_CS);
SPI_SD.begin(SD_SCK, SD_MISO, SD_MOSI);
display.textStatus("SD CARD:");
while(!SD.begin(SD_CS, SPI_SD, 4000000)) {
ESP_LOGE(TAG_MAIN, "SD mount failed");
display.print("FAILED");
delay(4000);
display.textStatus("SD CARD:");
delay(500);
}
ESP_LOGI(TAG_MAIN, "SD Card OK");
display.print("OK");
ESP_LOGI(TAG_MAIN, "ADXL345 SPI3 SCK: %d, MISO: %d, MOSI: %d", CLK_ADSX, MISO_ADSX, MOSI_ADSX);
SPI_ADXL.begin(CLK_ADSX, MISO_ADSX, MOSI_ADSX);
// Inicjalizacja ADXL345
ESP_LOGI(TAG_MAIN, "ADXL345 init");
display.textStatus("ADXL345: ");
if(!adxl.begin(&SPI_ADXL, 5000000, ADXL345FastSPI::RATE_3200HZ, ADXL345FastSPI::RANGE_16G, 1)){
ESP_LOGE(TAG_MAIN, "ADXL345 Error");
display.print("FAILED");
isAccelExists = false;
uint8_t counter = 0;
while(counter<5){ counter++; delay(1000); }
display.clear();
display.textCenter(0, "PLEASE CONNECT");
display.textCenter(1, "SENSOR MODULE");
display.textCenter(2, "ANY KEY RESTART");
display.textCenter(3, "GURU MEDITATION");
while(true){
if(digitalRead(BTN_UP) == LOW) reboot();
if(digitalRead(BTN_OK) == LOW) reboot();
if(digitalRead(BTN_DOWN) == LOW) reboot();
}
} else {
display.print(String(adxl.size()));
ESP_LOGI(TAG_MAIN, "ADXL345 OK: %d COUNT", adxl.size()); // liczba wykrytych
isAccelExists = true;
}
DateTime now = rtc.now();
ESP_LOGI(TAG_MAIN, "RTC TIME: %d:%d:%d %d:%d:%d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second());
delay(1000);
if(config.connect){
display.textStatus("WiFi Connect...");
wifi.begin();
int retry_count = 0;
while (WiFi.status() != WL_CONNECTED && retry_count < 60) {
delay(500);
retry_count++;
Watchdog::feed();
if(retry_count % 10 == 0) display.print(".");
}
if (WiFi.status() != WL_CONNECTED) {
ESP_LOGW(TAG_MAIN, "WiFi Failed. Starting Configuration Portal...");
wifi.startConfigPortal(display);
} else {
ESP_LOGI(TAG_MAIN, "WiFi OK");
wifiTestThread.onRun(checkWiFi);
wifiTestThread.setInterval(5000);
uploadThread.onRun(runUploader);
uploadThread.setInterval(30000);
}
} else {
offlineThread.onRun(showOfflineScreen);
offlineThread.setInterval(1000);
}
measureThread.onRun(measure);
measureThread.setInterval(config.pause);
if (Watchdog::addThisTask()) {
ESP_LOGI(TAG_MAIN, "Added main task to Watchdog");
}
ESP_LOGI(TAG_MAIN, "System ready");
display.clear();
}
void runUploader() {
if (!testingNow) {
uploader.processQueue(3);
}
}
void resetBtnClick(){
uint8_t counter = 10;
ESP_LOGI(TAG_MAIN, "RESET BTN to 10 sec.");
while(settings.isBtnReset()){
Serial.print(counter); Serial.print(",");
counter--;
delay(1000);
display.clear();
display.textCenter(0,"WARNING!!!");
display.textCenter(1, "Factory reset");
display.textCenter(2, "keep holding for");
display.textStatus(String(counter).c_str());
if (counter <= 1) {
display.clear();
display.textCenter(0, "RESET CONFIG");
display.textCenter(1, "release key");
ESP_LOGI(TAG_MAIN, "RESET CONFIG");
while(settings.isBtnReset()){;}
configManager.resetToDefaults();
display.textStatus("RESTARTING!");
delay(500);
isRebootRequired = true;
} else {
isRebootRequired = true;
}
}
}
void showError(String err){
Watchdog::feed();
display.clear();
display.println(err);
ESP_LOGE(TAG_MAIN, "%s", err.c_str());
delay(3000);
}
void checkWiFi(){
Watchdog::feed();
bool isConnected = WiFi.isConnected();
String ip = WiFi.localIP().toString();
wifi.checkWiFiConnection();
display.updateBarWiFi(WiFi.RSSI(), isConnected);
display.updateNetwork(ip, isConnected);
}
void showOfflineScreen(){
if((!config.connect) && (!testingNow)) {
bool isGB;
Watchdog::feed();
float freeSpace = capture.freeSpaceFloat(&isGB);
display.displayOffline(testingNow, adxl.connectedSensorsCount(), capture.freeSpaceFloat(), licznik, false);
}
}
void reboot() {
display.clear();
display.textCenter(1, "SYSTEM");
display.textCenter(2, "RESTARTING");
#if defined(ARDUINO_RASPBERRY_PI_PICO)
watchdog_enable(1, 1);
while (true);
#endif
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
ESP_LOGI(TAG_MAIN, "RESTART");
ESP.restart();
#endif
#if defined(ARDUINO_ARCH_STM32)
NVIC_SystemReset();
#endif
}
void measure(){
Watchdog::feed();
testingNow = true;
offlineThread.enabled = false;
DateTime now = rtc.now();
ESP_LOGI(TAG_MAIN, "RTC TIME: %d:%d:%d %d:%d:%d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second());
char bdate[15]; char btime[15];
snprintf(bdate, sizeof(bdate), "%04d-%02d-%02d", now.year(), now.month(), now.day());
snprintf(btime, sizeof(btime), "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
display.initMeasure(config.measure, testingNow, runMeasure, config.pause, config.duration, config.connect, licznik, bdate, btime);
ESP_LOGI(TAG_MAIN, "MEASURE RUNNING");
capture.captureAuto(config.duration, "/");
testingNow = false;
Watchdog::feed();
if(!capture.isExit){
capture.printLastFileInfoSerial();
capture.readHeaderAndPrint(capture.generateNextFilename().c_str());
ESP_LOGI(TAG_MAIN, "MEASURE FINISH");
} else {
ESP_LOGI(TAG_MAIN, "MEASURE INTERRUPT");
}
runMeasure = false;
ESP_LOGI(TAG_MAIN, "DISPLAY Offline");
display.displayOffline(testingNow, adxl.connectedSensorsCount(), capture.freeSpaceFloat(), licznik, true);
offlineThread.enabled = true;
}
void toogleMode(){
config.measure = !config.measure;
configManager.saveConfig();
display.textStatus("Mode changed");
delay(500);
display.textStatus("");
}
void settingsDevice(){
settings.setConfigDevice();
configManager.saveConfig();
settings.finishConfigDevice();
}
///////////// LOOP ////////////////////////////////////////////
void loop() {
if (settings.isPressed(2)){
Watchdog::feed();
if(runMeasure) {
capture.isExit = true;
runMeasure = false;
display.textStatus("Stopped");
delay(3000);
} else runMeasure = true;
if(runMeasure) ESP_LOGI(TAG_MAIN, "BTN MEASURE: START"); else ESP_LOGI(TAG_MAIN, "BTN MEASURE: STOP");
Watchdog::feed();
delay(300);
if (runMeasure) measureThread.run();
}
if(settings.isPressed(3)) settingsDevice(); // DOWN
if(settings.isPressed(1)) toogleMode(); // UP
if(testingNow) {
if((runMeasure) && (settings.isPressed(2))){
runMeasure = false;
display.textStatus("STOPPING. WAIT");
}
return;
}
if(wifiTestThread.shouldRun() && (config.connect))
wifiTestThread.run();
if(uploadThread.shouldRun() && (config.connect))
uploadThread.run();
if(offlineThread.shouldRun() && (!config.connect)){
offlineThread.run();
}
if(!isAccelExists) {
ESP_LOGE(TAG_MAIN, "ADXL module error:halt");
display.clear();
delay(500);
display.textCenter(0, "SENSORS");
display.textCenter(1, "NOT EXISTS");
display.textCenter(2, "SYSTEM STOPPED");
Watchdog::feed();
delay(2000);
} else {
if(measureThread.shouldRun() && (config.measure) && (!runMeasure)){
Watchdog::feed();
ESP_LOGI(TAG_MAIN, "Measure thread run");
measureThread.run();
}
}
if (isRebootRequired) {
ESP_LOGI(TAG_MAIN, "Reboot required");
Watchdog::feed();
delay(1000);
reboot();
}
Watchdog::feed();
delay(20);
licznik ++;
}