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
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.
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.
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