info:mighty_boost_sample_sketch
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
info:mighty_boost_sample_sketch [2016/02/23 09:19] – created 75.177.137.2 | info:mighty_boost_sample_sketch [2016/02/23 09:31] (current) – 75.177.137.2 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | * {{: | ||
- | // ************************************************************************************************************* | ||
- | // MightyBoost control sample sketch | ||
- | // ************************************************************************************************************* | ||
- | // Copyright (2015) Felix Rusu of http:// | ||
- | // http:// | ||
- | // MightyBoost is a smart backup PSU controllable by Moteino, and this sketch is a sample control sketch to run | ||
- | // MightyBoost in this mode. | ||
- | // Be sure to check back for code updates and patches | ||
- | // ************************************************************************************************************* | ||
- | // This sketch will provide control over the essential features of MightyBoost: | ||
- | // - provide switched 5V power to a sensitive load like RaspberryPi which should not lose power instantly | ||
- | // - Control the " | ||
- | // - Monitor input supply and switch to battery backup when external power is lost | ||
- | // - Monitor battery voltage and issue a shutdown/ | ||
- | // This sketch may be extended to include integration with other LowPowerLab automation products | ||
- | // ************************************************************************************************************* | ||
- | // License | ||
- | // ************************************************************************************************************* | ||
- | // This program is free software; you can redistribute it | ||
- | // and/or modify it under the terms of the GNU General | ||
- | // Public License as published by the Free Software | ||
- | // Foundation; either version 2 of the License, or | ||
- | // (at your option) any later version. | ||
- | // | ||
- | // This program is distributed in the hope that it will | ||
- | // be useful, but WITHOUT ANY WARRANTY; without even the | ||
- | // implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
- | // PARTICULAR PURPOSE. | ||
- | // License for more details. | ||
- | // | ||
- | // You should have received a copy of the GNU General | ||
- | // Public License along with this program; if not, write | ||
- | // to the Free Software Foundation, Inc., | ||
- | // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
- | // | ||
- | // Licence can be viewed at | ||
- | // http:// | ||
- | // | ||
- | // Please maintain this license information along with authorship | ||
- | // and copyright notices in any redistribution of this code | ||
- | // ************************************************************************************************************* | ||
- | #define LED | ||
- | #define BUTTON | ||
- | #define SIG_SHUTOFF | ||
- | #define SIG_BOOTOK | ||
- | // !!NOTE!! Originally this was D7 but it was moved to A0 at least temporarily. | ||
- | // On MightyBoost R1 you need to connect D7 and A0 with a jumper wire. | ||
- | // The explanation for this is given here: http:// | ||
- | #define OUTPUT_5V | ||
- | #define BATTERYSENSE | ||
- | // hence the actual input voltage = analogRead(A7) * 0.00322 (3.3v/1024) * 1.47 (10k+4.7k voltage divider ratio) | ||
- | // when plugged in this should be 4.80v, nothing to worry about | ||
- | // when on battery power this should decrease from 4.15v (fully charged Lipoly) to 3.3v (discharged Lipoly) | ||
- | // trigger a shutdown to the target device once voltage is around 3.4v to allow 30sec safe shutdown | ||
- | #define LOWBATTERYTHRESHOLD | ||
- | |||
- | #define RESETHOLDTIME | ||
- | #define SHUTDOWNHOLDTIME | ||
- | #define ShutoffTriggerDelay | ||
- | #define RecycleTime | ||
- | // should be at least 3000 more than Min | ||
- | // if nothing happens after this window, if button is | ||
- | // still pressed, force cutoff power, otherwise switch back to normal ON state | ||
- | #define RESETPULSETIME | ||
- | #define ForcedShutoffDelay | ||
- | // for this long, force shutdown (this should be less than RecycleTime) | ||
- | #define ShutdownFinalDelay | ||
- | // to allow all PI LEDs to stop activity (pulse LED faster) | ||
- | |||
- | #define PRINTPERIOD | ||
- | |||
- | int lastValidReading = 1; | ||
- | unsigned long lastValidReadingTime = 0; | ||
- | unsigned long NOW=0; | ||
- | int PowerState = 0; | ||
- | long lastPeriod = -1; | ||
- | float systemVoltage = 5; | ||
- | |||
- | void setup() { | ||
- | Serial.begin(115200); | ||
- | pinMode(BUTTON, | ||
- | pinMode(SIG_BOOTOK, | ||
- | pinMode(SIG_SHUTOFF, | ||
- | pinMode(LED, | ||
- | pinMode(OUTPUT_5V, | ||
- | pinMode(A7, INPUT); | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | digitalWrite(OUTPUT_5V, | ||
- | } | ||
- | |||
- | void loop() { | ||
- | int reading = digitalRead(BUTTON); | ||
- | NOW = millis(); | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | boolean batteryLow = systemVoltage < LOWBATTERYTHRESHOLD; | ||
- | |||
- | if (batteryLow || reading != lastValidReading && NOW - lastValidReadingTime > 200) | ||
- | { | ||
- | lastValidReading = reading; | ||
- | lastValidReadingTime = NOW; | ||
- | | ||
- | if (batteryLow || reading == 0) | ||
- | { | ||
- | //make sure the button is held down for at least ' | ||
- | NOW = millis(); | ||
- | while (!batteryLow && (PowerState == 1 && millis()-NOW < RESETHOLDTIME)) { delay(10); if (digitalRead(BUTTON) != 0) return; } | ||
- | |||
- | // | ||
- | analogWrite(LED, | ||
- | while (!batteryLow && (PowerState == 1 && millis()-NOW < SHUTDOWNHOLDTIME)) | ||
- | { | ||
- | if (digitalRead(BUTTON) != 0) | ||
- | { | ||
- | if (BOOTOK()) | ||
- | { | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | delay(RESETPULSETIME); | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | |||
- | NOW = millis(); | ||
- | boolean recycleDetected=false; | ||
- | while (millis()-NOW < RecycleTime) //blink LED while waiting for BOOTOK to go high | ||
- | { | ||
- | //blink 3 times and pause | ||
- | digitalWrite(LED, | ||
- | delay(100); | ||
- | digitalWrite(LED, | ||
- | delay(100); | ||
- | digitalWrite(LED, | ||
- | delay(100); | ||
- | digitalWrite(LED, | ||
- | delay(100); | ||
- | digitalWrite(LED, | ||
- | delay(100); | ||
- | digitalWrite(LED, | ||
- | delay(500); | ||
- | |||
- | if (!BOOTOK()) recycleDetected = true; | ||
- | else if (BOOTOK() && recycleDetected) | ||
- | return; | ||
- | } | ||
- | return; //reboot pulse sent but it appears a reboot failed; exit all checks | ||
- | } | ||
- | else return; //ignore everything else (button was held for RESETHOLDTIME, | ||
- | } | ||
- | } | ||
- | | ||
- | // | ||
- | //so I dont want to cutoff power before it had a chance to fully boot up | ||
- | if (batteryLow || (PowerState == 1 && BOOTOK())) | ||
- | { | ||
- | // signal Pi to shutdown | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | |||
- | //now wait for the Pi to signal back | ||
- | NOW = millis(); | ||
- | float in, out; | ||
- | boolean forceShutdown = true; | ||
- | | ||
- | while (millis()-NOW < RecycleTime) | ||
- | { | ||
- | if (in > 6.283) in = 0; | ||
- | in += .00628; | ||
- | | ||
- | out = sin(in) * 127.5 + 127.5; | ||
- | analogWrite(LED, | ||
- | delayMicroseconds(1500); | ||
- | | ||
- | //account for force-shutdown action (if button held for ForcedShutoffDelay, | ||
- | if (millis()-NOW <= (ForcedShutoffDelay-SHUTDOWNHOLDTIME) && digitalRead(BUTTON) != 0) | ||
- | forceShutdown = false; | ||
- | if (millis()-NOW >= (ForcedShutoffDelay-SHUTDOWNHOLDTIME) && forceShutdown) | ||
- | { | ||
- | PowerState = 0; | ||
- | digitalWrite(LED, | ||
- | digitalWrite(OUTPUT_5V, | ||
- | break; | ||
- | } | ||
- | | ||
- | if (millis() - NOW > ShutoffTriggerDelay) | ||
- | { | ||
- | // Pi signaling OK to turn off | ||
- | if (!BOOTOK()) | ||
- | { | ||
- | PowerState = 0; | ||
- | digitalWrite(LED, | ||
- | NOW = millis(); | ||
- | while (millis()-NOW < ShutdownFinalDelay) | ||
- | { | ||
- | if (in > 6.283) in = 0; | ||
- | in += .00628; | ||
- | | ||
- | out = sin(in) * 127.5 + 127.5; | ||
- | analogWrite(LED, | ||
- | delayMicroseconds(300); | ||
- | } | ||
- | | ||
- | digitalWrite(OUTPUT_5V, | ||
- | break; | ||
- | } | ||
- | } | ||
- | } | ||
- | | ||
- | // last chance: if power still on but button still pressed, force cutoff power | ||
- | if (PowerState == 1 && digitalRead(BUTTON) == 0) | ||
- | { | ||
- | PowerState = 0; | ||
- | digitalWrite(OUTPUT_5V, | ||
- | } | ||
- | | ||
- | digitalWrite(SIG_SHUTOFF, | ||
- | } | ||
- | else if (PowerState == 1 && !BOOTOK()) | ||
- | { | ||
- | NOW = millis(); | ||
- | unsigned long NOW2 = millis(); | ||
- | int analogstep = 255 / ((ForcedShutoffDelay-SHUTDOWNHOLDTIME)/ | ||
- | while (digitalRead(BUTTON) == 0) | ||
- | { | ||
- | if (millis()-NOW2 > 100) | ||
- | { | ||
- | analogWrite(LED, | ||
- | NOW2 = millis(); | ||
- | } | ||
- | if (millis()-NOW > ForcedShutoffDelay-SHUTDOWNHOLDTIME) | ||
- | { | ||
- | //TODO: add blinking here to signal final shutdown delay | ||
- | PowerState = 0; | ||
- | digitalWrite(OUTPUT_5V, | ||
- | break; | ||
- | } | ||
- | } | ||
- | } | ||
- | else if (PowerState == 0) | ||
- | { | ||
- | PowerState = 1; | ||
- | digitalWrite(OUTPUT_5V, | ||
- | } | ||
- | } | ||
- | |||
- | digitalWrite(LED, | ||
- | } | ||
- | |||
- | int currPeriod = millis()/ | ||
- | if (currPeriod != lastPeriod) | ||
- | { | ||
- | lastPeriod=currPeriod; | ||
- | Serial.print(" | ||
- | systemVoltage = analogRead(BATTERYSENSE) * 0.00322 * 1.47; | ||
- | Serial.print(systemVoltage); | ||
- | if (systemVoltage > 4.3) | ||
- | Serial.println(" | ||
- | else Serial.println(" | ||
- | } | ||
- | } | ||
- | |||
- | boolean BOOTOK() { | ||
- | return analogRead(SIG_BOOTOK) > 800; | ||
- | } |
info/mighty_boost_sample_sketch.1456237182.txt.gz · Last modified: 2016/02/23 09:19 by 75.177.137.2