Hallo ich habe ein kleines Problem mit einer Temperatursteuerung. Die Schaltung besteht aus vier Thermoelementen die an der oberen Temperaturgrenze 12mV abgeben. Diese werden dann jeweils mit einem Operationsverstärker auf 3.2V verstärkt und auf einen ADC-Eingang eines Atmega8 gelegt. Für den AVR habe ich ein Assembler Programm geschrieben das diese vier "Temperaturwerte" überwachen und die entsprechenden Heizelemente schalten soll.(natürlich mit Hysterese) Allerdings schwankt die Spannung an den ADC Eingängen wohl ziemlich sodass der Wert ständig an die obere und untere Grenze der Hysterese kommt. Hab es schon mit 100nF Kondensatoren am OP Eingang versucht aber das bringt nicht viel. Jetzt will ich versuchen den Mittelwert aus mehreren Messungen zu bilden. Leider hab ich noch sehr wenig Erfahrung mit dem Programmieren von AVR. Gibt es vielleicht schon eine Assembler-Routine dafür oder kann mir jemand helfen eine zu schreiben? Bin für jede Hilfe Dankbar! Gruß, falken
Von wo hast du den Rest des Programmes her, dass du es nicht fertig bringst ein paar Werte zu addieren (am besten 2^n) und dann durch die Anzahl summierter Messungen zu teilen (bzw. nach rechts zu shiften mit lsr)? In dieser Frage steckt auch schon ein Tipp...
Das ist teilweise selbst geschrieben. Da wo es um den ADC ging hab ich manche Programmbeispiele aus dem myAVR Einsteigerset übernommen. Hab allerdings noch nix mathematisches gemacht. Wie oft müsste man denn nach rechts schieben um zum Beispiel durch 16 zu teilen?
Gegenfrage: Wie oft muss man im Dezimalsystem nach rechts schieben um durch 100 zu teilen?
Hi Ungefähr 3,25 mal !! Was naturlich nicht so einfach geht. In Assembler benutzt man vorzugsweise 2er-Potenzen, also 2,4,8,16...1024... . Einmal Rechtschieben entspricht einer Division durch 2. Vor dem Schieben sollte man den Wert 'aufrunden', in dem man z.B. vor einer Division durch Acht 4 addiert. MfG Spess
Schon mal danke für den Tip! Aber auch wenn sichs jetzt blöd anhört versteh ich nicht ganz was das addieren mit dem aufrunden zu tun hat. Gruß, falken
Hi Beispiel: Dein Wert ist 7. Wenn du 3mal nach rechts schiebst (Division durch 8) kommt 0 raus. Wenn du vorher 4 addierst kommt 1 raus. Das entspricht 7/8 mehr als 0. MfG Spess
machs am besten so: du benuzt 2 register Du addierst auf das erste (nenen wir es R0) deinen Meßwert drauf Du addierst auf das zweite (nenen wir es R1) das Carry also etwa so: add r0, meßwert adc r1, null (null = ein register was die 0 enthält) dies wiederholst du 256 mal. Nun hast du im R0 den Mittelwert über 256 Meßwerte. Alle Regsiter wieder auf 0 setzen --> neue Meßreihe beginnen
Und das ohne etwas zu verschieben? Müsste dann ja auch mit weniger Messwerten z.B. 64 funktionieren, oder?
Hi Persönlich würde ich das allerdings über eine gleitende Mittelwertbildung realisieren (Ringpuffer+ Pointer). Dadurch bekommt man nach dem ersten Durchlauf für jeden Messwert einen Mittelwert. MfG Spess
Beitrag "Re: Mittelwert berechnung" Ist zum "Beruhigen" von ADC-Werten bestens geeignet und erfordert extrem wenig Ressourcen. ...
OPAMP-Ausgang--------Widerstand---------ADC-Eingang | Kondensator | Masse
Hallo Läubi, mal ne Frage zur Funktion: > add r0, meßwert > adc r1, null (null = ein register was die 0 enthält) > dies wiederholst du 256 mal. > Nun hast du im R0 den Mittelwert über 256 Meßwerte. > Alle Regsiter wieder auf 0 setzen --> neue Meßreihe beginnen In r0 wird im Prinzip die Summe aller Messwerte erfasst, in r1 die Anzahl, sehe ich das soweit richtig? Dann müsste man mit r0/r1 den Mittelwert bekommen. Ich habe da folgende Bedenken/Fragen: - man kann dann nur solange Werte mitteln, solange r0 nicht überläuft, oder? - warum nicht in einer Schleife r1 mit "inc r1" erhöhen? - wie funktioniert die Teilung (wenn keine Zweierpotenz)? Gruß Fred
Hi Das Verfahren funktioniert nur mit 8Bit-Werten. Die Addition von 256 Bytes bleibt innerhalb von 16Bit(2 Register). Im o.g. Fall ist r0 das Low-Byte und r1 das High-Byte und nicht der Zähler. Um den Übertrag von 'add r0,meßwert' zu berücksitigen wird das 'adc r1,0' (wobei 0 ein mit 0 geladenenes Register ist). Rechtsschieben ist nicht notwendig,weil das High-Byte einer 16 Bit Zahl dem Ergebnis von 8 mal 16Bit Rechtsschieben ist. MfG Spess
Läubi Mail@laeubi.de wrote: > machs am besten so: > du benuzt 2 register > > Du addierst auf das erste (nenen wir es R0) deinen Meßwert drauf > Du addierst auf das zweite (nenen wir es R1) das Carry also etwa so: > > > add r0, meßwert > adc r1, null (null = ein register was die 0 enthält) > > dies wiederholst du 256 mal. > > Nun hast du im R0 den Mittelwert über 256 Meßwerte. Der Mittelwert (ohne Rundungskorrektur) ist in R1, nicht in R0
Hi Also ich hab es jetz mal so versucht wie im Anhang zu sehen. Aber das Egebnis stimmt leider nicht. Wenn die Werte zwischen 180 und 200 schwanken müsste der Mittelwert ja dawischen liegen. Er liegt aber nahe null. Sieht vielleicht jemand einen Fehler im Code den ich übersehen habe?
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.