Skip to content

Instantly share code, notes, and snippets.

@smithjacobj
Created September 6, 2021 07:43
Show Gist options
  • Save smithjacobj/68256ab26c6b06a3d5142944f4c1225d to your computer and use it in GitHub Desktop.
Save smithjacobj/68256ab26c6b06a3d5142944f4c1225d to your computer and use it in GitHub Desktop.
Source for a basic Arduino Uno 1S BMS I created for a DeWalt 20v MAX project.
//
// edit these
//
// how long should we wait for inrush to stabilize?
const int kInrushWait = 2 * 1000; // 2 seconds
// what voltage should this shut off at?
const float kMinSafeVolts = 14.f;
// test the divider at 25v and set the output value here.
const float kActualOutputAt25v = 4.98f;
// how long should we sleep for before allowing output again? really, we just
// want to annoy the user into charging or switching batteries.
const int kLowVoltageSleepDelay = 2 * 1000; // 2 seconds
// leave these alone
const float kDividerReferenceInput = 25.f;
const float kDividerReferenceOutput = 5.f;
const float kMaxAnalogReadValue =
kActualOutputAt25v / kDividerReferenceOutput * 1024.f;
const float kSafeVoltageRatio = kMinSafeVolts / 25.f;
const int kMinSenseValue = kSafeVoltageRatio * kMaxAnalogReadValue;
const int kSensePin = A0;
const int kRelayPin = 2;
void relayOn() {
digitalWrite(kRelayPin, LOW);
digitalWrite(LED_BUILTIN, HIGH);
}
void relayOff() {
digitalWrite(kRelayPin, HIGH);
digitalWrite(LED_BUILTIN, LOW);
}
void setup() {
pinMode(kRelayPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
// latch the relay on until the low voltage condition
relayOn();
// wait for inrush
delay(kInrushWait);
}
void loop() {
// read until low voltage condition and shut down
const int senseValue = analogRead(kSensePin);
if (senseValue < kMinSenseValue) {
relayOff();
delay(kLowVoltageSleepDelay);
} else {
relayOn();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment