Created
December 31, 2014 18:44
-
-
Save BobBurns/9b7594e25d50f34ab904 to your computer and use it in GitHub Desktop.
Piezo vibration detector to test with Leaky Faucet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;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