Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Piezo vibration detector to test with Leaky Faucet
;sound sensor program using piezo to detect a dripping faucet
;adapted from the footstep detector from AVR-Programming by Elliot Williams
;
;flash with avrdude -c avrisp -p m168 -P /dev/tty.usbmodem1411 -b 19200 -U flash:w:piezoLeak.hex
;
;use adc2 on PC2 for piezo input
; make sure to check registers before importing into ble program
.equ UBBRvalue = 12
.def temp = r16
.def count = r17
.def flags = r18
.def byte_tx = r19 ;for serial transmit routine
.def xL = r26 ;x reg used as global counter
.def xH = r27
.def yL = r28
.def yH = r29
.def zL = r30
.def zH = r31
.device atmega168
;---- global variables ----
.equ L_FLG = 2 ;global leak flag
.equ C_FLG = 3 ;counter overflow flag
.cseg
.org 0
;----- Main -----
reset:
;inittialize Stack
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,high(RAMEND)
out SPH,temp
;initialize USART
ldi temp,high(UBBRvalue) ;baud rate param
sts UBRR0H,temp
ldi temp,low(UBBRvalue)
sts UBRR0L,temp
lds temp,UCSR0A
ori temp,(1 << U2X0) ;set use 2x because %error actual baud > .5
sts UCSR0A,temp
;--- USART register values
ldi temp,(1 << TXEN0) | (1 << RXEN0) ;enable transmit and receive
sts UCSR0B,temp
ldi temp,(1 << UCSZ01) | (1 << UCSZ00) ;8 data bits, 1 stop bit
sts UCSR0C,temp
;--- init ADC ---
sbi DDRB,PB1
lds temp,ADMUX
sbr temp,(1 << REFS0) ;use external avcc
sts ADMUX,temp
lds temp,ADCSRA
sbr temp,(1 << ADPS1) | (1 << ADPS2) ;set clock prescale /64
sbr temp,(1 << ADEN) ;enable adc
sts ADCSRA,temp
;--- init variables ---
ldi xL,low(midval)
ldi xH,high(midval)
ldi temp,0xff ;init midval to 511
st X+,temp
ldi temp,0x01
st X,temp
ldi xL,low(hival)
ldi xH,high(hival)
ldi temp,0x08
st X+,temp
ldi temp,0x02
st X,temp ;init hival to 520 (0x0208)
ldi xL,low(loval)
ldi xH,high(loval)
ldi temp,0xf4
st X+,temp
ldi temp,0x01
st X,temp ;init loval to 500 (0x01f4)
ldi xL,low(noise)
ldi xH,high(noise)
ldi temp,0x00
st X+,temp
st X,temp ;init noise to 0
;--- start getting data ---
evt_lp: lds temp,ADMUX
sbr temp,(1 << MUX1)
sts ADMUX,temp
lds temp,ADCSRA
sbr temp,(1 << ADSC) ;start conversion
sts ADCSRA,temp
ad_lp: lds temp,ADCSRA
sbrc temp,ADSC
rjmp ad_lp
ldi xL,low(adcval)
ldi xH,high(adcval)
lds temp,ADCL
st X+,temp
lds temp,ADCH
andi temp,0b00000011
st X,temp
;--- calculate middle value ---
; r22 = temp_L
; r23 = temp_H
; r24 = temp2_L
; r25 = temp2_H
ldi xL,low(midval)
ldi xH,high(midval)
ld r24,X+
ld r25,X ;high byte
sbiw r25:r24,8
clc
ldi count,4
divlp: lsr r25
lsr r24
clc
dec count
brne divlp
; r24:r25 contain ((midval - 8) >> 4)
; next subtract result from midval and add adcval
ldi xL,low(midval)
ldi xH,high(midval)
ld r22,X+ ;low byte in r23 to match result byte order
ld r23,X
clc
sub r22,r24 ;subtract low byte of result from midval
sbc r23,r25 ;high byte with carry
; result in r22(low):r23(high)
clc
ldi xL,low(adcval)
ldi xH,high(adcval)
ld r24,X+
ld r25,X
clc
add r24,r22 ;add low bytes first
adc r25,r23 ;add highh bytes with carry
; store result in midval
clc
ldi xL,low(midval)
ldi xH,high(midval)
st X+,r24
st X,r25
;done with first calculation, now compare
;midval is in r25:r24
clc
ldi count,4
divlp2: lsr r25
lsr r24
clc
dec count
brne divlp2 ;divide midval by 16
;---- if adc > midval/16 do true ----
ldi xL,low(adcval)
ldi xH,high(adcval)
ld r22,X+
ld r23,X
cp r23,r25
brsh skp1
rjmp else ;a < m
skp1: clc
cp r23,r25
brne true ;means r23 is greater
clc
cp r24,r22 ; if (a > m) == cp m,a brsh skip
brsh else
true:
;---- highval = adcval + highval - ((highval - 8) >> 4) ----
ldi xL,low(hival)
ldi xH,high(hival)
ld r25,X
sbiw r25:r24,8
clc
ldi count,4
divlp3: lsr r25
lsr r24
clc
dec count
brne divlp3
; next subtract result from hival and add adcval
ldi xL,low(hival)
ldi xH,high(hival)
ld r22,X+ ;low byte in r23 to match result byte order
ld r23,X
clc
sub r22,r24 ;subtract low byte of result from hival
sbc r23,r25 ;high byte with carry
; result in r22(low):r23(high)
clc
ldi xL,low(adcval)
ldi xH,high(adcval)
ld r24,X+
ld r25,X
clc
add r24,r22 ;add low bytes first
adc r25,r23 ;add highh bytes with carry
; store result in hival
clc
ldi xL,low(hival)
ldi xH,high(hival)
st X+,r24
st X,r25
rjmp chk_adc
else:
;skip compare b/c its almost the opposite
;---- loval = adcval + loval - ((loval - 8) >> 4) ----
ldi xL,low(loval)
ldi xH,high(loval)
ld r24,X+
ld r25,X
sbiw r25:r24,8
clc
ldi count,4
divlp4: lsr r25
lsr r24
clc
dec count
brne divlp4
; next subtract result from loval and add adcval
ldi xL,low(loval)
ldi xH,high(loval)
ld r22,X+ ;low byte in r23 to match result byte order
ld r23,X
clc
sub r22,r24 ;subtract low byte of result from loval
sbc r23,r25 ;high byte with carry
; result in r22(low):r23(high)
clc
ldi xL,low(adcval)
ldi xH,high(adcval)
ld r24,X+
ld r25,X
clc
add r24,r22 ;add low bytes first
adc r25,r23 ;add highh bytes with carry
; store result in loval
clc
ldi xL,low(loval)
ldi xH,high(loval)
st X+,r24
st X,r25
;---- next check adc to see if its above or below thresholds
chk_adc:
;--- first get noise volume ---
ldi xL,low(loval)
ldi xH,high(loval)
ld r24,X+
ld r25,X
adiw r25:r24,16 ;lowval + padding
ldi xL,low(hival)
ldi xH,high(hival)
ld r22,X+
ld r23,X
clc
sub r22,r24
sbc r23,r25 ;highval - lowval + padding
ldi xL,low(noise)
ldi xH,high(noise)
st X+,r22
st X,r23
;now make compare
ldi xL,low(midval)
ldi xH,high(midval)
ld r24,X+
ld r25,X
clc
add r24,r22
adc r25,r23 ;add noise+midval
clc
ldi count,4
dvlp4: lsr r25
lsr r24
clc
dec count
brne dvlp4
ldi xL,low(adcval)
ldi xH,high(adcval)
ld r22,X+
ld r23,X
cp r23,r25
brsh tstequ
rjmp nxt2
tstequ: clc
cp r23,r25
brne tru2
clc
cp r24,r22
brlo nxt2
tru2: ldi byte_tx,0x48 ;'H'
rcall transmit
sbi PORTB,PB1
mov byte_tx,r23 ;adc H
rcall transmit
mov byte_tx,r22
rcall transmit
rjmp evt_lp
nxt2: clc
cp r23,r25
brne lt
cp r22,r24
brlo lt
ldi byte_tx,0x01
rcall transmit
mov byte_tx,r23
rcall transmit
mov byte_tx,r22
rcall transmit
rjmp evt_lp
lt: ldi byte_tx,0x4c ;'L'
rcall transmit
cbi PORTB,PB1
mov byte_tx,r23
rcall transmit
mov byte_tx,r22
rcall transmit
rjmp evt_lp
;*** Subroutines ***
transmit:
lds temp,UCSR0A
sbrs temp,UDRE0
rjmp transmit
sts UDR0,byte_tx
ret
;variable data
.dseg
adcval: .byte 2
midval: .byte 2
hival: .byte 2
loval: .byte 2
noise: .byte 2
pad: .byte 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.