Forum: Mikrocontroller und Digitale Elektronik 1000 Messungen, höchsten Wert Speichern und ausgeben


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Max R. (jackill)


Lesenswert?

Hallo liebe Forengemeinde,
ich möchte mich mal kurz vorstellen und danach werde ich mein Problem 
schildern welches sich mir auftut.

Ich heiße Max, bin nun 27 Jahre alt und habe mir vor einiger Zeit einen 
Arduino UNO gekauft. Nach langen hin und her habe ich mich nun doch mal 
ran getraut. Ich hatte vorher null Ahnung von Programmierung und habe es 
einfach mal als Herausforderung gesehen.

Ich komme nun zu meinem Problem. Ich möchte über den Analogen Eingang in 
60 Sekunden 1000 schwankende Spannungswerte bis max. 5V nehmen und den 
höchsten über ein LCD Display ausgeben lassen. Das Display ist 
angeschlossen und funktioniert soweit auch einwandfrei. Andere 
Programmierungen und Spielereien habe ich bisher gut meistern können und 
ich habe mir einiges angelesen und schon umsetzen können. Es macht echt 
spaß aber an dieser Sache hänge ich ein wenig. Hat jemand einen Tipp wie 
ich das verwirklichen kann?
Wie kann man einen Maximalwert speichern? Gibt es da eine Möglichkeit?

Ich grüße Euch

Max

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Max Reiche schrieb:
> Wie kann man einen Maximalwert speichern? Gibt es da eine Möglichkeit?
1
if(new_value > max_value)
2
  max_value = new_value;

von Thomas D. (thomasderbastler)


Lesenswert?

Erste Messung = U Speichern
nächste Messungen U2
ist U2 > U dann speichern..

von Enrico (Gast)


Lesenswert?

Die einfachste Möglichkeit ist, dass du deinen ersten Messwert 
speicherst und bei jedem weiteren, den du einliest, überprüfst ob der 
größer als der Alte ist und wenn ja diesen überschreibst.

max = messwert
wiederhole 1000 mal
  messwert einlesen
  wenn messwert > max dann
    max = messwert

max ausgeben

von Stefan (Gast)


Lesenswert?

Ich würde die ganzen Werte in einem Array speichern. Dann durch eine 
Schleife jagen und mit einem Sortieralgorithmus (Bubblesort oder 
Bucketsort) sortieren.

Da sind jetzt sicher einige Schlagworte gefallen die man in google 
klopfen kann :)

von npn (Gast)


Lesenswert?

Max Reiche schrieb:
> Wie kann man einen Maximalwert speichern? Gibt es da eine Möglichkeit?

Wie würdest du das mit einem Blatt Papier und einem Stift machen? 
Natürlich nicht in 5 Sekunden, ist klar. Aber mal die prinzipielle 
Vorgehensweise.
Dir sagt jemand Zahlen an. Du schreibst die erste Zahl auf. Wenn die 
nächste Zahl, die dir angesagt wird, größer ist als die bisher 
aufgeschriebene, dann schreibst du diese auf und streichst die andere 
durch. Wenn sie kleiner ist, machst du gar nichts und wartest auf die 
nächste Zahl. Und so weiter...
Und was hast du am Ende auf deinem Blatt stehen? Genau - die größte Zahl 
von allen, die genannt wurden.
Spiel dir das mal mit Stift und Papier durch, dann wird alles klar, ok? 
:-)

von Max G. (l0wside) Benutzerseite


Lesenswert?

Pseudocode:
1
maxwert := 0
2
for n := 1 to 1000
3
    neuerwert := liesADC
4
    wenn neuerwert > maxwert:
5
        maxwert := neuerwert
6
7
    warte 60ms
8
    
9
print maxwert

Das nach C zu übertragen überlasse ich dir.

Max

von Max H. (hartl192)


Lesenswert?

Stefan schrieb:
> Ich würde die ganzen Werte in einem Array speichern. Dann durch eine
> Schleife jagen und mit einem Sortieralgorithmus (Bubblesort oder
> Bucketsort) sortieren.
Ist das nicht ein bisschen aufwändig um nur den maximalen Wert zu 
finden?

von hp-freund (Gast)


Lesenswert?

Max Reiche schrieb:
> über den Analogen Eingang in
> 5 Sekunden 100 schwankende Spannungswerte

Wenn Du nicht alle Werte benötigst sondern nur den Maximalen, dann 
einfach bei jeder Messung den aktuellen Wert mit dem Vorwert vergleichen 
und den größeren als aktuellen speichern.

von schreiber (Gast)


Lesenswert?

Hallo Max,

Ich kenn' mich mit der Arduino-Sprache nicht aus, daher kann ich dir 
kein Code geben. Aber für die Erklärung braucht man kein Code. ;)

Du initialisierst eine Variable mit 0. (ich nenne sie jetzt max_var)

dann ließt du deinen Analog-Eingang aus und vergleichst ihn mit max_var.
Wenn der Wert größer ist, dann überschreibst du max_var.
Wenn nicht, dann kommt einfach die nächste Messung.

Und am Schluss gibst du max_var am Bildschirm aus.
(Ressourcen sparend zu kosten der Laufzeit)

Oder

Du initialisierst ein Array[1000] schreibst bei jeder Messung den Wert 
in ein Feld. Und am Schluss durchsuchst du das Array nach dem größten 
Wert und gibst ihn aus.
(schnelle Laufzeit, hoher Ressourcenverbrauch)

Grüße
Schreiber.

von Stefan (Gast)


Lesenswert?

Ja ok. Durchaus ein argument :D.

Bei 1000 Messwerten in 60 Sekunden geht dass sicher auch dass man den 
Messwert direkt mit dem vorherigen vergleicht.

Bei zeitkritischen Messungen würde ich persönlich zuerst die Messung 
durchführen und dann den Maximalwert ermitteln.

Aber du hast recht :)

von Max H. (hartl192)


Lesenswert?

schreiber schrieb:
> dann ließt du deinen Analog-Eingang aus und vergleichst ihn mit max_var.
> ...
> (Ressourcen sparend zu kosten der Laufzeit)
>
> Oder
>
> Du initialisierst ein Array[1000] schreibst...
> (schnelle Laufzeit, hoher Ressourcenverbrauch)
Welchen Algorithmus zum suchen des Maximums verwendest du, dass das 
Array zu durchsuchen nennenswert schneller ist als nach jeder Messung 
eine if-Abfrage und eventuell eine Zuweisung?

von schreiber (Gast)


Lesenswert?

Es geht darum dass die Messungen schneller hintereinander ausgeführt 
werden. An sich dürfte das Auswerten im Endeffekt gleich lang dauern

von ein anderer Stefan (Gast)


Lesenswert?

Der Atmega hat 2k RAM. Das ist mit 1000 AD-Werten voll. Schlechte 
Karten, um erstmal alle Werte zwischenzuspeichern.

Gruß, Stefan

von Stefan (Gast)


Lesenswert?

Ich denke es war anders gemeint (so wie ich es auch schon geschrieben 
hab). Die Laufzeit von der ersten Messung bis zur Ausgabe auf dem 
Display ist nicht schneller. ABER:

Die Messwerte können schneller hintereinander aufgenommen werden, weil 
sie zwischen den Messungen nicht verarbeitet werden.

Aber wie gesagt, spielt bei 1000 Messungen in 60 Sekunden keine Rolle.

von npn (Gast)


Lesenswert?

Max H. schrieb:
> Welchen Algorithmus zum suchen des Maximums verwendest du, dass das
> Array zu durchsuchen nennenswert schneller ist als nach jeder Messung
> eine if-Abfrage und eventuell eine Zuweisung?

Na er nimmt das erste Element des Arrays, speichert es in eine Variable, 
dann guckt er das zweite an. Und wenn das größer ist, wird die Variable 
überschrieben. Dann das dritte... :-))
duckundweg

von schreiber (Gast)


Lesenswert?

ein anderer Stefan schrieb:
> Der Atmega hat 2k RAM. Das ist mit 1000 AD-Werten voll. Schlechte
> Karten, um erstmal alle Werte zwischenzuspeichern.

Na wenn das so ist, hat sich das ja mit dem Array sowieso erledigt :P

von Stefan (Gast)


Lesenswert?

Schade drum :D

von Karl (Gast)


Lesenswert?

schreiber schrieb:
> Du initialisierst ein Array[1000] schreibst bei jeder Messung den Wert
> in ein Feld. Und am Schluss durchsuchst du das Array nach dem größten
> Wert und gibst ihn aus.
> (schnelle Laufzeit, hoher Ressourcenverbrauch)

Ein Array mit 1000 Messwerten wir schlecht in den Arbeitsspeicher des 
AVRs passen.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan schrieb:
> Ich würde die ganzen Werte in einem Array speichern. Dann durch eine
> Schleife jagen und mit einem Sortieralgorithmus (Bubblesort oder
> Bucketsort) sortieren.
Ich hoffe, das das nur ein Witz war (der Smiley deutet das an), aber ich 
glaube, genau so werden heute uC programmiert...

Max Reiche schrieb:
> Ich möchte über den Analogen Eingang in 60 Sekunden 1000 schwankende
> Spannungswerte bis max. 5V nehmen
Sollen die 60 Sekunden in gleiche Abschnitte "unterteilt" werden? Dann 
müsstest du im Raster von 60ms abtasten...

Ich würde hier den statt eines delay() den erweiterbaren Ansatz über 
Zeitstempel (hier die Variable "nexttime") wählen:
1
maxwert = 0;
2
n = 0;
3
nexttime = 0;
4
5
do {
6
   ms = millis();
7
   if (ms > nexttime) {
8
     neuerwert = liesADC();
9
     if (neuerwert > maxwert)
10
       maxwert = neuerwert;
11
     nexttime = ms+60;
12
     n++;
13
   }
14
} while (n<1000)

: Bearbeitet durch Moderator
von Max R. (jackill)


Lesenswert?

Wow, danke für die schnellen und zahlreichen Antworten. Ich werde mich 
da mal jetzt näher in diese Richtung mit beschäftigen und euch auf dem 
laufenden halten.
Das schöne ist ja dass man nach und nach immer besser durchsteigt. Ich 
danke euch.

von Peter D. (peda)


Lesenswert?

schreiber schrieb:
> Du initialisierst ein Array[1000] schreibst bei jeder Messung den Wert
> in ein Feld. Und am Schluss durchsuchst du das Array nach dem größten
> Wert und gibst ihn aus.
> (schnelle Laufzeit, hoher Ressourcenverbrauch)

Im Gegenteil, es ist erheblich langsamer.
Maxwert und ADC-Wert ab in 2 Register + Compare geht ruckzuck.
Aber erstmal alles in den SRAM schaufeln und danach dort sortieren, 
dauert deutlich länger.
Der AVR kann ja keine Operationen direkt im SRAM ausführen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.