Nabend Gemeinde,
in den letzten Tagen war ich damit beschäftigt, einen kleinen autonomen Roboter zu bauen der mit Infrarotsensoren laufen sollte.
Da sich vieleicht hier jemand mit geringen Elektronikkentnissen auch mal soetwas bauen möchte, dachte ich, stelle ich hier mal mein Programm rein.
Das Programm ist in Assembler, und ausgelegt auf den Pic 16F870.
Assemblerschreibsoftware ist MPlab von Microchip und Brennersoftware ist USBurn von Sprut.de
Das Programm funktioniert auch mit allen anderen Pics, vorraussetzung:
-AD Wandler
-2-4Inputs
-8Outputs
und die config so wie die Speicherzeilen der Konstanten und Variablen müssen angepasst werden.
Sensoren:
Es sollten welche sein, die bei näherndem Objekt eine größerwerdende Signalspannung ausgeben, z.B Infrarotsensoren.
Taster gehen aber auch Problemlos, dafür muss nichts im Porgramm geändert werden.
-----------------------------------------------------------------------
;Autonom
list p=16f870
#include <p16f870.inc>
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_ON & _LVP_OFF & _CPD_OFF & _WRT_ENABLE_OFF & _DEBUG_OFF
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
; Konstanten festlegen
freq Equ D'20' ; Frequenzangabe
zschl1 Equ 0x20 ; Zähler für Zeit-Schleife
zschl2 Equ 0x21 ; Zähler für Zeit-Schleife
zschl3 Equ 0x22 ; Zähler für Zeit-Schleife
motor Equ 0x23
sensorschw Equ 0x24
;***** VARIABLE DEFINITIONS
w_temp EQU 0x71 ; variable used for context saving
status_temp EQU 0x72 ; variable used for context saving
; Macros festlegen
b0 MACRO ; auf Bank 0 schalten
bcf STATUS, RP0
bcf STATUS, RP1
ENDM
b1 MACRO ; auf Bank 1 schalten
bsf STATUS, RP0
bcf STATUS, RP1
ENDM
b2 MACRO ; auf Bank 2 schalten
bcf STATUS, RP0
bsf STATUS, RP1
ENDM
b3 MACRO ; auf Bank 3 schalten
bsf STATUS, RP0
bsf STATUS, RP1
ENDM
b02 MACRO ; auf Bank 0 oder 2 schalten
bcf STATUS, RP0
ENDM
b13 MACRO ; auf Bank 1 oder 3 schalten
bsf STATUS, RP0
ENDM
;**********************************************************************
ORG 0x000 ; processor reset vector
clrf PCLATH ; ensure page bits are cleared
goto Init ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
Init
b1
movlw B'00000000'
movwf TRISB
movlw B'11111111'
movwf TRISA
bcf ADCON1,3
bcf ADCON1,2
bcf ADCON1,1
bcf ADCON1,0
b0
; ADC einschalten
BSF ADCON0,0
; ADC speed für 20 MHz einstellen
BSF ADCON0, 7 ; ADCS1=1
BCF ADCON0, 6 ; ADCS0=0
; Daten rechtsbündig
b1 ; Bank1
BCF ADCON1, 7
b0 ; Bank0
;---------------------------------------------------------
movlw .xx ;<----xx durch gewünschten Wert ersetzen movwf sensorschw ; ( größer=frühere reaktion des bots
;******************************************
main
movlw .50 ;Wert bestimmt wie lange die Aktion ausgeführt wird
call Zeit
BCF motor,0
BCF motor,1
abfrage
; Sensor rechts auswerten
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BCF ADCON0, 3 ; ADCHS0=0
movlw .2
call Zeit
BSF ADCON0, 2 ; ADC starten
loop
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop
movlw sensorschw
subwf ADRESH
BTFSC STATUS,0
BSF motor,0 ;Wenn Signal, dann bit setzen
; Sensor2 rechts auswerten
BCF ADCON0, 5 ; ADCHS2=0
BSF ADCON0, 4 ; ADCHS1=0
BCF ADCON0, 3 ; ADCHS0=0
movlw .2
call Zeit
BSF ADCON0, 2 ; ADC starten
loop1
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop1
movlw sensorschw
subwf ADRESH
BTFSC STATUS,0
BSF motor,0 ;Wenn Signal, dann bit setzen
; Sensor links auswerten
BCF ADCON0,5 ; ADCHS2=0
BCF ADCON0,4 ; ADCHS1=0
BSF ADCON0,3 ; ADCHS0=0
movlw .2
call Zeit
BSF ADCON0,2 ; ADC starten
loop2
BTFSC ADCON0,2 ; ist der ADC fertig?
GOTO loop2
movlw sensorschw
subwf ADRESH
BTFSC STATUS,0
BSF motor,1 ;wenn Signal, dann bit setzen
; Sensor2 links auswerten
BCF ADCON0,5 ; ADCHS2=0
BSF ADCON0,4 ; ADCHS1=0
BSF ADCON0,3 ; ADCHS0=0
movlw .2
call Zeit
BSF ADCON0,2 ; ADC starten
loop3
BTFSC ADCON0,2 ; ist der ADC fertig?
GOTO loop3
movlw sensorschw
subwf ADRESH
BTFSC STATUS,0
BSF motor,1 ;wenn Signal, dann bit setzen
;Motoren ansteuern
BTFSC motor,0 ;Wenn kein Bit gesetzt wurde(kein Sig.) dann überspringen
goto links ;linken Motor auf rückwärts
;Motor links vorwärts
BSF PORTB, 0 ;N-Fet Rechtsunten der H-Brücke aus
BCF PORTB, 1 ;P-Fet Linksoben der H-Brücke aus
BSF PORTB, 2 ;P-Fet Rechtsoben der H-Brücke an
BCF PORTB, 3 ;N-Fet Linksunten der H-Brücke an
weiter ;Wenn linke Motoren auf rückwärts gestellt wurden, gehts hier weiter
BTFSC motor,1 ;Wenn kein Bit gesetzt wurde, dann überspringen
goto rechts ;rechte Motoren auf rückwärts
;Motor rechts vorwärts
BSF PORTB, 4 ;N-Fet Rechtsunten der H-Brücke aus
BCF PORTB, 5 ;P-Fet Linksoben der H-Brücke aus
BSF PORTB, 6 ;P-Fet Rechtsoben der H-Brücke an
BCF PORTB, 7 ;N-Fet Linksunten der H-Brücke an
goto main
links
;Motor links Rückwärts
BCF PORTB, 2 ;P-Fet Rechtsoben der H-Brücke aus
BSF PORTB, 3 ;N-Fet Linksunten der H-Brücke aus
nop
nop
BCF PORTB, 0 ;N-Fet Rechtsunten der H-Brücke an
BSF PORTB, 1 ;P-Fet Linksoben der H-Brücke an
goto weiter
rechts
;Motor rechts rückwärts
BCF PORTB, 6 ;P-Fet Rechtsoben der H-Brücke aus
BSF PORTB, 7 ;N-Fet Linksunten der H-Brücke aus
nop
nop
BCF PORTB, 4 ;N-Fet Rechtsunten der H-Brücke an
BSF PORTB, 5 ;P-Fet Linksoben der H-Brücke an
goto main
;------------------------------------------------------------
; Unterprogramme
; Zeitschleife
Zeit
movwf zschl1 ; ms übertragen
Zeit1
nop ; warten
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
movlw D'47' ; Zeitkonstante für 1ms
movwf zschl2 ; übertragen
Zeit2
nop ; warten
movlw freq ; Zeitkonstante für Frequenz
movwf zschl3 ; übertragen
Zeit3
nop ; warten
nop
decfsz zschl3, F ; vorbei?
goto Zeit3 ; nein, noch nicht
decfsz zschl2, F ; vorbei?
goto Zeit2 ; nein, noch nicht
decfsz zschl1, F ; vorbei?
goto Zeit1 ; nein, noch nicht
return ; Zeit abgelaufen
END ; directive 'end of program'
Kleine Erklärung:
Das Programm Schaltet nur zwischen Vorwärts und Rückwärts um, es wird dazwischen nich erst gebremst. Den kleinen Motoren macht das nichts. Bei großen Motoren, bzw einem schweren Bot muss eine Bremsfunktion eingefügt werden.
Die
"movlw .xx
call Zeit"
Befehle dienen dazu, eine bestimmte Zeit an millisekunden abzuwarten.
Das Programm wandelt den analogen Sensorwert in einen Digitalen Wert zwischen 0 und 128 um. 0=0V,128=~5V
Von diesem Wert wird dann ein frei wählbarer Wert subtrahiert.
Haben wir nun ein negatives Ergebnis, ist das Sensorsignal unter dem grenzwert, und es wird ein Carrybit gesetzt.
Ist es positiv, wird keines gesetzt.
Nun wird geguckt ob das Carrybit gesetzt oder nicht gesetzt wurde.
Theorie: Wurde eins gesetzt, ist noch genug Platz zwischen Wand und Roboter.
Praxis: Seltsamerweise ist es in der Praxis genau andersherum. Wurde eins Gesetzt, ist der Abstand zur Wand unter dem Sollwert. Liegt eventuell an irgendwelchen Eigenheiten vom Chip. Sprich 0=5v, 128=0V
Beschaltung:
Sensoranschlüsse:
An0=Sensorrechts
An1=Sensorrechts
An2=Sensorlinks
An3=Sensorlinks
Pinbelegung bzw Anschluss der H-Brücken:
H-Brücke für links:
PortB,0=PNP s1
PortB,1=NPN s2
PortB,2=NPN s1
PortB,3=PNP s2
H-brücke rechts:
PortB,4=PNP s1
PortB,5=NPN s2
PortB,6=NPN s1
PortB,7=PNP s2
Es ist wichtig diese Belegung einzuhalten, da es sonst einen Kurzschluss gibt
s1=stufe1
s2=stufe2
Stufe 1 ist jeweils die linke Seite der H-Brücke
und Stufe 2 jeweils die Rechte.
Vorwiderstände:
Als Basisvorwiderstände kann man 1k ohm nehmen, sofern man nur Minigetriebemotoren betreiben will.Wenn möglich größer, oder Transistoren mit hohem Verstärkungsfaktor.
Pulldownwiderstände:
Da die Sensoren ein positives Ausgangssignal haben, brauch man Pulldownwiderstände an den Eingängen.
Diese dienen dazu, den Kondensator des ADCs wieder zu entladen.
10Kohm reichen hier aus.
Jeder der schonmal einen Pic programmiert hat, auch wenn es nur eine blinke Led war, sollte das Anschließen der H-Brücken hinbekommen.
Falls fragen zum Programm oder zur Pinbelegung bestehen, fragt ruhig.
Hoffe ich kann jemanden mit dem Programm etwas erfreuen :]
Gruß Kai
Ps: Die Aktionszeit nach main muss auf die Motorengeschwindigkeit angepasst werden. Umso schneller, umso kleiner.