Files
PI_mikrokontroler_2/include/Measure.h
2026-05-10 20:46:23 +02:00

124 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef MEASURE_H
#define MEASURE_H
#include <Arduino.h>
#include <Watchdog.h>
#include <SPI.h>
#include <SD.h>
#include <FS.h>
#include <RTClib.h>
#include <Display.h>
#include "ADXL345FastSPI.h" // <-- zgodnie z main.cpp
#include <Logger.h>
#include <Pinout.h>
// Domyślne parametry akwizycji ADXL345 (mogą być nadpisane w ADXL345FastSPI::begin)
static constexpr uint32_t SPI_HZ = 5000000; // 5 MHz (MODE3)
static constexpr float ODR_HZ = 3200.0f; // maks. ODR
// Zakres ustawiany w main.cpp przez ADXL345FastSPI::begin(..., RANGE_2G, ...)
struct FileInfo {
String path; // np. "/3/00000057.wmt"
uint64_t size; // bajty
bool exists; // true, jeśli ostatni plik istnieje
};
struct SpaceInfo {
double value;
const char *unit; // "GB" | "MB" | "UNKNOWN"
};
class DataCapture {
// --- Nagłówek pliku WMT ---
struct FileHeader {
char magic[3]; // "WMT"
uint16_t version; // 1
uint16_t headerSize; // sizeof(FileHeader)
uint32_t sampleSize; // sizeof(Sample)
uint32_t timestamp; // UNIX startu akwizycji
uint32_t reccount; // liczba rekordów Sample w pliku
} __attribute__((packed));
public:
// --- Rekord próbki ---
struct Sample {
uint32_t offset; // µs od startu akwizycji (wspólny dla ramki)
uint8_t sensor_id; // 0..3
int16_t x, y, z; // surowe ADXL345
bool ready; // 1 = obecna
} __attribute__((packed));
// Konstruktor dopasowany do main.cpp przyjmuje ADXL345FastSPI
DataCapture(ADXL345FastSPI &adxl, Display &display, RTC_DS3231 &rtc, fs::FS &storage, size_t bufferSize = 131072 /* 128 KB */);
~DataCapture();
bool capture(uint32_t captureSeconds, const char *filename);
bool captureAuto(uint32_t captureSeconds, const char *baseDirectory = "/logs");
void printSamplingRate(uint32_t reccount, uint32_t captureSeconds, String filename);
void readHeaderAndPrint(const char *path);
void stop();
bool isActive() const { return measurementActive_; }
// SD utils
SpaceInfo freeSpaceMB();
float freeSpaceFloat(bool *isGB = nullptr);
String unixToDateTime(uint32_t ts);
// plik z najwyższym indeksem
FileInfo getLastFileInfo();
bool deleteAllOnSD();
bool isExit = false; // true oznacza przerwanie pomiaru
private:
ADXL345FastSPI &adxl_;
Display &display_;
RTC_DS3231 &rtc_;
fs::FS &_fs;
// Katalogowanie
const String _baseDir = "/";
const String _ext = ".wmt";
const uint8_t _digits = 8;
const uint16_t _maxFilesPerDir = 400;
// Bufor zapisu (PSRAM)
uint8_t *buffer_ = nullptr;
size_t bufferSize_ = 0;
size_t bufferIndex_ = 0;
bool measurementActive_ = false;
bool flushToFile(File &f);
static uint8_t crc8(const uint8_t *data, size_t len);
void setTestingIndicator_(bool on, String myDir, String myFile);
bool isEscape(){
bool ispress = (GPIO.in & (1UL << BTN_OK)) == 0;
if(ispress) {
isExit = true;
measurementActive_;
display_.textStatus("Cancelling. Wait!");
}
return ispress;
} // szybkidigitalRead : czy BTN stop???
public:
bool isAllDigits(const char *s);
uint32_t toUint(const char *s);
static const char *basenameFromPath(const char* full);
bool isWmtWithDigits(const char *name, uint32_t &idxOut) const;
String makeIndexedName(uint32_t idx) const;
static String joinPath(const String &a, const String &b);
bool ensureDir(uint32_t dirNum);
uint32_t findHighestNumericDir();
void scanDirForWmt(uint32_t dirNum, uint32_t &count, uint32_t &highestIdx);
bool recursiveDelete(const String &path);
String dirPath(uint32_t dirNum) const;
String allocateNextFilePath();
String generateNextFilename();
void printLastFileInfoSerial();
};
#endif // MEASURE_H