Werte Zwischenspeichern

Hallo Leute,

Ich bin ein ganz frischer Arduino Uno Nutzer. Zuvor habe ich meine kleinen Projekte mit Bascom realisiert möchte nun aber auf Arduino umsteigen. Ich benutzte zur Bascom weil ich zu doof für C bin. Doch Arduino konnte mir die Angst vor dem totalen Versagen ein bisschen nehmen :slight_smile:

Mein erstes kleines Projekt allerdings treibt mich jetzt schon in den Wahnsinn.

Es ist eigentlich ganz einfach.

Ich habe an ein UNO ein 20x4LCD angeschlossen über den ich Werte der Analogen Eingänge Anzeigen möchte mit einen Maxwertespeicher. Anzeigetechnisch funktioniert das alles doch der Maximalwert bringt mich zum Verzweifeln.
Mein Maximalwert ist immer der Aktuelle Wert.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x20 for a 20 chars and 4 line display

void setup()
{
Serial.begin(9600);

lcd.init();
lcd.backlight();
lcd.clear();

}

void loop()
{

int AGT1MAX;
int AGT1MAX = analogRead(A0);
if (AGT1MAX < AGT1) { AGT1MAX = AGT1;} //Mit dieser Zeile möchte ich eigentlich erreichen das wenn
//AGT1MAX größer als AGT1 ist das AGT1MAX den Wert von AGT1 übernimmt
//und abspeichert doch das tut er nicht.

Serial.println("AGT11");
Serial.println(AGT11);

//Zeile 1
lcd.setCursor(0,0);
lcd.print("AGT1=");
lcd.print(AGT1);
lcd.print("C");
lcd.print(" MAX=");
lcd.print(AGT1MAX);
lcd.print("C ");
delay(1000) ;

}

Vielleicht kann ja jemand mal drüber schauen und mir einen Tip geben woran der Fehler liegen könnte da ich im Moment auf dem Schlauch stehe.

MfG Stefan

void loop()
{

  int AGT1MAX;  
  int AGT1MAX = analogRead(A0);
  if (AGT1MAX < AGT1) { AGT1MAX = AGT1;}

Müsste das nicht so aussehen:

void loop()
{

  int AGT1MAX;  
  int AGT1 = analogRead(A0);
  if (AGT1MAX < AGT1) { AGT1MAX = AGT1;}

AGT1 wird bei dir ja nirgends deklariert?!

Serial.println("AGT11");
  Serial.println(AGT11);

Und wo kommt AGT11 vor?

loop() ist eine Funktion die ständig läuft. Variablen die lokal in Funktionen deklariert werden haben nur Gültigkeit für einen Durchlauf und werden dann wieder zurückgesetzt.

In dem Fall hast du zwei Möglichkeiten:
1.) Die Variable global zu deklarieren
2.) So lokal zu deklarieren und "static" davor zu schreiben:
http://arduino.cc/de/Reference/Static

Option 2 ist besser. Und sowohl globale als auch statische Variablen werden automatisch mit 0 initialisiert. Lokale haben einen zufälligen Wert.

Das sollte glaube ich eher so aussehen:

void loop()
{
   static int AGT1max; 
   int AGT1current = analogRead(A0);

   if (AGT1current > ATG1max) 
   { 
       AGT1max = ATG1current;
   } 
}

Hallo Stephan,
so in der Art:

int MaxWert=0
int MinWert=0
int MessWert=0

void loop

if (Messwert > MaxWert)
MaxWert = Messwert

if (Messwert < MinWert)
MinWert = Messwert

Gruß und Spaß
Andreas

Das mit dem Static hatte ich bisher noch nicht gesehen.
Globale Variablen werden dann doch VOR dem Void Setup definiert oder?

Hiermal der Aktuelle Code

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // Adresse für I"²C Display setzen und festlegen wie groß das Display ist.

void setup()
{
  Serial.begin(9600);
  
  
  lcd.init();                     
  lcd.backlight();
  lcd.clear();
  lcd.setCursor( 2,0);
  lcd.print("4-Fach AGT Modul");
  lcd.setCursor(3,1);
  lcd.print("@ Stefan Mandl");
  delay(3000);
 }


void loop()
{

    
  // Variablen für Maximalwerte festlgen
   static int AGT1max;    
   static int AGT2max;
   static int AGT3max;
   static int AGT4max;

//Analoge Eingänge einlesen und zu Ordnen
  int AGT1 = analogRead(A0);
  int AGT2 = analogRead(A1);
  int AGT3 = analogRead(A2);
  int AGT4 = analogRead(A3);
  
// Maximalwerte Speichern

  if (AGT1 > AGT1max) {AGT1max = AGT1 ; }   
  if (AGT2 > AGT2max) {AGT2max = AGT2 ; } 
  if (AGT3 > AGT3max) {AGT3max = AGT3 ; } 
  if (AGT4 > AGT4max) {AGT4max = AGT4 ; } 
  
    
  //Zeile 1
  lcd.setCursor(0,0);
  lcd.print("AGT1=");
  lcd.print(AGT1);
  lcd.print("C");
  lcd.print(" MAX=");
  lcd.print(AGT1max);
  lcd.print("C  ");
  lcd.setCursor(0,1);
  lcd.print("AGT2=");
  lcd.print (AGT2);
  lcd.print("C");
  lcd.print(" MAX=");
  lcd.print(AGT2max);
  lcd.print("C  ");
  lcd.setCursor(0,2);
  lcd.print("AGT3=");
  lcd.print(AGT3);
  lcd.print("C");
  lcd.print(" MAX=");
  lcd.print(AGT3max);
  lcd.print("C  ");
  lcd.setCursor(0,3);
  lcd.print("AGT4=");
  lcd.print(AGT4);
  lcd.print("C");
  lcd.print(" MAX=");
  lcd.print(AGT4max);
  lcd.print("C  ");
  delay(250) ;

  
  
}

Gefällt mir schon mal nicht schlecht das ganze. Ich glaube ich könnte mich an Arduino gewöhnen.
Als nächstes kommt das einlesen eines Key Pads für eine kleine Menüführung für zürcksetzen der Maximalwerte.
Frei wählbare Warntemperatur mit schalten eines Ausganges/Display blinken etc..

Danke für eure Hilfe

Ja, globale Variablen werden außerhalb von Funktionen definiert. Darauf sollte man aber verzichten wenn es nicht unbedingt nötig ist. Wenn man nicht mit Klassen arbeitet muss man sich zwar keine Gedanken um Kapselung machen, aber es ist vor allem bei längerem Programmen ratsam, Variablen dort zu deklarieren wo sie auch gebracht werden. Alleine der Übersicht wegen.

Globale Variablen sind eigentlich nur nötig für Dinge die in mehreren Funktionen sichtbar sein müssen, z.B. Pin Definitionen, allgemeine Einstellungen und Parameter, oder Variablen die von Interrupts verändert werden und außerhalb abgefragt werden. Manchmal ist auch schlicht einfacher Dinge global zu deklarieren, aber oft lässt es sich vermeiden.

Und "void" ist nur der Rückgabe Parameter der Funktion. Das heißt dass sie nichts zurück gibt. Es ist keine Name und keine Bezeichnung dafür. Man kann das auch so schreiben:
void loop(void)
Aber der Parameterliste ist es optional

Sieht doch gut aus!

Als nächstes wirst du feststellen, das am hintere Rand deines Displays immer Zeichen stehen beleiben, wenn die werte kleiner werden. Das liegt daran, dass lcd.print() eben nur genau die Ziffern schreibt, die da sind.

Nach dem Code

lcd.setCursor(0,0);
lcd.print(123);
lcd.setCursor(0,0);
lcd.print(5);

hast du "523" auf dem Display stehen.

dafür solltest du eine Funktion verwenden, die deine Werte rechtsbündig in ein Feld schreibt:

void WriteInt2LCD(double Val, byte Stellen,  byte Zeile, byte Spalte){
  /* Funktion zum schreiben eines Wertes rechtsbündig in das spezifierte Feld
   Val: der zu schreibende Wert. 
   Stellen: länge des Feldes
   Zeile, Spalte: Erstes Zeichen des zu beschreibenden Feldes
   */
  lcd.setCursor(Spalte,Zeile);
  
  if (Stellen > 4 && Val < 10000){lcd.print(" ");}  //100er Stelle Leer? führende Stelle füllen;
  if (Stellen > 3 && Val < 1000){lcd.print(" ");}  //1000er Stelle Leer? führende Stelle füllen;
  if (Stellen > 2 && Val < 100){lcd.print(" ");}  //100er Stelle Leer? führende Stelle füllen;
  if (Stellen > 1 && Val < 10) {lcd.print(" ");}  // 10er Stelle Leer? führende Stelle füllen;
  lcd.print(Val);  
} // WriteInt2LCD

Noch ein Punkt: das LCD beschreiben kostet sehr viel Zeit.
Es lohnt sich (falls du Zeitkritischen Anwendung hast) die festen Texte nur einmal zu schreiben (bzw. wenn das Menue geändert wurde), und die Werte am besten auch nur, wenn sie sich geändert haben.
Also z.B. so:

if (Anzeigewert != wert) {
  lcd.print(wert);
  Anzeigewert = wert;
}