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
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; |
Erste Messung = U Speichern nächste Messungen U2 ist U2 > U dann speichern..
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
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 :)
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? :-)
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
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?
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.
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.
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 :)
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?
Es geht darum dass die Messungen schneller hintereinander ausgeführt werden. An sich dürfte das Auswerten im Endeffekt gleich lang dauern
Der Atmega hat 2k RAM. Das ist mit 1000 AD-Werten voll. Schlechte Karten, um erstmal alle Werte zwischenzuspeichern. Gruß, Stefan
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.
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
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
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.
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
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.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.