Bygget är baserat på en digispark attiny85(den som har kretskortet som usb kontakt), den har en 78M05 regulator som klarar LiPo spänningen direkt.
Kortet som styr är handlött med en bunt ytmonterat, se schema.
Själva kortet har till uppgift att se till att batteriet stängs av innan LiPo cellerna tar skada, Bosch batterierna har inte något mer skydd än en felpolaritetsdiod i sig...
Själva led lampan är från ebay, söker man på "18W LED Floodlight" så hittar man en del..
Kod: Markera allt
/*
//Battery voltage VBAT-|39k|--ADC--|10k|---GND (P2, ADC1, 24.5v->5v, ADC*24X ~50mV error ~0.2%)
//Battery detection (P4, ADC2)
// Use internal pull-up to get a resistor divider..
// 400...1023 --> open detection
// 176...399 --> 18.0V battery, 5Lipo cells
// 50....175 --> 14.4V battery, 4Lipo cells
// 0.....50 --> short detection
*/
#include <SoftSerial.h>
#include <stdint.h>
#include <avr/wdt.h>
#define BATTERY_TYPE_UNKNOWN 0
#define BATTERY_TYPE_14V4 1
#define BATTERY_TYPE_18V 2
SoftSerial debugSerial(1, 1);
uint8_t battery_type = BATTERY_TYPE_UNKNOWN;
/*
* @brief Read analog input, mean filter with 64 values..
*/
uint16_t analog_read(uint8_t ch){
uint16_t val=0;
//take 64 samples
for(int i=0;i<64;i++){
val += analogRead(ch);
}
val /= 64;
return val;
}
uint8_t detect_battery(void){
uint16_t adc = analog_read(2);
uint8_t type=BATTERY_TYPE_UNKNOWN;
if( (adc <= 400) && (adc >= 176)){
type = BATTERY_TYPE_18V;
}
if( (adc <= 175) && (adc >= 50)){
type = BATTERY_TYPE_14V4;
}
return type;
}
/**
* @brief Get battery voltage
*/
uint16_t read_battery_voltage(void){
uint16_t battery_voltage = analog_read(1)*24U;
/* Calibration value(mV) */
battery_voltage -= 150;
return battery_voltage;
}
void shutdown(void){
digitalWrite(0, HIGH);
}
// the setup function runs once when you press reset or power the board
void setup() {
/* if WDT reset occur, shutdown directly */
if(MCUSR & (1<<WDRF)){
pinMode(0, OUTPUT);
digitalWrite(0, HIGH);
}
wdt_disable();
wdt_reset();
wdt_enable(WDTO_4S);
// initialize digital pin 13 as an output.
pinMode(0, OUTPUT); /* Shutdown pin */
pinMode(1, OUTPUT); /* Debug output/led */
pinMode(2, INPUT); /* Battery voltage */
pinMode(3, INPUT); /* not used */
pinMode(4, INPUT_PULLUP); /* Battery type, use pull-up as analog divider */
debugSerial.begin(9600);
debugSerial.txMode();
battery_type = detect_battery();
}
void debug(void){
uint16_t detect_adc = analog_read(2);
uint16_t battery_voltage = analog_read(1)*24U;
debugSerial.println(F("Debug: "));
debugSerial.println(detect_adc);
debugSerial.println(battery_voltage);
if(battery_type == BATTERY_TYPE_18V){
debugSerial.println(F("Battery type 18V"));
}else if(battery_type == BATTERY_TYPE_14V4){
debugSerial.println(F("Battery type 14V4"));
}
debugSerial.println("");
}
// the loop function runs over and over again forever
void loop() {
uint16_t vbat = read_battery_voltage();
uint16_t min_vbat=0xFFFF;
if(battery_type == BATTERY_TYPE_UNKNOWN){
debugSerial.println(F("Unknown battery, shutdown"));
shutdown();
}
//5 cells battery
if( (battery_type == BATTERY_TYPE_18V) && (vbat < (3400*5))){
debugSerial.println(F("Low battery, shutdown"));
shutdown();
}
//4 cells battery
if( (battery_type == BATTERY_TYPE_14V4) && (vbat < (3400*4))){
debugSerial.println(F("Low battery, shutdown"));
shutdown();
}
wdt_reset();
delay(1000);
debug(); //some debug output
}