Sunteți pe pagina 1din 97

O insect social care poate localiza muta apoi spre un alt Buglet i de a comunica folosind sunet i lumin.

Interaciuni diferite, n funcie de faptul dac brbat sau femeie.

Buglet Ghidul utilizatorului


Buglets poate fi brbat sau femeie, i s interacioneze n moduri diferite, n funcie de acest lucru. Pentru a face o Buglet de sex feminin, rotii presetat (VR1) complet spre stnga (sens antiorar), precum i de a face o Buglet brbat se ntoarce pe deplin la dreapta (sensul acelor de ceasornic). Dac o Buglet este brbat sau femeie este indicat fie de un flash albastru sau roz, respectiv, dup ncercare, puterea de-pe sine. Dac dou brbat Buglets se confrunt n mod direct ntre ele o vor face "an", adic ei vor huidui i amenin reciproc, i poate decide s perceap. Ele pot lovi reciproc la unele de vitez, prin urmare, necesitatea de dopuri de cauciuc de pe coarnele lor. Un Buglet poate arta, eventual, prezentarea, atunci cnd ncarc. Docile Buglet va strlucire verde, ntruct dominant Buglet va clipi rou i albastru n timp ce beepuri n triumf. Docile Buglet va aminti special Buglet le-a prezentat, i atunci cnd aceasta ndeplinete lng aceeai Buglet va arta prezentarea din nou verde stralucitoare. Dou femei Buglets va interaciona cu triluri de call-i-rspuns i sincronizate culori.

Un brbat i femeie Buglet vor interaciona, de asemenea, cu sunet, culoare i micare. O Buglet lipsii de orice comunicare cu alte persoane din speciile sale se vor expune n cele din urm un comportament aberant. Buglets sunt creaturi sociale i au nevoie de compania de felul lor. *********************************************************************** *** ; FILE: buglet.asm * ; CONTENTS: Buglet robot * ; COPYRIGHT: MadLab Ltd. 2007 * ; AUTHOR: James Hutchby * ; UPDATED: 29/03/07 * ; *********************************************************************** *** list p=16F628A include "p16f628a.inc" __config _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _LVP_OFF & _CP_ON __idlocs h'A110' errorlevel -205,-207,-302,-305,-306 ; *********************************************************************** *** ; * ; Specification * ; * ; *********************************************************************** *** ; power-up self-test - RGB LEDs flash once in turn and beeps twice, ; echoes left and right IR sensors to red and green LEDs, first with low ; power then with high power, beeps twice again ; if preset moved left to right or right to left during self-test, echoes LDR ; sensor to LEDs, otherwise tests both motors briefly

; male = preset hard right, female = preset hard left ; male/female indicated by blue/pink flash ; H(ue) = 0 to 360 (corresponding to 360 degrees around hexcone) (= 0 to 239 binary) ; red 0 - yellow 60 - green 120 - cyan 180 - blue 240 - magenta 300 - red 360 ; S(aturation) = 0.0 (shade of grey) to 1.0 (pure colour) (= 0 to 255 binary) ; V(alue) = 0.0 (black) to 1.0 (white) (= 0 to 255 binary) ; IR message format: ; command/flags ; bit 7 - male (1) or female (0) ; bit 6 - left (1) or right (0) ; bit 5 - high (1) or low (0) power ; bits 0 to 4 - command (bit 4 set if data present) ; source ID ; destination ID (0 if broadcast) ; data (if command bit 4 set) ; checksum/timestamp ; periodically will spin in a random direction then zig zag for a short distance ; also moves when light level changes ; male-male 'rutting': ; if two males directly face each other, hiss and flash red for a period then ; ram each other, submissive shows green, dominant flashes red/blue and beeps ; submissive remembers ID and shows green and submits when next encountered ; female-female: ; call and response chirruping with synchronised random colour bursts ; ; ; ; male-female: female chirrups and displays pink male clicks and displays blue, inches towards female beeping followed by synchronised colour fading when meet

; if isolated and no communication with others, after a while goes crazy ; then eventually sleeps ; *********************************************************************** *** ; * ; Port assignments * ; *

; *********************************************************************** *** PORTA_IO PORTB_IO #define #define #define #define #define #define #define #define #define #define #define #define #define #define LED_R LED_G LED_B SPEAKER1 SPEAKER2 LDR PRESET IR_RX IR_TX1_LO IR_TX1_HI IR_TX2_LO IR_TX2_HI MOTOR1 MOTOR2 equ equ equ equ equ equ macro bcf LED_R bcf LED_G bcf LED_B endm motors_off macro bcf MOTOR1 bcf MOTOR2 endm charge_ldr macro movlw PORTB_IO|(1<<0) tris_B endm discharge_ldr macro equ equ b'10111011' b'00110001' PORTB,7 PORTA,6 PORTB,6 PORTB,1 PORTB,2 PORTB,0 PORTA,3 PORTB,5 PORTA,7 PORTA,1 PORTA,0 PORTB,4 PORTA,2 PORTB,3 PORTB b'00000110' PORTA_IO&~(1<<1)|(1<<7)|(1<<0) PORTA_IO&~(1<<7)&~(1<<0)|(1<<1) PORTB_IO&~(1<<4) PORTB_IO|(1<<4) ; port A I/O status ; port B I/O status ; red LED ; green LED ; blue LED ; piezo speaker ; LDR ; preset ; ; ; ; ; IR receiver left IR emitter - low power left IR emitter - high power right IR emitter - low power right IR emitter - high power

; left motor ; right motor

SPEAKER_PORT SPEAKER_MASK PORTA_HI PORTA_LO PORTB_HI PORTB_LO LEDS_off

movlw PORTB_IO&~(1<<0) tris_B bcf LDR endm charge_preset macro

movlw PORTA_IO|(1<<3) tris_A endm discharge_preset macro

movlw PORTA_IO&~(1<<3) tris_A bcf PRESET endm ; *********************************************************************** *** ; * ; Constants and timings * ; * ; *********************************************************************** *** CLOCK Hz DUTY_CYCLE DUTY_STEPS MAX_RGB HUE_STEPS MALE_R MALE_G MALE_B FEMALE_R FEMALE_G FEMALE_B MAX_SPEED ACCELERATION IR_CARRIER IR_BURST IR_RECOVERY ms IR_START_ON equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ d'4000000' d'100' d'128' d'127' d'6'*d'40' d'0' d'0' d'127' d'127' d'30' d'50' d'64' d'2' d'38' d'1000' d'1' d'2400' ; processor clock frequency in ; LED duty cycle frequency in Hz ; number of duty cycle steps ; maximum RGB ; number of hue steps ; blue ; pink

; maximum motor speed ; motor acceleration ; IR carrier frequency in kHz ; IR carrier burst period in us ; IR receiver recovery time in ; IR start bit on period in us

IR_START_OFF IR_DATA0_ON IR_DATA1_ON IR_DATA_OFF IR_GAP IR_TIMEOUT MOTION_MASK DISCHARGE ms MAX_NOTE DURATION MOD1_FRQ MOD2_FRQ CNTL_FRQ CHIRRUP_PITCH CHIRRUP_TIME MSG_LEN MSG_NUM SUB_NUM ; states STATE_NULL STATE_M_M STATE_M_F STATE_F_M STATE_F_F ; message flags MSG_SEX MSG_SIDE MSG_POWER ; message commands MSG_NULL MSG_HELLO MSG_ACK MSG_RAM MSG_SUBMIT MSG_HUE MSG_MATE MSG_MASK

equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ

d'600' d'600' d'1200' d'600' d'1200' d'25' ~b'111' d'1' d'6'*d'12' h'c000' d'15' d'3' d'100' d'27' d'35' d'5' d'10' d'5' d'0' d'1' d'2' d'3' d'4' 7 6 5 h'00' h'01' h'02' h'03' h'04' h'15' h'16' h'1f'

; ; ; ; ;

IR IR IR IR IR

start bit off period in us data 0 bit on period in us data 1 bit on period in us data bit off period in us inter-byte gap in us

; IR wait timeout in ms ; LDR motion detector mask ; capacitor discharge period in ; maximum speaker note ; note duration ; ; ; ; ; modulation frequency #1 modulation frequency #2 control frequency in Hertz chirrup pitch chirrup duration in 1/100 s

; message length (with data) ; number of stacked messages ; submission list size ; ; ; ; ; null male-male male-female female-male female-female

; male/female ; left/right ; high/low power ; ; ; ; ; ; ; null hello acknowledge ram submit hue mate

; *********************************************************************** *** ; *

; File register usage * ; * ; *********************************************************************** *** cblock h'20' context:3 ticks:2 rtc rtc_ timer timeout hue, saturation, value red, green, blue red_, green_, blue_ sector, fraction temp_R, temp_G, temp_B duty offset speed1, speed2 (off) to 64 (fully on) accel1, accel2 pitch:2 duration:2 mod1_cnt, mod2_cnt message:MSG_LEN flags ID target light state bits shift command isolated addr rand:2 arg1:2, arg2:2 count:2, loop, repeat work1, work2, work3 temp1, temp2 RAM0 endc if RAM0 > h'80' error "File register usage overflow" endif ; bank 0 ; ; ; ; ; ; ; ; ; ; ; ; ; saved context clock ticks real-time clock (counts 1/2 s) previous value timer timeout timer, -1 if disabled current colour in HSV space current colour in RGB space PWM counters colour wheel sector and fraction temporary RGB components duty cycle counter hue offset

; motor speeds (pwm duty cycles), 0 ; instantaneous motor speeds ; note pitch ; note/chirrup duration ; chirrup modulation counters ; current message ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; various flags unique random ID target ID light level state bits count shift register saved command/flags isolated timer RAM/EEPROM address random number arithmetic routine arguments scratch counters work registers isr registers

cblock h'a0' context_:3 messages:MSG_NUM*MSG_LEN submission:SUB_NUM RAM1 endc

; bank 1 ; saved context ; message stack ; submission list

if RAM1 > h'f0' error "File register usage overflow" endif ; flags MALE TX_LFT TX_RGT TX_HI FUND MOD1 MOD2 STATIC LEDS

equ equ equ equ equ equ equ equ

0 1 2 3 4 5 6 7

; ; ; ; ; ; ; ;

set if male set if left IR transmitter set if right IR transmitter set if high power transmitters chirrup fundamental flag chirrup modulation #1 flag chirrup modulation #2 flag set if static

macro r_,g_,b_ if r_ == 0 clrf red else movlf r_,red endif if g_ == 0 clrf green else movlf g_,green endif if b_ == 0 clrf blue else movlf b_,blue endif endm macro l_,r_ if l_ == 0 clrf speed1 else movlf l_,speed1 endif if r_ == 0 clrf speed2 else movlf r_,speed2 endif

MOTORS

endm ; *********************************************************************** *** ; * ; Macros * ; * ; *********************************************************************** *** routine label table label entry macro label endm macro label addwf PCL endm macro value retlw value endm macro label call label endm macro label goto label endm macro iorlw 0 endm macro f1,f2 movfw f1 movwf f2 endm macro n,f movlw n movwf f endm macro bsf STATUS,RP0 movwf TRISA bcf STATUS,RP0 endm macro ; define lookup table ; routine

; define table entry

index

; index lookup table

jump

; jump through table

tstw

; test w register

movff

; move file to file

movlf

; move literal to file

tris_A

; tristate port A

tris_B

; tristate port B

bsf STATUS,RP0 movwf TRISB bcf STATUS,RP0 endm option_ macro bsf STATUS,RP0 movwf OPTION_REG bcf STATUS,RP0 endm ; set options

;------------------------------------------------------------------------; reset and interrupt service routine vectors ;------------------------------------------------------------------------org 0 goto main_entry org 4 goto isr ; *********************************************************************** *** ; * ; Lookup tables * ; * ; *********************************************************************** *** lookup movwf PCL table fraction_tbl entry entry entry entry entry entry entry entry entry entry entry entry d'0' d'7' d'13' d'20' d'26' d'33' d'39' d'46' d'52' d'59' d'65' d'72' ; look up table

entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry entry if 0

d'78' d'85' d'92' d'98' d'105' d'111' d'118' d'124' d'131' d'137' d'144' d'150' d'157' d'163' d'170' d'177' d'183' d'190' d'196' d'203' d'209' d'216' d'222' d'229' d'235' d'242' d'248' d'255'

table note_tbl note_ period macro freq set (((CLOCK<<1)/freq)-NOTE_OVERHEAD+NOTE_LOOP/2)/NOTE_LOOP entry high period entry low period endm note_ d'435' note_ note_ note_ note_ note_ note_ note_ note_ note_ note_ note_ endif d'461' d'488' d'517' d'548' d'581' d'615' d'652' d'691' d'732' d'775' d'821' ; 2 octaves below international A ; ; ; ; ; ; ; ; ; ; ; A# B C C# D D# E F F# G G#

(435Hz)

; *********************************************************************** *** ; * ; Procedures * ; * ; *********************************************************************** *** ;------------------------------------------------------------------------; LED pwm control ;------------------------------------------------------------------------routine do_leds decfsz duty goto dol1 movlf DUTY_STEPS,duty movff red,red_ skpz bsf LED_R movff green,green_ skpz bsf LED_G movff blue,blue_ skpz bsf LED_B dol1 decf red_ skpnz bcf LED_R decf green_ skpnz bcf LED_G decf blue_ skpnz bcf LED_B return ;------------------------------------------------------------------------; dc motor pwm control ;------------------------------------------------------------------------; start of duty cycle ? ; branch if not ; recharge counter ; initialise PWM counters

; red PWM

; green PWM

; blue PWM

do_motors swapf andlw movwf swapf andlw iorwf

macro ticks+0,w h'f0' temp1 ticks+1,w h'0f' temp1 ; left motor pwm

movfw temp1 andlw h'3f' subwf accel1,w skpnz clrc skpc bcf MOTOR1 skpnc bsf MOTOR1 movfw subwf movlw skpz addwf movfw subwf skpnc subwf accel1 speed1,w ACCELERATION accel1 speed1 accel1,w accel1

; accelerate

comf temp1,w andlw h'3f' subwf accel2,w skpnz clrc skpc bcf MOTOR2 skpnc bsf MOTOR2 movfw subwf movlw skpz addwf movfw subwf skpnc subwf endm accel2 speed2,w ACCELERATION accel2 speed2 accel2,w accel2

; right motor pwm

; accelerate

;------------------------------------------------------------------------; interrupt service routine ;-------------------------------------------------------------------------

routine isr movwf context+0 swapf STATUS,w clrf STATUS movwf context+1 movff PCLATH,context+2 clrf PCLATH btfss PIR1,TMR1IF goto isr1 bcf PIR1,TMR1IF incf rtc decf timeout btfsc timeout,7 incf timeout goto isr2 isr1 bcf PIR1,TMR2IF incf ticks+1 skpnz incf ticks+0 call do_leds movfw ticks+1 andlw h'0f' bnz isr2 do_motors isr2 movff swapf movwf swapf swapf retfie ;------------------------------------------------------------------------; locks the LEDs ;------------------------------------------------------------------------routine lock_LEDS LEDS_off btfsc red,6 context+2,PCLATH context+1,w STATUS context+0 context+0,w ; dc motor pwm control ; restore context ; clear interrupt ; increment clock ticks ; clear interrupt ; increment real-time clock ; decrement timeout timer if ; not disabled ; save context ; bank 0 ; page 0

; LED pwm control

bsf LED_R btfsc green,6 bsf LED_G btfsc blue,6 bsf LED_B return ;------------------------------------------------------------------------; generates a pseudo random number, returns the number in w reg ;------------------------------------------------------------------------routine get_random movfw rand+0 iorwf rand+1,w bnz getr1 movfw movwf xorlw movwf getr1 TMR0 rand+1 h'ff' rand+0 ; seed generator

rlf rand+0,w xorwf rand+0,w movwf work1 swapf rand+1,w btfsc rand+0,4 xorlw h'80' xorwf work1 rlf work1 rlf rand+1 rlf rand+0 movfw rand+1 return

; calculate next in sequence ; msb <= Q15 ^ Q14 ; msb <= Q12 ^ Q3

; << 1 + (Q15 ^ Q14 ^ Q12 ^ Q3) ; w <= random number

;------------------------------------------------------------------------; short beep ;------------------------------------------------------------------------BEEP_PITCH BEEP_PERIOD equ equ d'35' d'250' ; beep pitch ; beep period

routine beep_2 call beep movlw d'15' call wait

routine beep bcf INTCON,GIE motors_off call lock_LEDS bcf SPEAKER1 bsf SPEAKER2 movlf BEEP_PERIOD,work1 beep1 beep2 movlf BEEP_PITCH,work2 clrwdt decfsz work2 goto beep2 movlw SPEAKER_MASK xorwf SPEAKER_PORT decfsz work1 goto beep1 bcf SPEAKER1 bcf SPEAKER2 bsf INTCON,GIE return ;------------------------------------------------------------------------; reads a byte from data memory, fed with the address in addr, returns ; the byte in w reg ;------------------------------------------------------------------------if 0 routine read_EEPROM movfw addr bsf STATUS,RP0 movwf EEADR bsf EECON1,RD movfw EEDATA bcf STATUS,RP0 return endif ; read byte ; interrupts on ; half-cycle delay ; interrupts off

; toggle speaker output

;------------------------------------------------------------------------; writes a byte to data memory, fed with the address in addr and the ; byte in w reg ;------------------------------------------------------------------------if 0 routine write_EEPROM bsf STATUS,RP0 movwf EEDATA bcf STATUS,RP0 movfw addr bsf STATUS,RP0 movwf EEADR bcf INTCON,GIE bsf EECON1,WREN movlf h'55',EECON2 movlf h'aa',EECON2 bsf EECON1,WR nop btfsc EECON1,WR goto wr1 bcf EECON1,WREN bcf STATUS,RP0 bsf INTCON,GIE return endif ;------------------------------------------------------------------------; delay ;------------------------------------------------------------------------delay64 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 return macro cycles if (cycles) < 0 error "Delay cycles negative" endif variable i = cycles ; ; ; ; ; ; ; [8] [8] [8] [8] [8] [8] [8] ; write byte

wr1

delay16 delay

; delay for a number of cycles

while i > d'64' call delay64 i -= d'64' endw if i >= d'16' variable n = (i-d'16')/d'8' call delay16-n i -= (n*d'8')+d'16' endif while i >= d'4' nop i -= d'4' endw

; [64]

; [8+8n+8]

; [4]

if i != 0 error "Delay cycles not multiple of 4" endif endm ;------------------------------------------------------------------------; waits for (at least) the number of ms in w reg ;------------------------------------------------------------------------routine wait_ms movwf work1 WAIT wait1 wait2 set CLOCK/(d'1000'*d'80') ; ; ; ; [4] [64] [4] [8]

movlf WAIT,work2 clrwdt delay d'64' decfsz work2 goto wait2 decfsz work1 goto wait1 return

;------------------------------------------------------------------------; waits for the number of 1/100 s in w reg ;------------------------------------------------------------------------routine short_wait movlw 1

goto wait routine wait_tenth movlw d'10' goto wait routine wait_half movlw d'50' goto wait routine wait_one movlw d'100' goto wait routine long_wait clrw routine wait movwf work1 wait3 movfw ticks+1 addlw (DUTY_CYCLE*DUTY_STEPS)/d'100' movwf work2 clrwdt movfw ticks+1 subwf work2,w bz wait5 decf ticks+1,w subwf work2,w bnz wait4 decfsz work1 goto wait3 return ; *********************************************************************** *** ; I/O routines * ; *********************************************************************** *** ;------------------------------------------------------------------------; multiplication (8-bit arg1 * 8-bit arg2 >> 8 -> 8-bit arg1) ;-------------------------------------------------------------------------

wait4

wait5

routine mult movlf d'8',count movff arg1,shift movff arg2,arg2+1 clrf arg1+0 clrf arg1+1 clrf arg2+0 mult1 rrf shift bnc mult2 movfw arg2+1 addwf arg1+1 skpnc incf arg1+0 movfw arg2+0 addwf arg1+0 mult2 clrc rlf arg2+1 rlf arg2+0 decfsz count goto mult1 return ;------------------------------------------------------------------------; converts HSV colour space to RGB colour space ;------------------------------------------------------------------------routine conv_RGB movfw movwf movwf movwf value temp_R temp_G temp_B ; special case ; determine the colour wheel ; and fraction (0 to 39)

tstf saturation bz conv8 movff hue,fraction sector (0 to 5) movlf -1,sector movlw d'40' conv0 incf sector subwf fraction bc conv0 addwf fraction

movfw fraction index fraction_tbl movwf fraction incf saturation,w bnz conv1 incf value,w bnz conv1 clrf work1 comf fraction,w movwf work2 movff fraction,work3 goto conv2 conv1 comf saturation,w saturation)) / 256 movwf arg1 movff value,arg2 call mult movff arg1,work1 movff saturation,arg1 fraction) / 256)) / 256 movff fraction,arg2 call mult comf arg1 movff value,arg2 call mult movff arg1,work2 comf fraction,w (255 - fraction)) / 256)) / 256 movwf arg1 movff saturation,arg2 call mult comf arg1 movff value,arg2 call mult movff arg1,work3 conv2 tstf sector bnz conv3 movff work3,temp_G movff work1,temp_B goto conv8 conv3 decf sector bnz conv4 movff work2,temp_R movff work1,temp_B

; scale to 8-bit range

; special case

; (value * (255 -

; (value * (255 - (saturation *

; (value * (255 - (saturation *

; sector 0

; sector 1

goto conv8 conv4 decf sector bnz conv5 movff work1,temp_R movff work3,temp_B goto conv8 conv5 decf sector bnz conv6 movff work1,temp_R movff work2,temp_G goto conv8 conv6 decf sector bnz conv7 movff work3,temp_R movff work1,temp_G goto conv8 conv7 conv8 movff work1,temp_G movff work2,temp_B bcf INTCON,GIE clrc rrf temp_R,w movwf red clrc rrf temp_G,w movwf green clrc rrf temp_B,w movwf blue bsf INTCON,GIE return ;------------------------------------------------------------------------; samples the LDR sensor, returns the result in w reg (0 to 255) ;------------------------------------------------------------------------routine get_ldr discharge_ldr movlw DISCHARGE call wait_ms ; discharge the capacitor ; sector 5 ; sector 4 ; sector 3 ; sector 2

clrwdt clrf count bcf INTCON,GIE motors_off call lock_LEDS charge_ldr getl1 incf count bz getl2 delay d'8' btfss LDR goto getl1 getl2 bsf INTCON,GIE decf count,w return ;------------------------------------------------------------------------; samples the preset, returns the result in w reg (0 to 255) ;------------------------------------------------------------------------routine get_preset discharge_preset movlw DISCHARGE call wait_ms clrwdt clrf count bcf INTCON,GIE motors_off call lock_LEDS charge_preset getp1 variable n = d'7' while n > 0 incf count btfsc PRESET goto getp2 ; [4] ; charged ? [8] ; branch if yes ; charge the capacitor ; interrupts off ; discharge the capacitor ; charge the capacitor ; [4] ; branch if timeout [8] ; [8] ; charged ? [4] ; loop if not [8] ; interrupts on ; interrupts off

n -= 1 endw incf count bz getp2 btfss PRESET goto getp1 getp2 bsf INTCON,GIE decf count,w return ;------------------------------------------------------------------------; tests for an obstacle, returns the C flag set if obstacle detected ;------------------------------------------------------------------------; total time in ms = ((2*IR_BURST)/d'1000')+IR_RECOVERY routine test_obstacle bcf INTCON,GIE motors_off call lock_LEDS movlw PORTA_HI btfss flags,TX_HI movlw PORTA_LO tris_A movlw PORTB_HI btfss flags,TX_HI movlw PORTB_LO tris_B clrf count ITERS set ((IR_BURST*IR_CARRIER)/d'1000')+1 ; high or low power emitters ; interrupts off ; [4] ; branch if timeout [8] ; charged ? [4] ; loop if not [8] ; interrupts on

movlf ITERS,loop DELAY DELAY testo1 set set (((CLOCK/d'1000')+IR_CARRIER)/(IR_CARRIER*2))-d'44' (DELAY+2)&~3 ; ; ; ; ; ; ; IR emitter on [8/4] [0/4] [8/4] [0/4] [8/4] [0/4] [8/4]

btfsc flags,TX_LFT bsf IR_TX1_HI btfsc flags,TX_RGT bsf IR_TX2_HI btfsc flags,TX_LFT bsf IR_TX1_LO btfsc flags,TX_RGT

bsf IR_TX2_LO delay DELAY clrwdt btfss IR_RX incf count btfsc flags,TX_LFT bcf IR_TX1_HI btfsc flags,TX_RGT bcf IR_TX2_HI btfsc flags,TX_LFT bcf IR_TX1_LO btfsc flags,TX_RGT bcf IR_TX2_LO delay DELAY decfsz loop goto testo1 movlw ITERS/2 subwf count,w bnc testo3 clrf count ITERS set

; [0/4] ; half-cycle delay ; [4] ; [8/4] ; [0/4] ; ; ; ; ; ; ; ; IR emitter off [8/4] [0/4] [8/4] [0/4] [8/4] [0/4] [8/4] [0/4]

; half-cycle delay ; [4] ; [8]

((CLOCK/d'1000000')*IR_BURST)/d'56'

movlf ITERS,loop testo2 clrwdt btfss IR_RX incf count delay d'32' decfsz loop goto testo2 movlw ITERS/2 subwf count,w bc testo3 bsf INTCON,GIE movlw IR_RECOVERY call wait_ms setc return testo3 bsf INTCON,GIE ; interrupts on ; interrupts on ; receiver recovery time ; signal obstacle ; [4] ; [8/4] ; [0/4] ; [32] ; [4] ; [8]

clrc return

; signal no obstacle

;------------------------------------------------------------------------; IR bit routines ;------------------------------------------------------------------------routine tx_on movwf work1 HALF HALF set set CLOCK/(2*IR_CARRIER*d'1000') (HALF+2)&~3

btfss flags,TX_HI goto ton2 ton1 btfsc flags,TX_LFT bsf IR_TX1_HI btfsc flags,TX_RGT bsf IR_TX2_HI clrwdt delay HALF-d'20' nop bcf IR_TX1_HI nop bcf IR_TX2_HI delay HALF-d'28' decfsz work1 goto ton1 return ton2 btfsc flags,TX_LFT bsf IR_TX1_LO btfsc flags,TX_RGT bsf IR_TX2_LO clrwdt delay HALF-d'20' nop bcf IR_TX1_LO nop bcf IR_TX2_LO delay HALF-d'28' decfsz work1 goto ton2 return ir_on macro us movlw us/((2*HALF)/(CLOCK/d'1000000')) call tx_on ; ; ; ; ; ; ; ; ; ; ; ; ; IR emitters on [8/4] [0/4] [8/4] [0/4] [4] half-cycle delay IR emitters off [4] [4] [4] [4] half-cycle delay [4] [8] ; ; ; ; ; ; ; ; ; ; ; ; ; IR emitters on [8/4] [0/4] [8/4] [0/4] [4] half-cycle delay IR emitters off [4] [4] [4] [4] half-cycle delay [4] [8]

endm routine tx_off movwf work1 bcf bcf bcf bcf toff1 IR_TX1_HI IR_TX2_HI IR_TX1_LO IR_TX2_LO ; ; ; ; [4] [32] [4] [8]

clrwdt delay d'32' decfsz work1 goto toff1 set d'48'

CYCLES

return ir_off macro us movlw us/(CYCLES/(CLOCK/d'1000000')) call tx_off endm ;------------------------------------------------------------------------; transmits an IR byte, fed with the byte in w reg ;------------------------------------------------------------------------routine tx_byte movwf shift clrf work2 ir_on IR_START_ON ir_off IR_START_OFF movlf d'8',bits txb1 rlf shift bc txb2 ir_on IR_DATA0_ON ir_off IR_DATA_OFF goto txb3 txb2 ir_on IR_DATA1_ON ir_off IR_DATA_OFF ; data bits ; start bit

incf work2 txb3 decfsz bits goto txb1 btfsc work2,0 goto txb4 ir_on IR_DATA0_ON goto txb5 ir_on IR_DATA1_ON ir_off IR_DATA_OFF ir_off IR_GAP return ;------------------------------------------------------------------------; receives an IR byte, returns the byte in w reg with the C flag set ; if error ;------------------------------------------------------------------------routine rx_byte rxb1 clrf count clrwdt incf count bz rxb6 delay d'40' btfsc IR_RX goto rxb1 clrf count clrwdt incf count bz rxb6 delay d'24' btfss IR_RX goto rxb2 clrf shift clrf work2 movlf d'8'+1,bits rxb3 rxb4 clrf count clrwdt incf count bz rxb6 btfsc IR_RX goto rxb4 clrf count ; wait for high ; ; ; ; [4] branch if timeout [8] [4] [8] ; ; ; ; ; ; ; ; ; ; ; ; ; ; wait for start bit [4] [4] branch if timeout [8] [40] [4] [8] wait for end of start bit [4] [4] branch if timeout [8] [24] [4] [8] ; parity bit

txb4 txb5

rxb2

; wait for low

rxb5

clrwdt incf count bz rxb6 btfss IR_RX goto rxb5 set set

; ; ; ;

[4] branch if timeout [8] [4] [8]

CYCLES MID

d'24' ((IR_DATA0_ON+IR_DATA1_ON)/2)/((CYCLES*d'1000000')/CLOCK)

movlw MID subwf count,w rlf shift rrf shift,w skpnc incf work2 decfsz bits goto rxb3 btfsc work2,0 goto rxb6 clrc return rxb6 setc return ; *********************************************************************** *** ; message routines * ; *********************************************************************** *** ;------------------------------------------------------------------------; calculates the checksum for the current message, returns the checksum ; in w reg ;------------------------------------------------------------------------routine get_checksum movfw message+0 variable n = 1 while n < MSG_LEN-2 xorwf message+n,w n += 1 endw btfsc message+0,4 ; signal error ; test parity bit ; signal no error

xorwf message+n,w return ;------------------------------------------------------------------------; transmits a message ;------------------------------------------------------------------------routine tx_message bcf message+0,MSG_SEX btfsc flags,MALE bsf message+0,MSG_SEX bcf message+0,MSG_POWER btfsc flags,TX_HI bsf message+0,MSG_POWER call get_checksum btfss message+0,4 movwf message+3 btfsc message+0,4 movwf message+4 movlw PORTA_HI btfss flags,TX_HI movlw PORTA_LO tris_A movlw PORTB_HI btfss flags,TX_HI movlw PORTB_LO tris_B bcf INTCON,GIE motors_off call lock_LEDS movlf message,FSR movlf MSG_LEN,repeat btfss message+0,4 decf repeat movfw 0 call tx_byte incf FSR decfsz repeat goto txm1 bsf INTCON,GIE return routine tx_left ; transmit bytes ; calculate checksum

; high or low power emitters

; interrupts off

txm1

; interrupts on

bsf flags,TX_LFT bcf flags,TX_RGT bsf message+0,MSG_SIDE goto tx_message routine tx_right bsf flags,TX_RGT bcf flags,TX_LFT bcf message+0,MSG_SIDE goto tx_message routine tx_both sides bsf flags,TX_RGT bsf flags,TX_LFT call get_random andlw 1<<MSG_SIDE xorwf message+0 goto tx_message random routine tx_random call get_random andlw 1 bz tx_left goto tx_right

; transmit on left side

; transmit on right side

; transmit on left and right

; transmit left or right at

;------------------------------------------------------------------------; receives a message, returns the Z flag set if timeout or the C flag ; set if error ;------------------------------------------------------------------------routine rx_message motors_off ITERS set ; motors off

((IR_TIMEOUT*(CLOCK/d'1000'))/d'48')>>8 ; wait for start bit ; [4] ; [4] ; [8] ; ; ; ; ; ; [4] [4] [4] branch if timeout [8] [4] [8]

rxm1

movlf ITERS,count+0 clrf count+1 clrwdt tstf count+1 skpnz decf count+0 decf count+1 movfw count+0 iorwf count+1,w bz rxm5 btfsc IR_RX goto rxm1

bcf INTCON,GIE motors_off call lock_LEDS movlf message,FSR movlf MSG_LEN-1,repeat call rx_byte bc rxm4 movwf 0 incf FSR decfsz repeat goto rxm2 btfss message+0,4 goto rxm3 call rx_byte bc rxm4 movwf 0 incf FSR call get_checksum decf FSR xorwf 0,w bnz rxm4 clrc clrz bsf INTCON,GIE return rxm4 setc clrz bsf INTCON,GIE return rxm5 setz clrc return

; interrupts off

; receive bytes ; branch if error

rxm2

rxm3

; test checksum

; signal no error ; interrupts on

; signal error ; interrupts on

; signal timeout

;------------------------------------------------------------------------; returns the message command in w reg ;------------------------------------------------------------------------routine get_command movfw message+2 skpz subwf ID,w movlw MSG_NULL ; correct destination ?

bnz getc1 movfw message+0 andlw MSG_MASK getc1 return

; branch if not ; message command

;------------------------------------------------------------------------; copies the message stack to the current message, fed with FSR pointing ; to the stack, returns FSR advanced ;------------------------------------------------------------------------routine get_message variable n = 0 while n < MSG_LEN movff 0,message+n incf FSR n += 1 endw return ;------------------------------------------------------------------------; copies the current message to the message stack, fed with FSR pointing ; to the stack, returns FSR advanced ;------------------------------------------------------------------------routine put_message variable n = 0 while n < MSG_LEN movff message+n,0 incf FSR n += 1 endw return ;------------------------------------------------------------------------; clears the message stack ;------------------------------------------------------------------------routine clear_messages movlf messages,FSR movlf MSG_NUM*MSG_LEN,count clrf 0

clrm1

incf FSR decfsz count goto clrm1 return ;------------------------------------------------------------------------; pushes the current message onto the stack ;------------------------------------------------------------------------routine push_message movlf messages+MSG_NUM*MSG_LEN,FSR movlf (MSG_NUM-1)*MSG_LEN,count movlw MSG_LEN+1 subwf FSR movff 0,work1 movlw MSG_LEN addwf FSR movff work1,0 decfsz count goto pushm1 movff rtc,message+4 movlf messages,FSR goto put_message ;------------------------------------------------------------------------; expires old messages on the stack ;------------------------------------------------------------------------routine expire_messages ; message lifetime in seconds MSG_LIFETIME equ d'6' movlf messages+4,FSR movlf MSG_NUM,count movfw 0 subwf rtc,w sublw d'2'*MSG_LIFETIME bc expir2 movlw 4 subwf FSR clrf 0 addwf FSR movlw MSG_LEN addwf FSR decfsz count goto expir1 ; set timestamp

pushm1

expir1

; message expired ? ; branch if not ; discard message

expir2

return ;------------------------------------------------------------------------; acknowledges a message ;------------------------------------------------------------------------routine ack_message movlw d'2' call wait_ms movlf MSG_ACK,message+0 movff message+1,message+2 movff ID,message+1 goto tx_both ; command ; destination ID ; source ID ; acknowledge

;------------------------------------------------------------------------; waits for acknowledge, returns the NZ flag set if received ;------------------------------------------------------------------------routine wait_ack call rx_message bz wack1 bc wack1 call get_command sublw MSG_ACK bnz wack1 clrz return wack1 setz return ;------------------------------------------------------------------------; tests for the presence of a male or female, returns the NZ flag set ; if detected ;------------------------------------------------------------------------routine test_male movlw 1 ; signal not acknowledged ; wait for message ; branch if timeout or error ; acknowledge ? ; branch if not ; signal acknowledged

goto test0 routine test_female test0 clrw movwf work1 movlf messages,FSR movlf MSG_NUM,count test1 call get_message tstf message+0 bz test5 movfw message+0 tstf work1 skpnz comf message+0,w andlw 1<<MSG_SEX bz test5 movff message+1,target btfss flags,MALE goto test6 movff FSR,addr movff count,work2 clrf work3 goto test3 test2 call get_message tstf message+0 bz test4 movfw target subwf message+1,w bnz test4 test3 btfsc message+2,MSG_SIDE bsf work3,0 btfss message+2,MSG_SIDE bsf work3,1 decfsz count goto test2 movlw b'11' subwf work3 bz test6 movff addr,FSR movff work2,count ; detected ? ; branch if yes ; must acknowledge left and ; right messages ; null message ? ; branch if yes ; null message ? ; branch if yes ; correct sex ?

; branch if not ; target ID ; female ? ; branch if yes

test4

test5

decfsz count goto test1 setz return ; signal not detected

test6

clrz return

; signal detected

;------------------------------------------------------------------------; clears the submission list ;------------------------------------------------------------------------routine clear_submission movlf submission,FSR movlf SUB_NUM,count clrf 0 incf FSR decfsz count goto clrs1 return ;------------------------------------------------------------------------; pushes an ID onto the submission list, fed with the ID in w reg ;------------------------------------------------------------------------routine push_submission movwf work1 movlf submission+SUB_NUM,FSR movlf SUB_NUM-1,count decf FSR decf FSR movfw 0 incf FSR movwf 0 decfsz count goto pushs1 movlf submission,FSR movff work1,0 return

clrs1

pushs1

;------------------------------------------------------------------------; tests for the presence of an ID in the submission list, fed with the ; ID in w reg, returns the NZ flag set if present ;------------------------------------------------------------------------routine test_submission btfss flags,MALE goto tests2 movwf work1 movlf submission,FSR movlf SUB_NUM,count movfw 0 subwf work1,w bz tests3 incf FSR decfsz count goto tests1 setz return tests3 clrz return ; *********************************************************************** *** ; sound routines * ; *********************************************************************** *** ;------------------------------------------------------------------------; plays a note, fed with the note in w reg (1 to 72 = 6 octaves A to G), ; or 0 for note off ;------------------------------------------------------------------------if 0 routine play_note tstw bz play6 movwf work1 sublw MAX_NOTE ; note off ? ; branch if yes ; signal found ; signal not found ; male ? ; branch if not

tests1

tests2

movlw MAX_NOTE skpc movwf work1 clrf work2 decf work1 incf work2 movlw d'12' subwf work1 bc play1 addwf work1 movfw work1 addwf work1,w index note_tbl movwf pitch+0 incf work1,w addwf work1,w index note_tbl movwf pitch+1 play2 decf work2 bz play3 clrc rrf pitch+0 rrf pitch+1 bnc play2 incf pitch+1 skpnz incf pitch+0 goto play2 movlf high DURATION,duration+0 movlf low DURATION,duration+1 bcf INTCON,GIE motors_off call lock_LEDS play4 clrwdt movlw SPEAKER_MASK xorwf SPEAKER_PORT movff pitch+0,work1 movff pitch+1,work2 tstf work2 skpz incf work1 play5 decfsz work2 goto play5 decfsz work1 goto play5 ; [4] ; toggle speaker output [4] ; [4] ; [8] ; [8] ; [4] ; [8/4] ; [0/4] ; half-cycle delay [4] ; [8] ; interrupts off ; determine octave and offset

play1

; look up period

; adjust for octave

play3

NOTE_LOOP

equ

d'12' ; ; ; ; ; ; ; [4] [4] [4] [8/4] [0/4] [4] loop until finished [12]

movfw pitch+1 subwf duration+1 movfw pitch+0 skpc incf pitch+0,w subwf duration+0 bc play4 NOTE_OVERHEAD equ d'40'+d'36'

bsf INTCON,GIE play6 bcf SPEAKER1 bcf SPEAKER2 return endif

; interrupts on ; sound off

;------------------------------------------------------------------------; clicks ;------------------------------------------------------------------------CLICK_PITCH CLICK_PERIOD CLICK_WAIT equ equ equ d'25' d'75' d'10' ; click pitch ; click period ; click wait

routine click bcf INTCON,GIE motors_off bcf SPEAKER1 bsf SPEAKER2 movlf CLICK_PERIOD,work1 click1 click2 movlf CLICK_PITCH,work2 clrwdt decfsz work2 goto click2 call do_leds movlw SPEAKER_MASK xorwf SPEAKER_PORT decfsz work1 goto click1 bcf SPEAKER1 bcf SPEAKER2 ; toggle speaker output ; half-cycle delay ; interrupts off

bsf INTCON,GIE movlw CLICK_WAIT call wait return

; interrupts on

;------------------------------------------------------------------------; hisses, fed with the time in w reg, returns the C flag set if IR ; transmission ;------------------------------------------------------------------------routine hiss movwf count+0 bcf INTCON,GIE motors_off call lock_LEDS bcf SPEAKER1 bsf SPEAKER2 hiss1 hiss2 clrf count+1 call get_random andlw h'1f' movwf work1 incf work1 clrwdt setc btfss IR_RX goto hiss4 decfsz work1 goto hiss3 movlw SPEAKER_MASK xorwf SPEAKER_PORT bcf LED_R btfsc TMR1H,5 bsf LED_R decfsz count+1 goto hiss2 decfsz count+0 goto hiss1 clrc hiss4 bcf SPEAKER1 ; signal no transmission ; interrupts off

hiss3

; IR transmission ? ; branch if yes

; toggle speaker output ; flash red

bcf SPEAKER2 bcf LED_R bsf INTCON,GIE return ;------------------------------------------------------------------------; sounds a 'chirrup' ;------------------------------------------------------------------------routine chirrup bcf INTCON,GIE motors_off movlf CHIRRUP_TIME,duration movlw b'10000111' option_ bcf flags,FUND bcf flags,MOD1 bcf flags,MOD2 clrf TMR0 movlw 1 movwf mod1_cnt movwf mod2_cnt chir1 btfss flags,MOD1 goto chir2 btfss flags,MOD2 goto chir2 btfss flags,FUND goto chir2 bsf SPEAKER1 bcf SPEAKER2 goto chir3 chir2 chir3 chir4 bcf SPEAKER1 bsf SPEAKER2 movlf CHIRRUP_PITCH,work1 clrwdt decfsz work1 goto chir4 call do_leds ; clear speaker output ; ; ; ; half-cycle delay [4] [4] [8] ; toggle speaker output ; interrupts off ; duration ; weak pull-ups disabled, ; prescale TMR0 1:256 ; interrupts on

movlw 1<<FUND xorwf flags movfw TMR0 andlw h'80' bnz chir1 CNTL set

; toggle fundamental flag ; control

(CLOCK/4)/(d'256'*CNTL_FRQ) ; recharge timer ; modulation #1 ; recharge counter ; toggle flag ; modulation #2 ; recharge counter ; toggle flag

movlf -CNTL,TMR0 decfsz mod1_cnt goto chir5 movlw CNTL_FRQ/(2*MOD1_FRQ) movwf mod1_cnt movlw 1<<MOD1 xorwf flags chir5 decfsz mod2_cnt goto chir6 movlw CNTL_FRQ/(2*MOD2_FRQ) movwf mod2_cnt movlw 1<<MOD2 xorwf flags chir6 decfsz duration goto chir1 incf duration btfsc flags,MOD1 goto chir1 btfsc flags,MOD2 goto chir1 bcf SPEAKER1 bcf SPEAKER2 movlw b'10001111' option_ bsf INTCON,GIE return

; sound off ; weak pull-ups disabled, ; prescale WDT 1:128 ; interrupts on

;------------------------------------------------------------------------; random tone ;------------------------------------------------------------------------routine random_tone

call get_random bcf INTCON,GIE motors_off call lock_LEDS bcf SPEAKER1 bsf SPEAKER2 movlf BEEP_PERIOD,work1 tone1 movfw rand+0 andlw h'0f' addlw h'18' movwf work2 clrwdt decfsz work2 goto tone2 movlw SPEAKER_MASK xorwf SPEAKER_PORT decfsz work1 goto tone1 bcf SPEAKER1 bcf SPEAKER2 bsf INTCON,GIE return ; *********************************************************************** *** ; executive routines * ; *********************************************************************** *** ;------------------------------------------------------------------------; echoes the IR sensors to the LEDs ;------------------------------------------------------------------------routine test_ir clrf blue bcf flags,TX_HI bsf flags,TX_LFT ; interrupts on ; half-cycle delay ; interrupts off

tone2

; toggle speaker output

bcf flags,TX_RGT call test_obstacle clrw skpnc movlw MAX_RGB movwf red clrf green call wait_half bcf flags,TX_LFT bsf flags,TX_RGT call test_obstacle clrw skpnc movlw MAX_RGB movwf green clrf red call wait_half bsf flags,TX_HI bsf flags,TX_LFT bcf flags,TX_RGT call test_obstacle clrw skpnc movlw MAX_RGB movwf red clrf green call wait_half bcf flags,TX_LFT bsf flags,TX_RGT call test_obstacle clrw skpnc movlw MAX_RGB movwf green clrf red call wait_half clrf red clrf green return ;------------------------------------------------------------------------; echoes the LDR sensor to the LEDs ;-------------------------------------------------------------------------

routine test_ldr movlf d'255',saturation movlf d'255',value testl1 call get_ldr movwf hue movlw subwf movlw skpnc movwf HUE_STEPS hue,w HUE_STEPS-1 hue ; sample the LDR

call conv_RGB call wait_tenth goto testl1 ;------------------------------------------------------------------------; echoes the preset to the LEDs ;------------------------------------------------------------------------if 0 routine test_preset movlf d'255',saturation movlf d'255',value testp1 call get_preset movwf hue movlw subwf movlw skpnc movwf HUE_STEPS hue,w HUE_STEPS-1 hue ; sample the preset

call conv_RGB call wait_tenth goto testp1 endif ;------------------------------------------------------------------------; moves a step, fed with the step period in 1/100s in w reg, returns the ; C flag set if obstacle detected

;------------------------------------------------------------------------if 0 routine move_step movwf repeat bcf flags,TX_HI moves1 bsf flags,TX_LFT bcf flags,TX_RGT call test_obstacle bc moves3 call short_wait decf repeat bz moves2 bcf flags,TX_LFT bsf flags,TX_RGT call test_obstacle bc moves3 call short_wait decfsz repeat goto moves1 moves2 clrc return moves3 call short_wait setc return endif ;------------------------------------------------------------------------; roaming (obstacle avoidance) ;------------------------------------------------------------------------if 0 routine roam ROAM_FORWARD ROAM_TURN equ equ d'40' d'60' ; signal obstacle detected ; signal obstacle not detected ; obstacle detected ? ; branch if yes ; obstacle detected ? ; branch if yes

bcf flags,TX_HI roam1 motors_off call wait_tenth leds_off bsf flags,TX_LFT bcf flags,TX_RGT call test_obstacle bnc roam2 bcf flags,TX_LFT bsf flags,TX_RGT call test_obstacle bc roam5 goto roam3 bcf flags,TX_LFT bsf flags,TX_RGT call test_obstacle bc roam4 clrf red clrf green movlf MAX_SPEED,speed1 movlf MAX_SPEED,speed2 movlw ROAM_FORWARD call wait goto roam1 roam3 clrf green movlf MAX_RGB,red clrf speed2 movlf MAX_SPEED,speed1 movlw ROAM_TURN call wait goto roam1 roam4 clrf red movlf MAX_RGB,green clrf speed1 movlf MAX_SPEED,speed2 movlw ROAM_TURN call wait goto roam1 roam5 movlf MAX_RGB,red movlf MAX_RGB,green call get_random clrw ; both LEDs on ; turn left or right at random ; green LED on ; turn left ; red LED on ; turn right ; move forward ; test for obstacles

roam2

; left and right detected ; left detected

; right detected

btfsc rand+0,7 movlw MAX_SPEED movwf speed1 clrw btfss rand+0,7 movlw MAX_SPEED movwf speed2 movfw rand+1 andlw h'7f' call wait goto roam endif ;------------------------------------------------------------------------; initialises hardware ;------------------------------------------------------------------------routine initialise clrf PORTA movlw PORTA_IO tris_A clrf PORTB movlw PORTB_IO tris_B clrf INTCON bsf STATUS,RP0 clrf PIE1 bcf STATUS,RP0 clrf PIR1 movlf h'07',CMCON clrf CCP1CON clrf RCSTA bsf STATUS,RP0 clrf TXSTA clrf VRCON bcf STATUS,RP0 clrwdt clrf PCLATH LEDS 0,0,0 movlf 1,duty clrf speed1 clrf accel1 clrf speed2 ; motors off ; clear watchdog timer ; page 0 ; LEDS off ; initialise ports

; disable interrupts

; disable comparators

clrf accel2 movlw b'10001111' option_ bcf PIR1,TMR1IF movlf b'00110001',T1CON clrf TMR1H clrf TMR1L PERIOD set ; weak pull-ups disabled, ; prescale WDT 1:128 ; initialise Timer1 ; timer on, prescale 1:8

(CLOCK/4)/(DUTY_CYCLE*DUTY_STEPS) ; initialise Timer2 ; duty cycle period ; timer on, no prescaling ; enable interrupts

bcf PIR1,TMR2IF bsf STATUS,RP0 movlf PERIOD,PR2 bcf STATUS,RP0 movlf b'00000100',T2CON clrf TMR2 bsf bsf bsf bcf bsf bsf STATUS,RP0 PIE1,TMR1IE PIE1,TMR2IE STATUS,RP0 INTCON,PEIE INTCON,GIE

return ;------------------------------------------------------------------------; main entry point ;------------------------------------------------------------------------routine main_entry call initialise bsf STATUS,RP0 movfw PCON bsf PCON,NOT_POR bcf STATUS,RP0 andlw 1<<NOT_POR bnz main2 main1 movlf h'20',FSR clrf 0 incf FSR btfss FSR,7 goto main1 call get_preset movwf arg1 LEDS MAX_RGB,0,0 call wait_half ; self test ; initialise hardware ; power-up ?

; branch if not ; clear bank 0

LEDS 0,MAX_RGB,0 call wait_half LEDS 0,0,MAX_RGB call wait_half LEDS 0,0,0 movlw d'25' call wait call beep_2 movlw d'25' call wait call test_ir call beep_2 movlw d'25' call wait call get_preset movwf arg2 movfw arg1 xorwf arg2,w xorlw h'c0' andlw h'c0' bz test_ldr call get_ldr xorwf ID swapf ID call get_preset xorwf ID skpnz incf ID MOTORS MAX_SPEED,MAX_SPEED call wait_half MOTORS 0,0 call get_preset andlw h'80' bcf flags,MALE skpz bsf flags,MALE movlw MALE_R skpnz movlw FEMALE_R movwf red movlw MALE_G skpnz movlw FEMALE_G movwf green movlw MALE_B skpnz movlw FEMALE_B movwf blue call wait_half ; preset moved ? ; test IR sensors

; branch if yes ; create a unique (non-zero) ID

; test motors

; male/female indication

LEDS 0,0,0 call clear_submission bsf flags,STATIC clrf isolated main2 goto main_loop ; clear submission list ; initially static ; initialise isolated timer

;------------------------------------------------------------------------; main loop ;------------------------------------------------------------------------routine main_loop ; wander timeout in seconds WANDER_TIMEOUT equ d'20' call initialise clrf state clrf target movlf -1,timeout clrf rtc clrf rtc_ call clear_messages call get_preset female andlw h'80' bcf flags,MALE skpz bsf flags,MALE btfsc flags,MALE goto do_male goto do_female ;------------------------------------------------------------------------; wander ;------------------------------------------------------------------------routine wander WANDER_WAIT WANDER_RAND equ equ d'150' h'7f' ; disable timeout timer ; clear real-time clock ; clear message stack ; determine whether male or ; re-initialise hardware ; null state

ZIGZAG_WAIT ZIGZAG_RAND

equ equ

d'25' h'03'

LEDS 0,0,0 call get_random clrw btfss movlw movwf clrw btfsc movlw movwf ; spin left or right at random rand+1,0 MAX_SPEED speed1 rand+1,0 MAX_SPEED speed2

movlw WANDER_WAIT call wait movfw rand+0 andlw WANDER_RAND addlw 1 call wait movfw andlw addlw movwf wand1 rand+1 ZIGZAG_RAND ZIGZAG_RAND/2 repeat ; zig zag forward

MOTORS MAX_SPEED,0 movlw ZIGZAG_WAIT call wait MOTORS 0,MAX_SPEED movlw ZIGZAG_WAIT call wait decfsz repeat goto wand1 MOTORS 0,0 call long_wait call long_wait bcf flags,STATIC goto main_loop ; not static

;------------------------------------------------------------------------; crazy ;------------------------------------------------------------------------routine crazy

CRAZY_WAIT CRAZY_RAND SPIN_WAIT SPIN_RAND SLEEP_TIMEOUT

equ equ equ equ equ

d'10' h'1f' d'400' h'7f' d'15'

movlf SLEEP_TIMEOUT,repeat craz1 call get_random andlw CRAZY_RAND addlw CRAZY_WAIT movwf count movlw MAX_RGB clrf red btfsc rand+1,0 movwf red clrf green btfsc rand+1,1 movwf green clrf blue btfsc rand+1,2 movwf blue call random_tone movlw d'10' call wait decfsz count goto craz2 LEDS 0,0,0 clrw btfss movlw movwf clrw btfsc movlw movwf rand+1,3 MAX_SPEED speed1 rand+1,3 MAX_SPEED speed2 ; spin left or right at random ; random colour

craz2

movlw SPIN_WAIT/2 call wait movlw SPIN_WAIT/2 call wait movfw rand+0 andlw SPIN_RAND addlw 1 call wait MOTORS 0,0 decfsz repeat goto craz1

clrf PORTA clrf PORTB movlw b'10000111' option_ clrf INTCON clrwdt sleep nop

; LEDs and motors off ; prescale TMR0 1:256 ; disable interrupts

; standby mode

;------------------------------------------------------------------------; male ;------------------------------------------------------------------------routine do_male ; probability masks PROB_M equ h'03' PROB_M_F equ h'07' PROB_M_M equ h'03' ; rutting period in seconds RUTTING_PERIOD equ d'10' ; periods in 1/100 s INCH_MALE equ INCH_FEMALE equ d'7' d'12' ; initialise wander timer ; sample the LDR ; high power emitters ; real-time clock tick ?

movlf WANDER_TIMEOUT*2,timer call get_ldr movwf light bsf flags,TX_HI dom1 movfw rtc xorwf rtc_,w xorwf rtc_ tstw bz dom2 call expire_messages decf isolated bz crazy decf timer bz wander btfsc flags,STATIC goto dom2

; branch if not ; expire messages ; isolated timeout ? ; branch if yes ; wander timeout ? ; branch if yes ; static ? ; branch if not

call get_ldr xorwf light,w xorwf light andlw MOTION_MASK bnz wander dom2 clrf state call test_male bnz do_male_male call test_female bnz do_male_female LEDS 0,0,0 movlf -1,timeout call get_random andlw PROB_M bz dom3 call rx_message bz dom1 bc dom1 call do_message goto dom1 dom3 movlf MSG_HELLO,message+0 movff ID,message+1 clrf message+2 call tx_random right movff message+0,command call wait_ack bz dom1 movff command,message+2 call push_message goto dom1

; test for light level change

; branch if change

; male detected ? ; branch if yes ; female detected ? ; branch if yes

; disable timeout timer

; wait for message ; branch if timeout or error ; process message

; command ; source ID ; broadcast ; transmit 'HELLO' on left or ; save command ; acknowledged ? ; branch if not ; save message

;------------------------------------------------------------------------; male-male ;------------------------------------------------------------------------routine do_male_male

movlf STATE_M_M,state call get_random andlw PROB_M_M bz domm2 movfw rand+0 andlw 3 bz domm3 domm1 call rx_message bz do_male bc do_male call do_message goto do_male domm2 movlf MSG_HELLO,message+0 movff ID,message+1 clrf message+2 call tx_random movff message+0,command call wait_ack bz do_male movff command,message+2 call push_message goto do_male domm3 LEDS 0,0,0 movlw d'2'*RUTTING_PERIOD btfsc timeout,7 movwf timeout tstf timeout bnz domm4 call get_random andlw 3 bnz domm4 movlf MSG_RAM,message+0 movff ID,message+1 movff target,message+2 call tx_both call wait_ack bnz ram

; set state

; wait for message ; branch if timeout or error ; process message

; command ; source ID ; broadcast ; transmit 'HELLO' on left or ; save command ; acknowledged ? ; branch if not ; save message

right

; start timeout timer if ; disabled ; timeout ? ; branch if not

; command ; source ID ; destination ID ; signal 'RAM' ; acknowledged ? ; ram if yes

domm4

call get_random andlw h'10' addlw h'20' call hiss bc domm1 MOTORS MAX_SPEED,MAX_SPEED movlw INCH_MALE call wait MOTORS 0,0 goto domm2

; hiss

; inch forward

;------------------------------------------------------------------------; male-female ;------------------------------------------------------------------------routine do_male_female movlf STATE_M_F,state call get_random andlw PROB_M_F bz domf1 call rx_message bz do_male bc do_male call do_message goto do_male domf1 bcf flags,TX_HI call get_random movfw rand+0 andlw h'0f' movwf offset movlf movff movff movff MSG_MATE,message+0 ID,message+1 target,message+2 offset,message+3 ; low power emitters ; random hue offset ; wait for message ; branch if timeout or error ; process message ; set state

; ; ; ;

command source ID destination ID hue offset

call tx_both call wait_ack bnz mate LEDS MALE_R,MALE_G,MALE_B call click call click

; transmit 'MATE' ; acknowledged ? ; branch if yes

; clicks

btfsc rand+0,0 call click btfsc rand+0,1 call click LEDS 0,0,0 movfw rand+0 andlw 1 bz do_male MOTORS MAX_SPEED,MAX_SPEED movlw INCH_FEMALE call wait MOTORS 0,0 goto do_male ;------------------------------------------------------------------------; female ;------------------------------------------------------------------------; probability masks PROB_F equ h'1f' PROB_F_F equ h'0f' PROB_F_M equ h'07' ; periods in 1/100 s CHIRRUP_WAIT equ CHIRRUP_FLASH equ d'50' d'100' ; inch forward

routine do_female movlf WANDER_TIMEOUT*2,timer call get_ldr movwf light bsf flags,TX_HI movlf d'255',saturation movlf d'255',value dof1 movfw rtc xorwf rtc_,w xorwf rtc_ tstw bz dof2 call expire_messages decf isolated bz crazy ; real-time clock tick ? ; initialise wander timer ; sample the LDR ; high power emitters

; branch if not ; expire messages ; isolated timeout ? ; branch if yes

decf timer bz wander btfsc flags,STATIC goto dof2 call get_ldr xorwf light,w xorwf light andlw MOTION_MASK bnz wander dof2 clrf state call test_male bnz do_female_male call test_female bnz do_female_female call get_random andlw PROB_F bz dof3 call rx_message bz dof1 bc dof1 call do_message goto dof1 dof3 movlf MSG_HELLO,message+0 movff ID,message+1 clrf message+2 call tx_both movff message+0,command call wait_ack bz dof4 movff command,message+2 call push_message dof4 call chirrup goto dof1

; wander timeout ? ; branch if yes ; static ? ; branch if not ; test for light level change

; branch if change

; male detected ? ; branch if yes ; female detected ? ; branch if yes

; wait for message ; branch if timeout or error ; process message

; command ; source ID ; broadcast ; transmit 'HELLO' ; save command ; acknowledged ? ; branch if not ; save message ; chirrup

;------------------------------------------------------------------------; female-female ;-------------------------------------------------------------------------

routine do_female_female WANDER_PROB equ h'1f' ; set state

movlf STATE_F_F,state call get_random andlw PROB_F_F bz doff1 call rx_message bz do_female bc do_female call do_message goto do_female doff1 movfw sublw skpc clrw sublw movwf rand+0 HUE_STEPS HUE_STEPS hue

; wait for message ; branch if timeout or error ; process message

; select a hue at random

movlf MSG_HUE,message+0 movff ID,message+1 clrf message+2 movff hue,message+3 call tx_both movff message+0,command call wait_ack bz doff2 movff command,message+2 call push_message call conv_RGB call chirrup movlw CHIRRUP_FLASH call wait LEDS 0,0,0 movfw rand+0 andlw WANDER_PROB bz wander goto do_female doff2 call chirrup

; ; ; ;

command source ID broadcast hue

; transmit 'HUE' ; save command ; acknowledged ? ; branch if not ; save message

; chirrup

; chirrup

goto do_female ;------------------------------------------------------------------------; female-male ;------------------------------------------------------------------------routine do_female_male movlf STATE_F_M,state call get_random andlw PROB_F_M bz dofm1 call rx_message bz do_female bc do_female call do_message goto do_female dofm1 movlf MSG_HELLO,message+0 movff ID,message+1 clrf message+2 call tx_random right movff message+0,command call wait_ack bz dofm2 movff command,message+2 call push_message dofm2 ; save command ; acknowledged ? ; branch if not ; save message ; command ; source ID ; broadcast ; transmit 'HELLO' on left or ; wait for message ; branch if timeout or error ; process message ; set state

LEDS FEMALE_R,FEMALE_G,FEMALE_B call chirrup LEDS 0,0,0 goto do_female ; chirrup

;------------------------------------------------------------------------; processes a message ;------------------------------------------------------------------------routine do_message

movfw message+2 skpz subwf ID,w bnz mess6 clrf isolated movfw message+0 andlw MSG_MASK movwf command sublw MSG_ACK bz mess6 movfw command sublw MSG_HELLO bnz mess2 btfss flags,MALE goto mess1 movfw message+1 call test_submission bnz submit btfsc message+0,MSG_SEX goto mess5 call ack_message LEDS MALE_R,MALE_G,MALE_B call click call click btfsc rand+0,0 call click btfsc rand+0,1 call click LEDS 0,0,0 goto mess6 mess1 btfsc message+0,MSG_SEX goto mess5 call ack_message call chirrup goto mess6 mess2 movfw command sublw MSG_RAM bnz mess3 movlw STATE_M_M

; correct destination ? ; branch if not ; not isolated ; message command

; acknowledge ? ; branch if yes ; 'HELLO' ? ; branch if not

; submit ? ; branch if yes ; female source ? ; branch if not ; acknowledge message

; clicks

; female source ? ; branch if not ; acknowledge message ; chirrup

; 'RAM' ? ; branch if not ; male-male state ?

subwf state,w bnz mess6 call ack_message call wait_tenth call ack_message goto ram mess3 movfw command sublw MSG_HUE bnz mess4 movff message+3,hue call push_message call ack_message movlw CHIRRUP_WAIT call wait call conv_RGB call chirrup

; branch if not ; acknowledge message

; ram ; 'HUE' ? ; branch if not ; hue ; save message ; acknowledge message

; chirrup

movlw CHIRRUP_FLASH-CHIRRUP_WAIT call wait LEDS 0,0,0 goto mess6 mess4 movfw command sublw MSG_MATE bnz mess5 movff message+3,offset call ack_message goto mate mess5 mess6 call ack_message return ; acknowledge message ; 'MATE' ? ; branch if not ; hue offset ; acknowledge message

;------------------------------------------------------------------------; male-male ram ;------------------------------------------------------------------------; ram period in seconds RAM_PERIOD equ d'3'

routine ram bcf flags,TX_HI LEDS MAX_RGB,0,0 MOTORS MAX_SPEED,MAX_SPEED movlw d'2'*RAM_PERIOD*2 movwf timeout ram1 tstf timeout bz ram6 movlw d'2'*RAM_PERIOD subwf timeout,w bc ram2 MOTORS 0,0 ram2 call get_random andlw 3 bnz ram3 movlf MSG_SUBMIT,message+0 movff ID,message+1 movff target,message+2 call tx_both call wait_ack bnz ram4 ram3 call rx_message bz ram1 bc ram1 call get_command sublw MSG_SUBMIT bnz ram1 MOTORS 0,0 bsf flags,TX_HI variable n = d'3' while n > 0 call ack_message call wait_tenth n -= 1 endw movfw target call push_submission if 0 ; high power emitters ; acknowledge message ; command ; source ID ; destination ID ; transmit 'SUBMIT' ; acknowledged ? ; branch if yes ; wait for message ; branch if timeout or error ; 'SUBMIT' received ? ; branch if not ; start timeout timer ; timeout ? ; branch if yes ; low power emitters ; red

; add to submission list

call get_random andlw h'80' movlw 0 skpz movwf speed1 skpnz movwf speed2 VEER equ d'150'

; veer to the right or left

movlw VEER call wait endif goto submit ram4 MOTORS 0,0 call wait_half ram5 movlf d'20',repeat call beep LEDS 0,0,MAX_RGB call wait_tenth call beep LEDS MAX_RGB,0,0 call wait_tenth decfsz repeat goto ram5 MOTORS 0,0 LEDS 0,0,0 call long_wait call long_wait goto wander ;------------------------------------------------------------------------; male-male submit ;------------------------------------------------------------------------routine submit MOTORS 0,0 LEDS 0,MAX_RGB/4,0 call long_wait call long_wait goto main_loop ; dominant - flash and beep ; submissive

ram6

;------------------------------------------------------------------------; male-female mate ;------------------------------------------------------------------------routine mate MATE_REPEAT equ d'6'

MOTORS 0,0 LEDS 0,0,0 mate1 movlf MATE_REPEAT*2,repeat call beep call wait_tenth decfsz repeat goto mate1 clrf hue movlf MATE_REPEAT,repeat mate2 call wait_tenth clrf saturation movlf d'255',value mate3 decf saturation call conv_RGB call short_wait decfsz saturation goto mate3 movfw addwf movlw subwf skpnc movwf mate4 offset hue HUE_STEPS hue,w hue ; fade to white ; beep

incf saturation call conv_RGB call short_wait incfsz saturation goto mate4 movlf d'255',saturation clrf value

mate5

decf value call conv_RGB call short_wait decfsz value goto mate5

; fade to black

call wait_tenth movfw addwf movlw subwf skpnc movwf mate6 offset hue HUE_STEPS hue,w hue

incf value call conv_RGB call short_wait incfsz value goto mate6 decfsz repeat goto mate2 LEDS 0,0,0 call long_wait call long_wait goto wander

; *********************************************************************** *** ; EEPROM data * ; *********************************************************************** *** org h'2100' end

Monster hexapod este un robot care foloseste o dioda emitatoare de infrarosu pentru ochi sale, i se mut pe picioarele sale ase. Se pare lsat atunci cnd detecteaz obstacole, i continu s se mite nainte, dac nu exist nici o umbr n faa senzorului. Caracteristici:

Foloseste un emitting diode infrarou ca senzor. Dou seturi de motoare de viteze (neasamblat)

Necesit (1) 9V i (2) "AA" baterii.

O insect electronic care chirrups, vibreaz antenelor sale, si reactioneaza la lumina si sunet. Poate fi instruii cu fluierul furnizate pentru a rspunde la lumina in moduri diferite (la ciripitul n timpul zilei i la lumina ochilor si pe timp de noapte, de exemplu). Proprietarul insectoid Ghidul Testarea 1. Conectai acumulatorul. Dumneavoastr insectoid ar trebui s ciripitul o dat. 2. Scoatei bateria i apoi reconectai-l cu senzorul de lumin (LDR) aproape de o lumin. Ochii (LED1 LED2 i) trebuie s se aprind. 3. Scoatei bateria i apoi reconectai-l de data aceasta cu senzorul de lumin n ntuneric. Ochii ar trebui s rmn n afara. 4. D-o explozie singur pe scurt fluier. Ochii ar trebui s clipeasc rapid de cteva ori. 5. insectoid Twitches sa antene ori de cte ori chirrups. Gradul de deplasare a antenelor depinde foarte mult de greutatea la capete. Reglai buci de Blu-Tack prin adugarea sau eliminarea de cantitati mici pn la cea mai mare micare se obine ("rezonan"). Reinei, totui, c micarea antenelor este destul de subtil, cel mult, un tnr de milimetri. 6. Dac dumneavoastr insectoid sa comportat ca i cum acest lucru, atunci este de lucru n mod corespunztor. Suntei acum gata sa iti dresezi insectoid . Pregtire Comportamentul de insectoid ca rspuns la lumin pot fi modificate. Aciunile sale de triluri i iluminatul ochii sale pot fi modificate independent. Fluierul este folosit pentru a instrui insectoid . Vrtej de fluierul nva aceasta s nu fac ceva. Cu alte cuvinte, fluier acioneaz ca o pedeaps. De exemplu, n cazul n care insectoid tocmai a chirruped i ai vrut s-l arunce n aer, apoi s tac fluier. insectoid va clipi ochii de cteva ori s recunoasc faptul c le-a neles. Dac, pe de alt parte, tu ai vrut s arunce n aer, apoi ciripitul fluier, atunci cnd este silenios i va nva s ciripitul n viitor.

Insectoid trebuie s fie nvai destul de cteva ori nainte de formare are un efect complet. Pstrai suflare fluierul pn cnd insectoid se comport aa cum dorii s. Atunci cnd pe deplin instruit insectoid nu va mai clipi ochii, ca rspuns la fluierul. De exemplu, ai putea antrena dvs. insectoid la lumina ochilor si n ntuneric i ciripitul n lumina soarelui. Sau, alternativ, la lumina ochilor si n timpul zilei i ciripitul pe timp de noapte. Mai realist ai putea nva s doarm n timpul zilei i s vin n via doar pe timp de noapte. Insectoid va aminti ei de formare profesional dup ce bateria este eliminat. Dac dorii s restaurai insectoid la stat neinstruit, nainte de re-formare, inei-l direct sub o lumin foarte strlucitoare, sau atingei o tor la senzorul de lumina, si in acelasi timp conectati bateria. insectoid va da un semnal sonor lung i resetai se la "setrile din fabric". Prieten sau duman Insectoid va recunoate pe alii din speciile sale proprii (se recunoate ciripitul). n cazul n care consider c un alt insectoid este un rival, atunci l va amenina. Program

FILE: insect.asm * ; CONTENTS: 'Insectoid' insect * ; COPYRIGHT: MadLab Ltd. 1998-2006 * ; AUTHOR: James Hutchby * ; UPDATED: 21/07/06 * ; *********************************************************************** *** list p=12F629 #include "p12f629.inc" __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _PWRTE_ON & _BODEN_OFF & _CP_ON & _CPD_OFF __idlocs h'BD21' errorlevel -207,-302,-305,-306 ; *********************************************************************** *** ; * ; Specification * ; * ; *********************************************************************** ***

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

Stimulus -------dark dark dark dark light light light light

Response -------eyes chirrup eyes + chirrup eyes chirrup eyes + chirrup

test chirrup on power-up LEDs echo LDR light sensor on power-up training whistle within 1 second of response LEDs flash when training whistle acknowledged 8 whistles inhibits response LEDs stop flashing when fully trained sleep mode when fully trained if null response faint click as wakes from sleep = 'heartbeat' threatens if recognises another

; training saved to EEPROM ; subsequently loads training from EEPROM on power-up ; factory reset if very bright light on power-up (signalled by long beep) ; *********************************************************************** *** ; * ; Port assignments * ; * ; *********************************************************************** *** GPIO_IO GATE LDR MIC LEDS PIEZO ANTENNAE LEDS_on equ equ equ equ equ equ equ macro bcf GPIO_,LEDS movff GPIO_,GPIO bsf STATUS,RP0 bcf TRISIO,LEDS bcf STATUS,RP0 b'111000' 2 5 3 4 1 0 ; GPIO I/O status ; ; ; ; ; ; microphone enable LDR microphone LEDs speaker antennae

; LEDs on

endm LEDS_off macro bsf STATUS,RP0 bsf TRISIO,LEDS bcf STATUS,RP0 endm charge macro bsf STATUS,RP0 bsf TRISIO,LDR bcf STATUS,RP0 endm discharge macro bcf GPIO_,LDR movff GPIO_,GPIO bsf STATUS,RP0 bcf TRISIO,LDR bcf STATUS,RP0 endm ; *********************************************************************** *** ; * ; Constants and timings * ; * ; *********************************************************************** *** CLOCK MIC_SAMPLE MIC_REPEAT equ d'4000000' equ equ d'20' d'3' ; processor clock frequency in Hz ; microphone sample period in ms ; number of successive sample periods ; discharge capacitor ; charge capacitor ; LEDs off

; total sample period in ms SAMPLE_TIME equ MIC_SAMPLE*MIC_REPEAT DISCHARGE RESET BRIGHT THRESHOLD WHISTLE_FRQ CNTL_FRQ FUND_FRQ MOD1_FRQ equ equ equ equ equ equ equ equ d'1' d'2' d'100' d'5' d'3000' d'100' d'4000' d'15' ; capacitor discharge period in 1/100 s ; factory reset threshold ; bright threshold ; silence threshold ; whistle frequency in Hz ; control frequency (100 Hz) ; chirrup fundamental frequency ; modulation frequency #1

MOD2_FRQ ANTENNAE_ON ANTENNAE_OFF CHIRRUP_PITCH CHIRRUP_TIME RECOG_DELAY HEADER_CYCLES CLICK_PERIOD ON_FRQ OFF_FRQ

equ equ equ equ equ equ equ equ equ equ

d'3' d'3' d'3'

; modulation frequency #2 ; antennae pulse on time in 1/100 s ; antennae pulse off time in 1/100 s

CLOCK/(2*FUND_FRQ*d'16') d'35' d'5' d'250' d'10' d'4800' d'3200' ; chirrup duration in 1/100 s ; delay when recognising in 1/100 s ; ; ; ; click click click click header duration in cycles period in ms 'on' frequency in Hz 'off' frequency in Hz

; click 'on' and 'off' durations in cycles ON_CYCLES equ (ON_FRQ*CLICK_PERIOD)/d'1000' OFF_CYCLES equ (OFF_FRQ*CLICK_PERIOD)/d'1000' BITS ID FLASH_RATE FLASH_REPEAT equ equ equ equ d'2' b'01' d'6' d'4' ; number of data bits ; ID code ; LEDs flash rate ; LEDs flash repeat

; differentiated sound events SILENCE equ b'00' ; no pulses in sample period NOISE equ b'01' ; varying or overflow pulses WHISTLE equ b'10' ; sustained pulses at whistle frequency ; training mask and value TRAINING equ (b'11'<<6)|(b'11'<<4) TRAINING_ equ (WHISTLE<<6)|(WHISTLE<<4) RESPONSE MAGIC BEEP_PITCH equ equ equ d'8' d'42' d'40' ; response count ; valid EEPROM data ; long beep pitch

; *********************************************************************** *** ; * ; File register usage * ; * ; *********************************************************************** *** RAM MAX equ set h'20' h'60' ; various flags

cblock RAM flags

GPIO_ ndx training:d'8' response history pulses timer rand_l, rand_h pitch service mod1_cnt, mod2_cnt duty_cnt tx_data prev count_l, count_h sound count, loop work1, work2 RAM_ endc

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

shadow copy EEPROM index training counters (4 x dark + 4 x light) response (00 to 11) sound event history buffer previous pulse count response timer random number chirrup pitch service flags modulation counters antennae duty cycle counter transmit data previous microphone state pulse count sound event scratch counters work registers

if RAM_ > MAX error "File register usage overflow" endif ; flag bits LIGHT TRAINED_DARK TRAINED_LIGHT equ equ equ 0 1 2 0 1 0 1 2 3 ; set if light sensed ; set if fully trained in dark ; set if fully trained in light ; set if eyes on ; set if chirruping ; ; ; ; fundamental flag modulation #1 flag modulation #2 flag antennae duty cycle flag

; response bits EYES equ CHIRRUP equ ; service flags FUND equ MOD1 equ MOD2 equ DUTY equ

; *********************************************************************** *** ; * ; Macros * ; * ; *********************************************************************** *** routine label macro label endm ; routine

table label entry

macro label addwf PCL endm macro value retlw value endm macro label call label endm macro label goto label endm macro iorlw 0 endm macro f1,f2 movfw f1 movwf f2 endm macro n,f movlw n movwf f endm

; define lookup table

; define table entry

index

; index lookup table

jump

; jump through table

tstw

; test w register

movff

; move file to file

movlf

; move literal to file

;------------------------------------------------------------------------; reset vector ;------------------------------------------------------------------------org 0 bsf STATUS,RP0 call h'3ff' movwf OSCCAL bcf STATUS,RP0 goto main_entry ; *********************************************************************** *** ; * ; Procedures * ; *

; *********************************************************************** *** ;------------------------------------------------------------------------; returns a pseudo random number in w reg ;------------------------------------------------------------------------routine get_random movfw rand_l iorwf rand_h,w bnz rand1 movff pulses,rand_l movff TMR0,rand_h rand1 rlf rand_h,w xorwf rand_h,w movwf work1 swapf rand_l,w btfsc rand_h,4 xorlw h'80' xorwf work1 rlf work1 rlf rand_l rlf rand_h movfw rand_l return ;------------------------------------------------------------------------; timing delay, fed with the delay in 1/100 s in the w reg ;------------------------------------------------------------------------routine delay movwf count delay1 delay2 delay3 movlw CLOCK/(d'100'*d'16'*d'256') movwf work1 clrf work2 clrwdt decfsz work2 goto delay3 decfsz work1 goto delay2 decfsz count ; [4] ; [4] ; [8] ; seed generator ; calculate next in sequence ; msb <= Q15 ^ Q14 ; msb <= Q12 ^ Q3

; << 1 + (Q15 ^ Q14 ^ Q12 ^ Q3) ; random number

goto delay1 return ;------------------------------------------------------------------------; writes the EEPROM with w reg ;------------------------------------------------------------------------routine write_EEPROM bsf STATUS,RP0 movwf EEDATA movff ndx,EEADR movfw EEDATA bsf EECON1,RD xorwf EEDATA bz write2 movwf EEDATA bsf EECON1,WREN movlf h'55',EECON2 movlf h'aa',EECON2 bsf EECON1,WR clrwdt btfsc EECON1,WR goto write1 bcf EECON1,WREN bcf STATUS,RP0 return ;------------------------------------------------------------------------; reads the EEPROM into w reg ;------------------------------------------------------------------------routine read_EEPROM bsf STATUS,RP0 movff ndx,EEADR bsf EECON1,RD movfw EEDATA bcf STATUS,RP0 return

write1

write2

;------------------------------------------------------------------------; transmits a click, fed with the number of cycles in the w reg ;------------------------------------------------------------------------routine tx_on movwf count movlw CLOCK/(2*ON_FRQ*d'12') goto tx0 routine tx_off movwf count movlw CLOCK/(2*OFF_FRQ*d'12') tx0 tx1 movwf pitch clrwdt bsf GPIO_,PIEZO movff GPIO_,GPIO tx2 movff pitch,work1 decfsz work1 goto tx2 bcf GPIO_,PIEZO movff GPIO_,GPIO tx3 movff pitch,work1 decfsz work1 goto tx3 decfsz count goto tx1 return ;------------------------------------------------------------------------; transmits an ID code ;------------------------------------------------------------------------routine tx_ID movlw HEADER_CYCLES call tx_on ; header ; toggle speaker output ; half-cycle delay ; [4] ; [8] ; toggle speaker output ; half-cycle delay ; [4] ; [8]

bit tx4

movlf 1+BITS+1,count_h movlf ID<<(7-BITS),tx_data movlw OFF_CYCLES btfsc tx_data,7 movlw ON_CYCLES btfss tx_data,7 call tx_off btfsc tx_data,7 call tx_on rlf tx_data decfsz count_h goto tx4 return

; start bit + data bits + stop

;------------------------------------------------------------------------; sounds a long beep ;------------------------------------------------------------------------routine long_beep movlf d'10',count long1 long2 clrf work1 clrwdt bsf GPIO_,PIEZO movff GPIO_,GPIO long3 movlf BEEP_PITCH,work2 decfsz work2 goto long3 bcf GPIO_,PIEZO movff GPIO_,GPIO long4 movlf BEEP_PITCH,work2 decfsz work2 goto long4 decfsz work1 goto long2 decfsz count goto long1 return ;------------------------------------------------------------------------; sounds a 'chirrup' and moves the antennae, fed with the duration in ; toggle speaker output ; half-cycle delay

; toggle speaker output ; half-cycle delay

; 1/100 s in the w reg ;------------------------------------------------------------------------routine chirrup movwf count movlf CHIRRUP_PITCH,pitch bsf STATUS,RP0 movlw b'10000111' movwf OPTION_REG bcf STATUS,RP0 clrf service clrf TMR0 movlw movwf movwf movwf beep1 1 mod1_cnt mod2_cnt duty_cnt ; pitch ; prescale TMR0 1:256, ; weak pull-ups disabled

btfss service,MOD1 goto beep2 btfss service,MOD2 goto beep2 btfsc service,FUND bsf GPIO_,PIEZO btfss service,FUND ; toggle speaker output

beep2

bcf GPIO_,PIEZO movff GPIO_,GPIO movff pitch,work1 clrwdt decfsz work1 goto beep3 movlw 1<<FUND xorwf service btfsc service,DUTY bsf GPIO_,ANTENNAE btfss service,DUTY bcf GPIO_,ANTENNAE movff GPIO_,GPIO movfw TMR0 andlw h'80' bnz beep1

; clear speaker output ; ; ; ; half-cycle delay [4] [4] [8]

beep3

; toggle fundamental flag ; move antennae

; control

CNTL

set

(CLOCK/4)/(d'256'*CNTL_FRQ) ; recharge timer

movlf -CNTL,TMR0

decfsz mod1_cnt goto beep4 movlw CNTL_FRQ/(2*MOD1_FRQ) movwf mod1_cnt movlw 1<<MOD1 xorwf service beep4 decfsz mod2_cnt goto beep5 movlw CNTL_FRQ/(2*MOD2_FRQ) movwf mod2_cnt movlw 1<<MOD2 xorwf service beep5 decfsz duty_cnt goto beep6 movlw btfss movlw movwf ANTENNAE_ON service,DUTY ANTENNAE_OFF duty_cnt

; modulation #1 ; recharge counter ; toggle flag ; modulation #2 ; recharge counter ; toggle flag ; antennae duty cycle ; recharge counter

movlw 1<<DUTY xorwf service beep6 decfsz count goto beep1 incf count btfsc service,MOD1 goto beep1 btfsc service,MOD2 goto beep1 bcf GPIO_,PIEZO bcf GPIO_,ANTENNAE movff GPIO_,GPIO return

; toggle flag

;------------------------------------------------------------------------; samples the LDR light sensor, returns the result in w reg ;------------------------------------------------------------------------routine get_ldr discharge movlw DISCHARGE ; discharge the capacitor

call delay LEDS_off clrwdt clrf count charge variable n = d'8' while n > 0 incf count btfsc GPIO,LDR goto getl2 n -= 1 endw getl1 incf count bz getl3 btfss GPIO,LDR goto getl1 getl2 getl3 incf count btfss response,EYES goto getl4 LEDS_on decf count,w return ;------------------------------------------------------------------------; polls the microphone and light sensor ;------------------------------------------------------------------------routine poll bcf flags,LIGHT call get_ldr sublw BRIGHT skpnc bsf flags,LIGHT clrf sound clrf prev clrf count ; poll the LDR ; [4] ; branch if timeout [8] ; charged ? [4] ; loop if not [8] ; [4] ; charged ? [8] ; branch if yes ; charge the capacitor

getl4

; signal silence ; previous microphone state

poll1

clrf count_l clrf count_h

; clear pulse count

; number of loop iterations LOOP set (CLOCK*MIC_SAMPLE)/(d'1000'*d'60'*d'16') movlf LOOP,work1 poll2 poll3 movlf d'16',work2 movlw 1 xorwf prev nop movlw 0 btfsc GPIO,MIC movlw 1 xorwf prev movwf prev skpnz incf count_l skpnz incf count_h decfsz work2 goto poll3 clrwdt decfsz work1 goto poll2 incf count tstf count_h bnz poll6 movlw THRESHOLD subwf count_l,w bnc poll5 ; high frequency ? ; branch if yes ; silence ? ; branch if yes ; [4] ; [4] ; sample the microphone [4] ; [4] ; [8] ; [4] ; [4] ; branch if no change [4] ; increment pulse count [4] ; [8] ; [4] ; [8]

; number of click pulses PULSES set (2*ON_FRQ*MIC_SAMPLE)/d'1000' min max set set (PULSES*(d'100'-d'10'))/d'100' (PULSES*(d'100'+d'10'))/d'100' ; within tolerance of number ; of click pulses ?

movlw min subwf count_l,w bnc poll4 movlw max subwf count_l,w bnc rx_ID

; branch if yes

; number of whistle pulses PULSES set (2*WHISTLE_FRQ*MIC_SAMPLE)/d'1000'

min max poll4

set set

(PULSES*(d'100'-d'40'))/d'100' (PULSES*(d'100'+d'40'))/d'100' ; within tolerance of number ; of whistle pulses ?

movlw min subwf count_l,w bnc poll6 movlw max subwf count_l,w bnc poll7 goto poll6

; branch if yes

poll5 poll6 poll7 poll8

tstf sound bz poll8 movlf NOISE,sound goto poll8 movlf WHISTLE,sound movlw MIC_REPEAT subwf count,w bnz poll1 return ; signal noise ; signal whistle ; loop for all sample periods

;------------------------------------------------------------------------; tests for a click, returns the click state in the carry flag ;------------------------------------------------------------------------routine test_click clrf prev clrf count_l ; previous microphone state ; clear pulse count

; number of loop iterations LOOP set (CLOCK*CLICK_PERIOD)/(d'1000'*d'6'*d'56') movlf LOOP,work1 testc1 movlw 1 xorwf prev nop movlw 0 btfsc GPIO,MIC movlw 1 xorwf prev movwf prev skpnz ; [4] ; [4] ; sample the microphone [4] ; [4] ; [8] ; [4] ; [4] ; branch if no change [4]

incf count_l clrwdt decfsz work1 goto testc1 MID_CYCLES equ

; increment pulse count [4] ; [4] ; [4] ; [8]

(ON_CYCLES+OFF_CYCLES)/2 ; carry flag set if 'on' click

movlw (2*MID_CYCLES)/d'6' subwf count_l return

;------------------------------------------------------------------------; receives an ID code ;------------------------------------------------------------------------routine rx_ID rx1 call test_click bc rx1 movlf 1+BITS+1,count_h bit rx2 clrf tx_data goto rx3 call test_click call test_click call test_click call test_click call test_click call test_click rlf tx_data decfsz count_h goto rx2 rrf tx_data bc rx4 btfsc tx_data,BITS goto rx4 movfw tx_data xorlw ID bz recognise rx4 clrf history goto main_loop ;------------------------------------------------------------------------; another recognised ; test stop bit ; test start bit ; test ID code ; wait for start bit ; start bit + data bits + stop

rx3

; clear the history buffer

;------------------------------------------------------------------------routine recognise LEDS_on call tx_ID LEDS_off movlw RECOG_DELAY call delay goto recognise ; LEDs on ; transmit ID code ; LEDs off ; delay ; loop

;------------------------------------------------------------------------; initialises training ;------------------------------------------------------------------------routine init_training movlf training,FSR movlf d'8',count movlf RESPONSE,0 incf FSR decfsz count goto init1 bcf flags,TRAINED_DARK bcf flags,TRAINED_LIGHT return ;------------------------------------------------------------------------; saves training to EEPROM ;------------------------------------------------------------------------routine save_training movlf training,FSR movlf 1,ndx movlf d'8',count movfw 0 call write_EEPROM incf FSR incf ndx decfsz count goto save1 clrf ndx

init1

save1

movlw MAGIC call write_EEPROM return ;------------------------------------------------------------------------; loads training from EEPROM ;------------------------------------------------------------------------routine load_training movlf 1,ndx movlf training,FSR movlf d'8',count call read_EEPROM movwf 0 movlw RESPONSE+1 subwf 0,w movlw RESPONSE skpnc movwf 0 incf ndx incf FSR decfsz count goto load1 return ;------------------------------------------------------------------------; erases training from EEPROM ;------------------------------------------------------------------------routine erase_training clrf ndx clrw call write_EEPROM return ;------------------------------------------------------------------------; modifies training ;------------------------------------------------------------------------modify_training macro ; decrement training counter if ; not zero

load1

movlw training+0 btfsc flags,LIGHT

movlw training+4 addwf response,w movwf FSR tstf 0 skpz decf 0 endm ;------------------------------------------------------------------------; determines if fully trained ;------------------------------------------------------------------------test_trained except one clrf work1 tstf skpz incf tstf skpz incf tstf skpz incf tstf skpz incf training+0 work1 training+1 work1 training+2 work1 training+3 work1 ; check integrity macro ; trained if all counters ; in a set are zero

tstf work1 skpnz call init_training bcf flags,TRAINED_DARK decf work1 skpnz bsf flags,TRAINED_DARK clrf tstf skpz incf tstf skpz incf tstf skpz incf tstf skpz incf work1 training+4 work1 training+5 work1 training+6 work1 training+7 work1

tstf work1

; check integrity

skpnz call init_training bcf flags,TRAINED_LIGHT decf work1 skpnz bsf flags,TRAINED_LIGHT endm ;------------------------------------------------------------------------; gets a random response ;------------------------------------------------------------------------get_response macro

call get_random getr1 andlw b'11' movwf response movlw training+0 btfsc flags,LIGHT movlw training+4 addwf response,w movwf FSR incf response,w tstf 0 bz getr1 endm ;------------------------------------------------------------------------; flashes LEDs ;------------------------------------------------------------------------routine flash_leds flash1 movlf FLASH_REPEAT,pulses LEDS_on movlw FLASH_RATE call delay LEDS_off movlw FLASH_RATE call delay decfsz pulses goto flash1 return ; response permitted ?

; branch if not

;------------------------------------------------------------------------; main entry point ;------------------------------------------------------------------------routine main_entry clrf GPIO clrf GPIO_ bsf STATUS,RP0 movlf GPIO_IO,TRISIO bcf STATUS,RP0 bsf STATUS,RP0 movlw b'10000000' movwf OPTION_REG clrf WPU bcf STATUS,RP0 bcf INTCON,GIE movlf b'111',CMCON clrf PCLATH bsf GPIO_,GATE movff GPIO_,GPIO ; enable the microphone ; initialise port

; prescale TMR0 1:2, ; weak pull-ups disabled

; interrupts off

movfw STATUS ; wake-up from sleep ? andlw (1<<NOT_TO)|(1<<NOT_PD) clrwdt bnz main1 ; branch if not movlf 1,timer goto main_loop main1 clrf flags call get_ldr sublw RESET bnc main2 call erase_training call long_beep goto main4 main2 call get_ldr sublw BRIGHT bnc main3 LEDS_on movlw CHIRRUP_TIME call chirrup ; echo light sensor to LEDs ; clear flags ; factory reset ? ; branch if not ; erase training ; long beep

main3

; test chirrup

main4

LEDS_off clrf history clrf response call init_training clrf rand_l clrf rand_h clrf timer clrf ndx call read_EEPROM xorlw MAGIC bnz main_loop call load_training

; LEDs off ; clear the history buffer

; initialise training ; clear random number ; initialise timer ; valid EEPROM data ? ; branch if not ; load training

;------------------------------------------------------------------------; main loop ;------------------------------------------------------------------------routine main_loop bsf STATUS,RP0 movlf GPIO_IO,TRISIO bcf STATUS,RP0 loop1 clrwdt bsf STATUS,RP0 movlw b'10000000' movwf OPTION_REG clrf WPU bcf STATUS,RP0 bcf INTCON,GIE movlf b'111',CMCON clrf PCLATH bsf GPIO_,GATE movff GPIO_,GPIO call poll rrf sound,w rrf history clrc btfsc sound,1 setc rrf history ; enable the microphone ; poll the sensors ; add event to history buffer ; re-initialise port

; clear watchdog timer ; prescale TMR0 1:2, ; weak pull-ups disabled

; interrupts off

test_trained movlw 1<<TRAINED_DARK btfsc flags,LIGHT movlw 1<<TRAINED_LIGHT andwf flags,w bnz loop2 movfw history andlw TRAINING xorlw TRAINING_ bnz loop2 modify_training call flash_leds clrf history clrf timer goto main_loop loop2 decf timer movfw timer andlw h'0f' bnz loop1 call save_training get_response movlw 1<<TRAINED_DARK response ? btfsc flags,LIGHT movlw 1<<TRAINED_LIGHT andwf flags,w bz loop3 tstf response bz loop6 LEDS_off btfss response,EYES goto loop4 LEDS_on btfss response,CHIRRUP goto loop5 call tx_ID movlw CHIRRUP_TIME call chirrup clrf history

; determine if fully trained ; fully trained ?

; branch if yes ; training whistle ? ; branch if not ; modify training ; flash LEDs

; reset timer

; end of response period ? ; loop if not ; save training ; random response ; fully trained and null

; branch if yes ; set LEDs

loop3

loop4

; transmit ID code ; chirrup

loop5 loop6

goto loop1 LEDS_off clrf GPIO clrf GPIO_ bsf STATUS,RP0 movlw b'10001111' movwf OPTION_REG bcf STATUS,RP0 bsf STATUS,RP0 bsf TRISIO,PIEZO bcf STATUS,RP0 clrwdt sleep goto main_entry ; standby mode ; LEDs off ; disable the microphone ; prescale WDT 1:128, ; weak pull-ups disabled

; *********************************************************************** *** ; initial EEPROM data * ; *********************************************************************** *** org h'2100' de 0 end ; untrained

stnga i dreapta cu infra-rou obstacole detectoare independente bi-direcionale motoare cutie de viteze furnizate cu picioare i jeni 2 LED-uri, piezo difuzor, senzor de lumin se conecteaz la tastatura PC PS / 2 (nu este furnizat) n timp real de la distan de control Mod de cltori (evitarea obstacolelor) Mod de labirint (perete text) Mod de dans (mutri programabile) alimentat de 6 celule AA documentat codul surs

.
Atractiv luminos de culoare bug-n form de miniatur robot. Microbug este mereu foame pentru lumina si calatoreste spre ea!

Caracteristici

deschis cu dou motoare asiu Subminiature sensibilitate la lumina reglabila pentru o gam foarte larg de intensitate luminoas, permite utilizatorului s controleze de bug-cum ar fi comportamentul "Ochii" cu LED-uri indic direcia de conducere opriri in intuneric total

Specificaii

sursa de alimentare: 2 x 1,5 V baterii AAA (nu sunt incluse). Dimensiuni: 100 x 60mm (4,0 "x 2,4")

Atractiv viu colorate bug-n form de miniatur robot. Microbug este mereu foame pentru lumina, ea conduce spre ea.

Caracteristici

deschis cu dou motoare asiu Subminiature sensibilitate la lumina reglabila se potriveste aproape orice intensitate a luminii i face posibil pentru a controla comportamentul su "bug-cum ar fi" reglabil de vitez Alegerea a dou medii diferite "Ochii" cu LED-uri indic direcia de conducere opriri in intuneric total

Specificaii

sursa de alimentare: 2 x 1,5 V baterii AAA (nu sunt incluse). Dimensiuni: 110 x 90 mm (4,3 "x 3.5")

Wee Beastie Un robot c "feed-uri" din surse de lumina, apoi ricoeaz n jurul valorii de pe podea. Doua motoare cu off-centru de greuti duce la Beastie Wee s se mute ntr-un mod imprevizibil pe picioarele sale de izvor. Utilizeaza 2 x AA celule.

"Furaje" Beastie Wee inndu-l de sub o surs de lumin puternic. LED-urile vor clipi, deoarece ncepe s se hrneasc i va clipi repede i mai repede pn cnd este complet ncrcat (care dureaz aproximativ 45 de secunde). Apoi, locul Beastie Wee pe podea la distan de lumin i-l va agasa i se rostogoleasc i sri n jurul valorii de timp de pn la 2 minute (cnd este complet Fed). Reinei c Beastie Wee funcioneaz cel mai bine pe suprafete dure, mai degrab dect covoare, i este mai bine a se utiliza celule reincarcabile AA (Ni-Cd sau NiMH), mai degrab dect cele de unic folosin. Dac utilizai celule de unic folosin, atunci ele trebuie s fie alcalin de nalt calitate.

S-ar putea să vă placă și