please dont rip this site

October 2003 MassMind Newsletter

Yes, I know I skipped September, it is still in the works but having digital camera issues. I can't seem to get good closeups. Yet. I will.

Ranging

This issue is all about finding the distance from one point to another. Several methods are discussed:

Laser

I've had the joy of working on a really interesting project with a real 3D CAD expert. Mostly I helped with some math and spewed out ideas, but the simplicity and the results are astounding. The project is a laser 3D scanner built for much less than any commercial unit.

The basic idea is probably best shown by these pictures from http://www.cyberg8t.com/pendragn/actlite.htm (which is no longer, but has been cached)

- =

And then the position of the laser line is used to calculate the depth of the object.

Hardware

Because the Laser and Motor have to be timed and driven together both use the parallel port data lines. Only 3 of the 8 data lines are needed:

Also the software interface for the parallel port is easy to use with Jan Axelsons Inpout32.dll (available at www.lvr.com).

Software

Routines are:

And the result is a "point cloud" that describes your subject. Additional software will be added to process the points into lines or faces, smooth and reduce the complexity of the image.

Now, this process can, and has to some degree, been done with a microcontroller. Here are the potential problems and how they are avoided:

  1. Memory for two pictures and workspace: By processing the data as it comes rather than after, and using a much faster hardware setup, most memory requirements are removed. First, process each scan line separately while turning the laser on and off. If you scan with a camera, use color and polarization filters to ensure that the camera only sees the laser. Verify that the spot you picked up on the first scan is the laser by checking to see if it is gone in the next scan. If you use mechanical scanning (great for robots since there is generally a shaft turning somewhere that can have a mirror added to it) then a PLL or other signal filter can be combined with a modulated laser to reject noise. On each scan line, record only the position of the laser. This is the time from a horizontal sync pulse or start of scan to the detection of the laser light. At this point we are only collecting one data point per scan line. Now, process that scan line, looking for anything interesting and discard it if it has no value. For example, you might check to see if the scan line is showing an object to the left or right and at what distance.
  2. High precision, floating point trigonometry: By reducing the resolution of the scan and lowering our expectations of the outcome, we can bring the math within the capabilities of the microcontroller. And actually, most can do really extensive math given some clever programming.

Sonar

This simple sonar ranging device eliminates a lot of the usual discrete components by executing complex functions in the software of the microcontroller. Several times per second, the it generates a few cycles (about 8) of a 40 kHz square wave on an output that directly drives the transmitter element. It then begins counting "ticks" (fast program loops) which will accumulate until it either detects a response from the 567 tone decoder or a maximum period has expired. Immediately following the 40 kHz burst, the output of the 567 chip is ignored for a short time. This is because the 567 will detect the burst, and the transmitter element will continue to ring or resonate for a short time. The 567 tone decoder chip is a phase locked loop designed to detect when the input frequency is within a certain pass-band. The passband or detection range is determined by the values of the discrete components connected to it. This makes it very easy to use. The 567 has been around for many years, it's cheap, and very useful. Ultrasonic sound waves emitted from the transmitter element travel through the air, hit an object and bounce back to the unit where the receiver element detects them. The output of the receiver is amplified and sent into the 567 chip. The 567 chip drives its output low when it detects the reflected 40 kHz signal. It will react to all reflections so it may produce more than one output pulse, but this version of the code will only register the first one. Several readings per second are averaged and a value proportional to the detected distance is sent out via a serial line. The pictures show this connected to a serial LCD. Be aware that the value is for demonstration purposes only and not been scaled to any actual units of length like feet or centimeters. You would have to add your own code or lookup table to display specific units of measure.

The program is designed to run in different modes. The dip-switches are used to select the mode of operation, such as "normal pulse o/p", "continuous tone o/p" with is used for tuning the 567 for best detection, "binary serial o/p", "ascii serial o/p", etc.

The processor has a "serin" pin which can be used as a control input from another processor. Through this pin, it could receive instructions but this block of code is unfinished and should be tailored to your application. If selected, nothing will happen, however, it would be a simple matter to add code that would allow the input to act as a "logic enable" or to accept various serial commands. Alternatively, the serin pin could be programmed as some sort of o/p.

The "serout" pin is used to output the range test results. In ascii o/p mode, the results are sent with the LCD-Backpack's value for the "I" instruction (#254) value first that instructs a backpack-LCD or serial-LCD to enter "instruction mode". The next byte sent is the address of line2 (#192) which sets the cursor of the LCD to the start of line 2. Then three ascii digits are sent, MSD first, center digit, LSD last. If the result is a BCD number less than 3 digits, spaces are sent to clear those digits from the display. In binary o/p mode, the straight binary test result is sent.

The transmitter is a 40kHz transducer from Digikey, part# P9895-ND.

The receiver is a 40kHz transducer from Digikey, part# P9890-ND.

The PCB design uses several surface mount components. It saves a lot of hole drilling and lead bending and clipping. Also, assemblies end up smaller, better looking and easier to modify or service. Soldering surface mount (especially the larger variants) is ease

;Filename:      SONAR1.SRC
;Created:       MAY.4.97
;Last Modified: MAY.4.97
;Language:      PARALLAX assembler
;PCBname:       SONAR1.JOB
;Schematic:     SONAR1.SCH
;Processor:     PIC16C71
;Written By:    William J. Boucher
;
;DESCRIPTION:
;
;This program is designed to run the mini robot sonar1 module as a
;rangefinder sensor.  It generates a 40kHz pulse, the measures the time
;until an echo is detected.  The dip-switches are used to select different
;modes of operate, such as "normal pulse o/p", "continuous tone o/p"
;for tuning purposes, "binary serial o/p", "ascii serial o/p", etc.
;This sensor is intended for use in miniature robot applications.
;The transmitter is a 40kHz transducer from Digikey, part# P9895-ND.
;The receiver is a 40kHz transducer from Digikey, part# P9890-ND.
;The processor has a "serin" pin which can be used as a control input from
;another processor.  Through this pin, it could receive instructions.
;Also, the serin pin could be programmed as some sort of o/p.
;The "serout" pin is used to output the range test results.
;In ascii o/p mode, the results are sent with the "I" (254) value first
;which instructs a Stamp-based LCD to enter "instruction mode".
;The next byte sent is the address of line2 "192" which sets the cursor
;of the LCD to the start of line 2.  Then three ascii digits are sent,
;MSD first, center digit, LSD last.  If the result is a BCD number less
;than 3 digits, spaces are sent to clear those digits from the display.
;In binary o/p mode, the straight binary test result is sent.

;The serial data is programmed to have a bit width of 0.104ms (9600baud).
;The data words are sent with:
;- a single high start bit
;- inverted data, LSB first
;- a single low stop bit.
;
;TASKLIST 1/ Initialize registers & variable names & inputs/outputs.
;         2/ Read dipswitches to determine mode.
;         3/ Enter mode.
;         4/ Calculate/update variables as required.
;         5/ Send 8 bit result data in format selected.
;         6/ Repeat at step 2.
;
;----------------------------------------------------------------------------
                DEVICE  PIC16C71,HS_OSC,WDT_OFF,PWRT_ON,PROTECT_OFF
                ID      'SOR1' ;FIRST 2 & LAST 2 CHARS OF FILENAME
;----------------------------------------------------------------------------
;EQUATES:
;
LINE1           =       128             ;LCD LINE1 START ADDRESS
LINE2           =       192             ;LCD LINE2 START ADDRESS
I               =       254             ;LCD INSTRUCTION COMMAND
CLRLCD          =       1               ;LCD CLEAR INSTRUCTION

XMIT1           =       5.2             ;PIN 1 OF TRANSMITTER
XMIT2           =       5.3             ;PIN 2 OF TRANSMITTER

SERIN           =       6.0             ;SERIAL INPUT PIN
SEROUT          =       6.1             ;SERIAL O/P PIN
DETECT          =       6.2             ;INPUT FROM OUTPUT OF LM567 TONE DETECTOR

DIPSW1          =       6.4             ;DIP SWITCH 1
DIPSW2          =       6.5             ;DIP SWITCH 2
DIPSW3          =       6.6             ;DIP SWITCH 3
DIPSW4          =       6.7             ;DIP SWITCH 4
TIMER           =       1               ;TMR0 ON BOARD TIMER
TIMERVAL40K     =       228             ;VALUE CONTROLS LOOP FREQ TO 40kHz
                                        ;226=38.5kHz
                                        ;224=35.2kHz
                                        ;31=5.45kHz
TIMERFLAG       =       11.2            ;TIMER0 OVERFLOW FLAG
XMITA           =       00000100B
XMITB           =       00001000B
XMITLOW         =       0
XMITENABLE      =       11110011B
XMITDISABLE     =       11111111B

;----------------------------------------------------------------------------
;VARIABLE STORAGE
                ORG     0CH     ;SET TO START OF GENERAL PURPOSE RAM
DELAYCOUNTER1   DS      1
DELAYCOUNTER2   DS      1
DELAYCOUNTER3   DS      1
SERINDATA       DS      1
SEROUTDATA      DS      1
BIN             DS      1 
R1              DS      1
R2              DS      1 
COUNTER1        DS      1
COUNTER2        DS      1
BITCOUNTER      DS      1
TEMP            DS      1
TABLEENTRY      DS      1
TABLEVALUE      DS      1
RANGERESULT     DS      1
RANGEAVERAGE    DS      1
RANGEDATAH      DS      1
RANGEDATAL      DS      1
RESULTCOUNTER   DS      1
STATS           DS      1
;----------------------------------------------------------------------------
                ORG     0
;INITIALIZE VARIABLES
INITIALIZE      CLR     8               ;TURN OFF A2D CONVERTER & SET CLKRATE
                                        ;& SET TO CHANNEL 0 <3:0>
                SETB    RP0             ;SET RP0 TO UPPER REGISTER BANK
                MOV     1,#00000000B    ;SET OPTION REG. RB-PULL-UPS ON
                                        ; & TIMER PRESCALER TO 1:2
                                        ; & ASSIGN PRESCALER TO TIMER
                MOV     8,#3            ;SET PORT1 INPUTS AS DIGITAL
               ;MOV     RA,#XMITDISABLE ;SET PORT RA DATA DIRECTIONS
                MOV     RA,#XMITENABLE  ;SET PORT RA DATA DIRECTIONS
                MOV     RB,#11110101B   ;SET PORT RB DATA DIRECTIONS
                CLRB    RP0             ;SET RP0 TO LOWER REGISTER BANK
                CLRB    SEROUT
                CLR     STATS
                MOV     RESULTCOUNTER,#8
;----------------------------------------------------------------------------
MAINLOOP        MOV     TEMP,RB
                NOT     TEMP
                SWAP    TEMP
                AND     TEMP,#00001111B
                MOV     W,TEMP
                JMP     PC+W
                JMP     MODE0
                JMP     MODE1
                JMP     MODE2
                JMP     MODE3
                JMP     MODE4
                JMP     MODE5
                JMP     MODE6
                JMP     MODE7
                JMP     MODE8
                JMP     MODE9
                JMP     MODE10
                JMP     MODE11
                JMP     MODE12
                JMP     MODE13
                JMP     MODE14
;----------------------------------------------------------------------------
;MODE15:
MODE15          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE14:
MODE14          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE13:
MODE13          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE12:
MODE12          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE11:
MODE11          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE10:
MODE10          JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE9:
MODE9           JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE8:
MODE8           JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE7:
MODE7           JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE6:USE SERIN COMMANDS TO CONTROL MODULE
MODE6           CALL    RECEIVE
                CJE     SERINDATA,#'1',MODE6A
                JMP     MAINLOOP
MODE6A          CALL    RANGETEST
                MOV     SEROUTDATA,RANGERESULT
                CALL    TRANSMIT
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE5:SERIN IS LOGIC ENABLE FOR MODE4
MODE5           JB      SERIN,MODE4
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE4:GENERATE CONTIUOUS 40kHz TRANSMISSION FOR CALIBRATION PURPOSES
MODE4          ;CALL    XMITON          ;ENABLE TRANSMITTER DRIVER PINS
                JNB     TIMERFLAG,$     ;WAIT HERE TIL TIMER RUNS OUT
                                        ;TIMERVALUE SET TO GIVE 40kHz
               ;NOP                     ;FREQUENCY FINE TUNE
                MOV     TIMER,#TIMERVAL40K      ;LOAD TIMER0
                CLRB    TIMERFLAG               ;CLEAR TIMER0 OVERFLOW FLAG
                JB      XMIT1,MODE4A            ;TEST PRESENT O/P STATE
                NOP
                MOV     RA,#XMITA               ;FLIP O/P STATE
                JMP     MAINLOOP
MODE4A          MOV     RA,#XMITB               ;FLIP O/P STATE
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE3:SERIN IS LOGIC ENABLE FOR MODE1
MODE3           JB      SERIN,MODE1
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE2:SERIN IS LOGIC ENABLE FOR MODE0
MODE2           JB      SERIN,MODE0
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE1:CONTINUOUS RANGING - SENDS DATA IN BINARY VIA SEROUT AT 9600 BAUD
MODE1           CALL    RANGETEST
                MOV     SEROUTDATA,RANGERESULT
                CALL    TRANSMIT
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;MODE0:CONTINUOUS RANGING - SENDS DATA TO STAMP-LCD VIA SEROUT AT 9600 BAUD
MODE0           JB      STATS.0,MODE0RUN
                SETB    STATS.0               ;INDICATE LCD INTIALIZED
                CALL    POWERUPDELAY          ;WAIT FOR LCD TO INITIALIZE
                MOV     SEROUTDATA,#I         ;LOAD "INSTRUCTION" VALUE
                CALL    TRANSMIT
                MOV     SEROUTDATA,#CLRLCD
                CALL    TRANSMIT
                CALL    DELAY5MS

                ;WRITE TITLE ON LCD LINE1
                MOV     SEROUTDATA,#I         ;LOAD "INSTRUCTION" VALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                MOV     SEROUTDATA,#LINE1     ;LOAD ADDRESS FOR CURSUR
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                MOV     COUNTER2,#10          ;LOAD NUMBER OF TABLE ENTRIES TO READ
                MOV     TABLEENTRY,#10        ;LOAD TABLE ADDRESS TO READ
                CALL    MODE0A                ;PRINT LINE ON DISPLAY

                ;WRITE TITLE ON LCD LINE2
                MOV     SEROUTDATA,#I         ;LOAD "INSTRUCTION" VALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                MOV     SEROUTDATA,#LINE2     ;LOAD ADDRESS FOR CURSUR
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                MOV     COUNTER2,#10          ;LOAD NUMBER OF TABLE ENTRIES TO READ
                MOV     TABLEENTRY,#20        ;LOAD TABLE ADDRESS TO READ
                CALL    MODE0A                ;PRINT LINE ON DISPLAY
                JMP     MODE0RUN

MODE0A          CALL    READTABLE             ;GET TABLE VALUE
                MOV     SEROUTDATA,TABLEVALUE ;LOAD VALUE TO SEND
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                INC     TABLEENTRY
                DJNZ    COUNTER2,MODE0A
                RET

MODE0RUN        CALL    RANGETEST             ;RUN DISTANCE MEASUREMENT TEST
                CALL    RANGEAVER
                MOV     BIN,RANGEAVERAGE      ;LOAD RANGE TEST RESULT TO CONVERT
                CALL    BIN2BCD               ;CONVERT BINARY RESULT TO BCD
                MOV     SEROUTDATA,#I         ;LOAD "INSTRUCTION" VALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                MOV     SEROUTDATA,#LINE2+7   ;LOAD ADDRESS FOR CURSUR
                CALL    TRANSMIT              ;SEND VALUE TO LCD

                MOV     TABLEENTRY,R1         ;LOAD 1'st (MSD) DIGIT TO SEND
                AND     TABLEENTRY,#00001111B
                CALL    READTABLE             ;CONVERT NUMBER TO ASCII
                MOV     SEROUTDATA,TABLEVALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD

                MOV     TABLEENTRY,R2         ;LOAD 2'nd DIGIT TO SEND
                SWAP    TABLEENTRY
                AND     TABLEENTRY,#00001111B
                CALL    READTABLE
                MOV     SEROUTDATA,TABLEVALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD

                MOV     TABLEENTRY,R2         ;LOAD 3'rd (LSD) TO SEND
                AND     TABLEENTRY,#00001111B
                CALL    READTABLE
                MOV     SEROUTDATA,TABLEVALUE
                CALL    TRANSMIT              ;SEND VALUE TO LCD
                JMP     MAINLOOP
;----------------------------------------------------------------------------
;TRANSMIT: SENDS AN 8-BIT BYTE SERIALLY OUT THROUGH THE SEROUT PIN
TRANSMIT       ;CLC                     ;CLEAR CARRY
STARTBIT        SETB    SEROUT          ;BEGIN THE START BIT
                CALL    BITDELAY        ;DELAY PRODUCES BIT WIDTH FOR 9600 BAUD
SENDDATA        MOV     BITCOUNTER,#8  ;INITIALIZE THE SERIAL DATA BIT COUNTER
READDATA        RR      SEROUTDATA      ;READ STATE OF BIT AND SEND INVERTED
                JC      SENDA0          ;IF DATA BIT=1, SEND A 0
SENDA1          SETB    SEROUT          ;SEND A 1
                JMP     WAITABIT        ;GO TO WAITABIT
SENDA0          CLRB    SEROUT          ;SEND A 0
WAITABIT        CALL    BITDELAY        ;
                DJNZ    BITCOUNTER,READDATA ;WERE ALL BITS SENT YET?
STOPBIT         CLRB    SEROUT          ;CLEAR SEROUT TO BEGIN STOP BIT
                CALL    BITDELAY        ;
               ;CLRB    SEROUT          ;END STOP BIT
               ;RET
;----------------------------------------------------------------------------
;WORD DELAY; 20 X 1 BIT = 2.083ms @ 20MHz
WORDDELAY       MOV     DELAYCOUNTER2,#14
WDA             MOV     DELAYCOUNTER1,#255
                DJNZ    DELAYCOUNTER1,$
                DJNZ    DELAYCOUNTER2,WDA
                RET
;----------------------------------------------------------------------------
;DELAY5MS: 5ms DELAY, USED AFTER SOME LCD INSTRUCTIONS
DELAY5MS        MOV     DELAYCOUNTER2,#33
D5MSA           MOV     DELAYCOUNTER1,#255
                DJNZ    DELAYCOUNTER1,$
                DJNZ    DELAYCOUNTER2,D5MSA
                RET
;----------------------------------------------------------------------------
;DELAY100MS: 100ms DELAY, USED AFTER SOME LCD INSTRUCTIONS
DELAY100MS      MOV     DELAYCOUNTER3,#3
D100MSA         MOV     DELAYCOUNTER2,#217
D100MSB         MOV     DELAYCOUNTER1,#255
                DJNZ    DELAYCOUNTER1,$
                DJNZ    DELAYCOUNTER2,D100MSB
                DJNZ    DELAYCOUNTER3,D100MSA
                RET
;----------------------------------------------------------------------------
;RECEIVE:GETS A BYTE FROM SERIN AT 9600 BAUD - NOT DONE YET
RECEIVE         CLR     SERINDATA
                RET
;----------------------------------------------------------------------------
;NOTE: BIT DELAYS FOLLOWING PRODUCE 9600 BAUD RATE w/20MHz XTAL
;;---------------------------------------------------------------------------
;TIME DELAY; 1 BIT = 104.166us @ 20MHz
BITDELAY        MOV     DELAYCOUNTER1,#172
                DJNZ    DELAYCOUNTER1,$
                RET
;----------------------------------------------------------------------------
;;TIME DELAY; 1 BIT = 0.104ms @ 20MHz
;HALFBITDELAY    MOV     DELAYCOUNTER1,#86
;                DJNZ    DELAYCOUNTER1,$
;                DJNZ    DELAYCOUNTER1,HBDELAYA
;                RET
;----------------------------------------------------------------------------
;POWERUPDELAY; 1s @ 20MHz
POWERUPDELAY    MOV     DELAYCOUNTER3,#250
PUDA            MOV     DELAYCOUNTER2,#255
PUDB            MOV     DELAYCOUNTER1,#26
                DJNZ    DELAYCOUNTER1,$
                DJNZ    DELAYCOUNTER2,PUDB
                DJNZ    DELAYCOUNTER3,PUDA
                RET
;----------------------------------------------------------------------------
;Binary number to be converted starts out stored like this:
;
; binary low byte
;   BIN
; ########
;
;BCD result ends up stored like this:
;
;R0 = digit5 (MSD) in lower nibble:digit4
;                     R1    :    R2 LSD
;                      dig3 : dig2 dig1
;                 0000 #### : #### ####

BIN2BCD         CLC                             ; clear the carry bit
		MOV     COUNTER1,#8
		CLR     R1
		CLR     R2
LOOP8           RL      BIN
		RL      R2
		RL      R1
		DJNZ    COUNTER1,ADJDEC
		RET

ADJDEC          MOV     FSR,#R2
		CALL    ADJBCD
		MOV     FSR,#R1
		CALL    ADJBCD
		JMP     LOOP8 

ADJBCD          MOV     W,#3
		ADD     W,INDIRECT
		MOV     TEMP,W
		SNB     TEMP.3          ; test if result > 7
		MOV     INDIRECT,W
		MOV     W,#48           ;OR #30H
		ADD     W,INDIRECT
		MOV     TEMP,W
		SNB     TEMP.7          ; test if result > 7
		MOV     INDIRECT,W      ; save as MSD
                RET
;----------------------------------------------------------------------------
RANGETEST       MOV     TIMER,#TIMERVAL40K      ;LOAD TIMER0
                CLRB    TIMERFLAG               ;CLEAR TIMER0 OVERFLOW FLAG
                MOV     COUNTER1,#10    ;NUMBER OF HALFCYCLES TO XMIT
               ;CALL    XMITON          ;ENABLE TRANSMITTER DRIVER PINS

RTA             JNB     TIMERFLAG,$     ;WAIT HERE TIL TIMER RUNS OUT
                                        ;TIMERVALUE SET TO GIVE 40kHz
                MOV     TIMER,#TIMERVAL40K      ;LOAD TIMER0
                CLRB    TIMERFLAG               ;CLEAR TIMER0 OVERFLOW FLAG
                JB      XMIT1,RTB       ;TEST PRESENT O/P STATE
                NOP
                MOV     RA,#XMITA       ;FLIP O/P STATE
                JMP     RTC
RTB             MOV     RA,#XMITB       ;FLIP O/P STATE
RTC             DJNZ    COUNTER1,RTA    ;CYCLE AGAIN?
                MOV     RA,#XMITLOW     ;PULL DOWN BOTH SIDES OF TRANSMITTER
               ;CALL    MINRETURN       ;RUN SHORT DELAY
               ;CALL    XMITOFF         ;DISABLE TRANSMITTER DRIVER PINS        
               ;CALL    MINRETURN       ;RUN SHORT DELAY
                CALL    WORDDELAY ;MAYBE REMOVE THIS LATER
;                CLR     TEMP            
;RTG             JB      DETECT,RTF      ;TEST FOR START OF VALID RANGE
;                CALL    RANGETICK
;                DJNZ    TEMP,RTG
RTF             CLR     TEMP            ;CLEAR RANGING ACCUMULATOR
RTD             JNB     DETECT,SEERETURN;SEE A RETURN YET?
                CALL    RANGETICK       ;RUN SHORT DELAY BETWEEN RANGE INCREMENTS
                ADD     TEMP,#1
                JNZ     RTD             ;CHECK FOR OVER-RANGE
                JNC     SEERETURN       ;CHECK FOR MAX-RANGE
                DEC     TEMP            ;SET TO MAX RANGE
SEERETURN       MOV     RANGERESULT,TEMP;SAVE TEST RESULT
                MOV     COUNTER1,TEMP   ;RUN A DELAY WHICH FILLS IN THE REST
                NOT     COUNTER1        ; OF THE TIME A MAX RANGE HIT TAKES.
                JZ      RTDONE
RTE             CALL    RANGETICK
                DJNZ    COUNTER1,RTE
RTDONE          RET
;----------------------------------------------------------------------------
;RANGEAVER:AVERAGES RESULTS OF 8 TESTS BEFORE UPDATING RANGEAVER VALUE
RANGEAVER       ADD     RANGEDATAL,RANGERESULT
                SNC
                INC     RANGEDATAH
                DJNZ    RESULTCOUNTER,RANGEAVEREND
                RR      RANGEDATAH
                RR      RANGEDATAL
                RR      RANGEDATAH
                RR      RANGEDATAL
                RR      RANGEDATAH
                RR      RANGEDATAL
                RR      RANGEDATAH
                RR      RANGEDATAL
                MOV     RANGEAVERAGE,RANGEDATAL
                CLR     RANGEDATAL
                CLR     RANGEDATAH
                MOV     RESULTCOUNTER,#8
RANGEAVEREND    RET
;----------------------------------------------------------------------------
;MINRETURN:TIME FOR SOUND TO TRAVEL 6" OUT AND 6" BACK = 885us
;(SPEED OF SOUND 13560"/s)
MINRETURN       MOV     DELAYCOUNTER2,#6
MRA             MOV     DELAYCOUNTER1,#244
                DJNZ    DELAYCOUNTER1,$
                DJNZ    DELAYCOUNTER2,MRA
                RET
;;----------------------------------------------------------------------------
;;RANGETICK:TIME FOR SOUND TO TRAVEL MAXIMUM RANGE (24') / 255 = 139us
;;(SPEED OF SOUND 13560"/s)
;RANGETICK       MOV     DELAYCOUNTER1,#229  ;VALUE WAS 230, BUT THIS IS
;                                            ;ADJUSTED TO COMPENSATE FOR
;                                            ;SURROUNDING INSTRUCTIONS IN LOOP
;                                            ;WHICH CALLS THIS ROUTINE.
;                DJNZ    DELAYCOUNTER1,$
;                RET
;;----------------------------------------------------------------------------
;RANGETICK:TIME FOR SOUND TO TRAVEL MAXIMUM RANGE (??') / 255 = ???us
;(SPEED OF SOUND 13560"/s)
RANGETICK       MOV     DELAYCOUNTER1,#50
                DJNZ    DELAYCOUNTER1,$
                RET
;----------------------------------------------------------------------------
;XMITON:ENABLES TRANSMITTER DRIVERS
XMITON          SETB    RP0             ;SET RP0 TO UPPER REGISTER BANK
                MOV     RA,#XMITENABLE
                CLRB    RP0             ;SET RP0 TO LOWER REGISTER BANK
                RET
;----------------------------------------------------------------------------
;XMITOFF:DISABLES TRANSMITTER DRIVERS
XMITOFF         SETB    RP0             ;SET RP0 TO UPPER REGISTER BANK
                MOV     RA,#XMITDISABLE
                CLRB    RP0             ;SET RP0 TO LOWER REGISTER BANK
                RET
;----------------------------------------------------------------------------
READTABLE       MOV     PCLATH,#LCDMESSAGES< ;TABLE = LCDMESSAGES
                MOV     W,TABLEENTRY
                CALL    LCDMESSAGES ;READ TABLE FROM LOCATION MESSAGE# ADDR
               ;CLRB    PCLATH.3
                CLR     PCLATH
                MOV     TABLEVALUE,W
                RET
;----------------------------------------------------------------------------
                ORG     03E1H
LCDMESSAGES     JMP     PC+W                                            ;Mess#
                RETW    '0','1','2','3','4','5','6','7','8','9';E0-9      1
                RETW    'S','o','n','a','r','1',' ',' ',' ',' ';E10-19    2
                RETW    'r','a','n','g','e',':',' ','-','-','-';E20-29    3
;----------------------------------------------------------------------------

                
                ;END OF LISTING

Mechanical

Mechanical ranging is old news, but it is seldom done really well. Here are a couple "better" ideas.

Bumpers

Bumpers don't give enough warning because they are generally simple on/off things that don't stick out very far. One of the most brilliant things I've ever seen was the design of a "sane" car that had a huge spring "bumper" that looped out in front of the car and extended a little out to each side. The attachment points on either side were hinged and then extended so that they crossed under the car. At that point, they intersected a "joystick" which ran up to the driver through a ball joint. I've drawn up a little picture and the red dot is the joystick. The left and right edges of the spring have rollers which are designed to follow a special curb at either side of each lane. When they are "squeezed" the result is that the stick is pushed forward, increasing the speed of the car. Contact with the front of the spring pulls the stick back, slowing the vehicle. Any misalignment of left to right pressure causes the car to steer to a corrective course and thereby follow the "curbs." Dead simple, hopefully reliable, and... proportional. It was designed by a little girl for her science fare entry and I've never been able to forget it. I wish I knew where she ended up.

For smaller applications, the connection points can be pots or other rotary encoders. The difference between the readings indicates front/back contact. The addition of the readings is proportional to the amount of left/right contact.

Particle gun

Huh? The idea here is to throw some small object and see if it bounces back. Won't that mess up the area? Not if you throw particles of the environment around you. "Throw" air. Look for the returning breeze. Or water, sand, etc... This is the same method that gives you that weird sense of solid objects close by when you are not able to see and the hair on your face or arms pick up the little currents of air that are bounding off the wall you will walk into just before you have time to stop. This is heightened the more skin exposed and can be quite accurate when leaving a pitch dark house out the back door without ones clothes. Don't ask.

It was first suggested to me by one of the few ladies on the PICList but the only implementation of this I have ever seen was an entry in a robot "firefighter" competition by an obviously brilliant engineer. He (sorry girls, it was a he) started off with the fact that the candle needed to be blown out. Rather than depend on accurate positioning, he realized that he could just "spit" air in all directions at the given height of the candle. So he mounted a whisper fan vertically and found an inverted cone-like baffle that would direct the air to all sides. After setting that up, he realized that the air from the top was being circulated back to the bottom faster when the bot was up near a wall. His bumpers became nothing more than flags and never contacted anything under normal operation. When he ran the 'bot we realized that another advantage of the proportional sensing of wall proximity allowed him to go much faster and round the corners without slowing down because he had some room between first sensing the wall and actually hitting it. The 'bot had no brains to speak of, it just turned away from any flag that dropped down. Sadly, the rules of the competition didn't allow the 'bot to just blow out the candle and keep going; the judges ruled that it had to actually sense the flame and this 'bot never had that ability! He did put out the candle faster than anyone else, just about every run.

See also:

Other

Capacitive field

Also known as a stud sensor. Good for short range sensing. They need to be re-calibrated constantly so you need some other way of knowing that nothing is in the area at all. I know of two versions:
 

IR

In a word, unreliable except under very controlled conditions. They get used in bathrooms all the time to flush the toilets and turn on the sinks. In a nice SoCal restaurant, while exporting the byproduct of processing my pre-dinner drink, I kept hearing a sink turning on and off. On the way out I saw why: A high window was allowing sunlight to fall just on the inside of the sink at about the point that the sensor was looking. It would warm up, the sink would turn on, the water spray was enough to cool the sink and turn the water off again. Anyone who has used a TV remote from any distance should realize that IR is NOT a viable technology. If you must, see also:


file: /Techref/new/letter/news0310.htm, 43KB, , updated: 2024/1/22 18:33, local time: 2024/12/8 11:23,
TOP NEW HELP FIND: 
18.97.9.170:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/new/letter/news0310.htm"> October 2003 MassMind Newsletter</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to massmind.org!

 

Welcome to massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .