Forum: Mikrocontroller und Digitale Elektronik PIC 16F877A Vergleichen ob Analoger Wert in bestimmten Bereich liegt


von willer77 (Gast)


Lesenswert?

Hallo,

ich würde gern mit einem PIC 16F877A einen Motor ein bzw ausfahren. Dazu 
lese ich eine beim Motor angebrachte Lichtschranke über den AD Wandler 
ein. Einen zweiten Wert gebe ich über einen Poti vor, dieser ist der 
Soll Wert für den Motor. Das heißt also ich gebe eine Spannung am Poti 
vor und wandle diese ebenfalls am ADC. Dann Vergleiche ich den Wert mit 
dem eingelesenen Wert von der Lichtschranke und vergleiche auf > oder < 
in dem ich beide Werte voneinander abziehe, und das Carry Flag auswerte. 
So weiß ich ob der Motor rechts oder links loslaufen soll. Weiter 
vergleiche ich dann ständig den Wert der Lichtschranke mit dem nur 
einmal eingelesene Wert des Poti-sobald ein Vorzeichenwechsel 
stattfindet, stoppe ich den Motor. dann geht alles wieder von vorne los- 
neuer Sollwert wird eingelesen und wieder geschaut wo der Motor 
hinlaufen soll. Jetzt habe ich das Problem das mein Motor natürlich 
ständig um den Sollwert herum vor und zurück läuft- ich würde also gerne 
sagen das der Motor stehen bleiben soll sobald er sich in einem 
bestimmten Bereich befindet. Wie könnte ich das machen??? Dachte 
irgendwie an eingegebene Tabellenwerte die ich dann irgendwie auswerte?? 
Kenn mich aber dafür zu wenig aus-bin für jede Anregung dankbar!!!

von Matthias L. (Gast)


Lesenswert?

Du brauchst eine =>Hysterese.

Erst wenn die Differenz Soll-Ist vom Betrage her größer als X ist, wird 
entsprechend verfahren.

von Falk B. (falk)


Lesenswert?


von willer77 (Gast)


Lesenswert?

Danke für die schnellen Antworten. Genau so etwas brauche ich, dass ist 
mir vom Prinzip her klar, nur wie kann ich sowas in Assembler umsetzen??

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Du musst dir einen Bereich schaffen, indem dein Motor stehen bleibt. 
Also angenommen dein Poti hat den Wert 500. Dann subtrahierst du einmal 
10 von diesem Wert, das ist dein unterer Vergleichswert. Nun addierst du 
in einem zweiten Schritt 10 hinzu, dass ist dein oberer Vergleichswert. 
Damit würde der Motor zwischen 490 und 510 stehen bleiben. Ist ein wenig 
mehr Schreiberei in Assembler aber grundsätzlich nicht allzu schwierig. 
Falls 8 Bit genau genug sind, dann benutze nur die höheren 8 Bit von dem 
ADC. Das spart dir die Rechnerei mit den 16-Bit Zahlen.

Sven

von Falk B. (falk)


Lesenswert?

1
.equ max=123
2
.equ min=89
3
4
.dseg
5
st_ausgang:    .byte   1
6
7
.cseg 
8
; messwert in r16
9
asm_st:
10
  cpi r16, max
11
  brlo asm_st_no_max
12
  ldi r17,1          ; obere Schwelle überschritten -> 1
13
  sts st_ausgang,r17
14
  ret
15
asm_st_no_max:
16
  cpi r16, min
17
  brsh asm_st_no_min
18
  ldi r17,0         ; untere Schwelle unterschritten -> 0
19
  sts st_ausgang,r17
20
  ret
21
asm_st_no_min:
22
  ret               ; zwischen den Schwellen, keine Änderung

In PIC-ASM sehr ähnlich, kann ich aber nicht.

MFG
Falk

von willer77 (Gast)


Lesenswert?

@falk
Danke für den Code, leider kenn ich mich damit nicht aus!!

@stepp64
8 bit würden locker reichen-obwohl ich zur zeit noch mit 16 bit rechne. 
Das Problem was ich habe liegt immer noch in den Vergleichsprozessen. 
Ich addiere bzw subtrahiere von meinem Poti_Wert jeweils z.B 10 und lege 
diese Werte in zwei Speicherzellen ab. Aber wie kann ich dann am 
schnellsten meinen Lichtschrankenwert damit vergleichen-ob erim Bereich 
liegt oder drunter bzw darüber. Ich steh da wohl irgendwie auf der 
Leitung.

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Also angenommen du hast den minimalen Wert in min gespeichert und den 
maximalen Wert in max. Dein Vergleichswert steht in pot.

Nun sagen wir mal: min ist 120,  max ist 140 und pot ist 130.

Nun musst du zwei Vergleiche machen. Vergleichen ob etwas größer oder 
kleiner ist kannst du nur über den Subtraktionsbefehl. Du lädst also pot 
nach w und subtrahierst min von w ab. Carry ist dann 0 wenn w größer war 
und 1 wenn es gleich oder kleiner war. Schau dir mal das Instruction set 
des 16F887 (nicht 877) an. Dort ist es besser beschrieben.

Bsp.
1
   movfw pot
2
   subwf min,w       ;das w hinter dem Komma ist wichtig, damit der Wert in   
3
                     ;min nicht überschrieben wird
4
   btfss STATUS,C
5
   goto  größer
6
7
kleiner
8
   .....
9
10
größer
11
   .....

Probier es im Simulator aus, da kannst du schön erkennen ob es 
funktioniert

von willer77 (Gast)


Lesenswert?

Danke für den Tipp. Ich werds morgen mal ausprobieren-hab mir schon 
gedacht das ich es so machen muss, ist halt so bei RISC!!! Sehe nur noch 
das Problem wenn mein Poti z.B. auf 9 ist und ich 10 abziehe für meinen 
unteren Grenzwert dann hab ich ja FF und Carry gesetzt-aber irgendwie 
muss das ja auch noch zu lösen sein!!

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Na sicher ist das zu lösen. Nach Subtraktionen und Additionen sollte man 
immer das Carryflag überprüfen und entsprechend reagieren.

Kommt in deinem Fall ein Überlauf zustande, dann setzt du den Wert pot 
halt einfach auf 0. Gilt ja in diesem Beispiel für alle Werte zwischen 0 
und 9.

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
Noch kein Account? Hier anmelden.