Hallo zusammen, nachdem ich ein Problem damit hatte, wie man eine Hysterese in Assembler programmiert Beitrag "Wie programmiert man eine Hysterese in Assembler ?" habe ich mal ein Programm hierzu geschrieben. Dort wird mit einem Poti dem ADC eine Spannung im Bereich 0 bis 5V vorgegeben und anhand der Schwellwerte acht LEDs angesteuert. Durch die Hilfestellung in dem oben genannten Thread bin ich darauf gekommen mit Flags zu arbeiten, die das Ueberschreiten bzw. das Unterschreiten der einzelnen Schwellwerte speichern. Bernd_Stein
Hi Das ist ja sehr voluminös geraten. Ist dir bewusst, das das Unterprogramm 'schwellwert_verarbeiten' völlig überflüssig ist? Der Wert den du dort ermittelst und ausgibst ist identisch mit dem Inhalt von SW_FLAGS den du dort verarbeitest. MfG Spess
spess53 schrieb: > Hi > > Das ist ja sehr voluminös geraten. > Das finde ich auch. Würde natürlich gerne sehen und nachvollziehen können wie man es " schlanker " machen kann. > > Ist dir bewusst, das das Unterprogramm 'schwellwert_verarbeiten' völlig > überflüssig ist? > Nein. Auch jetzt nicht nachdem ich es mir nochmal angeguckt habe. Ich habe mich halt hier dran orientiert : Beitrag "Re: Wie programmiert man eine Hysterese in Assembler ?" > > Der Wert den du dort ermittelst und ausgibst ist identisch mit dem Inhalt > von SW_FLAGS den du dort verarbeitest. > Ich verstehe leider nicht was Du mir damit sagen willst. So ist es recht übersichtlich programmiert, finde ich. Bernd_Stein
Hi >Ich verstehe leider nicht was Du mir damit sagen willst. >So ist es recht übersichtlich programmiert, finde ich. Der Wert, den du in SW_FLAGS an 'schwellwert_verarbeiten' übergibst ist identisch mit dem Wert den diese Routine an PortA ausgibt. Lass es mal durch den Simulator laufen und vergleiche mal r19 (SW_FLAGS) und r16 (A). >Das finde ich auch. Würde natürlich gerne sehen und nachvollziehen >können wie man es " schlanker " machen kann. Bekommst du morgen früh (hab wieder mal den USB-Stick stecken gelassen). Hat etwa ein viertel Codegröße. Aber schon mal als Anregung: Deine Schwellwerte sind z.B. alle durch 4 teilbar. Damit kannst du mit 8-Bit-Werten (ADC rechtsbündig mit ADLAR eingestellt) arbeiten. Erspart die ganzen 16-Bit Vergleiche. Schwellwerte nicht als Konstanten sondern als Tabelle im Flash. Damit können deine ellenlangen Vergleiche als Schleife ausgeführt werden. Der Ausgabewert wird beginnend mit 0b11111111 bei jedem Vergleich mit shl angepasst. MfG Spess
Hi Nachtrag: Wenn du schon etwas für die Codesammlung machst, dann nimm nicht so einen Oldtimer wie den ATTiny26. Der hat noch nicht einmal den vollständigen Befehlssatz eines aktuellen AVR. MfG Spess
Hi Wie versprochen. MfG Spess
spess53 schrieb: > Hi > > Wie versprochen. > > MfG Spess > Erstmal Danke. Ich kämpfe gerade mit dieser genialen Routine Beitrag "Tasten entprellen - Bulletproof" und deshalb habe ich noch nicht hierauf reagiert. Tut mir leid das ich so sprunghaft bin. Hoffe jedoch bald wieder auf diesen Thread zurück kommen zu können. Danke für deine Mühe. Bernd_Stein
spess53 schrieb: > Hi > > Der Wert, den du in SW_FLAGS an 'schwellwert_verarbeiten' übergibst ist > identisch mit dem Wert den diese Routine an PortA ausgibt. > Ja, aber das sollte ja nur ein anschauliches Beispiel für eine Hysterese sein. In z.B.
1 | ; |
2 | ;Aktionen entsprechend den Schwellwerten ausfuehren |
3 | ; |
4 | aktion_7: |
5 | ldi A,0b11111111 ;Alle Pins des... |
6 | out PORTA,A ;...Ports setzen |
7 | rjmp swv_end ;Ruecksprung aus Schwellwert verarbeiten |
könnte ja auch zusätzlich eine Pumpe eingeschaltet werden.
1 | aktion_7: |
2 | ldi A,0b11111111 ;Alle Pins des... |
3 | out PORTA,A ;...Ports setzen |
4 | sbi PORTB,PUMPE_EIN ;Pumpe einschalten |
>
Mir ist jedoch aufgefallen, das man bei so etwas ganz schön aufpassen
muß, wenn der Meßwert sich schneller ändert als das Abtasten durch den
ADC geschieht. So könnte z.B. die Pumpe eingeschaltet werden und beim
erneuten einlesen des Meßwertes einen Schwellwert unter dem liegen,
der die Pumpe wieder ausschaltet. Also müssen alle Schwellwerte darunter
auch die Pumpe ausschalten, was natürlich bei mehreren Schwellwerten
viel Schreibaufwand bzw. kopieren bedeutet.
Aber erstmal egal. Wollte nur mal zeigen, wie man evtl. eine Hysterese
in Assembler programmieren kann.
Danke für deinen Code.
Ehrlich gesagt kann ich ihn nicht nachvollziehen. Aber der ist ja eher
auf " so kurz wie möglich " getrimmt. Schön daran ist auch zu sehen,
wie man es machen kann den Code für den " Nachfolgecontroller "
anzupassen.
Bernd_Stein
@spess53 Habe deinen Code mal Hardwaremäßig ausprobiert. Dabei ist mir aufgefallen, das ich es schaffe ( mit 10k Poti ) wenn ich ganz feinfühlig bin jede LED bis auf die Unterste ( nahe bei Null Volt ) zum flimmern zu bringen. Das wollte ich ja durch eine Hysterese verhindern. Habe das Programm, weil ich noch nicht alles ganz verstehe im Simulator des AVR-Studios laufen lassen. Die Werte des ADCs waren dabei 120, 119, 120. Dort kann man sehr schön sehen, das es keine Hysterese an diesem Punkt gibt, was ja im Hardwaretest schon aufgefallen ist. Augenscheinlich scheinen also die beiden Programme das Selbe zu machen, nur im Detail betrachtet arbeiten sie etwas anders, da bei mir eine LED beim Überschreiten des Schwellwertes eingeschaltet wird und erst beim Unterschreiten der darunter liegenden Schaltwelle wieder ausgeschaltet wird. Diese Sequenz ist mir noch nicht ganz klar bzw. ich bin mir noch nicht sicher ob sie wirklich gebraucht wird. Aber mit dem AVR-Studio Simulator werde ich dies hoffentlich auch noch herausbekommen.
1 | lpm r21,Z |
2 | |
3 | cp r20,r21 |
4 | brcs end_loop ; wenn IST kleiner -> fertig |
5 | |
6 | in r16,PortA ; letzte Bargrafausgabe |
7 | ;com r16 ; negieren ( wegen STK 500 ) |
8 | bst r16,0 ; Bit0 nach T |
9 | bld r18,0 ; T nach Bit0 |
Bernd_Stein
Hallo, Bernd Stein schrieb: > Überschreiten des Schwellwertes eingeschaltet wird und erst beim > Unterschreiten der darunter liegenden Schaltwelle wieder ausgeschaltet > wird. SWerte: .db 240,210,180,150,120, 90, 60, 30, 15, 0 Also beim Aufstieg von 119 auf 120 wechselst Du in den Bereich [120..150[ , aber erst bei unterschreiten von 90 in den Bereich [90..120[ . Diese bedeutet, dass Du beim Abstieg immer einen Bereich hinterher hinkst, denn erst beim Wechsel auf 59 würde in den Bereich [60..90[ gewechselt. Du kämst wohl nict mehr auf den untersten Bereich zurück, denn die 0 kannst Du nicht unterschreiten. Wäre es nicht logischer, die Bereiche mit Überlappungen anzulegen. Bereich 1 :[0..50] // 0..40 Hysterese 0 und +10 oder Mitte 25 +- 25 Bereich 2 :[20..70] // 30..60 Hysterese -10 und +10 //Mitte 45 +- 25 Bereich 3 :[50..100] // 60..90 Hysterese -10 und +10 //Mitte 75 +- 25 .... Beim unterschreiten wechselt man in den Bereich darunter und beim überschreiten in denjenigen darüber.
Horst Hahn schrieb: > Hallo, > > Bernd Stein schrieb: >> Überschreiten des Schwellwertes eingeschaltet wird und erst beim >> Unterschreiten der darunter liegenden Schaltwelle wieder ausgeschaltet >> wird. > > SWerte: .db 240,210,180,150,120, 90, 60, 30, 15, 0 >... > > Wäre es nicht logischer, die Bereiche mit Überlappungen anzulegen. > Bereich 1 :[0..50] // 0..40 Hysterese 0 und +10 oder Mitte 25 +- 25 > Bereich 2 :[20..70] // 30..60 Hysterese -10 und +10 //Mitte 45 +- 25 > Bereich 3 :[50..100] // 60..90 Hysterese -10 und +10 //Mitte 75 +- 25 > .... > Beim unterschreiten wechselt man in den Bereich darunter und beim > überschreiten in denjenigen darüber. > Also durch diese theoretische Lösung steige ich nicht durch. Denke das durch den einfachen Vergleich eines Wertes und dann die sofortige Reaktion beim Überschreiten und Unterschreiten dessen, der Wurm zu suchen ist.
1 | cp r20,r21 ; Ist-Schwellwert |
2 | brcc end_loop ; wenn Schwellwert < -> fertig |
3 | lsr r18 ; Bargraf |
...
1 | end_loop: |
2 | com r18 ; negieren (wegen STK500) |
3 | out PortA,r18 |
4 | |
5 | rjmp mainloop |
Bernd_Stein
Hallo, @Bernd Stein > Denke das durch den einfachen Vergleich eines Wertes und dann die > sofortige Reaktion beim Überschreiten und Unterschreiten dessen, > der Wurm zu suchen ist. zuvor >120, 119, 120. Dort kann man sehr schön sehen, das es keine Hysterese an diesem Punkt gibt Dann zeig doch mal für 3 Bereiche auf wie das ablaufen soll, wenn der Wert langsam 0.. max ansteigt und dann wieder auf 0 abfällt. Mit Schaltschwellen und Umschaltwerten. I = 0..119; II = 120..199; III = 200..255
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.