Skip to content

Instantly share code, notes, and snippets.

@jamesmccartney
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesmccartney/328b3791af19a538d3ad to your computer and use it in GitHub Desktop.
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.
#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