Difference between revisions of "Camp2019 kits"

From The Alternative Power Network
Jump to navigation Jump to search
(Kit C: The AD(H)D timer)
 
(8 intermediate revisions by 2 users not shown)
Line 22: Line 22:
 
=== Kit C: The AD(H)D timer ===
 
=== Kit C: The AD(H)D timer ===
  
This kit has a microcontroller that needs some programming, ask for benadski at the HSNL tent to get yours programmed after soldering. (Hopefully the toolchain is set up on Thursday evening.)  
+
This kit has a microcontroller that needs some programming, so if you have bought the kit and did not let your chip be programmed at camp, please contact me (benadski) for a solution!
  
Code; sorry for the mess, check the source of the page for a better view...
+
;
<nowiki>
+
; ADDtimer.asm
;
+
;
; ADDtimer.asm
+
; Created: 11/07/2019 21:43:20
;
+
; Author : Wilenzo
; Created: 11/07/2019 21:43:20
+
;
; Author : Wilenzo
+
;                      ___
;
+
;                VCC -|*  |- GND
;                      ___
+
;    SW2 and TPI A0 -|  |- B3 POT wiper
;                VCC -|*  |- GND
+
;            TPI A1 -|  |- B2 POT V+ and buzzer
;    SW2 and TPI A0 -|  |- B3 POT wiper
+
;            TPI /R -|___|- B1 SW1 and LEDs  
;            TPI A1 -|  |- B2 POT V+ and buzzer
+
;            TPI /R -|___|- B1 SW1 and LEDs  
+
.def    locl  = r16
 +
.def    stat  = r17
 +
.def    dly1  = r18
 +
.def    dly2  = r19
 +
.def    dlyi  = r20
 +
.def    loci  = r21
 +
.def    tmrd  = r22
 +
 +
;.def   
 +
 +
; Status byte
 +
.equ    SLP  = 0  ; Set before sleep is executed
 +
.equ    ACP  = 1  ; Analog conversion pending
 +
.equ    SLR  = 2  ; Sleep request
 +
.equ    ALM  = 3  ; Alarm (beeper and LEDs)
 +
 +
; I/O pins or ADC channel
 +
.equ    SW2  = 0
 +
.equ    BTN  = 1
 +
.equ    LED  = 1
 +
.equ    BUZ  = 2
 +
.equ    POTP  = 2
 +
.equ    POTW  = 7
 +
 +
; Helpers
 +
.equ    VLMON = (1<<VLM1)|(1<<VLM0)|(1<<VLMIE)
 +
 +
; Init
 +
.org    $0000
 +
rjmp    RESET_vect
 +
 +
.org    $0001
 +
rjmp    INT0_vect
 +
 +
.org    $0006
 +
rjmp    TIM0_CA_vect
 +
 +
.org    $000A
 +
rjmp    VLM_vect
 +
 +
.org    $000B
 +
rjmp    ADC_vect
 +
 +
;Handles button and wake function
 +
INT0_vect:
 +
    ; Wait for pin to get high, set pot positive high, wait a few msecs
 +
    in    loci,    SREG
 +
    push  loci
 +
WAIT_PIN:
 +
    sbis  PINB,    BTN
 +
    rjmp  WAIT_PIN
 +
 +
    sbr  stat,    (1<<ACP)
 +
    sbi  PORTB,    POTP
 +
 +
I0SNOOZE:
 +
    dec  dlyi
 +
    brne  I0SNOOZE
 +
 +
    ; Check if awoken from sleep, if so: reset flag and ...
 +
    sbrs  stat,    SLP
 +
    rjmp  NOSLEEP
 +
    cbr  stat,    (1<<SLP)
 +
    in    locl,    SMCR
 +
    andi  locl,    ~(1<<SE)
 +
    out  SMCR,    locl
 +
NOSLEEP:
 +
    ; Code for button processing, start A/D conversion
 +
    sbi  ADCSRA,  ADSC
 +
 +
INT0_end:
 +
    pop  loci
 +
    out  SREG,    loci
 +
    reti
 +
 +
; Timing, fires every 30 seconds
 +
TIM0_CA_vect:
 +
    in    loci,    SREG
 +
    push  loci   
 +
 +
    ;cpi  tmrd,    0
 +
    ;breq  REPEAT
 +
 +
    dec  tmrd
 +
    brne  TIM0_END
 +
 +
    ldi  tmrd,    255
 +
    sbr  stat,    (1<<ALM)
 +
 +
    sbis  PINA,    SW2
 +
    rjmp  REPEAT
 +
    rcall LED_OFF
 +
    sbr  stat,    (1<<SLR)
 +
    rjmp  TIM0_END
 +
REPEAT:
 +
 +
    sbr  stat,    (1<<ACP)
 +
    sbi  PORTB,    POTP
 +
 +
T0SNOOZE:
 +
    dec  dlyi
 +
    brne  T0SNOOZE
 +
 +
    sbi  ADCSRA,  ADSC
 +
       
 +
TIM0_END:
 +
    pop  loci
 +
    out  SREG,    loci
 +
    reti
 +
 +
; Voltage level too low? Flash LED, do nothing else
 +
VLM_vect:
 +
    in    loci,    SREG
 +
    push  loci   
 +
 +
    sbi  DDRB,    LED
 +
 +
    ENDLESS:
 +
    dec  dlyi
 +
    brne  ENDLESS
 +
    sbrc  loci,    6
 +
    rcall LED_ON
 +
    dec  loci
 +
    brne  ENDLESS
 +
    ldi  loci,    80
 +
    rcall LED_OFF
 +
    rjmp  ENDLESS
 +
 +
    pop  loci
 +
    out  SREG,    loci
 +
    reti
 +
 +
; Conversion complete, set pot positive to 0V, process value
 +
ADC_vect:
 +
    in    loci,    SREG
 +
    push  loci 
 +
   
 +
    cbi  PORTB,    POTP
 +
    cbr  stat,    (1<<ACP)
 +
    in    tmrd,    ADCH
 +
    lsr  tmrd
 +
    cpi  tmrd,    10
 +
    brsh  MAX_VAL
 +
    ldi  tmrd,    10
 +
MAX_VAL:
 +
    cpi  tmrd,    120
 +
    brlo  VAL_OK
 +
    ldi  tmrd,    120
 +
VAL_OK:
 +
    pop  loci
 +
    out  SREG,    loci
 +
    reti
 +
 +
; LED on (with safe pushbutton thing)
 +
LED_ON:
 +
    ldi  locl,    0
 +
    out  EIMSK,    locl      ; INT0 off
 +
    nop
 +
    nop
 +
    cbi  PORTB,    LED
 +
    sbi  DDRB,    LED
 +
    ret
 +
 +
; LED off (with safe pushbutton thing)
 +
LED_OFF:
 +
    cbi  DDRB,    LED
 +
    sbi  PORTB,    LED
 +
    nop
 +
    nop
 +
    ldi  locl,    (1<<INT0)
 +
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
 +
    ret
 +
 +
RESET_vect:
 +
    cli
 +
 +
    clr  stat
 +
    ldi  locl,    low(RAMEND)
 +
    out  SPL,      locl
 +
    ldi  locl,    high(RAMEND)
 +
    out  SPH,      locl
 +
 +
    ; Set clock speed to 128kHz
 +
    ldi  locl,    0xD8
 +
    out  CCP,      locl
 +
    ldi  locl,    (1<<CLKMS0)
 +
    out  CLKMSR,  locl
 +
    ldi  locl,    0xD8
 +
    out  CCP,      locl
 +
    clr  locl
 +
    out  CLKPSR,  locl
 +
 +
    ; I/O init
 +
    ldi  locl,    (1<<SW2)
 +
    out  PUEA,    locl 
 +
    ldi  locl,    (1<<BUZ)
 +
    out  DDRB,    locl
 +
    ldi  locl,    (1<<BTN)
 +
    out  PUEB,    locl
 +
 +
FLASH:
 +
    rcall LED_ON
 +
    dec  dly1
 +
    brne  FLASH
 +
    rcall LED_OFF
 +
   
 +
    ; ADC setup, point mux to pot wiper enable with interrupt, left adjust and turn off digital input
 +
    ldi  locl,    POTW
 +
    out  ADMUX,    locl
 +
    ldi  locl,    (1<<ADEN)|(1<<ADIE)
 +
    out  ADCSRA,  locl
 +
    ldi  locl,    (1<<ADLAR)
 +
    out  ADCSRB,  locl
 +
    ldi  locl,    (1<<POTW)
 +
    out  DIDR0,    locl
 +
 +
    ; VLM setup (off for now)
 +
    ldi  locl,    0
 +
    out  VLMCSR,  locl
 +
 +
    ; Interrupts setup
 +
    ldi  locl,    (1<<INT0)
 +
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
 +
    ldi  locl,    0x60
 +
    ldi  loci,    0xEA
 +
    out  OCR0AH,  loci      ; Set timer compare match at 60000
 +
    out  OCR0AL,  locl
 +
    ldi  locl,    (1<<CS00)|(1<<CS01)|(1<<WGM02)
 +
    out  TCCR0B,  locl      ; CLKtmr = CLKio/64 => 2000Hz
 +
    ldi  locl,    (1<<OCIE0A)
 +
    out  TIMSK0,  locl      ; Interrupt fires every 30 seconds.
 +
     
 +
    ; Set sleep mode to power down
 +
    ldi  locl,    (1<<SM1)
 +
    out  SMCR,    locl      ; (1<<SE) just before sleep instruction and clear after waking.
 +
 +
    ; Enable interrupts and go
 +
    sei
 +
    rjmp  MAIN
 +
 +
ZZZ:
 +
    cbr  stat,    (1<<SLR)
 +
    sbr  stat,    (1<<SLP)
 +
    in    locl,    SMCR
 +
    ori  locl,    (1<<SE)
 +
    out  SMCR,    locl
 +
    sleep
 +
    rjmp  MAIN
 +
 +
; Check if battery voltage is OK, delay is for settling time.
 +
VLM_CHECK:
 +
    sbrc  stat,    ACP
 +
    ret
 +
    sbis  PORTB,    LED
 +
    ret
 +
    sbic  PORTB,    BUZ
 +
    ret
 +
    ldi  locl,    VLMON
 +
    out  VLMCSR,  locl
 +
    ldi  dly1,    4
 +
VLM_DLY:
 +
    dec  dly1
 +
    brne  VLM_DLY
 +
    ldi  locl,    0
 +
    out  VLMCSR,  locl
 +
    ret
 +
 +
; LED and buzzer sequence
 +
ALARM:
 +
    ldi  dly2,  5
 +
ALARM_LOOP:
 +
    ;sbi  PORTB,  BUZ  piezo only
 +
    cbi  PORTB,  BUZ
 +
    rcall LED_ON
 +
    ;cbi  PORTB,  BUZ  piezo only
 +
    dec  dly1
 +
    brne  ALARM_LOOP
 +
    rcall LED_OFF
 +
    sbi  PORTB,  BUZ
 +
BLEEP:
 +
;    sbi  PORTB,  BUZ  piezo only
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
;    cbi  PORTB,  BUZ  piezo only
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    nop
 +
    dec  dly1
 +
    brne  BLEEP
 +
    dec  dly2
 +
    brne  ALARM_LOOP
 +
    cbr  stat,  (1<<ALM)
 +
    cbi  PORTB,  BUZ
 +
    ret
 +
 +
; Just wait here and check voltage from time to time
 +
MAIN:
 +
    dec  dly1
 +
    brne  MAIN
 +
    sbrc  stat,    ALM
 +
    rcall ALARM
 +
    dec  dly2
 +
    brne  MAIN
 +
    rcall VLM_CHECK
 +
    sbrc  stat,    SLR
 +
    rjmp  ZZZ
 +
    rjmp  MAIN
  
.def    locl  = r16
+
[[File:Schema_ADHD.png]]
.def    stat  = r17
 
.def    dly1  = r18
 
.def    dly2  = r19
 
.def    dlyi  = r20
 
.def    loci  = r21
 
.def    tmrd  = r22
 
  
;.def   
+
=== Kit D: The Lithium cell balancer PCB ===
  
; Status byte
+
This kit is an intelligent cell balancer prototype, the microcontroller can be programmed to read out the cell voltage, discharge the cell to a certain voltage and to send a undervoltage or overvoltage signal on a bus to another PCB that controls charging and discharging of the whole pack (or single cell).
.equ    SLP  = 0  ; Set before sleep is executed
 
.equ    ACP  = 1  ; Analog conversion pending
 
.equ    SLR  = 2  ; Sleep request
 
.equ    ALM  = 3  ; Alarm (beeper and LEDs)
 
  
; I/O pins or ADC channel
+
More info [[Lithium_batteries|here]]!
.equ    SW2  = 0
 
.equ    BTN  = 1
 
.equ    LED  = 1
 
.equ    BUZ  = 2
 
.equ    POTP  = 2
 
.equ    POTW  = 7
 
 
 
; Helpers
 
.equ    VLMON = (1<<VLM1)|(1<<VLM0)|(1<<VLMIE)
 
 
 
; Init
 
.org    $0000
 
rjmp    RESET_vect
 
 
 
.org    $0001
 
rjmp    INT0_vect
 
 
 
.org    $0006
 
rjmp    TIM0_CA_vect
 
 
 
.org    $000A
 
rjmp    VLM_vect
 
 
 
.org    $000B
 
rjmp    ADC_vect
 
 
 
;Handles button and wake function
 
INT0_vect:
 
    ; Wait for pin to get high, set pot positive high, wait a few msecs
 
    in    loci,    SREG
 
    push  loci
 
WAIT_PIN:
 
    sbis  PINB,    BTN
 
    rjmp  WAIT_PIN
 
 
 
    sbr  stat,    (1<<ACP)
 
    sbi  PORTB,    POTP
 
 
 
I0SNOOZE:
 
    dec  dlyi
 
    brne  I0SNOOZE
 
 
 
    ; Check if awoken from sleep, if so: reset flag and ...
 
    sbrs  stat,    SLP
 
    rjmp  NOSLEEP
 
    cbr  stat,    (1<<SLP)
 
    in    locl,    SMCR
 
    andi  locl,    ~(1<<SE)
 
    out  SMCR,    locl
 
NOSLEEP:
 
    ; Code for button processing, start A/D conversion
 
    sbi  ADCSRA,  ADSC
 
 
 
INT0_end:
 
    pop  loci
 
    out  SREG,    loci
 
    reti
 
 
 
; Timing, fires every 30 seconds
 
TIM0_CA_vect:
 
    in    loci,    SREG
 
    push  loci   
 
 
 
    ;cpi  tmrd,    0
 
    ;breq  REPEAT
 
 
 
    dec  tmrd
 
    brne  TIM0_END
 
 
 
    ldi  tmrd,    255
 
    sbr  stat,    (1<<ALM)
 
 
 
    sbis  PINA,    SW2
 
    rjmp  REPEAT
 
    rcall LED_OFF
 
    sbr  stat,    (1<<SLR)
 
    rjmp  TIM0_END
 
REPEAT:
 
 
 
    sbr  stat,    (1<<ACP)
 
    sbi  PORTB,    POTP
 
 
 
T0SNOOZE:
 
    dec  dlyi
 
    brne  T0SNOOZE
 
 
 
    sbi  ADCSRA,  ADSC
 
       
 
TIM0_END:
 
    pop  loci
 
    out  SREG,    loci
 
    reti
 
 
 
; Voltage level too low? Flash LED, do nothing else
 
VLM_vect:
 
    in    loci,    SREG
 
    push  loci   
 
 
 
    sbi  DDRB,    LED
 
 
 
    ENDLESS:
 
    dec  dlyi
 
    brne  ENDLESS
 
    sbrc  loci,    6
 
    rcall LED_ON
 
    dec  loci
 
    brne  ENDLESS
 
    ldi  loci,    80
 
    rcall LED_OFF
 
    rjmp  ENDLESS
 
 
 
    pop  loci
 
    out  SREG,    loci
 
    reti
 
 
 
; Conversion complete, set pot positive to 0V, process value
 
ADC_vect:
 
    in    loci,    SREG
 
    push  loci 
 
   
 
    cbi  PORTB,    POTP
 
    cbr  stat,    (1<<ACP)
 
    in    tmrd,    ADCH
 
    lsr  tmrd
 
    cpi  tmrd,    10
 
    brsh  MAX_VAL
 
    ldi  tmrd,    10
 
MAX_VAL:
 
    cpi  tmrd,    120
 
    brlo  VAL_OK
 
    ldi  tmrd,    120
 
VAL_OK:
 
    pop  loci
 
    out  SREG,    loci
 
    reti
 
 
 
; LED on (with safe pushbutton thing)
 
LED_ON:
 
    ldi  locl,    0
 
    out  EIMSK,    locl      ; INT0 off
 
    nop
 
    nop
 
    cbi  PORTB,    LED
 
    sbi  DDRB,    LED
 
    ret
 
 
 
; LED off (with safe pushbutton thing)
 
LED_OFF:
 
    cbi  DDRB,    LED
 
    sbi  PORTB,    LED
 
    nop
 
    nop
 
    ldi  locl,    (1<<INT0)
 
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
 
    ret
 
 
 
RESET_vect:
 
    cli
 
 
 
    clr  stat
 
    ldi  locl,    low(RAMEND)
 
    out  SPL,      locl
 
    ldi  locl,    high(RAMEND)
 
    out  SPH,      locl
 
 
 
    ; Set clock speed to 128kHz
 
    ldi  locl,    0xD8
 
    out  CCP,      locl
 
    ldi  locl,    (1<<CLKMS0)
 
    out  CLKMSR,  locl
 
    ldi  locl,    0xD8
 
    out  CCP,      locl
 
    clr  locl
 
    out  CLKPSR,  locl
 
 
 
    ; I/O init
 
    ldi  locl,    (1<<SW2)
 
    out  PUEA,    locl 
 
    ldi  locl,    (1<<BUZ)
 
    out  DDRB,    locl
 
    ldi  locl,    (1<<BTN)
 
    out  PUEB,    locl
 
 
 
FLASH:
 
    rcall LED_ON
 
    dec  dly1
 
    brne  FLASH
 
    rcall LED_OFF
 
   
 
    ; ADC setup, point mux to pot wiper enable with interrupt, left adjust and turn off digital input
 
    ldi  locl,    POTW
 
    out  ADMUX,    locl
 
    ldi  locl,    (1<<ADEN)|(1<<ADIE)
 
    out  ADCSRA,  locl
 
    ldi  locl,    (1<<ADLAR)
 
    out  ADCSRB,  locl
 
    ldi  locl,    (1<<POTW)
 
    out  DIDR0,    locl
 
 
 
    ; VLM setup (off for now)
 
    ldi  locl,    0
 
    out  VLMCSR,  locl
 
 
 
    ; Interrupts setup
 
    ldi  locl,    (1<<INT0)
 
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
 
    ldi  locl,    0x60
 
    ldi  loci,    0xEA
 
    out  OCR0AH,  loci      ; Set timer compare match at 60000
 
    out  OCR0AL,  locl
 
    ldi  locl,    (1<<CS00)|(1<<CS01)|(1<<WGM02)
 
    out  TCCR0B,  locl      ; CLKtmr = CLKio/64 => 2000Hz
 
    ldi  locl,    (1<<OCIE0A)
 
    out  TIMSK0,  locl      ; Interrupt fires every 30 seconds.
 
     
 
    ; Set sleep mode to power down
 
    ldi  locl,    (1<<SM1)
 
    out  SMCR,    locl      ; (1<<SE) just before sleep instruction and clear after waking.
 
 
 
    ; Enable interrupts and go
 
    sei
 
    rjmp  MAIN
 
 
 
ZZZ:
 
    cbr  stat,    (1<<SLR)
 
    sbr  stat,    (1<<SLP)
 
    in    locl,    SMCR
 
    ori  locl,    (1<<SE)
 
    out  SMCR,    locl
 
    sleep
 
    rjmp  MAIN
 
 
 
; Check if battery voltage is OK, delay is for settling time.
 
VLM_CHECK:
 
    sbrc  stat,    ACP
 
    ret
 
    sbis  PORTB,    LED
 
    ret
 
    sbic  PORTB,    BUZ
 
    ret
 
    ldi  locl,    VLMON
 
    out  VLMCSR,  locl
 
    ldi  dly1,    4
 
VLM_DLY:
 
    dec  dly1
 
    brne  VLM_DLY
 
    ldi  locl,    0
 
    out  VLMCSR,  locl
 
    ret
 
 
 
; LED and buzzer sequence
 
ALARM:
 
    ldi  dly2,  5
 
ALARM_LOOP:
 
    ;sbi  PORTB,  BUZ  piezo only
 
    cbi  PORTB,  BUZ
 
    rcall LED_ON
 
    ;cbi  PORTB,  BUZ  piezo only
 
    dec  dly1
 
    brne  ALARM_LOOP
 
    rcall LED_OFF
 
    sbi  PORTB,  BUZ
 
BLEEP:
 
;    sbi  PORTB,  BUZ  piezo only
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
;    cbi  PORTB,  BUZ  piezo only
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    nop
 
    dec  dly1
 
    brne  BLEEP
 
    dec  dly2
 
    brne  ALARM_LOOP
 
    cbr  stat,  (1<<ALM)
 
    cbi  PORTB,  BUZ
 
    ret
 
 
 
; Just wait here and check voltage from time to time
 
MAIN:
 
    dec  dly1
 
    brne  MAIN
 
    sbrc  stat,    ALM
 
    rcall ALARM
 
    dec  dly2
 
    brne  MAIN
 
    rcall VLM_CHECK
 
    sbrc  stat,    SLR
 
    rjmp  ZZZ
 
    rjmp  MAIN
 
</nowiki>
 

Latest revision as of 16:00, 1 September 2019

At CCCamp 2019 there are a few electronic kits available for soldering, some related to our goal, some not.

But anyway, here is the info you were looking for!

Kit A: Solar powered noise maker:

This kit is a simple bleeping sound generator, it has all SMD parts except for the headphone connector and the solar panel.

PCB.png

The PCB and components are RoHS compatible, but you could use leaded solder too. The small point on the outline of the LEDs is the anode/positive side of the LED. If you have finished soldering the PCB and there is a bit of light it should make some noise. Place your ear near the piezo or attach stereo headphones. The LEDs only blink in bright lights. The pads on the outside of the PCB can be used as finger contacts or to solder other components to influence the sound. The (-) pad on the top side of the picture is not connected correctly, but the other (-) pad is.

Schema bliep.png

Kit B: The EMF detector / RevSniffer:

Revsniffer.png

The schematic is pretty simple, but it works in a complex way. Any of the three transistors can work as an amplifier or detector. It all depends on the strength of the signal. After assembling, hold the button and point the inductor/antenna to the device you want to listen to. If there is a static or no field, you will hear some hissing noise, that's the noise generated by the electrons dancing inside the transistors. If there is a stable high frequency field, you will hear nothing, if there is some modulation, this will make all kinds of nice noises, from simple clicks to highly complex and beautiful sounds! Have fun! The provided headphones are cheap, so if you don't hear anything, try another set.

Kit C: The AD(H)D timer

This kit has a microcontroller that needs some programming, so if you have bought the kit and did not let your chip be programmed at camp, please contact me (benadski) for a solution!

;
; ADDtimer.asm
;
; Created: 11/07/2019 21:43:20
; Author : Wilenzo
;
;                      ___
;                VCC -|*  |- GND
;     SW2 and TPI A0 -|   |- B3 POT wiper
;             TPI A1 -|   |- B2 POT V+ and buzzer
;             TPI /R -|___|- B1 SW1 and LEDs 

.def    locl  = r16
.def    stat  = r17
.def    dly1  = r18
.def    dly2  = r19
.def    dlyi  = r20
.def    loci  = r21
.def    tmrd  = r22

;.def    

; Status byte 
.equ    SLP   = 0   ; Set before sleep is executed
.equ    ACP   = 1   ; Analog conversion pending
.equ    SLR   = 2   ; Sleep request
.equ    ALM   = 3   ; Alarm (beeper and LEDs)

; I/O pins or ADC channel
.equ    SW2   = 0
.equ    BTN   = 1
.equ    LED   = 1
.equ    BUZ   = 2
.equ    POTP  = 2
.equ    POTW  = 7

; Helpers
.equ    VLMON = (1<<VLM1)|(1<<VLM0)|(1<<VLMIE)

; Init
.org    $0000
rjmp    RESET_vect

.org    $0001
rjmp    INT0_vect

.org    $0006
rjmp    TIM0_CA_vect

.org    $000A
rjmp    VLM_vect

.org    $000B
rjmp    ADC_vect

;Handles button and wake function
INT0_vect:
    ; Wait for pin to get high, set pot positive high, wait a few msecs
    in    loci,     SREG
    push  loci
WAIT_PIN:
    sbis  PINB,     BTN
    rjmp  WAIT_PIN

    sbr   stat,     (1<<ACP)
    sbi   PORTB,    POTP

I0SNOOZE:
    dec   dlyi
    brne  I0SNOOZE

    ; Check if awoken from sleep, if so: reset flag and ...
    sbrs  stat,     SLP
    rjmp  NOSLEEP
    cbr   stat,     (1<<SLP)
    in    locl,     SMCR
    andi  locl,     ~(1<<SE)
    out   SMCR,     locl
NOSLEEP:
    ; Code for button processing, start A/D conversion
    sbi   ADCSRA,   ADSC

INT0_end:
    pop   loci
    out   SREG,     loci
    reti

; Timing, fires every 30 seconds
TIM0_CA_vect:
    in    loci,     SREG
    push  loci    

    ;cpi   tmrd,     0
    ;breq  REPEAT

    dec   tmrd
    brne  TIM0_END

    ldi   tmrd,     255
    sbr   stat,     (1<<ALM)

    sbis  PINA,     SW2
    rjmp  REPEAT
    rcall LED_OFF
    sbr   stat,     (1<<SLR)
    rjmp  TIM0_END
REPEAT:

    sbr   stat,     (1<<ACP)
    sbi   PORTB,    POTP

T0SNOOZE:
    dec   dlyi
    brne  T0SNOOZE

    sbi   ADCSRA,   ADSC
        
TIM0_END:
    pop   loci
    out   SREG,     loci
    reti

; Voltage level too low? Flash LED, do nothing else
VLM_vect:
    in    loci,     SREG
    push  loci    

    sbi   DDRB,     LED

    ENDLESS:
    dec   dlyi
    brne  ENDLESS
    sbrc  loci,     6
    rcall LED_ON
    dec   loci
    brne  ENDLESS
    ldi   loci,     80
    rcall LED_OFF
    rjmp  ENDLESS

    pop   loci
    out   SREG,     loci
    reti

; Conversion complete, set pot positive to 0V, process value
ADC_vect:
    in    loci,     SREG
    push  loci  
    
    cbi   PORTB,    POTP
    cbr   stat,     (1<<ACP)
    in    tmrd,     ADCH
    lsr   tmrd
    cpi   tmrd,     10
    brsh  MAX_VAL
    ldi   tmrd,     10
MAX_VAL:
    cpi   tmrd,     120
    brlo  VAL_OK
    ldi   tmrd,     120
VAL_OK:
    pop   loci
    out   SREG,     loci
    reti

; LED on (with safe pushbutton thing)
LED_ON:
    ldi   locl,     0
    out   EIMSK,    locl       ; INT0 off
    nop
    nop
    cbi   PORTB,    LED
    sbi   DDRB,     LED
    ret

; LED off (with safe pushbutton thing)
LED_OFF:
    cbi   DDRB,     LED
    sbi   PORTB,    LED
    nop
    nop
    ldi   locl,     (1<<INT0)
    out   EIMSK,    locl       ; INT0 (low level for waking from sleep)
    ret

RESET_vect:
    cli

    clr   stat
    ldi   locl,     low(RAMEND)
    out   SPL,      locl
    ldi   locl,     high(RAMEND)
    out   SPH,      locl

    ; Set clock speed to 128kHz
    ldi   locl,     0xD8
    out   CCP,      locl
    ldi   locl,     (1<<CLKMS0)
    out   CLKMSR,   locl
    ldi   locl,     0xD8
    out   CCP,      locl
    clr   locl
    out   CLKPSR,   locl

    ; I/O init 
    ldi   locl,     (1<<SW2)
    out   PUEA,     locl  
    ldi   locl,     (1<<BUZ)
    out   DDRB,     locl
    ldi   locl,     (1<<BTN)
    out   PUEB,     locl

FLASH:
    rcall LED_ON
    dec   dly1
    brne  FLASH
    rcall LED_OFF
    
    ; ADC setup, point mux to pot wiper enable with interrupt, left adjust and turn off digital input
    ldi   locl,     POTW
    out   ADMUX,    locl
    ldi   locl,     (1<<ADEN)|(1<<ADIE)
    out   ADCSRA,   locl
    ldi   locl,     (1<<ADLAR)
    out   ADCSRB,   locl
    ldi   locl,     (1<<POTW)
    out   DIDR0,    locl

    ; VLM setup (off for now)
    ldi   locl,     0
    out   VLMCSR,   locl

    ; Interrupts setup
    ldi   locl,     (1<<INT0)
    out   EIMSK,    locl       ; INT0 (low level for waking from sleep)
    ldi   locl,     0x60
    ldi   loci,     0xEA
    out   OCR0AH,   loci       ; Set timer compare match at 60000
    out   OCR0AL,   locl
    ldi   locl,     (1<<CS00)|(1<<CS01)|(1<<WGM02)
    out   TCCR0B,   locl       ; CLKtmr = CLKio/64 => 2000Hz
    ldi   locl,     (1<<OCIE0A)
    out   TIMSK0,   locl       ; Interrupt fires every 30 seconds.
      
    ; Set sleep mode to power down
    ldi   locl,     (1<<SM1)
    out   SMCR,     locl       ; (1<<SE) just before sleep instruction and clear after waking.

    ; Enable interrupts and go
    sei
    rjmp  MAIN

ZZZ:
    cbr   stat,     (1<<SLR)
    sbr   stat,     (1<<SLP)
    in    locl,     SMCR
    ori   locl,     (1<<SE)
    out   SMCR,     locl
    sleep
    rjmp  MAIN

; Check if battery voltage is OK, delay is for settling time.
VLM_CHECK:
    sbrc  stat,     ACP
    ret
    sbis  PORTB,    LED
    ret
    sbic  PORTB,    BUZ
    ret
    ldi   locl,     VLMON
    out   VLMCSR,   locl
    ldi   dly1,     4 
VLM_DLY:
    dec   dly1
    brne  VLM_DLY
    ldi   locl,     0
    out   VLMCSR,   locl
    ret

; LED and buzzer sequence
ALARM:
    ldi   dly2,   5
ALARM_LOOP:
    ;sbi   PORTB,  BUZ  piezo only
    cbi   PORTB,  BUZ
    rcall LED_ON
    ;cbi   PORTB,  BUZ  piezo only
    dec   dly1
    brne  ALARM_LOOP
    rcall LED_OFF
    sbi   PORTB,  BUZ
BLEEP:
;    sbi   PORTB,  BUZ  piezo only
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
;    cbi   PORTB,  BUZ  piezo only
    nop
    nop
    nop
    nop
    nop
    nop
    dec   dly1
    brne  BLEEP
    dec   dly2
    brne  ALARM_LOOP
    cbr   stat,   (1<<ALM)
    cbi   PORTB,  BUZ
    ret

; Just wait here and check voltage from time to time
MAIN:
    dec   dly1
    brne  MAIN
    sbrc  stat,     ALM
    rcall ALARM
    dec   dly2
    brne  MAIN
    rcall VLM_CHECK
    sbrc  stat,     SLR
    rjmp  ZZZ
    rjmp  MAIN

Schema ADHD.png

Kit D: The Lithium cell balancer PCB

This kit is an intelligent cell balancer prototype, the microcontroller can be programmed to read out the cell voltage, discharge the cell to a certain voltage and to send a undervoltage or overvoltage signal on a bus to another PCB that controls charging and discharging of the whole pack (or single cell).

More info here!