Last active
August 29, 2015 14:23
-
-
Save jamesmccartney/328b3791af19a538d3ad to your computer and use it in GitHub Desktop.
Example of a simple battery capacity meter using a multimap function with two arrays, one of a basic lipo voltage curve and corresponding capacity percentage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
#include <Adafruit_GFX.h> | |
#include "woody_eyes.h" | |
#include <Adafruit_NeoPixel.h> | |
#define PIN 32 | |
woody_eyes eye; | |
int reading; | |
float voltage; | |
float out[] = {14,21,27,35,43,48,56,63,70,77,84,94,100}; | |
float in[] = {3.67,3.70,3.73,3.76,3.80,3.83,3.86,3.90,3.93,3.96,4.00,4.10,4.20}; | |
float capacity; | |
void setup() { | |
pinMode(A10,OUTPUT); | |
eye.clearBuffer(); | |
eye.setTextColor(WHITE); | |
eye.setTextSize(1); | |
delay(500); // to give the eyes a chance to open | |
eye.select(eyeleft); | |
eye.begin(); | |
eye.display(); | |
eye.select(eyeright); | |
eye.begin(); | |
eye.display(); | |
analogReadResolution(12); | |
} | |
void loop() { | |
eye.select(eyeright); // Voltage to the right eye | |
eye.clearBuffer(); | |
eye.setCursor(0, 0); | |
reading = analogRead(A10); // RAW Bat voltage | |
voltage = float(reading) / 4095 * 4.2; | |
if(voltage <= 4.10){ | |
//shitty attempt to compensate for load voltage drop, makes things look more logical | |
voltage += 0.1; | |
} | |
eye.print(voltage); // should be something between 3.3 and 4.2 | |
eye.println(" RAW"); | |
//calculate capacity | |
capacity = FmultiMap(voltage, in, out, 13); | |
eye.print(capacity); | |
eye.println("%"); | |
eye.display(); | |
delay(5000); | |
} | |
// note: the in array should have increasing values | |
float FmultiMap(float val, float * _in, float * _out, uint8_t size) | |
{ | |
// take care the value is within range | |
// val = constrain(val, _in[0], _in[size-1]); | |
if (val <= _in[0]) return _out[0]; | |
if (val >= _in[size-1]) return _out[size-1]; | |
// search right interval | |
uint8_t pos = 1; // _in[0] allready tested | |
while(val > _in[pos]) pos++; | |
// this will handle all exact "points" in the _in array | |
if (val == _in[pos]) return _out[pos]; | |
// interpolate in the right segment for the rest | |
return (val - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment