Hallo zusammen. Ich hoffe jemand kann mir helfen.
Ich habe folgendes vor bzw gemacht.
Ich verwende ein Spannungsmess-Modul (INA219) und ein 128x64Pixel Oled (S/W) Display (SSD1309) welches via SPI angeschlossen ist.
Für das Display und die Grafik verwende ich die U8g2lib
- U8g2: Library for monochrome displays
> Die Grafik Bibliothek von Adafruit habe ich noch nicht getestet weil ich nicht wusste ob das 1309 Display damit läuft <
Ich will die Spannungswerte als fortlaufenden Graphen anzeigen lassen also nicht, dass der Graph von links nach rechts läuft und wenn er angekommen ist wird alles gelöscht sondern dass das Bild immer weiter läuft und man alle Werte nach links verschoben werden.
Das funktioniert auch alles doch das große Problem ist die Geschwindigkeit. Ich habe es mal "gemessen" und ein Durchlauf (bis das Bild aktualisiert wird) dauert ca. 630ms.
Ich habe mit 2 verschiedenen Bibliotheken (INA226.h und INA226_WE.h) mal einen Durchlauf gemessen, wenn 125 Werte eingelesen werden. Mehr war im Code nicht drin. Da dauerte ein Durchlauf 160ms bzw 159ms.
#include <Wire.h>
#include <INA226_WE.h>
#define I2C_ADDRESS 0x40
INA226_WE ina226(I2C_ADDRESS);
unsigned long lastMillis;
float shuntVoltage_mV = 0.0;
float busVoltage_V = 0.0;
void setup() {
Wire.begin();
ina226.init();
ina226.setAverage(AVERAGE_4);
ina226.setConversionTime(CONV_TIME_1100);
ina226.setMeasureMode(CONTINUOUS);
ina226.setCurrentRange(MA_400);
ina226.setCorrectionFactor(0.95);
ina226.waitUntilConversionCompleted();
lastMillis = millis();
Serial.begin(9600);
}
void loop() {
for(int g = 125; g >= 1; g--)
{
Serial.print("Bus voltage: ");
Serial.println(ina226.getBusVoltage_V(), 3);
Serial.print("Shunt voltage: ");
Serial.println(ina226.getShuntVoltage_mV()/1000, 3);
}
Serial.println(millis() - lastMillis);
lastMillis = millis();
}
Da ich für die X-Achse 125 float Werte benötige, habe ich einen Teensy LC (48 MHz) verwendet.
Ein Arduino Nano oder Micro hatte leider zu wenig Speicher für die vielen Werte.
Der Ablauf im geplanten Programm (je Durchlauf) ist wie folgt.
Variablen:
float Spannung[126];
float messwert = 0;
im loop:
Als erstes lese ich den Wert ein und dann in das Array gepackt:
messwert = loadVoltage_V;
Spannung[2] = messwert;
loadVoltage_V ist das Ergebnis aus busVoltage_V + (shuntVoltage_mV/1000) und kommt von der INA226_WE.h Bibliothek.
Dann wird neu sortiert so dass der neue Wert links ist >> Graph läuft von links nach rechts
for(int g = 124; g >= 2; g--)
{
Spannung[g+1] = Spannung[g];
//Serial.println(Spannung[g]);
}
Und dann zeichne ich den Graphen
for (int i = 125; i >= 2; i--) {
if ((20 + ((mittelwert_neu + differenz)*1500 - (Spannung[i] + differenz)*1500)) >= 63) {
y_draw = 63;
}
else {
if ((20 + ((mittelwert_neu + differenz)*1500 - (Spannung[i] + differenz)*1500)) <= 8) {
y_draw = 8;
}
else {
y_draw = (20 + ((mittelwert_neu + differenz)*1500 - (Spannung[i] + differenz)*1500));
}}
u8g2.drawPixel(i,y_draw);
}
Bezogen auf den Mittelwert: Nach einer bestimmten Zeit wird ein neuer Mittelwert berechnet um den Graphen immer auf einer Höhe zu halten wenn die Spannung mal sinkt. Das soll ggf alle 60 Sekunden mal passieren.
Die Differenz ist zum Ausgleich bezogen auf den ersten Mittelwert der beim Start gebildet wird und dem aktuellen. Damit wird auch der Graph auf der Höhe gehalten.
Die *1500 ist für eine feinere Anzeige von Abweichungen bzw. damit werden Nachkommastellen zu ganzen Zahlen und dann kann ich das besser als Pixel anzeigen lassen.
Mit dem y_draw schränke ich den Ausschlag der Höhe ein, so das immer auf der ganzen X-Achse ein Wert zu sehen ist.
Also in jedem Durchgang wird ein Wert eingelesen, alle Graph-Werte neu Sortiert und dann der ganze Graph gezeichnet also alle Werte in die Liste als Punkte eingetragen.
Das ganze läuft aber sehr langsam - 0,63s (630ms) pro Durchgang und ich weiß nicht warum das so lange dauert.
Ich hoffe jemand hat da für mich einen Tipp oder eine Idee.
Danke vorab und viele Grüße