Advertisement
shchuko

CapacitySensor

Nov 12th, 2019
2,059
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Capacity sensor, ATtiny85
  2. ; Clock 8mHz
  3. ; Antenna - PB3
  4. ; Charge electrode - PB2 (connect to the ground ot body)
  5. ; PWM output - PB0
  6.  
  7. .include "tn85def.inc"
  8.  
  9. .def rMP1 = r16             ; Multi-purpose register 1 = r16
  10. .def rMP2 = r17             ; Multi-purpose register 2 = r17
  11. .def rSUM = r6              ; Register to save sum = r6
  12. .def rCOUNTER = r5          ; Counter register = r5
  13.  
  14. rjmp init                   ; Start from init
  15.  
  16.  
  17.  
  18. ; ========== INIT ==========
  19. init:
  20.     ; Reset rSUM to 10 == number of readings
  21.     ldi rMP1, 10       
  22.     mov rCOUNTER, rMP1 
  23.     ; Clear sum register
  24.     clr rSUM       
  25.    
  26.     cli                     ; Disable interrupts
  27.     sbi DDRB, DDB0          ; Set OC0A as output
  28.     sbi DDRB, DDB2          ; Set PB2 as output
  29.    
  30.     ; Setup Timer 0
  31.     ; Fast PWM mode, output A low at cycle start
  32.     ldi rMP1, (1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(1<<WGM00)
  33.     out TCCR0A, rMP1        ; To timer control register A
  34.    
  35.     ; Set Timer 0 Prescaler = 1
  36.     ldi rMP1, 1<<CS00
  37.     out TCCR0B, rMP1        ; To timer control register B
  38.    
  39.     ; PWM compare value
  40.     ldi rMP1,0              ; Start from 0% intensity
  41.     out OCR0A,rMP1          ; To compare match register A
  42.     sei                     ; Enable interrupts
  43.     rjmp loop               ; To main loop
  44.  
  45.  
  46.  
  47. ; ========== LOOP ==========
  48. loop:  
  49.     ; Read antenna capacitance
  50.     ; Calculate average value reading capacitance several times,
  51.     rcall readCap           ; Capacitance value saved to rMP1
  52.     add rSUM, rMP1          ; rSUM += capValue
  53.     brcc repeatReadCap      ; If it does not overflows, go to repeatReadCap label (repeat reading)
  54.     ; If it overflows, set r6 to 255 (max value)
  55.     clr rSUM               
  56.     dec rSUM               
  57.     rjmp updatePWM          ; Skip and go to updatePWM label
  58.  
  59. repeatReadCap:
  60.     dec rCOUNTER            ; r5 is counting down the number of readings we've made
  61.     brne loop               ; If r5 != 0, go to label loop (one more reading)
  62.                             ; Else, update PWM value
  63. updatePWM:
  64.     ; Reset rSUM to 10 == number of readings
  65.     ldi rMP1, 10       
  66.     mov rCOUNTER, rMP1 
  67.    
  68.     lsr rSUM                ; Divide sum by two and set volume level
  69.     out OCR0A,r6            ; to compare match register A
  70.     clr rSUM                ; Clear sum value
  71.  
  72. rjmp loop           ; Go to loop begin
  73.  
  74.  
  75.  
  76. ; ========== CAPACITANCE READING ==========
  77. .equ chargePin = 2
  78. .equ antennaPin = 3
  79. readCap:
  80.     ; Setup ADC:
  81.     ; Vcc as Aref (default)
  82.     ; Left adjust
  83.     ; Read from PB3
  84.     ldi rMP1, (1<<ADLAR|1<<MUX1|1<<MUX0)
  85.     out ADMUX, rMP1
  86.  
  87.     ; Start reading capacitance
  88.     cbi PORTB, antennaPin       ; Ground antenna pin               
  89.     cbi PORTB, chargePin        ; Ground charge pin
  90.     ldi rMP1, 0b00011111        ; Prepare value for DDRB
  91.     out DDRB, rMP1              ; Set all port as output, load value
  92.     rcall wait                  ; Wait a bit for pin mode changing
  93.     cbi DDRB, antennaPin        ; Set antenna pin as high-impedance input
  94.     rcall wait                  ; Wait a bit for pin mode changing
  95.     cli                         ; Disable interrupts (timing critical)
  96.     sbi PORTB, chargePin        ; Set charge pin to high
  97.     rcall waitForCharge         ; Wait a specific amount of time
  98.     rcall readADC               ; Start reading
  99.  
  100.     ret                         ; Return, value saved to rMP1
  101.  
  102.  
  103.  
  104. ; ========== WAIT PROCEDURES ===========
  105. ; Simple wait for port mode changing
  106. wait:
  107.     ldi rMP2, 10                ; Set counter value to 10
  108. waitL:
  109.     dec rMP2                    ; Decrease counter
  110.     brne waitL                  ; If counter != 0, go to waitL label
  111.     ret                         ; Else return
  112.  
  113. ; Wait for capacitance changing
  114. waitForCharge:                 
  115.     ldi rMP2,8                  ; Set counter value to 8 (the value obtained by experiments)
  116. waitForChargeL:            
  117.     nop
  118.     nop
  119.     dec rMP2                    ; Decrease counter
  120.     brne waitForChargeL         ; If counter != 0, go to waitForChargeL label
  121.     ret                         ; Else return
  122.  
  123.  
  124.  
  125. ; ========== ADC READING ============
  126. readADC:
  127.     ; Enable ADC
  128.     ; Begin conversion cycle
  129.     ; Clear interrupt flag
  130.     ; Set division factor to 16
  131.     ldi rMP1, (1<<ADEN|1<<ADSC|1<<ADIF|1<<ADPS2)
  132.     out ADCSRA, rMP1
  133.     sei                         ; Enable interrupts
  134. waitForConversion:
  135.     sbis ADCSRA, ADIF           ; If conversion finished, skip the next command
  136.     rjmp waitForConversion      ; Wait for conversion, go to waitForConversion label
  137.     in rMP2, ADCL               ; Read low ADC byte to rMP2
  138.     in rMP1, ADCH               ; Read high ADC byte to rMP1
  139.     sbrc rMP2, 7                ; If low byte >= 128, skip the next command
  140.     inc rMP1                    ; Else increase rMP1 value
  141.     ret                         ; Return, capacitance value saved to rMP1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement