Project: Weave, Obstacle Avoiding Robot

Discussion in 'The Completed Projects Collection' started by Barnaby Walters, Jun 7, 2011.

  1. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
    This post sums up the work outlined in a previous thread, http://forum.allaboutcircuits.com/showthread.php?t=53089.

    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 ( (Unknown Language)):
    1. ;
    2. ;   Author: Barnaby Walters
    3. ;   Created: 27th March 2011
    4. ;  
    5. ;   For PIC: 16F886
    6. ;   Default Radix: Hex
    7. ;
    8. ;   Description:    Contains the IR enable/detect loop. Lights different LEDs to indicate which direction an object is seen in
    9. ;                   Runs at 4MHz   
    10. ;  
    11. ;   Currently:      The interrupt handler gets called, but not all of the logic works properly
    12. ;
    13. ; * * * * * * * * * * * * * * * *
    14.  
    15. list p=16f886
    16. include p16f886.inc
    17.    
    18.     ; Set up 16F886 Config Registers
    19.     __CONFIG    _CONFIG1, _MCLRE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_ON & _CP_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF
    20.                 ; For Config Bank 1: No MCLR Reset, no WDT, int. Osc no clkout, BOR On, Code protection, Low voltage protection — essectially, very few features.
    21.     __CONFIG    _CONFIG2, _BOR40V & _WRT_OFF
    22.                 ; Set the BOR voltage to 4v, and we don't want any write protection
    23.    
    24. ; Reserve Variables
    25. tmr1    equ 20h         ; Debug
    26. tmr2    equ tmr1 + 1
    27. temp    equ tmr2 + 1       
    28. IRData  equ temp + 1
    29. w_temp  equ IRData + 1
    30. status_temp equ w_temp + 1
    31.  
    32. #define     ls  0
    33. #define     rs  1
    34. #define     ll  2
    35. #define     rl  3   ; IRData structure: 7:4 = N/A; 3 = Right Lit; 2 = Left Lit; 1 = Right Signal; 0 = Left Signal
    36.  
    37. ;firstAvailableRegister equ 0x20
    38.  
    39.     org 0h
    40.     nop                     ; Allows ICD2 Debugger to work - not that I'm using that.
    41.     goto    main            ; Start main program
    42.     org 4h
    43.     goto    isrRoutine
    44.  
    45. include "/Users/barnabywalters/Documents/Electronics/PIC Programs/16F886/Weave.inc"     ; Port/Useful Definitions
    46.  
    47. ; Interrupt Service Routine
    48. isrRoutine
    49.     movwf   w_temp
    50.     movf    STATUS,w
    51.     movwf   status_temp     ; Save context
    52. ; Actual ISR
    53.     btfsc   IRData,ll       ; Is left emittor lit?
    54.     bsf     IRData,ls       ; If yes, store a signal received to the left
    55.    
    56.     btfsc   IRData,rl       ; Is right emittor lit?
    57.     bsf     IRData,rs       ; If yes, store a signal received to the right
    58.    
    59.     bsf     portc,hb        ; Light HB LED
    60.    
    61.     bcf     INTCON,INTF     ; Clear interrupt flag
    62.    
    63.     movf    status_temp,w   ; Restore context
    64.     movwf   STATUS
    65.     swapf   w_temp,f
    66.     swapf   w_temp,w
    67.     retfie                  ; Return
    68.    
    69. ; * * * * * * * * * * * SUBROUTINES * * * * * * * * * * * * * * *
    70.  
    71. ; Initalisation Routine
    72. init
    73.     clrf    PORTA
    74.     clrf    PORTB
    75.     clrf    PORTC
    76.     banksel OSCCON          ; switches to bank 1. We need to be here to mess about with TRIS registers
    77.     movlw   b'01100001'     ;
    78.     movwf   OSCCON          ; Osc Config: 0 (un) , 110 (4Mhz) , 000 (Rd Only) , 1 (Use internal Clk)
    79.    
    80.     movlw   b'00000000'     ;
    81.     movwf   TRISA           ; PORTA = all outputs. A0 = Right indicator A1 = Left Indicator
    82.     movlw   b'00000001'     ;
    83.     movwf   TRISB           ; PORTB 0:3 used. B1 = Right Enable B2 = Left Enable B0 = Sensor Input
    84.     movwf   WPUB            ; Weak pull-up on RB0
    85.     movlw   b'00000000'     ;
    86.     movwf   TRISC           ; PORTC = outputs. C3 = HB LED. Motors not used in this app (yet)
    87.     movlw   b'1000'
    88.     movwf   TRISE           ; PORTE 3 (MCLR) = Input
    89.    
    90.     banksel ANSELH
    91.     bcf     ANSELH,4
    92.    
    93.     banksel OPTION_REG
    94.    
    95.     bcf     OPTION_REG,NOT_RBPU ; Enable RB Pull Ups
    96.     bcf     OPTION_REG,INTEDG   ; Interrupt triggered on falling edge @ RB0
    97.    
    98.     movlw   b'10010000'
    99.     movwf   INTCON          ; Enable unmasked interrupts, Enable interrupt on RB0
    100.    
    101.     banksel PORTA       ; Switch to bank 0 so we can move on with the program
    102.     return                  ; Return to the program
    103.  
    104. ; Delay Routines:
    105.  
    106. D30IRCycles                 ; Delays program flow for 30 cycles @ 38kHz — 'On' time for IREDs
    107.     movlw   d'2'
    108.     movwf   tmr2
    109.     movlw   d'130'          ; 30 IR Cycles = 780 instruction cycles. GOTO = 2 instruction cycles
    110.     movwf   tmr1            ; This timer will have to be completely decremented two times for the full 780 cycles
    111. D30IR_Delay
    112.     decfsz  tmr1,F
    113.     goto    D30IR_Delay     ; Cycle 195 times
    114.     movwf   tmr1
    115.     decfsz  tmr2,F
    116.     goto    D30IR_Delay     ; Go back and cycle twice
    117.     return
    118.    
    119. D15IRCycles                 ; Delays program flow for 15 cycles @ 38kHz — 'Off' time for IREDs
    120.     movlw   d'195'          ; GOTO = 2 cycles. 2 * 195 = 390 instructions = 15 IR Cycles
    121.     movwf   tmr1
    122. D15IR_Delay
    123.     decfsz  tmr1,f
    124.     goto    D15IR_Delay
    125.     return 
    126.  
    127. ; Look-Up Tables:
    128.  
    129. motorControlLUT
    130.     movf    IRData,w
    131.     andlw   b'11'           ; Mask off the bits we're interested in (1:0)
    132.     movwf   temp            ; Store offset
    133.    
    134.     movlw   high tableStart ; Get the high order part of address of tableStart
    135.     movwf   PCLATH          ;
    136.     movlw   low tableStart  ; Get low order address of tableStart
    137.     addwf   temp, w         ; Add the offset
    138.     btfsc   STATUS, C       ; Did it overflow?
    139.     incf    PCLATH,f        ; If yes, add one to PCLATH
    140.     movwf   PCL             ; Modify PCL and use the table…
    141. tableStart 
    142.     goto    forwards
    143.     goto    softbackright
    144.     goto    softbackleft
    145.     goto    hardleft
    146.  
    147. ; * * * * * * * * * *   Main Program    * * * * * * * * * *
    148.  
    149. main
    150.     call    init            ; Set up ports, etc
    151.     ; Program structure: Constantly alternate between IR LEDs. Each one on for 30 cycles, the off for 15 cycles as per datasheet
    152.    
    153. sensorPollLoop
    154.  
    155.     bcf     portc,hb            ; Turn of HB LED
    156.    
    157.     call    D15IRCycles     ;  — — — — — — — Hold LEDs off for the required time — — — — — — —
    158.    
    159.     bsf     PORTB,2         ; Turn on the left IRED (Robot perspective)
    160.     bsf     IRData,ll       ; Left IRED currently emitting.
    161.    
    162.     call    D30IRCycles     ; Hold it on for a certain amount of time
    163.    
    164.     bcf     IRData,ll       ; Left IRED not currently emitting
    165.     bcf     PORTB,2         ; Turn off the left IRED
    166.    
    167.     call    D15IRCycles     ;  — — — — — — — Hold LEDs off for the required time — — — — — — —
    168.    
    169.     bsf     PORTB,1         ; Turn on the right IRED (Robot perspective)
    170.     bsf     IRData,rl       ; Right IRED currently emitting
    171.    
    172.     call    D30IRCycles     ; Hold it on for a certain amount of time
    173.    
    174.     bcf     IRData,rl       ; Right IRED not currently emitting
    175.     bcf     PORTB,1         ; Turn off the right IRED
    176.    
    177.     ;   — — — — — — — One complete sensor poll finished — — — — — — —
    178.     ; Now: See what data we have. For the moment, that means copying the data in IRData 3:2 to PORTA 3:2. How convenient…
    179.    
    180.     movf    IRData,w        ; Pop value of IRData into the W. Reg…
    181.     movwf   PORTA           ; …and copy it into PORTA. Sorted! That's indicated the direction the signal was found in.
    182.    
    183.     bcf     INTCON,GIE      ; Disable interrupts while sorting out motor control
    184.    
    185.     call    motorControlLUT ; Get the motor control signal required from the LUT
    186.     movwf   PORTC           ; Move the signal into PORTC
    187.    
    188.     bsf     INTCON,GIE      ; Enable interrupts again
    189.     clrf    IRData          ; Clear data from last sensor poll loop execution
    190.    
    191.     goto    sensorPollLoop
    192.    
    193.     end
     
  2. Wendy

    Moderator

    Mar 24, 2008
    20,766
    2,536
    This probably should have been in the previous thread. The completed projects section is meant for Completed Projects Forum, otherwise you need to use the Projects Forum.
     
  3. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    Why did you program the PIC in assembly? There are high-level languages you can use.
     
  4. Wendy

    Moderator

    Mar 24, 2008
    20,766
    2,536
    Why not, if you can? Assembly is a much more efficient language.
     
    PaulEE likes this.
  5. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
    Hello all,

    Yep, sorry about the multiple post. The previous thread was entitled "Motor driver + Power Regulator" — I tried to change it but couldn't. This thread has a more accurate title.

    As you know, whenever you program in higher languages it gets compiled into machine code. Anything that can be done more easily and efficiently in higher languages can still be done in asm. For my first project, I wanted to write in the lowest form I could feasibly do, to gain a better understanding of how the PIC is actually functioning.
    In the future I will be programming in higher level languages, but I see no reason to whilst I'm doing projects that can be written in asm.

    Thanks,
    Barnaby
     
  6. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    @Bill
    Have you tried to write the same program in assembly and in C? The first will have ten times the length of the second, let alone be much less comprehensive. With modern compilers you won't even notice any difference in running time.

    I personally find writing in assembly a waste of time in big projects, unless there's a good reason for it.
     
  7. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
    Hey, let's not turn this into a C vs ASM thread please! I wrote the code in ASM as I wanted to get some experience writing as close to the hardware as I could (all my other programming has been very high level: Javascript, PHP, Objective-C).

    On the comprehension note — I absolutely expect C to be far more comprehensive, when I do switch (that'll be when I start to do DSP work, or use things like USB/SD cards in my projects). To aid my own comprehension for Weave, I'm making myself a 'library' of sorts. The biggest problem I have had is remembering which bit of the motor control port does what, so I've made a whole set of subroutines that deal with changing motor direction. And, I make sure to comment everything extravagantly ;)

    Thanks,
    Barnaby
     
  8. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
  9. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    Nice video quality!
    On the topic now, I like the construction, seems very robust. The system seems to respond very fast and is able to maneuver in high speeds.

    Since you seem to have a problem with non reflective surfaces, two bumpers under the LEDs attached to two pushbuttons could help. A good practice I read once when using bumpers is to have them normally closing their switches (with a rubber band maybe) and on contact releasing it. That way you protect the switch from absorbing the collision force.
     
  10. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Barnaby,

    From your youtube video I perceive that your bot speed is a bit high. You may want to consider implementing a PWM scheme to give you a bit of speed control. Then you could throttle down as a function of the feedback from your collision avoidance sensors.

    hgmjr
     
  11. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    If you can sense analog in some way with your sensors, then you could slow down in the slightest sign of wall and then examine the new data more carefully.
     
  12. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    And if your sensor is not analog, you can, on detection, simply shift down to a slower speed commensurate with the distance sensitivity of your digital sensor. That way you would have some time to manuever your bot in a new direction that does not trigger your collision avoidance sensor.

    hgmjr
     
  13. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
    Hi there,

    Thanks, I'm pleased with how responsive the system is. Unfortunately, the fast speed changing has broken a tooth off one of the internal gears, which caused the rather horrible noises!

    That's a very interesting idea — I can't quite think how the manual NC switches would work? If they're held closed, I suppose I would have to build some extra mechanism that forces them open again. I'll have a play around with some microswitches and see if I can come up with something.

    That is a very good idea indeed — in fact, I purposefully connected the PIC's two PWM out pins to the enable pins of my motor drivers. Once I've figured out how to get them running and integrated their control into my library, I'll replace the faulty motor and go from there.

    Thanks a lot,
    Barnaby
     
  14. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    Check out these sketches:
    In the first, a rubber band holds a lever on the switch. On the other side of the lever, a bumper is situated.

    In the second picture a rubber band (not depicted) holds the bumper on the switch. The bumper is fitted in a linear guide.

    I think that the first solution is easier to implement.
     
  15. Barnaby Walters

    Thread Starter Member

    Mar 2, 2011
    103
    4
    Thanks for those sketches, that cleared up what you meant — I didn't think to mount the touch sensors in reverse.

    I've managed to give Weave PWM speed control, and build that into my 'software library' — so it runs at a much more forgiving speed now. I'll replace the broken motor at some point.

    Thanks,
    Barnaby
     
  16. Prinz

    New Member

    Nov 16, 2014
    16
    0
    Hello there, would like to have a look @ d complete asm code and d circuit diagrams. Nice job!
     
Loading...