Hi, wie schon im Betreff zu lesen ist habe ich ein Problem mit einer ungebauen AD Messnung. Ich messe einfach die Spannung über einem Poti und gebe damit die Potieinstellung von 0 - 100 % auf dem Display aus. Nun ist es aber so, dass die Messnung zwischen zwei prozentwerten hin und her springt (z.b. 64 und 65 %) ohne das ich den Poti drehe oder berühre. Das ist bei fast allen möglichen potieinstellungen so. Suche nun den Grund hierfür, denn bei einer 10 bit AD Wandler genauigkeit macht das ja mehr als 10 digit pro prozentwert, d.h. schon recht große Abweichungen. Bin momentan am rumrätseln, an was es liegen könnte: 1) der Versuchsaufbau auf dem Breadboard? 2) vielleicht ist der überlastete spannungregler (7805) dran schuld, der hat nur noch eine Spannung von 4,94 Volt, da er doch ziemlich gefordert wird (mc zeug + -21V erzeugung per maxim chip + 160x128 displayversorgung (hintergrundbeleuchtung läuft über ein anderes netzteil) 3) muss oder kann ich irgendwie durch anschliessen von kapazitäten oder induktivitäten den messwert stabilisieren? Vielen Dank für eure Hilfe
Fabian Knapp wrote: > Bin momentan am rumrätseln, an was es liegen könnte: > > 1) der Versuchsaufbau auf dem Breadboard? Versuchsaufbauten auf Breadboards sind in meinen Augen IMMER eine schwammige / störanfällige Angelegenheit. > 2) vielleicht ist der überlastete spannungregler (7805) dran schuld, der > hat nur noch eine Spannung von 4,94 Volt, da er doch ziemlich gefordert > wird (mc zeug + -21V erzeugung per maxim chip + 160x128 > displayversorgung (hintergrundbeleuchtung läuft über ein anderes > netzteil) Ich kann mir nicht vorstellen, dass der 7805 mit dieser Last in schwitzen kommt. > 3) muss oder kann ich irgendwie durch anschliessen von kapazitäten oder > induktivitäten den messwert stabilisieren? 1.) AVCC wie im Datenblatt über LC-Glied mit VCC verbinden 2.) Wenn du nur ein sehr niederfrequentes Signal auswerten willst (und das ist im Falle eines von Hand betätigtem Poti definitiv der Fall) ist es sehr hilfreich, ein C zwischen ADC-Eingang und GND zu setzen. 3.) Ich wäre jetzt nicht überrascht, wenn du schreiben würdest, dass dein Poti ziemlich hochohmig und die Leitung zwischen Poti und µC verhältnismässig lang ist. Vermutlich fängst du dir dann damit nen Netzbrumm ein. 4.) Es macht auch Sinn, das Poti nicht zwischen VCC und GND sondern zwischen AVCC und GND zu hängen. Gruß, Magnetus
Gegen Netzbrumm und andere Störungen (z.B. vom Handy oder Computermonitor) hilft auch eine Mittelung per Software. Etwa in dieser Form: mittelungsvariable = mittelungsvariable + ADC-wert gemittelter-wert = mittelungsvariable / mittelungsfaktor mittelungsvariable = mittelungsvariable - gemittelter-wert "gemittelter-wert" ist dabei der Wert mit dem Du weiterrechnest. Es ist übrigens praktisch, als mittelungsfaktor eine Wert 2^x zu nehmen (also 8,16 oder 32), weil dann die Division einfach und schnell mit Rechtsschieben erledigt werden kann. Gruß Johannes
johannes könntest du mir das nochmal erklären? klingt interessant aber verstehen tue ich es nicht. welchen wert nimmt die mittelungsvariable an usw. ich hatte bis jetzt nur die idee, denn wert einfach 2 oder 3 mal einzulesen und nur bei gleichheit das display zu aktualisieren
Ich würde das mit dem Mitteln erst mal vergessen. Steckbrett und genaues Messen ist eh schon so ne Sache. Atmel empfiehlt in den Datenblättern nicht umsonst die Beschaltung mit Cs und Spulen und getrennte Massefläche usw. Ließ dir das einfach mal durch. Der von Magnetus erwähnte Kondensator gegen Masse wirkt allerdings oft Wunder. Ja und je hochohmiger deine ganze Anordnung ist, desto mehr Rauschen hast du.
also ich hab mal 100n zwischen adc0 und gnd geklemmt und es ändert sich nix.
Ein klares Jein an Aufreger ;-) Ok, ein Aufbau auf dem "Frühstücksbrettchen" ist immer so ne Sache, aber gerade deswegen hab ich ja die Mittelung per Software ins Gespräch gebracht. Denn sie läuft innerhalb des Controllers und kann daher einen Breadboard-Aufbau wesentlich einfacher verifizieren als es mit puren Hardware-Mitteln möglich ist. Ich weiß nicht, ob Du schon mal eine Analogmessung mit einem STK zwecks Proof-Of-Concept pre-realisiert hast, ich weiß nur, dass ich da ohne den "Software- Kondensator" hinter dem ADC-Eingang schon mehr als einmal baden gegangen wäre. Denn nichts anderes ist die Mittelung in der beschriebenen Form: ein Integrator, wie ein C oder vielmehr ein RC-Glied am ADC-Eingang. Zu Fabians Frage: Die mittelungsvariable nimmt maximal den höchsten ADC-Wert mal mittelungsfaktor an, d.h. bei 10bit ADC-Wert und 16bit für die mittelungsvariable kannst Du bis zu einem mittelungsfaktor von 64 gehen. So hoch bin ich bisher aber nie gegangen, denn die Zeit für die hinreichend genau Annäherung an die Auflösung der Auswertung wird dann einfach zu groß - wenn Du einen programmierbaren Taschenrechner hast, gib mal die genannte Formel ein und zähl die Schritte, um auf Deine 1% Zielgenauigkeit zu kommen... Gruß Johannes
habe das grade mal alles auf dem papier mit mf = 2 ausprobiert und das scheint echt keine schlechte idee zu sein... bei 32 werten sollte man doch schon nah dran kommen! Danke wiedermal, solangsam hast du dir echt eine danksagung in meinem Projektbericht verdient :D
Hi! <(z.b. 64 und 65 %) Nunja, wenn du keine Hysterese zwischen den Werten einbaust hast du immer eine harte Umschaltschwelle weil der ADC sich nicht entscheiden kann ob die letzte Stelle nun 1 oder 0 sein muss. Mittelwert ist schon eine recht hilfreiche Sache, aber selbst damit wirst du es vermutlich nicht wegbekommen. Leider kennen wir deine Software nicht und es sind alles Vermutungen. Schaue doch einfach mal nach wie bei dir 64/65% ermittelt werden. Ich tippe jedenfalls auf fehlende Hysterese. Viel Erfolg, Uwe
Ich denke, Du wirst bei 8 oder 16 Schritten völlig zufrieden sein :-) Gruß Johannes
@Uwe da ich nicht weiss was eine Hyterese ist habe ich sie sicherlich nicht in meinem Programm drine :) könnte mir das jmd erklären? Würde mich interessieren!
Hysterese ist, wenn Du zum Umschalten von einem (Ausgabe)Wert auf einen anderen erst eine bestimmte Abweichung vom vorherigen Wert verlangst. Also z.B. dass bei 87 in der Anzeige der angzeigte Wert nicht schon bei 86,9 umspringt, sondern erst wenn er kleiner 86,5 wird, und entsprechend nach oben. Das kann mitunter eine Hilfe sein, aber nur sofern die Sprünge zwischen zwei Messwerten klein genug sind - wozu wiederum regelmäßig eine Integration bzw. Mittelung nach meinem Vorschlag nötig ist :-) Gruß Johannes
> da ich nicht weiss was eine Hyterese
Stell dir folgendes vor:
Du hast eine Heizung mit einem Thermostat. Du möchtest jetzt
25 Grad Raumtemperatur erreichen. Dazu programmierst du deine
Steuerung so, dass sie unterhalb von 25 Grad die Heizung einschaltet
und bei 25 Grad wieder aus. Damit könnte dir folgendes
passieren: Die Temp steigt auf 25.00001 Grad womit der Brenner
ausschaltet. Die Temp sinkt auf 25 Grad. Der Brenner schaltet wieder
ein. Temp: 25.00001 -> Brenner aus. Im Endeffekt ist der Brenner
nur am Ein/Ausschalten.
Daher macht man eine Hysterese hinein: Ausgeschaltet wird erst bei
26 Grad, eingeschaltet erst wenn die Temp im sinken wieder 24 Grad
erreicht hat. Im Mittel ergibt sich dann auch wieder 25 Grad.
Allerdings ist der Brenner jetzt viel ruhiger :-)
Dann hab ich sowas im groben vorhin schon zufällig programmiert: Ich habe mir überlegt, wie ich die Sprünge von zwei Prozentwerten unterbinden kann und habe dann programmiert, dass das Display erst was neues anzeigt, sobald sich mindestens 2% verändert haben. Nun habe ich keine ungewollten Prozentsprünge mehr drin :) Bin jetzt am überlegen, ob ich das ganze nun auf den gemessenen AD Wert schon anwenden soll und nicht auf den prozentwert, der ja dann mit 2% unterschied einen recht großen Schritt drinne hat. Vielleicht probiere ich es mal mit dem gemessenen 10 bit wert, indem ich angebe, dass er nur weiter mit rechnen soll , wenn er sich um mindestens 10 digits (ca 1%) ändert! Mal sehen obs funktioniert!
Damit bist Du erstmal so auf dem richtigen Dampfer! Kann jetzt bloss noch sein, dass der Wert vom ADC noch zu sehr "flattert". Gruß Johannes
moin moin, bei soetwas arbeite ich immer mit einem gleitenden Mittelwert. Z.B.: MittelWert = (MittelWert *3 + ADU-Wert) / 4 Ein neuer ADU-Wert geht also nur mit 25% in den Mittelwert ein. mfg Pieter
@Pieter auch keine schlechte idee :) werden ich eventuell mal ausprobieren :)
Hi habe noch ein Fehler im Code den ich nicht finden kann :( kann da vll. mal schnell jmd. drüber sehen? ADC_DIFFERENCE ist die von mir definierte Abweichung, die überschritten werden muss, um das Display zu aktualisieren (im Beispiel habe ich 10 verwendet). es sieht so aus als würde sich der MC die ganze Zeit reseten?! bin echt überfragt :( Anfangen tut die funktion mit PERCENT: sie öffnet sich, sobald in der hauptschleife ein neuer ADC wert abgefragt wurde und die wandlung abgeschlossen ist. PERCENT_2: sub r23,r16 ; r23 = r23 - r16 sbc r24,r17 ; r24 = r24 - r17 - c cpi r24,1 ; compare r24 - 1 brsh PERCENT_4 ; jump if r24 >= 1 cpi r23,ADC_DIFFERENCE ; compare r23 -ADC_DIFFERENCE brlo ADC_END ; jump if r23 < ADC_DIFFERENCE rjmp PERCENT_4 PERCENT_3: sub r16,r23 ; r16 = r16 - r23 sbc r17,r24 ; r17 = r17 - r24 - c cpi r17,1 ; compare r17 - 1 brsh PERCENT_4 ; jump if r17 >= 1 cpi r16,ADC_DIFFERENCE ; compare r16 - ADC_DIFFERENCE brlo ADC_END ; jump if r23 < ADC_DIFFERENCE rjmp PERCENT_4 PERCENT: clr r3 clr r1 in r16,ADCL ; ADC lowbyte in r17,ADCH ; ADC highbyte push r16 push r17 cp r16,r23 ; compare r16 - r23 cpc r17,r24 ; compare r17 - r24 - C breq ADC_END ; jump if new ADC = old ADC brlt PERCENT_2 ; jump if new ADC < old ADC brge PERCENT_3 ; jump if new ADC > old ADC PERCENT_4: pop r17 pop r16 mov r23,r16 mov r24,r17 subi r16,-1 sbci r17,-1 ;Dann mit 100 multiplizieren, wobei ein Wert >16bit ;herauskommen kann (R2-R4): ldi r18,100 mul r16, r18 ; adcl * 100 movw r2, r0 clr r4 mul r17, r18 ; adch * 100 add r3, r0 adc r4, r1 ;Nun teile ich durch Verschieben durch 256... mov r16,r3 ; r4:r3:r2 / 256 mov r17,r4 ;...addiere den entsprechenden Wert für die Rundung... subi r16,0xFE ; + (512/256) entspr. -2 sbci r17,0xFF ;...und teile per Rechtschieben noch einmal durch 4: lsr r17 ; / (1024/256) ror r16 ; entspr. r17:r16>>2 lsr r17 ror r16 mov r22,r16 ADC_END: pop r17 pop r16 ret ADC_END_4: ret
Wenn du über Percent_4 die Funktion abschließt hast du einmal PUSH aber zweimal POP. Stelle ADC_END_4 einfach vor ADC_END und es geht.
oh tatsächlich vielen dank! Hatte sogar zuerst ADC_END_4 vor ADC_END habe mir dann nachts irgendwann gedacht, dass es andersrum doch eleganter wäre... soviel zum denken ;)
Auf eines muss ich unbedingt noch hinweisen, weil ich in meiner AVR-Anfangszeit selber mal darauf hereingefallen bin. (Der AVR war mein erster 8Bitter mit dieser "bösen Falle".) Du hast zum Verzweigen nach PERCENT_2 und _3 die Befehle brlt und brge benutzt, statt wie an anderer Stelle, brlo und brsh. Das macht hier zwar nichts, denn die hier verglichen ADC-Werte sind immer klein genug, dass der Unterschied nicht auffällt. Nichtsdestotrotz sind brlt/brge für vorzeichenbehaftete Vergleiche, und können mit vorzeichenlosen Zahlen unverhofft "sehr seltsames" Verhalten zeigen, wenn bei einem der beiden verglichenen Werte das höchswertige Bit gesetzt ist, was im vorzeichenbehafteten Zahlenmodell negative Werte bedeutet. Beipielvergleiche (mit 8bit Zahlen): hex-werte ohne Vorz. mit Vorz. brsh/lo brge/lt 0x50<->0x7F 80<->127 +80<->+127 lo lt 0x7F<->0x50 127<->80 +127<->+80 sh ge 0x50<->0xA0 80<->160 +80<->-96 lo ge !! 0xA0<->0x50 160<->80 -96<->+80 sh lt !! 0xA0<->0xFF 160<->255 -96<->-1 lo lt 0xFF<->0xA0 255<->160 -1<->-96 sh ge Nochmal zu Deinem Code denke ich, dass die beiden clr-Befehle am Anfang von PERCENT wohl entfallen können. Gruß Johannes
Juche... habe die extremen ungenauigkeiten mit keiner programmiertechnischen methode wirklich rausbekommen. Habe jetzt einfach mal an den poti 3 kurze dickere und besser abgeschirmte kabel gelötet und habe gnd und 5v jeweils direkt nachm 7805 abgegriffen und den poti nen paar cm von den anderem zeug weg gemacht. Habe jetzt zusätzlich noch was programmiert, dass 16 mal den adc wert misst und davon den durchschnitt errechnet. Dieser Durchschnittswert wird nur als neuer ADC Wert übernommen, wenn er mindestens mit einer ADC_DIFFERENCE von 10 digit (unter einem Prozent) (andere Werte probiere ich noch) vom aktuell dargestellten ADC Wert sich unterscheidet. Und siehe da: Ich habe ÜBERHAUPT KEINE Sprünge mehr drin =) bin jetzt voll happy, jetzt weiss ich endlich mit einer ziemlichen sicherheit das es funktionieren wird wenn ich die platine geätzt hab :)
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.