Last active
September 12, 2025 09:54
-
-
Save bukowa/8db047fc52b5e56581b41dae7145fb02 to your computer and use it in GitHub Desktop.
INA226 Arduino Uno LCD Shield 2.4 TFT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <Wire.h> | |
#include <INA226_WE.h> // Upewnij się, że ta biblioteka jest zainstalowana | |
// --- Konfiguracja Sieci i Serwera --- | |
const char *ssid = "ESP_POMIAROWY"; | |
WiFiServer server(80); | |
// --- Konfiguracja INA226 --- | |
#define I2C_ADDRESS 0x40 | |
INA226_WE ina226 = INA226_WE(I2C_ADDRESS); | |
// --- Konfiguracja logiki pomiarowej (przeniesiona z Twojego kodu) --- | |
#define NUM_SAMPLES 150 | |
int voltage_samples_mV[NUM_SAMPLES]; | |
int current_samples_mA[NUM_SAMPLES]; | |
// Zmienne do automatycznego zakresu | |
float v_min_dynamic = 4.9, v_max_dynamic = 5.1; | |
float c_min_dynamic = 0.0, c_max_dynamic = 100.0; | |
// === Zmienne globalne do przechowywania OSTATNICH wyników === | |
// Te zmienne będą odczytywane przez serwer WWW | |
volatile float last_Vavg = 0.0; | |
volatile float last_Iavg = 0.0; | |
volatile float last_freqV = 0.0; | |
volatile float last_freqC = 0.0; | |
volatile float last_minV = 0.0; | |
volatile float last_maxV = 0.0; | |
volatile float last_minC = 0.0; | |
volatile float last_maxC = 0.0; | |
volatile float last_time_span_s = 0.0; | |
void setup() { | |
Serial.begin(115200); | |
// Inicjalizacja I2C dla ESP8266 (GPIO0 = SDA, GPIO2 = SCL) | |
// WAŻNE: Po wgraniu kodu, odłącz GPIO0 od masy! | |
Wire.begin(0, 2); | |
if(!ina226.init()){ | |
Serial.println("Nie znaleziono INA226!"); | |
while(1); | |
} | |
Serial.println("Znaleziono INA226!"); | |
// Ustawienia INA226 z Twojego kodu | |
ina226.setAverage(AVERAGE_1); | |
ina226.setConversionTime(CONV_TIME_140); | |
ina226.setResistorRange(0.1, 0.5); // Ustaw rezystor i maksymalny spodziewany prąd | |
// Konfiguracja punktu dostępowego | |
Serial.println("Konfiguracja Access Point..."); | |
WiFi.softAP(ssid); | |
IPAddress myIP = WiFi.softAPIP(); | |
Serial.print("Adres IP: "); | |
Serial.println(myIP); | |
// Uruchomienie serwera WWW | |
server.begin(); | |
Serial.println("Serwer WWW uruchomiony."); | |
} | |
void loop() { | |
// === BLOK 1: ZBIERANIE DANYCH === | |
float minV = 100.0, maxV = 0.0, sumV = 0.0; | |
float minC = 1000.0, maxC = 0.0, sumC = 0.0; | |
long startTime = micros(); | |
for(int i=0; i<NUM_SAMPLES; i++){ | |
float voltage = ina226.getBusVoltage_V(); | |
float current = ina226.getCurrent_mA(); | |
// Zapisywanie próbek nie jest konieczne, jeśli nie wysyłamy wykresu, | |
// ale zostawiam logikę na przyszłość. | |
voltage_samples_mV[i] = voltage * 1000; | |
current_samples_mA[i] = current; | |
if(voltage < minV) minV = voltage; | |
if(voltage > maxV) maxV = voltage; | |
sumV += voltage; | |
if(current < minC) minC = current; | |
if(current > maxC) maxC = current; | |
sumC += current; | |
} | |
long endTime = micros(); | |
// === BLOK 2: OBLICZENIA === | |
int v_zero_crossings = 0, c_zero_crossings = 0; | |
long v_avg_mV = sumV * 1000 / NUM_SAMPLES; | |
long c_avg_mA = sumC / NUM_SAMPLES; | |
for (int i = 1; i < NUM_SAMPLES; i++) { | |
if ((voltage_samples_mV[i-1] < v_avg_mV && voltage_samples_mV[i] >= v_avg_mV) || (voltage_samples_mV[i-1] > v_avg_mV && voltage_samples_mV[i] <= v_avg_mV)) v_zero_crossings++; | |
if ((current_samples_mA[i-1] < c_avg_mA && current_samples_mA[i] >= c_avg_mA) || (current_samples_mA[i-1] > c_avg_mA && current_samples_mA[i] <= c_avg_mA)) c_zero_crossings++; | |
} | |
float time_span_s = (endTime - startTime) / 1000000.0f; | |
// === AKTUALIZACJA ZMIENNYCH GLOBALNYCH === | |
// To jest "atomowa" operacja, która udostępnia nowe dane serwerowi | |
last_Vavg = sumV / NUM_SAMPLES; | |
last_Iavg = sumC / NUM_SAMPLES; | |
last_freqV = (v_zero_crossings / 2.0) / time_span_s; | |
last_freqC = (c_zero_crossings / 2.0) / time_span_s; | |
last_minV = minV; | |
last_maxV = maxV; | |
last_minC = minC; | |
last_maxC = maxC; | |
last_time_span_s = time_span_s; | |
// === BLOK 4: AKTUALIZACJA ZAKRESU (dla następnej pętli) === | |
v_min_dynamic = minV - (maxV - minV)*0.1; | |
v_max_dynamic = maxV + (maxV - minV)*0.1; | |
c_min_dynamic = minC - (maxC - minC)*0.1; | |
c_max_dynamic = maxC + (maxC - minC)*0.1; | |
if(v_max_dynamic <= v_min_dynamic) v_max_dynamic = v_min_dynamic + 0.1; | |
if(c_max_dynamic <= c_min_dynamic) c_max_dynamic = c_min_dynamic + 10; | |
// === BLOK 5: OBSŁUGA KLIENTA WWW === | |
// Ta część kodu nie blokuje pomiarów. Działa tylko, gdy ktoś się połączy. | |
handle_web_client(); | |
} | |
void handle_web_client() { | |
WiFiClient client = server.available(); | |
if (!client) { | |
return; | |
} | |
while(!client.available()){ | |
delay(1); | |
} | |
// Odpowiedź HTTP | |
client.println("HTTP/1.1 200 OK"); | |
client.println("Content-Type: text/html"); | |
client.println("Refresh: 2"); // Odśwież stronę co 2 sekundy | |
client.println(); | |
client.println("<!DOCTYPE HTML><html><head><title>ESP Pomiar Mocy</title>"); | |
client.println("<style>body { font-family: sans-serif; background-color: #282c34; color: #abb2bf; } table { border-collapse: collapse; width: 50%; } td, th { border: 1px solid #61afef; text-align: left; padding: 8px; } th { background-color: #3e4451; } .val { color: #98c379; }</style>"); | |
client.println("</head><body><h1>Pomiar poboru pradu przez ESP-01</h1>"); | |
client.println("<table>"); | |
client.println("<tr><th>Parametr</th><th>Wartosc</th></tr>"); | |
client.print("<tr><td>Srednie Napiecie</td><td class='val'>"); client.print(last_Vavg, 3); client.println(" V</td></tr>"); | |
client.print("<tr><td>Sredni Prad</td><td class='val'>"); client.print(last_Iavg, 2); client.println(" mA</td></tr>"); | |
client.print("<tr><td>Srednia Moc</td><td class='val'>"); client.print(last_Vavg * last_Iavg, 2); client.println(" mW</td></tr>"); | |
client.print("<tr><td>Min/Max Napiecie</td><td class='val'>"); client.print(last_minV, 3); client.print(" / "); client.print(last_maxV, 3); client.println(" V</td></tr>"); | |
client.print("<tr><td>Min/Max Prad</td><td class='val'>"); client.print(last_minC, 2); client.print(" / "); client.print(last_maxC, 2); client.println(" mA</td></tr>"); | |
client.print("<tr><td>Czestotliwosc (V/I)</td><td class='val'>"); client.print((int)last_freqV); client.print(" / "); client.print((int)last_freqC); client.println(" Hz</td></tr>"); | |
client.print("<tr><td>Czas probkowania</td><td class='val'>"); client.print(last_time_span_s * 1000, 2); client.println(" ms (dla 150 probek)</td></tr>"); | |
client.println("</table></body></html>"); | |
delay(1); | |
client.stop(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************** | |
* Finalny, działający kod do wyświetlania danych z czujnika INA226 | |
* na wyświetlaczu TFT. Działa po fizycznym rozdzieleniu połączeń I2C. | |
***************************************************************************/ | |
// Biblioteki dla czujnika INA226 | |
#include <Wire.h> | |
#include <INA226_WE.h> | |
// Biblioteki dla wyświetlacza TFT | |
#include <Adafruit_GFX.h> | |
#include <MCUFRIEND_kbv.h> | |
// --- Konfiguracja Czujnika INA226 --- | |
#define I2C_ADDRESS 0x40 | |
INA226_WE ina226 = INA226_WE(I2C_ADDRESS); | |
// Definicje pinów sterujących dla Twojego shielda | |
#define LCD_CS A3 | |
#define LCD_RS A2 | |
#define LCD_WR A1 | |
#define LCD_RD A0 | |
// TUTAJ JEST NASZA ZMIANA! Mówimy, że RESET jest teraz na pinie 10 | |
#define LCD_RESET 0 | |
// Inicjalizujemy sterownik, podając mu wszystkie piny ręcznie | |
MCUFRIEND_kbv tft(LCD_CS, LCD_RS, LCD_WR, LCD_RD, LCD_RESET); | |
// Definicje kolorów | |
#define BLACK 0x0000 | |
#define RED 0xF800 | |
#define GREEN 0x07E0 | |
#define CYAN 0x07FF | |
#define YELLOW 0xFFE0 | |
#define WHITE 0xFFFF | |
void setup() { | |
Serial.begin(9600); | |
Wire.begin(); | |
// --- Inicjalizacja czujnika INA226 --- | |
if(!ina226.init()){ | |
Serial.println("Nie udalo sie zainicjowac INA226. Sprawdz polaczenia."); | |
while(1){} | |
} | |
ina226.setMeasureMode(CONTINUOUS); | |
// --- Inicjalizacja wyświetlacza TFT --- | |
uint16_t id = 0x9341; | |
tft.begin(id); | |
tft.setRotation(1); | |
tft.fillScreen(BLACK); | |
tft.setTextSize(2); | |
// Wyświetl statyczne etykiety | |
tft.setTextColor(WHITE); | |
tft.setCursor(10, 20); | |
tft.println("Pomiar Mocy - INA226"); | |
tft.drawRect(5, 10, 310, 35, CYAN); | |
tft.setTextColor(YELLOW); | |
tft.setCursor(10, 70); | |
tft.print("Napiecie V-Bus:"); | |
tft.setCursor(10, 100); | |
tft.print("Napiecie bocznik:"); | |
tft.setCursor(10, 130); | |
tft.print("Prad:"); | |
tft.setCursor(10, 160); | |
tft.print("Moc:"); | |
} | |
void loop() { | |
// Zmienne do przechowywania odczytów | |
float shuntVoltage_mV = 0.0; | |
float busVoltage_V = 0.0; | |
float current_mA = 0.0; | |
float power_mW = 0.0; | |
// Wartość rezystora i maksymalny oczekiwany prąd | |
ina226.setResistorRange(0.1, 0.5); | |
// Odczytaj wartości z czujnika | |
shuntVoltage_mV = ina226.getShuntVoltage_mV(); | |
busVoltage_V = ina226.getBusVoltage_V(); | |
current_mA = ina226.getCurrent_mA(); | |
power_mW = ina226.getBusPower(); | |
// --- Wyświetlanie danych na ekranie TFT --- | |
tft.setTextColor(GREEN); | |
tft.setTextSize(2); | |
// 1. Napięcie magistrali | |
tft.fillRect(210, 70, 100, 20, BLACK); | |
tft.setCursor(210, 70); | |
tft.print(busVoltage_V, 3); | |
tft.print(" V"); | |
// 2. Napięcie bocznika | |
tft.fillRect(210, 100, 100, 20, BLACK); | |
tft.setCursor(210, 100); | |
tft.print(shuntVoltage_mV, 3); | |
tft.print(" mV"); | |
// 3. Prąd | |
tft.fillRect(210, 130, 100, 20, BLACK); | |
tft.setCursor(210, 130); | |
tft.print(current_mA, 3); | |
tft.print(" mA"); | |
// 4. Moc | |
tft.fillRect(210, 160, 100, 20, BLACK); | |
tft.setCursor(210, 160); | |
tft.print(power_mW, 3); | |
tft.print(" mW"); | |
// Wyświetl status przepełnienia | |
tft.fillRect(10, 210, 300, 20, BLACK); | |
tft.setCursor(10, 210); | |
if(!ina226.overflow){ | |
tft.setTextColor(GREEN); | |
tft.print("Status: OK"); | |
} else { | |
tft.setTextColor(RED); | |
tft.print("Status: PRZEPELNIENIE!"); | |
} | |
delay(1000); // Odświeżaj dane co sekundę | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************** | |
* INA-skop v3.1: Wersja zoptymalizowana pod kątem RAM | |
* Zmniejszona liczba próbek, aby zmieścić się w pamięci Arduino Uno. | |
***************************************************************************/ | |
#include <Wire.h> | |
#include <INA226_WE.h> | |
#include <Adafruit_GFX.h> | |
#include <MCUFRIEND_kbv.h> | |
// --- Konfiguracja --- | |
#define I2C_ADDRESS 0x40 | |
INA226_WE ina226 = INA226_WE(I2C_ADDRESS); | |
#define LCD_CS A3 | |
#define LCD_RS A2 | |
#define LCD_WR A1 | |
#define LCD_RD A0 | |
#define LCD_RESET 0 | |
MCUFRIEND_kbv tft(LCD_CS, LCD_RS, LCD_WR, LCD_RD, LCD_RESET); | |
// --- Definicje kolorów --- | |
#define BLACK 0x0000 | |
#define GREEN 0x07E0 | |
#define YELLOW 0xFFE0 | |
#define WHITE 0xFFFF | |
#define GREY 0x8410 | |
// --- Konfiguracja Oscyloskopu --- | |
// OPTYMALIZACJA RAM: Zmniejszamy liczbę próbek | |
#define NUM_SAMPLES 150 | |
byte samples_voltage_y[NUM_SAMPLES]; | |
byte samples_current_y[NUM_SAMPLES]; | |
#define GRID_Y_TOP 50 | |
#define GRID_Y_BOTTOM 210 | |
#define GRID_X_LEFT 40 | |
#define GRID_X_RIGHT 280 | |
// Zmienne do automatycznego zakresu | |
float v_min_dynamic = 4.9, v_max_dynamic = 5.1; | |
float c_min_dynamic = 0.0, c_max_dynamic = 100.0; | |
void draw_grid_dual_axis(float v_min, float v_max, float c_min, float c_max); | |
void setup() { | |
Wire.begin(); | |
if(!ina226.init()){ while(1); } | |
ina226.setAverage(AVERAGE_1); | |
ina226.setConversionTime(CONV_TIME_140); | |
ina226.setResistorRange(0.1, 0.5); | |
uint16_t id = 0x9341; | |
tft.begin(id); | |
tft.setRotation(1); | |
tft.fillScreen(BLACK); | |
} | |
void loop() { | |
float minV = 100.0, maxV = 0.0, sumV = 0.0; | |
float minC = 1000.0, maxC = 0.0, sumC = 0.0; | |
// 1. ZBIERANIE DANYCH | |
for(int i=0; i<NUM_SAMPLES; i++){ | |
float voltage = ina226.getBusVoltage_V(); | |
float current = ina226.getCurrent_mA(); | |
if(voltage < minV) minV = voltage; | |
if(voltage > maxV) maxV = voltage; | |
sumV += voltage; | |
if(current < minC) minC = current; | |
if(current > maxC) maxC = current; | |
sumC += current; | |
int y_v = map(voltage*1000, v_min_dynamic*1000, v_max_dynamic*1000, GRID_Y_BOTTOM, GRID_Y_TOP); | |
int y_c = map(current*1000, c_min_dynamic*1000, c_max_dynamic*1000, GRID_Y_BOTTOM, GRID_Y_TOP); | |
samples_voltage_y[i] = constrain(y_v, GRID_Y_TOP, GRID_Y_BOTTOM); | |
samples_current_y[i] = constrain(y_c, GRID_Y_TOP, GRID_Y_BOTTOM); | |
} | |
// 2. AKTUALIZACJA ZAKRESU | |
v_min_dynamic = minV - (maxV - minV)*0.1; | |
v_max_dynamic = maxV + (maxV - minV)*0.1; | |
c_min_dynamic = minC - (maxC - minC)*0.1; | |
c_max_dynamic = maxC + (maxC - minC)*0.1; | |
if(v_max_dynamic <= v_min_dynamic) v_max_dynamic = v_min_dynamic + 0.1; | |
if(c_max_dynamic <= c_min_dynamic) c_max_dynamic = c_min_dynamic + 10; | |
// 3. RYSOWANIE | |
tft.fillScreen(BLACK); | |
draw_grid_dual_axis(v_min_dynamic, v_max_dynamic, c_min_dynamic, c_max_dynamic); | |
for(int i=1; i<NUM_SAMPLES; i++){ | |
int x1 = map(i-1, 0, NUM_SAMPLES, GRID_X_LEFT, GRID_X_RIGHT); | |
int x2 = map(i, 0, NUM_SAMPLES, GRID_X_LEFT, GRID_X_RIGHT); | |
tft.drawLine(x1, samples_voltage_y[i-1], x2, samples_voltage_y[i], GREEN); | |
tft.drawLine(x1, samples_current_y[i-1], x2, samples_current_y[i], YELLOW); | |
} | |
// 4. WYŚWIETL STATYSTYKI | |
float Vavg = sumV / NUM_SAMPLES; | |
float Iavg = sumC / NUM_SAMPLES; | |
tft.setTextSize(2); | |
tft.setCursor(10, 10); | |
tft.setTextColor(GREEN); | |
tft.print("V: "); | |
tft.print(Vavg, 2); | |
tft.setCursor(160, 10); | |
tft.setTextColor(YELLOW); | |
tft.print("I: "); | |
tft.print(Iavg, 1); | |
tft.print("mA"); | |
} | |
void draw_grid_dual_axis(float v_min, float v_max, float c_min, float c_max){ | |
tft.drawRect(GRID_X_LEFT, GRID_Y_TOP, GRID_X_RIGHT - GRID_X_LEFT, GRID_Y_BOTTOM - GRID_Y_TOP, GREY); | |
tft.setTextSize(1); | |
tft.setTextColor(GREEN); | |
tft.setCursor(2, GRID_Y_TOP + 5); | |
tft.print(v_max, 2); | |
tft.print("V"); | |
tft.setCursor(2, GRID_Y_BOTTOM - 10); | |
tft.print(v_min, 2); | |
tft.print("V"); | |
tft.setTextColor(YELLOW); | |
tft.setCursor(GRID_X_RIGHT + 5, GRID_Y_TOP + 5); | |
tft.print(c_max, 0); | |
tft.print("mA"); | |
tft.setCursor(GRID_X_RIGHT + 5, GRID_Y_BOTTOM - 10); | |
tft.print(c_min, 0); | |
tft.print("mA"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************** | |
* INA-skop v4.3: Wersja OSTATECZNA. | |
* NAPRAWIONO błąd z obcinaniem precyzji w funkcji map() dla prądu. | |
* Przywrócono oryginalną, działającą logikę skalowania. | |
***************************************************************************/ | |
#include <Wire.h> | |
#include <INA226_WE.h> | |
#include <Adafruit_GFX.h> | |
#include <MCUFRIEND_kbv.h> | |
// --- Konfiguracja --- | |
#define I2C_ADDRESS 0x40 | |
INA226_WE ina226 = INA226_WE(I2C_ADDRESS); | |
#define LCD_CS A3 | |
#define LCD_RS A2 | |
#define LCD_WR A1 | |
#define LCD_RD A0 | |
#define LCD_RESET 0 | |
MCUFRIEND_kbv tft(LCD_CS, LCD_RS, LCD_WR, LCD_RD, LCD_RESET); | |
// --- Definicje kolorów --- | |
#define BLACK 0x0000 | |
#define GREEN 0x07E0 | |
#define YELLOW 0xFFE0 | |
#define WHITE 0xFFFF | |
#define GREY 0x8410 | |
#define ORANGE 0xFD20 | |
// --- Konfiguracja Oscyloskopu --- | |
#define NUM_SAMPLES 150 | |
byte samples_voltage_y[NUM_SAMPLES]; | |
byte samples_current_y[NUM_SAMPLES]; | |
int voltage_samples_mV[NUM_SAMPLES]; | |
int current_samples_mA[NUM_SAMPLES]; | |
#define GRID_Y_TOP 60 | |
#define GRID_Y_BOTTOM 210 | |
#define GRID_X_LEFT 40 | |
#define GRID_X_RIGHT 280 | |
// Zmienne do automatycznego zakresu (serce oryginalnej logiki) | |
float v_min_dynamic = 4.9, v_max_dynamic = 5.1; | |
float c_min_dynamic = 0.0, c_max_dynamic = 100.0; | |
void draw_grid_dual_axis(float v_min, float v_max, float c_min, float c_max); | |
void setup() { | |
Wire.begin(); | |
if(!ina226.init()){ while(1); } | |
ina226.setAverage(AVERAGE_1); | |
ina226.setConversionTime(CONV_TIME_140); | |
ina226.setResistorRange(0.1, 0.5); | |
uint16_t id = 0x9341; | |
tft.begin(id); | |
tft.setRotation(1); | |
tft.fillScreen(BLACK); | |
} | |
void loop() { | |
// === BLOK 1: ZBIERANIE DANYCH (pozostaje bez zmian) === | |
float minV = 100.0, maxV = 0.0, sumV = 0.0; | |
float minC = 1000.0, maxC = 0.0, sumC = 0.0; | |
long startTime = micros(); | |
for(int i=0; i<NUM_SAMPLES; i++){ | |
float voltage = ina226.getBusVoltage_V(); | |
float current = ina226.getCurrent_mA(); | |
voltage_samples_mV[i] = voltage * 1000; | |
current_samples_mA[i] = current; | |
if(voltage < minV) minV = voltage; | |
if(voltage > maxV) maxV = voltage; | |
sumV += voltage; | |
if(current < minC) minC = current; | |
if(current > maxC) maxC = current; | |
sumC += current; | |
int y_v = map(voltage*1000, v_min_dynamic*1000, v_max_dynamic*1000, GRID_Y_BOTTOM, GRID_Y_TOP); | |
int y_c = map(current*100, c_min_dynamic*100, c_max_dynamic*100, GRID_Y_BOTTOM, GRID_Y_TOP); | |
samples_voltage_y[i] = constrain(y_v, GRID_Y_TOP, GRID_Y_BOTTOM); | |
samples_current_y[i] = constrain(y_c, GRID_Y_TOP, GRID_Y_BOTTOM); | |
} | |
long endTime = micros(); | |
// === BLOK 2: OBLICZENIA (pozostaje bez zmian) === | |
int v_zero_crossings = 0, c_zero_crossings = 0; | |
long v_avg_mV = sumV * 1000 / NUM_SAMPLES; | |
long c_avg_mA = sumC / NUM_SAMPLES; | |
for (int i = 1; i < NUM_SAMPLES; i++) { | |
if ((voltage_samples_mV[i-1] < v_avg_mV && voltage_samples_mV[i] >= v_avg_mV) || (voltage_samples_mV[i-1] > v_avg_mV && voltage_samples_mV[i] <= v_avg_mV)) v_zero_crossings++; | |
if ((current_samples_mA[i-1] < c_avg_mA && current_samples_mA[i] >= c_avg_mA) || (current_samples_mA[i-1] > c_avg_mA && current_samples_mA[i] <= c_avg_mA)) c_zero_crossings++; | |
} | |
float time_span_s = (endTime - startTime) / 1000000.0f; | |
float freqV = (v_zero_crossings / 2.0) / time_span_s; | |
float freqC = (c_zero_crossings / 2.0) / time_span_s; | |
float Vavg = sumV / NUM_SAMPLES; | |
float Iavg = sumC / NUM_SAMPLES; | |
// === BLOK 3: RYSOWANIE I WYŚWIETLANIE (NOWA KOLEJNOŚĆ) === | |
// 3a. Najpierw przygotuj tło i siatkę | |
tft.fillScreen(BLACK); | |
draw_grid_dual_axis(v_min_dynamic, v_max_dynamic, c_min_dynamic, c_max_dynamic); | |
// 3b. Wyświetl statystyki (SZYBKIE) - PRZENIESIONE NA POCZĄTEK | |
tft.setTextSize(2); | |
tft.setCursor(10, 10); tft.setTextColor(GREEN); tft.print("V: "); tft.print(Vavg, 2); | |
tft.setCursor(160, 10); tft.setTextColor(YELLOW); tft.print("I: "); tft.print(Iavg, 1); tft.print("mA"); | |
tft.setCursor(10, 35); tft.setTextColor(ORANGE); tft.print("F(v):"); tft.print((int)freqV); | |
tft.setCursor(160, 35); tft.print("F(i):"); tft.print((int)freqC); | |
// 3c. Dopiero teraz narysuj wykres (CZASOCHŁONNE) | |
for(int i=1; i<NUM_SAMPLES; i++){ | |
int x1 = map(i-1, 0, NUM_SAMPLES, GRID_X_LEFT, GRID_X_RIGHT); | |
int x2 = map(i, 0, NUM_SAMPLES, GRID_X_LEFT, GRID_X_RIGHT); | |
tft.drawLine(x1, samples_voltage_y[i-1], x2, samples_voltage_y[i], GREEN); | |
tft.drawLine(x1, samples_current_y[i-1], x2, samples_current_y[i], YELLOW); | |
} | |
// === BLOK 4: AKTUALIZACJA ZAKRESU (pozostaje bez zmian) === | |
v_min_dynamic = minV - (maxV - minV)*0.1; | |
v_max_dynamic = maxV + (maxV - minV)*0.1; | |
c_min_dynamic = minC - (maxC - minC)*0.1; | |
c_max_dynamic = maxC + (maxC - minC)*0.1; | |
if(v_max_dynamic <= v_min_dynamic) v_max_dynamic = v_min_dynamic + 0.1; | |
if(c_max_dynamic <= c_min_dynamic) c_max_dynamic = c_min_dynamic + 10; | |
} | |
void draw_grid_dual_axis(float v_min, float v_max, float c_min, float c_max){ | |
tft.drawRect(GRID_X_LEFT, GRID_Y_TOP, GRID_X_RIGHT - GRID_X_LEFT, GRID_Y_BOTTOM - GRID_Y_TOP, GREY); | |
tft.setTextSize(1); | |
tft.setTextColor(GREEN); | |
tft.setCursor(2, GRID_Y_TOP + 5); tft.print(v_max, 2); tft.print("V"); | |
tft.setCursor(2, GRID_Y_BOTTOM - 10); tft.print(v_min, 2); tft.print("V"); | |
tft.setTextColor(YELLOW); | |
tft.setCursor(GRID_X_RIGHT + 5, GRID_Y_TOP + 5); tft.print(c_max, 0); tft.print("mA"); | |
tft.setCursor(GRID_X_RIGHT + 5, GRID_Y_BOTTOM - 10); tft.print(c_min, 0); tft.print("mA"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment