Ich möchte gerne eine GUI für meine Wetterstation auf mit meinem NodeMCU machen. Ich habe überhaupt keine Arduino Erfahrung, aber würde es einfach gerne selbst programmieren ohne ein Hilfsprogramm. Kann mir irgendjemand vielleicht sein Beispielprogramm mit Erklärung dazu zeigen?
Bisher bin ich bei dem Schritt, dass man auf das Display drückt und sich eine neue Seite öffnet. Wie kriege ich es z.B. hin, dass bei erneutem Drücken wieder die ursprüngliche bzw. Startseite dargestellt wird?
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
Es ist ein ESP8266. Ich habe mittlerweile eine andere Möglichkeit gefunden, aber danke für die schnelle Rückmeldung!
Ich hätte aber noch eine andere Frage zu meinem Projekt😅
Wie kann ich die Messwerte aus meinem BME in einem Array speichern und diese als Diagram darstellen lassen? Es sollen die letzten 20 Werte gespeichert werden.
Sketch dazu kann ich noch nicht schicken, weil ich noch keine Idee hatte wie ich dieses Problem lösen kann.
Informiere Dich mal zum Stichwort Ringpuffer, wenn Du das fortlaufend speichern willst. Ob und wie Du Grafik sinnvoll darstellen kannst, ist von Deinem Display abhängig.
Hallo,
du willst das auf dem TFT machen.? Dann schau dir mal Beispiele dazu an. Es gibt bestimmt Methoden um ein Pixel zu setzen, oder einen linie von -bis zwischen den Messwerten zu zeichnen.
Um die Werte in ein Array zu bekommen musst Du halt einen Variable als Schreibzeiger und eine zweite als Lesezeiger führen. (Ringpuffer ) Wenn das Array dann voll ist gehts wieder vorne los.
Für eine Webseite wurde sowas hier im Forum mal als chart gemacht.
mir fehlt halt im Moment der Link dahin
Hallo,
Fang doch erst mal damit an auf deinem Display eine Grafik anzuzeigen bei der feste Werte aus einem Array mit den 20 Werten angezeigt werden. Nutze erst mal Werte die auf die x,y Koordinaten des Displays passen. Umrechnen kannst du später machen.
Beispiel Display 128x64 Pixel
dann nimmst Du erst mal die x Positionen 0,5,10,15....95 macht 20 Werte
y Werte von 0-63.
Die Punkte kannst Du auf Deinem Display als Pixel zeichnen oder Linien zwischen den einzelnen Koordinaten zeichnen. line(x, y, x-+1, y+1) etwa so. Je nach Methode der verwendeten lib.
Ja das ist alles ein bisschen fummelig. Eventuell kann die Lib das aber auch schon irgendwie. Ich kenne das nur von einem 0,96" OLED Display , da hab ich so was mal gemacht, ziemlich mühselig.
Wenn das läuft denkst Du darüber nach wie Du die Werte des Sensors in das Array rein bekommst und was passiert wenn die 20 Werte alle drin sind.
Heinz
@Rentner hat recht, das GUI auf dem TFT ist vermutlich die größere Herausforderung...
Nichtsdestotrotz habe ich mal auf die Schnelle ein Beispiel geschrieben, mit dem man das Prinzip (hoffentlich) nachvollziehen kann:
const int MaxDaten = 5; // Die Anzahl der Daten um eins höher als die gewünschte Menge setzen
// vereinfacht die Ringpufferverwaltung
int Daten[MaxDaten];
int SchreibePos = 0;
int LesePos = 0;
void LesePosWeiter(){
LesePos++;
if (LesePos >= MaxDaten) LesePos = 0;
}
void SchreibePosWeiter(){
SchreibePos++;
if (SchreibePos >= MaxDaten) SchreibePos = 0;
if (SchreibePos == LesePos) LesePosWeiter();
}
void SchreibeDatum(int Wert){
Daten[SchreibePos] = Wert;
Serial.println("Position "+String(SchreibePos)+" <- "+String(Wert));
SchreibePosWeiter();
}
int LeseDatum(){
if (LesePos != SchreibePos) {
Serial.println("Position "+String(LesePos)+" -> "+String(Daten[LesePos]));
LesePosWeiter();
} else {
Serial.println("Keine weiteren Daten vorhanden!");
}
}
void RingBufferAnwendung(){
String line = "";
char c;
do
if (Serial.available()){
c = Serial.read();
if (c != '\r') line += c;
}
while (c != '\r');
if (line.length() == 0) {
LeseDatum();
} else {
SchreibeDatum(line.toInt());
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
RingBufferAnwendung();
}
Sketch auf ein Board laden
Seriellen Monitor mit 115200 Baud starten
Bedienung:
Zahlen eingeben, mit Return-Taste abschließen -> schreibt den Wert in die nächste Position des Ringpuffers
Return-Taste alleine eingeben -> gibt nach und nach solange Daten aus dem Ringpuffer aus, bis die aktuelle Schreibposition erreicht wird
Benötigt man x Daten, dann MaxDaten = x+1 Speicherplätze reservieren. Es werden nur die letzten (MaxDaten-1) Werte ausgegeben; theoretisch könnte man noch den letzten Wert "retten", so ist es aber am Einfachsten.
Im Beispiel sind es vier gewünschte Daten, daher MaxDaten = 5.
P.S.: Gibt man eine ungültige Zeichenfolge ein (z.B. Text), wird das als 0 gewertet.
Hallo,
ich hab da auch noch einen in der Bastelkiste gefunden und etwas angepasst.
jede Sekunde wird ein Wert in den Ringpuffer geschrieben. Es wird die nächste Schreibposition zurückgegeben. Alle 5s wird der gesamte Puffer ab der letzten Schreibposition im Ring auf dem Monitor ausgegeben. Das kannst Du aber auch mit jedem anderen Ereignis machen. Ausgegeben werden dann immer die letzten 20 Werte. Bei Dir müsste das dann wie in #9 angedacht auf Dein TFT "gezeichnet" werden. Wenn Du mit der Ausgabe links beginnst hast Du die zeitlich ältesten Werte links.
Zum Testen wird eine Zählervariable verwendet. Alternativ ein simulierter zufälliger Messwert um die 500.
Wenn Du die Messwerte eines BME280 verwenden willst musst Du eventuell den Ringpuffer als float anlegen , oder mit normierten Integern für die TFT Pixel arbeiten.
Heinz
/* Beispiel Ringpuffer
Puffergrösse 20 Integer
Ausgabe des gesamten Puffers auf Monitor
lesen und schreiben mit unterschiedlichem Zyklus
*/
int puffer[20];
int messwert;
int anzahl = sizeof(puffer) / sizeof(puffer[0]);
int wzeiger;
uint32_t altzeit, altzeit2;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(anzahl);
}
void loop() {
// put your main code here, to run repeatedly:
if (millis() - altzeit > 1000) { // Puffer schreiben
altzeit = millis();
wzeiger = writepuffer(messwert);
messwert = messwert + 1;
//messwert = 500 + random(-100, 100);
}
if (millis() - altzeit2 > 5000) { // Puffer anzeigen
altzeit2 = millis();
readpuffer(wzeiger);
}
}
uint16_t writepuffer( int wert) {
static int wz;
puffer[wz] = wert;
Serial.print("schreibzeiger"); Serial.print(wz);
Serial.print(" Wert "); Serial.println(wert);
wz++;
if (wz >= anzahl) {
wz = 0;
}
return wz;
}
void readpuffer(int z) {
int rz = 0;
int wert;
while (rz < anzahl) {
z--;
if (z < 0) z = anzahl - 1;
wert = puffer[z];
rz++;
Serial.print(wert); Serial.print(";");
}
Serial.println();
}
Danke für eure schnellen Antworten!
Ich habe mir alles durchgelesen und auch selbst noch ein wenig recherchiert und bin zu einer relativ guten Lösung gekommen...
Nochmal danke, dass ihr euch so schnell die Zeit genommen habt und LG!