Hallo. Hab da ein Problem bei dem ich nicht weiter komm. Hab am Analogeingang meines PIC (eigentlich Picaxe aber is ja nur nen Bootloader drauf) nen analoges Signal liegen, das 9 verschiedene Werte von 0v bis knapp 5V annehmen kann, zwischen denen ich dann unterscheiden will. Das Signal ändert sich eigentlich höchstens alle paar Sekunden mal, wenn überhaupt, aber ich krig ständig störungen eigekoppelt. Hardwareseitig hab ich schon alles mögliche versucht die zu dämpfen, aber ich krig se nicht klein genug. Die Störungen sind kurze Peaks im mikrosekunden-Bereich, aber gehen bis an den 5V-grenze hoch. Dadurch dass die Störungen recht häufig sind (so ca. 10-20 pro sec) erwisch ich beim Analogeingang lesen halt hin und wieder nen peak, statt dem tatsächlichen Signal, was sehr unerwünschte Fehlfunktionen hervorruft. Was ich jetzt bräuchte wäre ein Konzept für eine Art Tastenentprellung für den Analogeingang. Den Code selbst krig ich dann schon hin (Basic-dialekt) Was ich grad noch vergessen hab: Auch wenn der Tatsächliche Wert anliegt kann der um +/-2 oder 3 schwanken. Macht die sache natürlich nicht einfacher. Ausserdem hab ich maximal noch 5Byte und 2Bit zum Rechnen. Programmspeicher wär noch massig da. Ich komm einfach auf keine vernünftige lösung, vielleicht könnt ihr mir ja helfen. Schonmal vielen Dank Sebastian
Was ist mit einer 'gleitenden Mittelung' neuer_Wert = ( alter_Wert + Messwert ) / 2 alter_Wert = neuer_Wert Wenn das nicht reicht kannst Du auch noch einen Wert weiter zurueckgehen neuer_Wert = ( vorletzter Wert + letzter_Wert + Messwert ) / 3 vorletzter_Wert = letzter_Wert letzter_Wert = neuer_wert
@Christian Wie gesagt, Hardwareseitig hab ich schon alles mögliche versucht. Nen RC-glied is schon drin, aber beliebig gros kann ich das auch nicht machen, und so wie's is krig ich die sache nicht genug gedämpft. Vor allem weil abzusehen ist, dass ehr noch nen paar störimpulse mehr auf die leitung kommen wenn die sache mal weiter gebaut ist. Aber trotzdem danke. Das mit dem Mittelwert hab ich auch schon mal überlegt, aber mal angenommen ich hatte die ganze Zeit 0V anliegen. Dann ist alter_wert=0. Kommt jetzt aber nicht die nächste Stufe (ca. 0.5V) sondern die übernächste oder gleich 5V, dann hab ich erst mal nen paar Programmdurchläufe lang alle möglichen Zwischenwerte, kann mir aber eigentlich keinen einzigen flaschen Wert leisten. Is ne dumme Sache, ich weiss. Aber auch dir trotzdem Danke Sebastian
Hab grad mal nachgerechnet: Wenn ich einfach die Mittelung nen paar mal hintereinander drüberlaufen lass brauch ich mindestens 12 Durchgänge um bei einem Wechsel von 0V auf 5V keine Zwischenwerte mehr zu krigen. Müsste mal schaun wie lange das dauert. Die Sache ist nämlich auch noch halbwegs zeitkritisch und müsste bei jedem Programmdurchlauf für alle 4 Analogeingänge (nacheinander oder gleichzeitig ist egal) gemacht werden.
Du kannst Dir auch ganz einfach ein paar aeltere Werte merken. Nur wenn die alle im wesentlichen gleich sind, wird der Wert akzeptiert Sagen wir mal ein Merktiefe von 4 0 0 0 0 gemessener Wert: 1 1 weicht von den 4 letzten nicht innerhalb der Toleranz ab -> akzeptiert -> Neuer Wert 1 0 0 0 1 gemessener Wert: 0 wieder: innerhalb der Toleranz in Bezug auf die letzten 4 -> akzeptiert: Neuer Wert 0 0 0 1 0 gemessener Wert: 15 15 ist klar ausserhalb der Toleranz bei allen 4 vorhergegangenen Messungen -> abgelehnt Ausgabe: weiterhin 0 0 1 0 15 gemessener Wert: 1 Bei 3 von 4-en innerhalb der Toleranz -> angenommen -> neuer Wert 1 1 0 15 1 gemessener Wert: 5 ausserhalb der Toleranz bei allen 4 -> abgelehnt Ausgabe: weiterhin 1 0 15 1 5 gemessener Wert: 5 ausserhalb der Toleranz bei 3 von 4-en -> abgeleht Ausgabe: weiterhin 1 15 1 5 5 gemessener Wert: 5 abgelehnt, Ausgabe: weiterhin 1 1 5 5 5 gemessener Wert: 5 bei 3 von 4-en innerhalb der Toleranz -> angenommen -> Ausgabe: 5 so in etwa. An den Details muesste man wahrscheinlich noch feilen, aber im Prinzip ...
Ja, das Prinzip hab ich verstanden. Klingt recht intelligent, bringt aber 2 Große Probleme mit: Wenn ich bei jedem Programmdurchlauf genau einmal mess, reicht mir der Speicher nicht. Bräuchte ja für jeden Eingang 4Speicher-Variablen. (+eine für den neuen Wert) Macht 21. Hab aber nur noch 5. Oder hab ich da ne möglichkeit net mitbekommen daten zu speichern? Ich kenn nur die 14 Byte mit denen ich dann auch rechnen kann, und die im e²prom. Letzterer ist aber ja nur ca 100000 mal wiederbeschreibbar. Da wär mir die Lebenszeit des MC zu kurz. Wenn ich bei jedem Programmdurchlauf den Wert neu berechnen lass bremst das zu arg. Hab eben bei der Mittelung recht genau 20ms für den Übergang von 0 auf 5V gehabt. (Es warn dann doch ehr 30-50 Zyklen, weiss net warum genau) Bei 4 Eingängen macht das eine Gesamtzeit von 80ms. Meine momentane Schleife braucht auch nur 20ms. In den maximal knapp 200 ms die ein Eingang dadurch unbeobachtet bleibt ist mir die Modellbahnlock die ich damit steuer leider schon 5-10cm zu weit gefahren. Sebastian
"Das Signal ändert sich eigentlich höchstens alle paar Sekunden mal" "Die Sache ist nämlich auch noch halbwegs zeitkritisch" Was denn nun: mehrere Sekunden oder zeitkritisch ? Eine Möglichkeit wäre: 20 Messungen machen, die 2 kleinsten und 2 größten weg schmeißen, die restlichen 16 Mittelwert bilden. Kostet natürlich etwas SRAM um sich die 20 Werte zu mehrken. Peter
9 verschiedene Werte ist etwas umständlich, 8 oder 16 wäre einfacher. - Vor dem Rastern 1/2 der End-Auflösung addieren. - Dann (wie bereits gesagt) die letzten 3 Werte merken. - Einen neuen Wert nur akzeptieren, wenn der neue Wert mit den letzten 3 Werten identisch ist. Da ich nicht beim PIC zu Hause bin, sondern beim AVR, gibt's nur AVR-ASM. Das Auslesen des ADC für 16 Werte wäre dann: ; zuerst die alten Werte um ein Byte weiterschieben: mov alt3,alt2 ;Register kopieren mov alt2,alt1 ;Register kopieren mov alt1,alt0 ;Register kopieren ; Nun ADC einlesen, runden und Auflösung auf 16 reduzieren: in alt0,ADCH ;ADC einlesen subi alt0,-8) ;1/2 der Auflösung addieren (runden) swap alt0 ;gewünschtes oberes Nibble nach unten andi alt0,15 ;das relevante (untere) Nibble maskieren ; die unteren 4 Bit von alt0 repräsentieren nun den eingelesenen und ; auf Auflösung 16 (0..15) gerundeten Wert des ADC... ; Nun folgt der Vergleich mit den vorherigen Werten: cpse alt0,alt1 ;identisch? wenn ja, dann skip... rjmp weiter ;nein, weg hier... cpse alt0,alt2 ;identisch? wenn ja, dann skip... rjmp weiter ;nein, weg hier... cpse alt0,alt3 ;identisch? wenn ja, dann skip... rjmp weiter ;nein, weg hier... ; Der folgende Befehl wird nur erreicht, wenn alle Vergleiche ; positiv waren, also alle alt-Werte identisch waren: mov neu,alt0 ;ja, Wert übernehmen weiter: ;fertig, weiter mit anderen Aufgaben... Der Programmvorschlag ist aus dem Hut, also nicht getestet. Es kann sich also noch irgendwo ein Fehler eingeschlichen haben... ...
@Peter Das Signal ändert sich nicht besonders oft(pro sekunde,minute...) (wenn keine Störung drauf liegt), aber wenn es sich dann ändert möchte ich trotzdem möglichst schnell den neuen Wert vorliegen haben um damit zu werkeln. Ausserdem sollte der Auslesevorgang nicht den Rest des Programms übermäßig ausbremsen, da ich ja auch noch andere Eingänge hab auf die ich reagieren muss. Was mir grad noch kam: Um Missverständnissen vorzubeugen/sie auszuräumen: Meine Spannung kann 9 verschiedene Werte annehmen, Ausgelesen wird der Eingang mit 8bit, also 256 Stufen. @Hannes Wenn ich das richtig verstanden hab willst du das selbe machen wie Karl Heinz, nur dass du die Werte erst noch Rundest, nicht? Da stoss ich leider auf die gleichen Probleme wie schon angesprochen. Oder hab ich da wirklich was mit dem Speicher verpeilt? Bin noch nicht soo lange bei Mikrokontrollern, hab sie bisher aber auch noch nie ausgereizt.
Darf man fragen? Woran baust Du da? Worums mir geht: Du wirst um eine 'zetliche' Beobachtung des Signals nicht herumkommen. Schliesslich ist das die einzige Möglichkeit um eine Störung von einem realen Eregniss zu unterscheiden. Störungen sind kurz, reale Eregnisse sind lang. Es muss doch noch irgendwo eine Möglichkeit geben ein paar Bytes freizuschaufeln um diese History anlegen zu können. Notfalls mal von Basic weggehen und auf Assembler runterwechseln. 'Hochsprachen' sind meist nicht sehr Resourcenschonend. Deine Timing-Werte kann ich so nicht wirklich nachvollziehen. Machst Du das ganze mittels Timer oder pollst Du so friedlich vor dich hin? 20 ms sind eine ganze Menge Zeit. Das muesste mehr als massig ausreichen um mit Mittelung 4 ADC Eingaenge zu ueberwachen.
Nunja, ich bin kein PICler, kenne also die Architektur und Ressourcen des PIC nicht. - Sorry... Falls du aber noch SRAM frei hast, kannst du ja alle Variablen im SRAM halten und vor dem Auslesen des ADC in die (dann temporären) Register laden und hinterher wieder ins SRAM zurück schreiben. Da diese Routine keinerlei Wartezeit verursacht, kann sie zyklisch aufgerufen werden. Nach dem Auslesen wird die neue ADC-Quelle ausgewählt (beim AVR mit ADMUX), somit gibt es beim nächsten Aufruf der Routine schon (ohne Wartezeit!) ein gültiges Ergebnis des ADC. Man muss den Aufruf-Zyklus der Routine nur dem ADC-Tempo anpassen. Du kannst dabei immer reiherum messen, wenn du die Variablen im SRAM halten kannst. Dann erfolgen eben die 4 zu vergleichenden Messungen nicht direkt hintereinander, sondern nur jedes vierte mal. Das ist aber auch kein Problem. Das mit den 9 verschiedenen Spannungswerten ist allerdings doof. Sowas macht man nur, wenn es nicht anders geht. Für sowas nimmt man möglichst Zweierpotenzen, damit der MC nicht unnötig "rechnen" muss. Denn das Rastern des Wertevorrates eines Bytes (0..255) auf 9 Stufen ist bedeutend aufwendiger (rechenintensiver) als das Rastern auf 8 oder 16 Stufen. Überlege also mal, ob es wirklich 9 Stufen sein müssen. ...
Hallo! Oder eine einfache Methode, die auch beim Tastenentprellen gut angewendet werden kann. Du merkst Dir für jede Eingangsspannung die höchstwertigsten vier Bit. Macht bei vier Quellen 16 Bit. Bleiben noch drei von Deinen fünf Speicherstellen. Mit den restlichen 24 Bit kannst Du locker drei 6 Bit Zähler realisieren. Wenn sich ein Wert im nächsten Durchlauf ändert, so setzt Du den Zähler zurück. Ist der Wert gleich, so wird der Zähler erhöht. Wenn dieser einen Grenzwert erreicht, kannst Du den neuen Wert als stabilen Wert übernehmen. Durch die Größe des 6 Bit Zählers kannst Du einen Parameter für den Grenzwert einstellen, so dass das System zufriedenstellend funktioniert! Gruß, Rainer
Nich totschlagen bitte, ja? Dann verrat ich auch, dass ich nen ganzes Stück Speicher übersehn hab. Hab grad nochmal das Datenblatt gewälzt, da isses aufgefallen. Der Speicher sollte jetzt also nicht das Problem sein. 9 Stufen müssen sein. Ich könnte höchstens noch 7 "Pseudostufen" einführen die für nix stehen, dass ich auf 16 komme, aber ob das sinn der Sache ist. Wie gesagt, bin noch nicht so lange bei den MCs, daher progge ich nur so nen popligen Picaxe. Das sin pics mit nem aufgespielten Bootloader. Hab mich dafür entschieden, weil ich 1. Quasi noch überhaupt keine Ahnung von dem Zeug hatte, und 2. Ich mich nicht auch erst noch mit nem Programmiergerät rumärgern wollte. Wenn man komplett neu is wirds doch schon ziemlich zeitaufwändig bis man alles am laufen hat (denk ich). Und das war auch gleich Grund Nr. 3. Zwölfte Klasse Gymnasium lässt echt viel zu weig Freizeit, und ich wollte die sache zumindest noch zum laufen bringen bevor ich mit der Facharbeit anfangen muss. Die Entscheidung hat sich jetzt natürlich als nachteilig entschieden, da ich das teil NUR in diesem Basic-dialekt proggen kann. (mal abgesehn davon dass meine Assamblercodes wahrscheinlich noch länger wären) Das sch**ß Teil von Bootloader braucht sogar alle Timer für sich. Ich muss echt mal umsteigen auf "echte" Pics (oder AVRs?) Dass ich um eine Zeitmäßige Beobachtung nicht herumkomme ist mir klar. Aber ich will halt auch nicht ewig an dem Analogeingang "Entprellen", während mir am anderen Ende nen Zug in den anderen Rauscht. Aber mit dem neu gefundenen Speicher kann ich ja in jedem Durchlauf einen Messwert pro Eingang nehmen. Das sollte Zeitmäßig noch funktionieren. Was ich da baue? Ne Steuerung für meinen Schattenbahnhof bei meiner Modelleisenbahn. Wenn ich also nicht programmiere dann wekel ich an der Anlage rum -->noch weiger Zeit zum Proggen :-(
Die ganzen Software-Ansätze sind ja alle schön und gut. Doch wie sieht es mit der Hardware aus? Du sagst, Du hast ein RC-Glied drin? Wo ist das RC-Glied und wie sind die Bauteil-Werte? Wie ist die Schaltung sonst aufgebaut? Wie ist die Masseführung? Ich vermute eher, dass da irgendein Wurm auf der Hardwareseite ist. Beschreibe doch mal Deine Schaltung genauer, vielleicht kann man dann helfen!?!?
Natürlich kommt die Sache von der Hardwareseite. Woher genau weiss ich aber nicht. Wahrscheinlich wird auf na Signalleitung was eingekoppelt (über induktion?). Könnte sein, weil in näherer Umgebung leitungen liegen auf denen meine PWM-gesteuerten Loks ihren Strom ziehen. Hab schon versucht die Signalleitungen zu belasten (soweit dies meine Quelle zulässt), hat aber nix gebracht. Viellecht kommt's also auch woanders her. Das Signal geht auf nen OP, der noch was draufaddiert und an den MC schickt. Nach dem OP hab ich mein RC-Glied. Das filtert schon einiges raus. Hilft auch ziemlich, aber ab und zu sind störungen auf der Leitung, die so groß sin, dass ich kaum ne chance haben dürfte die auf dem Weg erträglich klein zu krigen. Jedenfalls mit nem erträglich kleinem Kondensator nich :-) Nach dem RC-gleid kommt nochma nen Widerstand, dann ne 5,1V Zenerdiode nach Masse um den Analogeingang zu schützen, und dann der Eingang. An der Hardwareseite hab ich echt schon ewig probiert, und auch mein Vater (gelernter Elektrotechniker) schon ausgequetscht. Aber nachdem ich noch nicht mal genau rausbekomm woher die Störung kommt dürfte es schwer sein sie in der Entstehehung zu bekämpfen. Deswegen hab ich mir halt überlegt es über die Sofware zu machen (zusätzlich zu den jetztigen Maßnahmen). Ich denke mal ich takte den Chip noch höher (momentan 4Mhz), dann läuft das Programm schneller durch, und ich kann mehr Messwerte nehmen, ohne eine kritische Verzögerung zu bekommen. Habs jetzt mal prinzipiell so gemacht: - Eingangswert runden (is praktischer wenns drum geht ob die werte gleich sin oder nicht) - Dann die letzten 3 Werte merken. - Einen neuen Wert nur akzeptieren, wenn der neue Wert mit den letzten 3 Werten identisch ist. Wie es ja oben schon beschrieben wurde. Funktioniert schon recht gut, muss es nur noch vernünftig in den Programmablauf integrieren. Auf jedenfall mal ganz dick Dankeschön. Ihr habt mir sehr geholfen. Sebastian
> Nach dem OP hab ich mein RC-Glied.
Das ist natürlich nix. Das RC-Glied gehört als erste Baugruppe auf der
Empfangsseite.
Dein OPV wird je einen recht hochohmingen Eingang haben, also
verursacht der kleinster Strom (induktiv eingekoppelt) schon einen
hohen Spannungsabfall.
Stell doch mal Deinen kompletten Schaltplan hier rein.
"Dein OPV wird je einen recht hochohmingen Eingang haben, also verursacht der kleinster Strom (induktiv eingekoppelt) schon einen hohen Spannungsabfall." Ja, is klar. Aber ich komm eigentlich über nen Optokoppler auf den OP. Wundert mich ja, dass der OP überhaupt so was schnelles schaltet (oder auch nicht?). Hab ja auch extra noch nen Widerstand parallel zum Optokoppler gelötet, um die Signalleitung zu belasten. Hat aber quasi nix gebraucht. Nen kompletten Schaltplan hab ich noch nicht. Hab mal aus dem bestehenden rauskopiert was relevant ist und nach meim Gedächtnis ergänzt. Spannungsversorgung des MC ist mit nem 7505 gemacht (mit kondensatoren), die OPs werden mit 14V betrieben. Die 2 Widerstände am Linken Rand sind die Eingänge. Auf dem einen liegt nen Komparator-OP (mit Hysterese von ca. 2-3V), am anderen Liegt der Optokoppler. Zu dem 1uF-C parallel zur Rückkopplung des einen OP hat mir mein Vater geraten. Hilft auch was. Ansonsten hätte man manches vielleicht anders lösen können(z.B. den nachträglich eingefügten C7), ich weiss, aber mein Lochraster-layout war eigetnlich weniger darauf ausgelegt noch was gegen Störimpulse zu bauen. Also mit so richtig dicken Kondensatoren ist auch nix. Aber vielleicht findest du ja was wie ich mit kleinen änderungen die Sache in Griff krig. Sebastian
Wie waers mit Median anstelle von Mittelwert. 5 Samples, sortieren und nur den "mittelsten ;-)" nehmen. Das funktiniert eigentlich immer solange mehr korrekte als gestoerte Werte reinkommen. Zum Thema R/C Glied, think small and fast not big! Deine Pulse muessen schnell weggebuegelt werden, ein Elko ist da viel zu langsam. Die Energie in den Pulsen scheint nicht zu gross zu sein. Mein Senf, Robert
C7 ist an der Stelle sehr ungünstig. Besser parallel zu D2. In welchem Bereich liegen die beiden Eingangsspannungen? Der LM324 braucht in dieser Schaltung eine negative Spannungsversorgung.
Hallo, scheint ja etwas schwieriger zu werden. Ich lese wie immer mit und habe mal was aufgemalt. Eine Frage hätte ich aber doch: Zitat .. Die 2 Widerstände am Linken Rand sind die Eingänge. Auf dem einen liegt nen Komparator-OP (mit Hysterese von ca. 2-3V), am anderen Liegt der Optokoppler. .. /Zitat Du addierst beide Spannungen, die eine vom Komparator und die vom OKoppler. Das habe ich nicht ganz verstanden. Gibts Du den Optokoppler frei, wenn der Komparator HIGH "hat"? Na egal Zu deinen Störimpulsen Eine negative Betriebsspannungen von einigen Volt wäre schon nicht schlecht, auch wenn der LM324 für Single Supply ausgelegt ist. Wenn Du tatsächlich mit Kondensatoren in der Rückkopplung arbeitest, hast Du definitv negative Spannungen in deinem Design. Das mag der OPV dann wirklich nicht. Du kannst aber auch deine OPV-Masse um ein-zwei Volt vituell anheben und diesen Offset dann in der SW wieder abziehen. Dein Filter, welches Du mit den Cs geschaffen hast, scheint mir aus dem Bauch heraus enstanden. Im Anhang habe ich mal ein halbwegs steiles (die DEMO lässt nichts steileres zu) Tiefpassfilter mit 10hz Grenzfrequenz aufmalen lassen. Vielleicht hilfts... Viele Grüße auch an alle AxelR.
Andi hat recht, der invertierende Eingang bildet ja eine virtuelle Masse und nen Kondensator von Masse nach Masse zu schalten ist witzlos. Parallel zu D2 und das Poti bildet dabei den Widerstand des RC-Tiefpaß. Peter
Der C7 ist tatsächlich aus dem Bauch heraus da hin gekommen. Aber wenn man so drüber nachdenkt ist er tatsächlich zimlich witztlos. Die OPs haben ne symmetrische Spannungsversorgung von +/-14 Volt. Ich vergess nur immer extra zu sagen dass sie symmetrisch ist. War gestern eh voll verpeilt. Der Komparator und der OKoppler schalten völlig unabhängig voneinander. Auch unterschiedliche Spannungen. Hab heut nochmal intensiv geforscht: Die Störung kommt ziemlich sicher von der Zuleitung zum Optokoppler. Jedenfalls kann ich sie da auch noch messen, und wenn ich die Zuleitung abklemme, funktioniert alles einwandfrei. Ohne Störimpulse. Der OP wird gegen Masse Durchgeschalten, vielleicht kann man da ja die Impulse direkt beim Entstehen killen? Wenn nicht werd ich wohl mal den OP anders beschalten müssen, oder parallel zur Diode noch weng Platzt finden. Sebastian
So, das mit den Filtern wird mir jetzt zu doof. Krig die sache einfach nicht vernünftig glatt. Nachdem ich ja jetzt weiss dass es vom Okoppler her kommt bau ich einfach zwischen O-koppler und den ersten OP noch nen Komparator mit na dicken Hysterese. Des Eingangssignal für den Komparator glätt ich noch mit nem RC- oder nem T-Glied (mal schaun). Überleg auch noch an dem Komparator zusätzlich zum Widerstand der Hysterese nen Rückkopplungs-C ans Invertierende Bein zu bauen. Dann klappt er auch bei einer sehr Starken Störung nicht sofort um. Der Kondensator macht dann ja soz. nen Integrator draus. Aber trotzdem danke an alle die mir geholfen haben. Sebastian
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.