Difference between revisions of "Camp2019 kits"

From The Alternative Power Network
Jump to navigation Jump to search
(Kit D: The Lithium cell balancer PCB)
(Kit C: The AD(H)D timer)
 
(3 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!
  
ExtraCrappyCode(tm); 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    locl  = r16
+
.def    dly1  = r18
.def    stat  = r17
+
.def    dly2  = r19
.def    dly1  = r18
+
.def    dlyi  = r20
.def    dly2  = r19
+
.def    loci  = r21
.def    dlyi  = r20
+
.def    tmrd  = r22
.def    loci  = r21
+
.def    tmrd  = r22
+
;.def     
 
+
;.def     
+
; Status byte  
 
+
.equ    SLP  = 0  ; Set before sleep is executed
; Status byte  
+
.equ    ACP  = 1  ; Analog conversion pending
.equ    SLP  = 0  ; Set before sleep is executed
+
.equ    SLR  = 2  ; Sleep request
.equ    ACP  = 1  ; Analog conversion pending
+
.equ    ALM  = 3  ; Alarm (beeper and LEDs)
.equ    SLR  = 2  ; Sleep request
+
.equ    ALM  = 3  ; Alarm (beeper and LEDs)
+
; I/O pins or ADC channel
 
+
.equ    SW2  = 0
; I/O pins or ADC channel
+
.equ    BTN  = 1
.equ    SW2  = 0
+
.equ    LED  = 1
.equ    BTN  = 1
+
.equ    BUZ  = 2
.equ    LED  = 1
+
.equ    POTP  = 2
.equ    BUZ  = 2
+
.equ    POTW  = 7
.equ    POTP  = 2
+
.equ    POTW  = 7
+
; Helpers
 
+
.equ    VLMON = (1<<VLM1)|(1<<VLM0)|(1<<VLMIE)
; Helpers
+
.equ    VLMON = (1<<VLM1)|(1<<VLM0)|(1<<VLMIE)
+
; Init
 
+
.org    $0000
; Init
+
rjmp    RESET_vect
.org    $0000
+
rjmp    RESET_vect
+
.org    $0001
 
+
rjmp    INT0_vect
.org    $0001
+
rjmp    INT0_vect
+
.org    $0006
 
+
rjmp    TIM0_CA_vect
.org    $0006
+
rjmp    TIM0_CA_vect
+
.org    $000A
 
+
rjmp    VLM_vect
.org    $000A
+
rjmp    VLM_vect
+
.org    $000B
 
+
rjmp    ADC_vect
.org    $000B
+
rjmp    ADC_vect
+
;Handles button and wake function
 
+
INT0_vect:
;Handles button and wake function
+
    ; Wait for pin to get high, set pot positive high, wait a few msecs
INT0_vect:
+
    in    loci,    SREG
    ; Wait for pin to get high, set pot positive high, wait a few msecs
+
    push  loci
    in    loci,    SREG
+
WAIT_PIN:
    push  loci
+
    sbis  PINB,    BTN
WAIT_PIN:
+
    rjmp  WAIT_PIN
    sbis  PINB,    BTN
+
    rjmp  WAIT_PIN
+
    sbr  stat,    (1<<ACP)
 
+
    sbi  PORTB,    POTP
    sbr  stat,    (1<<ACP)
+
    sbi  PORTB,    POTP
+
I0SNOOZE:
 
+
    dec  dlyi
I0SNOOZE:
+
    brne  I0SNOOZE
    dec  dlyi
+
    brne  I0SNOOZE
+
    ; Check if awoken from sleep, if so: reset flag and ...
 
+
    sbrs  stat,    SLP
    ; Check if awoken from sleep, if so: reset flag and ...
+
    rjmp  NOSLEEP
    sbrs  stat,    SLP
+
    cbr  stat,    (1<<SLP)
    rjmp  NOSLEEP
+
    in    locl,    SMCR
    cbr  stat,    (1<<SLP)
+
    andi  locl,    ~(1<<SE)
    in    locl,    SMCR
+
    out  SMCR,    locl
    andi  locl,    ~(1<<SE)
+
NOSLEEP:
    out  SMCR,    locl
+
    ; Code for button processing, start A/D conversion
NOSLEEP:
+
    sbi  ADCSRA,  ADSC
    ; Code for button processing, start A/D conversion
+
    sbi  ADCSRA,  ADSC
+
INT0_end:
 
+
    pop  loci
INT0_end:
+
    out  SREG,    loci
    pop  loci
+
    reti
    out  SREG,    loci
+
    reti
+
; Timing, fires every 30 seconds
 
+
TIM0_CA_vect:
; Timing, fires every 30 seconds
+
    in    loci,    SREG
TIM0_CA_vect:
+
    push  loci     
    in    loci,    SREG
+
    push  loci     
+
    ;cpi  tmrd,    0
 
+
    ;breq  REPEAT
    ;cpi  tmrd,    0
+
    ;breq  REPEAT
+
    dec  tmrd
 
+
    brne  TIM0_END
    dec  tmrd
+
    brne  TIM0_END
+
    ldi  tmrd,    255
 
+
    sbr  stat,    (1<<ALM)
    ldi  tmrd,    255
+
    sbr  stat,    (1<<ALM)
+
    sbis  PINA,    SW2
 
+
    rjmp  REPEAT
    sbis  PINA,    SW2
+
    rcall LED_OFF
    rjmp  REPEAT
+
    sbr  stat,    (1<<SLR)
    rcall LED_OFF
+
    rjmp  TIM0_END
    sbr  stat,    (1<<SLR)
+
REPEAT:
    rjmp  TIM0_END
+
REPEAT:
+
    sbr  stat,    (1<<ACP)
 
+
    sbi  PORTB,    POTP
    sbr  stat,    (1<<ACP)
+
    sbi  PORTB,    POTP
+
T0SNOOZE:
 
+
    dec  dlyi
T0SNOOZE:
+
    brne  T0SNOOZE
    dec  dlyi
+
    brne  T0SNOOZE
+
    sbi  ADCSRA,  ADSC
 
+
       
    sbi  ADCSRA,  ADSC
+
TIM0_END:
       
+
    pop  loci
TIM0_END:
+
    out  SREG,    loci
    pop  loci
+
    reti
    out  SREG,    loci
+
    reti
+
; Voltage level too low? Flash LED, do nothing else
 
+
VLM_vect:
; Voltage level too low? Flash LED, do nothing else
+
    in    loci,    SREG
VLM_vect:
+
    push  loci     
    in    loci,    SREG
+
    push  loci     
+
    sbi  DDRB,    LED
 
+
    sbi  DDRB,    LED
+
    ENDLESS:
 
+
    dec  dlyi
    ENDLESS:
+
    brne  ENDLESS
    dec  dlyi
+
    sbrc  loci,    6
    brne  ENDLESS
+
    rcall LED_ON
    sbrc  loci,    6
+
    dec  loci
    rcall LED_ON
+
    brne  ENDLESS
    dec  loci
+
    ldi  loci,    80
    brne  ENDLESS
+
    rcall LED_OFF
    ldi  loci,    80
+
    rjmp  ENDLESS
    rcall LED_OFF
+
    rjmp  ENDLESS
+
    pop  loci
 
+
    out  SREG,    loci
    pop  loci
+
    reti
    out  SREG,    loci
+
    reti
+
; Conversion complete, set pot positive to 0V, process value
 
+
ADC_vect:
; Conversion complete, set pot positive to 0V, process value
+
    in    loci,    SREG
ADC_vect:
+
    push  loci   
    in    loci,    SREG
+
   
    push  loci   
+
    cbi  PORTB,    POTP
   
+
    cbr  stat,    (1<<ACP)
    cbi  PORTB,    POTP
+
    in    tmrd,    ADCH
    cbr  stat,    (1<<ACP)
+
    lsr  tmrd
    in    tmrd,    ADCH
+
    cpi  tmrd,    10
    lsr  tmrd
+
    brsh  MAX_VAL
    cpi  tmrd,    10
+
    ldi  tmrd,    10
    brsh  MAX_VAL
+
MAX_VAL:
    ldi  tmrd,    10
+
    cpi  tmrd,    120
MAX_VAL:
+
    brlo  VAL_OK
    cpi  tmrd,    120
+
    ldi  tmrd,    120
    brlo  VAL_OK
+
VAL_OK:
    ldi  tmrd,    120
+
    pop  loci
VAL_OK:
+
    out  SREG,    loci
    pop  loci
+
    reti
    out  SREG,    loci
+
    reti
+
; LED on (with safe pushbutton thing)
 
+
LED_ON:
; LED on (with safe pushbutton thing)
+
    ldi  locl,    0
LED_ON:
+
    out  EIMSK,    locl      ; INT0 off
    ldi  locl,    0
+
    nop
    out  EIMSK,    locl      ; INT0 off
+
    nop
    nop
+
    cbi  PORTB,    LED
    nop
+
    sbi  DDRB,    LED
    cbi  PORTB,    LED
+
    ret
    sbi  DDRB,    LED
+
    ret
+
; LED off (with safe pushbutton thing)
 
+
LED_OFF:
; LED off (with safe pushbutton thing)
+
    cbi  DDRB,    LED
LED_OFF:
+
    sbi  PORTB,    LED
    cbi  DDRB,    LED
+
    nop
    sbi  PORTB,    LED
+
    nop
    nop
+
    ldi  locl,    (1<<INT0)
    nop
+
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
    ldi  locl,    (1<<INT0)
+
    ret
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
+
    ret
+
RESET_vect:
 
+
    cli
RESET_vect:
+
    cli
+
    clr  stat
 
+
    ldi  locl,    low(RAMEND)
    clr  stat
+
    out  SPL,      locl
    ldi  locl,    low(RAMEND)
+
    ldi  locl,    high(RAMEND)
    out  SPL,      locl
+
    out  SPH,      locl
    ldi  locl,    high(RAMEND)
+
    out  SPH,      locl
+
    ; Set clock speed to 128kHz
 
+
    ldi  locl,    0xD8
    ; Set clock speed to 128kHz
+
    out  CCP,      locl
    ldi  locl,    0xD8
+
    ldi  locl,    (1<<CLKMS0)
    out  CCP,      locl
+
    out  CLKMSR,  locl
    ldi  locl,    (1<<CLKMS0)
+
    ldi  locl,    0xD8
    out  CLKMSR,  locl
+
    out  CCP,      locl
    ldi  locl,    0xD8
+
    clr  locl
    out  CCP,      locl
+
    out  CLKPSR,  locl
    clr  locl
+
    out  CLKPSR,  locl
+
    ; I/O init  
 
+
    ldi  locl,    (1<<SW2)
    ; I/O init  
+
    out  PUEA,    locl   
    ldi  locl,    (1<<SW2)
+
    ldi  locl,    (1<<BUZ)
    out  PUEA,    locl   
+
    out  DDRB,    locl
    ldi  locl,    (1<<BUZ)
+
    ldi  locl,    (1<<BTN)
    out  DDRB,    locl
+
    out  PUEB,    locl
    ldi  locl,    (1<<BTN)
+
    out  PUEB,    locl
+
FLASH:
 
+
    rcall LED_ON
FLASH:
+
    dec  dly1
    rcall LED_ON
+
    brne  FLASH
    dec  dly1
+
    rcall LED_OFF
    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
    ; ADC setup, point mux to pot wiper enable with interrupt, left adjust and turn off digital input
+
    out  ADMUX,    locl
    ldi  locl,    POTW
+
    ldi  locl,    (1<<ADEN)|(1<<ADIE)
    out  ADMUX,    locl
+
    out  ADCSRA,  locl
    ldi  locl,    (1<<ADEN)|(1<<ADIE)
+
    ldi  locl,    (1<<ADLAR)
    out  ADCSRA,  locl
+
    out  ADCSRB,  locl
    ldi  locl,    (1<<ADLAR)
+
    ldi  locl,    (1<<POTW)
    out  ADCSRB,  locl
+
    out  DIDR0,    locl
    ldi  locl,    (1<<POTW)
+
    out  DIDR0,    locl
+
    ; VLM setup (off for now)
 
+
    ldi  locl,    0
    ; VLM setup (off for now)
+
    out  VLMCSR,  locl
    ldi  locl,    0
+
    out  VLMCSR,  locl
+
    ; Interrupts setup
 
+
    ldi  locl,    (1<<INT0)
    ; Interrupts setup
+
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
    ldi  locl,    (1<<INT0)
+
    ldi  locl,    0x60
    out  EIMSK,    locl      ; INT0 (low level for waking from sleep)
+
    ldi  loci,    0xEA
    ldi  locl,    0x60
+
    out  OCR0AH,  loci      ; Set timer compare match at 60000
    ldi  loci,    0xEA
+
    out  OCR0AL,  locl
    out  OCR0AH,  loci      ; Set timer compare match at 60000
+
    ldi  locl,    (1<<CS00)|(1<<CS01)|(1<<WGM02)
    out  OCR0AL,  locl
+
    out  TCCR0B,  locl      ; CLKtmr = CLKio/64 => 2000Hz
    ldi  locl,    (1<<CS00)|(1<<CS01)|(1<<WGM02)
+
    ldi  locl,    (1<<OCIE0A)
    out  TCCR0B,  locl      ; CLKtmr = CLKio/64 => 2000Hz
+
    out  TIMSK0,  locl      ; Interrupt fires every 30 seconds.
    ldi  locl,    (1<<OCIE0A)
+
     
    out  TIMSK0,  locl      ; Interrupt fires every 30 seconds.
+
    ; Set sleep mode to power down
     
+
    ldi  locl,    (1<<SM1)
    ; Set sleep mode to power down
+
    out  SMCR,    locl      ; (1<<SE) just before sleep instruction and clear after waking.
    ldi  locl,    (1<<SM1)
+
    out  SMCR,    locl      ; (1<<SE) just before sleep instruction and clear after waking.
+
    ; Enable interrupts and go
 
+
    sei
    ; Enable interrupts and go
+
    rjmp  MAIN
    sei
+
    rjmp  MAIN
+
ZZZ:
 
+
    cbr  stat,    (1<<SLR)
ZZZ:
+
    sbr  stat,    (1<<SLP)
    cbr  stat,    (1<<SLR)
+
    in    locl,    SMCR
    sbr  stat,    (1<<SLP)
+
    ori  locl,    (1<<SE)
    in    locl,    SMCR
+
    out  SMCR,    locl
    ori  locl,    (1<<SE)
+
    sleep
    out  SMCR,    locl
+
    rjmp  MAIN
    sleep
+
    rjmp  MAIN
+
; Check if battery voltage is OK, delay is for settling time.
 
+
VLM_CHECK:
; Check if battery voltage is OK, delay is for settling time.
+
    sbrc  stat,    ACP
VLM_CHECK:
+
    ret
    sbrc  stat,    ACP
+
    sbis  PORTB,    LED
    ret
+
    ret
    sbis  PORTB,    LED
+
    sbic  PORTB,    BUZ
    ret
+
    ret
    sbic  PORTB,    BUZ
+
    ldi  locl,    VLMON
    ret
+
    out  VLMCSR,  locl
    ldi  locl,    VLMON
+
    ldi  dly1,    4  
    out  VLMCSR,  locl
+
VLM_DLY:
    ldi  dly1,    4  
+
    dec  dly1
VLM_DLY:
+
    brne  VLM_DLY
    dec  dly1
+
    ldi  locl,    0
    brne  VLM_DLY
+
    out  VLMCSR,  locl
    ldi  locl,    0
+
    ret
    out  VLMCSR,  locl
+
    ret
+
; LED and buzzer sequence
 
+
ALARM:
; LED and buzzer sequence
+
    ldi  dly2,  5
ALARM:
+
ALARM_LOOP:
    ldi  dly2,  5
+
    ;sbi  PORTB,  BUZ  piezo only
ALARM_LOOP:
+
    cbi  PORTB,  BUZ
    ;sbi  PORTB,  BUZ  piezo only
+
    rcall LED_ON
    cbi  PORTB,  BUZ
+
    ;cbi  PORTB,  BUZ  piezo only
    rcall LED_ON
+
    dec  dly1
    ;cbi  PORTB,  BUZ  piezo only
+
    brne  ALARM_LOOP
    dec  dly1
+
    rcall LED_OFF
    brne  ALARM_LOOP
+
    sbi  PORTB,  BUZ
    rcall LED_OFF
+
BLEEP:
    sbi  PORTB,  BUZ
+
;    sbi  PORTB,  BUZ  piezo only
BLEEP:
+
    nop
;    sbi  PORTB,  BUZ  piezo only
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
;    cbi  PORTB,  BUZ  piezo only
    nop
+
    nop
;    cbi  PORTB,  BUZ  piezo only
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    nop
    nop
+
    dec  dly1
    nop
+
    brne  BLEEP
    dec  dly1
+
    dec  dly2
    brne  BLEEP
+
    brne  ALARM_LOOP
    dec  dly2
+
    cbr  stat,  (1<<ALM)
    brne  ALARM_LOOP
+
    cbi  PORTB,  BUZ
    cbr  stat,  (1<<ALM)
+
    ret
    cbi  PORTB,  BUZ
+
    ret
+
; Just wait here and check voltage from time to time
 
+
MAIN:
; Just wait here and check voltage from time to time
+
    dec  dly1
MAIN:
+
    brne  MAIN
    dec  dly1
+
    sbrc  stat,    ALM
    brne  MAIN
+
    rcall ALARM
    sbrc  stat,    ALM
+
    dec  dly2
    rcall ALARM
+
    brne  MAIN
    dec  dly2
+
    rcall VLM_CHECK
    brne  MAIN
+
    sbrc  stat,    SLR
    rcall VLM_CHECK
+
    rjmp  ZZZ
    sbrc  stat,    SLR
+
    rjmp  MAIN
    rjmp  ZZZ
 
    rjmp  MAIN
 
</nowiki>
 
  
 
[[File:Schema_ADHD.png]]
 
[[File:Schema_ADHD.png]]
Line 363: Line 360:
 
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).
 
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 [[http://altpwr.net/index.php?title=Lithium_batteries|here]]!
+
More info [[Lithium_batteries|here]]!

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!