The first piece of functionality I wanted to get working was the white line edge detection. Previously I had used photoresistors and a LM393 comparator chip. This time I wanted to try using LED Infra-red (IR) emitters and IR phototransitors detectors. This was to reduce the impact of environmental light on the edge detection sensors. Rather than a separate comparator chip I would use the comparator module in the pic16f628. I had some nice 3mm LED IR emitter and 3mm phototransistor in a dual plastic housing that I had gotten from an old robot kit I had purchased purely for parts. Not knowing the specs of either part I used a 1K resistor on the IR emitter. For the phototransistor I wasn't sure the part was actually a phototransister. As suggested in some example circuits I was using a 50K resistor in series. There was very little response (ie voltage change) to changes in light level, less than 0.2 volts. Trying a few different parts the result was the same. Finally I guessed this was a IR only phototransistor. Putting my finger to cover the IR LED and phototransistor (ie bouncing the IR led output back to the transistor) the transistor turned on - success! The voltage range of the test point on the photo transistor from off to on was approx 4.8V (off) to 0.4V (on).
Over on the microcontroller side of things I was using the comparator module as two common reference comparators (setting CM<2:0> = 011). For the reference voltage I used a 10K pot to divide the 5V input and thus be able to tune the trigger point of the comparator. I setup an ISR to trigger every time the comparator tripped. The ISR incremented a counter and the main loop displayed this count in binary on 4 leds (the counter rolled over at 10). Initially I was getting some twitchy responses with double counts, etc. I added a 50ms delay in the ISR on the reading of the sensor and this was eliminated. In addition to the counter being displayed I also toggled an led on port RA3 depending of the comparator output. Code and comments below. 2:0>
include "P16F628A.INC" ;include the defaults for the chip
list p=16f628a
__config (_CP_OFF & _CPD_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF)
; ra0 / ra1 = inputs V-
; ra2 common V+
; ra3 output to led
; variables
cblock 0x20
OUTCOUNT ; interrupt code counter
count ;used in delay routine
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
endc
#define W_TEMP 0x70 ; common memory area across all banks
#define STATUS_TEMP 0x71 ; temp vars for ISR
org 0
goto init ; skip ISR code
;
; ISR code
;
org 4
movwf W_TEMP ; Save W & STATUS, etc
swapf STATUS, W
bcf STATUS, RP0
movwf STATUS_TEMP ; end ISR save bits
incf OUTCOUNT,1 ; COUNT +1, then check and reset count if needed
movlw 0x0A ; put 10 in W
subwf OUTCOUNT,0 ; subtract 10 from count to see if count > 10
btfsc STATUS,0 ; check carry flag, skip if clear
clrf OUTCOUNT ; reset count to 0
call Delay50 ; wait 50ms for switch to get stable
bcf STATUS,RP0 ; select bank 0
btfsc CMCON,C2OUT ; if c2out is 1
bsf PORTA,3 ; turn on ra3 led
btfss CMCON,C2OUT ; if c2out is 0
bcf PORTA,3 ; turn off ra3 led
bcf PIR1, CMIF ; clear pending interrupts
swapf STATUS_TEMP, W ; restore W & STATUS
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
retfie ; end ISR end bits
init
movlw 0x03 ; init comparator mode
movwf CMCON ; CM<2:0> = 011
bsf STATUS,RP0 ; select bank 1
movlw 0x07 ; init data direction
movwf TRISA ; ra2/0 as inputs, ra 4/3 as output
movlw 0x00
movwf TRISB ; all port b as output - for counter
bcf STATUS,RP0 ; select bank 0
movf CMCON,F ; read cmcon to end change condition wrt interrupt setup
bcf PIR1, CMIF ; clear pending interrupts
bsf STATUS, RP0 ; select bank 1
bsf PIE1, CMIE ; enable comparator interrupts
bcf STATUS,RP0 ; select bank 0 - determine initial state of comp output
clrf PORTB ; clear portb
btfsc CMCON,C2OUT ; if c2out is 1
bsf PORTA,3 ; turn on ra3 led
btfss CMCON,C2OUT ; if c2out is 0
bcf PORTA,3 ; turn off ra3 led - finished initial state
clrf OUTCOUNT ; init COUNT at 0
bsf INTCON, PEIE ; enable peripheral interrupts
bsf INTCON, GIE ; enable global interrupts
main
movf OUTCOUNT,0 ; COUNT to W
movwf PORTB ; display count in hex on leds
goto main
;Delay routines
Long_Delay
movlw d'50' ;delay 5 seconds
call Delay100W
return
Delay100W movwf count ;delay W x 100mS
d2 call Delay100 ;maximum delay 25.5 seconds
decfsz count ,f
goto d2
return
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay10 movlw d'10' ;delay 10mS
goto d0
Delay1 movlw d'1' ;delay 1mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
return
;end of Delay routines
end
2:0>
Tuesday, November 20, 2012
Wednesday, November 14, 2012
Pennybot restart
Knowing as always time is short for robot building I wanted to break down the tasks to build pennybot into smaller achievable tasks that would take 1-2 weekends (I only get a few hours spare per weekend) to complete but would aid in the final design. Putting the chassis aside for now as it was mainly complete I concentrated on the microcontroller. I hadn't touched a microcontroller for 4 years so it was pretty much relearning from scratch.
The first thing to learn was MPLAB X. I could have stuck with MPLAB 8 but it was time to move on. I also had invested in a PicKit 3 as a serial port wasn't an option on any of the laptops I wanted to use for development. I used a simple "blink the leds" assembly program as the trial experiment.
I soldered up a little PicKit 3 breadboard header and cable, plugged everything in a hoped. I fell down the usual holes along the way (power from board or from pickit for example) and got burnt by having to be strict on the formatting in the MPLAB editor. Previously the text files could be pretty sloppy and still work with mpasm. However the formatting rules made me do things the proper way, which saved me time when I came back after a week or so to review some code.
I also jumped pic models to a pic16f628. That's right, I upgraded to a ~10 year old pic. One day I'll join the real world. Not having to have an external timing crystal (and getting two pins back) and the comparator module onboard were a big plus. Also it was a very simple cutover from the pic16f84. Finally I could buy (and did) 5 pic16f628 chips for $10 off ebay. This means I have enough for this project and a few others so any investment in time in learning to program this model would pay off. This did mean that C was pretty much out of the picture. However I liked learning how to do things in assembly. I enjoy having that real low level knowledge of what is going on even if the setup on some features (eg pwm) can get a bit messy.
I started development on a Windows 7 desktop. After awhile I moved onto a linux laptop. The only issue I had was the include statement. In Linux (which is case sensitive) the include file is in capitals. Everything else was fine. So with MPLABX and the PicKit 3 sorted out it was time to do some real programs.
The first thing to learn was MPLAB X. I could have stuck with MPLAB 8 but it was time to move on. I also had invested in a PicKit 3 as a serial port wasn't an option on any of the laptops I wanted to use for development. I used a simple "blink the leds" assembly program as the trial experiment.
I soldered up a little PicKit 3 breadboard header and cable, plugged everything in a hoped. I fell down the usual holes along the way (power from board or from pickit for example) and got burnt by having to be strict on the formatting in the MPLAB editor. Previously the text files could be pretty sloppy and still work with mpasm. However the formatting rules made me do things the proper way, which saved me time when I came back after a week or so to review some code.
I also jumped pic models to a pic16f628. That's right, I upgraded to a ~10 year old pic. One day I'll join the real world. Not having to have an external timing crystal (and getting two pins back) and the comparator module onboard were a big plus. Also it was a very simple cutover from the pic16f84. Finally I could buy (and did) 5 pic16f628 chips for $10 off ebay. This means I have enough for this project and a few others so any investment in time in learning to program this model would pay off. This did mean that C was pretty much out of the picture. However I liked learning how to do things in assembly. I enjoy having that real low level knowledge of what is going on even if the setup on some features (eg pwm) can get a bit messy.
I started development on a Windows 7 desktop. After awhile I moved onto a linux laptop. The only issue I had was the include statement. In Linux (which is case sensitive) the include file is in capitals. Everything else was fine. So with MPLABX and the PicKit 3 sorted out it was time to do some real programs.
Subscribe to:
Posts (Atom)