go_away

Author Topic: Summary: Weave, Modular Obstacle Avoider  (Read 1049 times)

0 Members and 1 Guest are viewing this topic.

Offline WaterPig MasterTopic starter

  • Full Member
  • ***
  • Posts: 62
  • Helpful? 3
  • Hurdy Gurdy playing at Raglan
Summary: Weave, Modular Obstacle Avoider
« on: June 07, 2011, 03:15:46 PM »
This post sums up the work outlined in a previous thread, http://www.societyofrobots.com/robotforum/index.php?topic=13689.0

Weave is my Modular, Expandable Obstacle Avoiding Robot. It currently consists of three circuit boards: Sensor Array, Brains and Motor Drivers. More detail about these boards are given in the previous thread, so I'll just outline them here:
The Sensor Array creates two selectable modulated IR beams at 38kHz, and a 38kHz IR sensor/demodulator.
The brains contain a PIC16F886 and supporting circuitry, as well as a mini breadboard for on-robot prototyping.
The motor driver board contains two MOSFET H-Bridges and a linear 5v regulator. It is built in dead-bug style and will be the first module to get replaced — in fact, split into motor control and power regulation, with low battery warning.

The program is written in ASM, and is attached for anyone who wants to have a look, copy, point out errors, etc. It essentially is fairly simple:

Constant Loop: Sends alternating pulses through each IR Led. After each set of two pulses, it checks to see if any signals were intercepted and sends motor control signals using a sort-of LUT.

Interrupt: The output of the IR detector is wired to RB0, the external interrupt pin. When a signal is intercepted, an ISR sees which IRED is currently emitting, and stores a result in that direction.

Demonstration video coming soon!

Thanks,
Barnaby

Code: [Select]
;
; Author: Barnaby Walters
; Created: 27th March 2011
;
; For PIC: 16F886
; Default Radix: Hex
;
; Description: Contains the IR enable/detect loop. Lights different LEDs to indicate which direction an object is seen in
; Runs at 4MHz
;
; Currently: The interrupt handler gets called, but not all of the logic works properly
;
; * * * * * * * * * * * * * * * *

list p=16f886
include p16f886.inc

; Set up 16F886 Config Registers
__CONFIG _CONFIG1, _MCLRE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_ON & _CP_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF
; For Config Bank 1: No MCLR Reset, no WDT, int. Osc no clkout, BOR On, Code protection, Low voltage protection, essentially, very few features.
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
; Set the BOR voltage to 4v, and we don't want any write protection

; Reserve Variables
tmr1 equ 20h ; Debug
tmr2 equ tmr1 + 1
temp equ tmr2 + 1
IRData equ temp + 1
w_temp equ IRData + 1
status_temp equ w_temp + 1

#define ls 0
#define rs 1
#define ll 2
#define rl 3 ; IRData structure: 7:4 = N/A; 3 = Right Lit; 2 = Left Lit; 1 = Right Signal; 0 = Left Signal

;firstAvailableRegister equ 0x20

org 0h
nop ; Allows ICD2 Debugger to work - not that I'm using that.
goto main ; Start main program
org 4h
goto isrRoutine

include "/Users/barnabywalters/Documents/Electronics/PIC Programs/16F886/Weave.inc" ; Port/Useful Definitions

; Interrupt Service Routine
isrRoutine
movwf w_temp
movf STATUS,w
movwf status_temp ; Save context
; Actual ISR
btfsc IRData,ll ; Is left emittor lit?
bsf IRData,ls ; If yes, store a signal received to the left

btfsc IRData,rl ; Is right emittor lit?
bsf IRData,rs ; If yes, store a signal received to the right

bsf portc,hb ; Light HB LED

bcf INTCON,INTF ; Clear interrupt flag

movf status_temp,w ; Restore context
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie ; Return

; * * * * * * * * * * * SUBROUTINES * * * * * * * * * * * * * * *

; Initalisation Routine
init
clrf PORTA
clrf PORTB
clrf PORTC
banksel OSCCON ; switches to bank 1. We need to be here to mess about with TRIS registers
movlw b'01100001' ;
movwf OSCCON ; Osc Config: 0 (un) , 110 (4Mhz) , 000 (Rd Only) , 1 (Use internal Clk)

movlw b'00000000' ;
movwf TRISA ; PORTA = all outputs. A0 = Right indicator A1 = Left Indicator
movlw b'00000001' ;
movwf TRISB ; PORTB 0:3 used. B1 = Right Enable B2 = Left Enable B0 = Sensor Input
movwf WPUB ; Weak pull-up on RB0
movlw b'00000000' ;
movwf TRISC ; PORTC = outputs. C3 = HB LED. Motors not used in this app (yet)
movlw b'1000'
movwf TRISE ; PORTE 3 (MCLR) = Input

banksel ANSELH
bcf ANSELH,4

banksel OPTION_REG

bcf OPTION_REG,NOT_RBPU ; Enable RB Pull Ups
bcf OPTION_REG,INTEDG ; Interrupt triggered on falling edge @ RB0

movlw b'10010000'
movwf INTCON ; Enable unmasked interrupts, Enable interrupt on RB0

banksel PORTA ; Switch to bank 0 so we can move on with the program
return ; Return to the program

; Delay Routines:

D30IRCycles ; Delays program flow for 30 cycles @ 38kHz — 'On' time for IREDs
movlw d'2'
movwf tmr2
movlw d'130' ; 30 IR Cycles = 780 instruction cycles. GOTO = 2 instruction cycles
movwf tmr1 ; This timer will have to be completely decremented two times for the full 780 cycles
D30IR_Delay
decfsz tmr1,F
goto D30IR_Delay ; Cycle 195 times
movwf tmr1
decfsz tmr2,F
goto D30IR_Delay ; Go back and cycle twice
return

D15IRCycles ; Delays program flow for 15 cycles @ 38kHz — 'Off' time for IREDs
movlw d'195' ; GOTO = 2 cycles. 2 * 195 = 390 instructions = 15 IR Cycles
movwf tmr1
D15IR_Delay
decfsz tmr1,f
goto D15IR_Delay
return

; Look-Up Tables:

motorControlLUT
movf IRData,w
andlw b'11' ; Mask off the bits we're interested in (1:0)
movwf temp ; Store offset

movlw high tableStart ; Get the high order part of address of tableStart
movwf PCLATH ;
movlw low tableStart ; Get low order address of tableStart
addwf temp, w ; Add the offset
btfsc STATUS, C ; Did it overflow?
incf PCLATH,f ; If yes, add one to PCLATH
movwf PCL ; Modify PCL and use the table…
tableStart
goto forwards
goto softbackright
goto softbackleft
goto hardleft

; * * * * * * * * * * Main Program * * * * * * * * * *

main
call init ; Set up ports, etc
; Program structure: Constantly alternate between IR LEDs. Each one on for 30 cycles, the off for 15 cycles as per datasheet

sensorPollLoop

bcf portc,hb ; Turn of HB LED

call D15IRCycles ;  — — — — — — — Hold LEDs off for the required time — — — — — — —

bsf PORTB,2 ; Turn on the left IRED (Robot perspective)
bsf IRData,ll ; Left IRED currently emitting.

call D30IRCycles ; Hold it on for a certain amount of time

bcf IRData,ll ; Left IRED not currently emitting
bcf PORTB,2 ; Turn off the left IRED

call D15IRCycles ;  — — — — — — — Hold LEDs off for the required time — — — — — — —

bsf PORTB,1 ; Turn on the right IRED (Robot perspective)
bsf IRData,rl ; Right IRED currently emitting

call D30IRCycles ; Hold it on for a certain amount of time

bcf IRData,rl ; Right IRED not currently emitting
bcf PORTB,1 ; Turn off the right IRED

;   — — — — — — — One complete sensor poll finished — — — — — — —
; Now: See what data we have. For the moment, that means copying the data in IRData 3:2 to PORTA 3:2. How convenient…

movf IRData,w ; Pop value of IRData into the W. Reg…
movwf PORTA ; …and copy it into PORTA. Sorted! That's indicated the direction the signal was found in.

bcf INTCON,GIE ; Disable interrupts while sorting out motor control

call motorControlLUT ; Get the motor control signal required from the LUT
movwf PORTC ; Move the signal into PORTC

bsf INTCON,GIE ; Enable interrupts again
clrf IRData ; Clear data from last sensor poll loop execution

goto sensorPollLoop

end

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 98
Re: Summary: Weave, Modular Obstacle Avoider
« Reply #1 on: June 07, 2011, 07:52:32 PM »
Thanks for posting to code. It looks rather nicely done with lots of comments. I saved myself a copying.

I also enjoyed your other thread about building the Weave. Neat little bot.

Just a suggestion:
I now like to put a list on the PIC pins with the function they are being used for in the code. I started doing that when I went to use code I wrote a year before and wanted to build a new board. Took me a couple of hours to go through the code to determine what each pin was used for.

Offline WaterPig MasterTopic starter

  • Full Member
  • ***
  • Posts: 62
  • Helpful? 3
  • Hurdy Gurdy playing at Raglan
Re: Summary: Weave, Modular Obstacle Avoider
« Reply #2 on: June 12, 2011, 04:26:53 AM »
Hi Waltr,

Quote
Thanks for posting to code. It looks rather nicely done with lots of comments. I saved myself a copying.

Thanks, I'm quite pleased with it! My commenting style comes from a couple of years of writing PHP scripts — I've developed a fairly lyrical, easy to understand style. I had to alter it a bit for ASM, but looking at some of microchip's appnotes helped. The most difficult thing was on the bit tests — I could never remember whether a 'true' signal was represented by a high or a low, and what happened when it was high or low, and how to structure the code that went after it!

Quote
Just a suggestion:
I now like to put a list on the PIC pins with the function they are being used for in the code. I started doing that when I went to use code I wrote a year before and wanted to build a new board. Took me a couple of hours to go through the code to determine what each pin was used for.

Yes, that's probably a very good idea. I am actually writing a sort of heavily commented software library specific to Weave, to help with future development. It also gives me some abstraction, e.g. I might decide to change which pins control the motors — by using generic motor control subroutines defined in a separate, #included document, I only have to alter them once. Here's the library as it stands currently – the other document will not compile without it:

Code: [Select]
LIST
; Weave Include File (Weave.inc)
; – Contains port/pin names to make programming Weave easier, as well as abstract subroutines for motor operations
NOLIST

portc equ PORTC
#define t1i 0 ; TMR1 Clock Input
#define m1e 1 ; Motor 1 = Left Motor
#define m2e 2 ; Motor 2 = Right Motor
#define hb 3 ; Heart Beat LED
#define m2f 4
#define m2b 5
#define m1f 6
#define m1b 7

portb equ PORTB
#define int 0 ; External Interrupt Pin

forwards
movlw b'01010110'
movwf portc
return

backwards
movlw b'10100110'
movwf portc
return

brake
movlw b'11110110'
movwf portc
return

coast
movlw b'11110000'
movwf portc
return

softleft
movlw b'00010100'
movwf portc
return

softright
movlw b'01000010'
movwf portc
return

softbackleft
movlw b'01100100'
movwf portc
return

softbackright
movlw b'10010010'
movwf portc
return

hardleft
movlw b'10010110'
movwf portc
return

hardright
movlw b'01100110'
movwf portc
return

LIST

I'm currently uploading a video to Youtube — only 128 mins left to go! I'll link to it here once it's up.

Thanks,
Barnaby

Offline WaterPig MasterTopic starter

  • Full Member
  • ***
  • Posts: 62
  • Helpful? 3
  • Hurdy Gurdy playing at Raglan
Re: Summary: Weave, Modular Obstacle Avoider
« Reply #3 on: June 12, 2011, 06:20:28 AM »
Here's the video:

[youtube]
Weave — Modular Robot Demonstration
[/youtube]

Thanks,
Barnaby

 


Get Your Ad Here

data_list