/* Dronestrober with BMS and charger when running on 4.4 volt or less it will strobe leds when run on more it will charge the battery to (approx.) 4.2 volt, let it drop to 4.0 before recharge will cut off operation at cell voltage about 3 volts dji phantom pro 3 lower leg 9x7mm flashing status readout battery mode: Vcc x.x volts 2 sec delay battery pin read, nonsense 2 sec delay flashing operation starts. USB power mode: Vcc x.x volts, ususally 5 blinks then 3 sec delay (5 volts) at least 2 sec delay battery x.x volts, 1 sec delay is the decimal separator 2 sec delay charging mode starts: flash every second: CHARGING flash every 5 seconds: CHARGING DONE */ //sleep stuff #include #include //#include #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif //for sleep mode watchdog timer volatile boolean f_wdt = 1; const int batpin = 3; // D3 and A3 for charging ans sensing battery voltage. const int ledpin = 4; // LED pin -> mosfet -> LED const int potpin = 1; // analogue input 1 (pin 2) for strobe setting, read only first 60 secs. or something. //battery data const int batmax = 4080; //max battery charge voltage mV const int batrecharge = 3950; //restart charge coltage mV const int batmin = 3100; //min battery charge voltage mV const int chargethreshold = 4400; //charge vs operation threshold int voltage; //battery measured int sensorValue; //temp readvalue int debug; //debug //variables will change: int runmode=1; int wdduration=5; int blinks; int ond=20; //on delay for LED int itv; //interval 1 for LED sleepdelay int sitv; //interval 2 for LED sleepdelay void setup() { //internal voltage reference //analogReference( INTERNAL2V56_NO_CAP ); //indicate on state digitalWrite(ledpin,HIGH); delay(10); digitalWrite(ledpin,LOW); //sleep before sensing input voltage. setup_watchdog(8); // approximately 4 seconds sleep before starting operation. system_sleep(); delay(10); //show Vcc int bdebug=readVcc()/1000; int adebug=(readVcc()/100)-(bdebug*10); while (bdebug>0) { digitalWrite(ledpin, HIGH); delay(1); digitalWrite(ledpin, LOW); delay(400); bdebug--; } delay(1000); while (adebug>0) { digitalWrite(ledpin, HIGH); delay(1); digitalWrite(ledpin, LOW); delay(400); adebug--; } delay(2000); //read input voltage if (readVcc() > chargethreshold) { runmode=1; //runmode for charging. } else { runmode=2; //runmode for strobing } pinMode(batpin, INPUT); pinMode(ledpin, OUTPUT); pinMode(potpin, INPUT); } void loop(){ if (f_wdt==1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs f_wdt=0; // reset flag } //check runmode //pinMode(batpin,INPUT); sensorValue = analogRead(batpin); voltage = (1000 * (sensorValue * (5.0 / 1023))); if (debug!= true) { int bdebug=voltage/1000; int adebug=(voltage/100)-(bdebug*10); while (bdebug>0) { digitalWrite(ledpin, HIGH); delay(1); digitalWrite(ledpin, LOW); delay(400); bdebug--; } delay(1000); while (adebug>0) { digitalWrite(ledpin, HIGH); delay(1); digitalWrite(ledpin, LOW); delay(400); adebug--; } delay(2000); debug=true; } if (runmode==1) { //charging if (voltage <= batmax) { // charge pinMode(batpin,OUTPUT); digitalWrite(batpin,HIGH); delay(1000); digitalWrite(ledpin,HIGH); delayMicroseconds(50); digitalWrite(ledpin,LOW); digitalWrite(batpin,LOW); pinMode(batpin,INPUT); delay(2); } else { runmode=3; } } if (runmode==2) { //flashing if (readVcc() > batmin) { // strobe if (blinks<250) { //stop measuring pot if over 250 blinks to lock blinkrate //read pot for sleeptimers blinks++; int pot = analogRead(potpin); //pot read value if (pot < 100) {itv=2;; sitv=0;} if (pot >= 100 && pot <=199) {itv=2;sitv=1;} if (pot >= 200 && pot <=299) {itv=2;sitv=2;} if (pot >= 300 && pot <=399) {itv=2;sitv=3;} if (pot >= 400 && pot <=499) {itv=3;sitv=1;} if (pot >= 500 && pot <=599) {itv=3;sitv=2;} if (pot >= 600 && pot <=699) {itv=3;sitv=3;} if (pot >= 700 && pot <=799) {itv=4;sitv=1;} if (pot >= 800 && pot <=899) {itv=4;sitv=2;} if (pot >= 900 && pot <=1024) {itv=4;sitv=3;} } //sleep if (wdduration==itv) { wdduration=itv+sitv; } else { wdduration=itv; } //blink digitalWrite(ledpin,HIGH); delay(ond); digitalWrite(ledpin,LOW); setup_watchdog(wdduration); system_sleep(); } else { // else battery is dead setup_watchdog(9); system_sleep(); } } if (runmode==3) { if (voltage <= batrecharge) { // charge runmode=1; } digitalWrite(ledpin,HIGH); delayMicroseconds(50); digitalWrite(ledpin,LOW); delay(5000); } } // set system into the sleep state // system wakes up when wtchdog is timed out void system_sleep() { cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here sleep_enable(); sleep_mode(); // System sleeps here sleep_disable(); // System continues execution here when watchdog timed out sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON } // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; int ww; if (ii > 9 ) ii=9; bb=ii & 7; if (ii > 7) bb|= (1<<5); bb|= (1<