Open FireDemon007 opened 6 years ago
That would be nice!
I'd love to see a battery indicator next to the RSSI graph. You just need to add 220k resistor (allowing to measure up to 5.4V to be on a safe side) in series with the battery to ADC pin to have 440k/100k voltage divider (D1 has 220k/100k divider by default on ADC pin, so you can measure 3v3).
I'm working on botching the sketch to make little battery display charge of battery, will probably share the code tomorrow. For some reason I can't upload code to my D1 after uploading this project (port unable to be opened) so will try tomorrow.
So I finished writing the botch, and did some testing on battery life. Without this mod, the monitor lived for about 24 hours of idling (RPi connected, not printing) on 2000mAh battery, so it shouldn't be shorter than this with this mod.
Add this to your printermonitor.ino
at line 1012 (after the function void drawRssi(OLEDDisplay *display)
and add drawBattery(display);
to void drawRssi(OLEDDisplay *display)
function after line 1010 (before the end of the function). So whenever the RSSI graph is updated, so is the battery status. I suggest you calibrate your resistors, as it could vary quite a lot depending on the tolerance of the resistor itself.
As I said this is a quick botch, it could use options to add sleep to prolong the battery life etc. and I didn't do any real testing, as I'm in the process of designing case for 2×18650, 128×64 OLED, D1 mini and TP4056 or battery shield module.
void drawBattery(OLEDDisplay *display){
/* Battery botch by Oxmaster
* ------------------------------------------------
* add this snippet to printermonitor.ino
* right after void drawRssi(OLEDDisplay *display)
* and drawBattery(display); at the end of
* drawRssi function (above this one)
* whenever the RSSI graph is updated, so is this
*-------------------------------------------------
* When using D1 battery shield:
*
* The shield has integrated 130k resistor, just
* bridge J2 connector on the back
* change voltageDividerRatio to 4.5
* and batteryVoltageRange = {3.1, 4.15}
*-------------------------------------------------
* When using TP4056
*
* Add 220k resistor inline with the battery
* Battery -> 220k resistor -> ADC0
* change voltageDividerRatio to 5.1
* and batteryVoltageRange = {2.5, 4.15}
*-------------------------------------------------
*
* to get better accuracy, calibrate the voltageDividerRatio
*/
// constants -------------------------------------------------------
// 1 bit equals x volts
const float bitPerVolt = 0.0009765625;
// voltage divider ratio (use to calibrate your divider)
// use different arduino sketch to get this value
const float voltageDividerRatio = 5.1;
//const float voltageDividerRatio = 4.5;
// min and max voltage that the battery will achieve
// used to calculate percentage of charge
// per TP5400 datasheet (D1 battery shield)
//const float batteryVoltageRange[2] = {3.1, 4.15};
// per TP4056 datasheet
const float batteryVoltageRange[2] = {2.5, 4.15};
// vars ------------------------------------------------------------
// !! do not change !!
const uint8_t dataPoints = 5;
static uint8_t dataIndex = 0;
static int8_t dataReadings[dataPoints] = {0, 0, 0, 0, 0};
static int16_t dataTotal = 0;
int8_t average = 0;
// calculations ----------------------------------------------------
uint16_t adcOutput = analogRead(A0);
// calculate voltage
float batteryVoltage = (float)adcOutput * bitPerVolt * voltageDividerRatio;
// convert voltage to percentage (map function)
// int16 because the value could go above 128, overflowing int8
int16_t batteryChargePercentage = (batteryVoltage - batteryVoltageRange[0]) * 100 / (batteryVoltageRange[1] - batteryVoltageRange[0]);
// constrain the value in case of anomaly
batteryChargePercentage = constrain(batteryChargePercentage, 0, 100);
// using running average, calculate the charge percentage
dataTotal -= dataReadings[dataIndex];
dataReadings[dataIndex] = batteryChargePercentage;
dataTotal += dataReadings[dataIndex];
dataIndex ++;
if (dataIndex >= dataPoints)
dataIndex = 0;
average = dataTotal / dataPoints;
// debug
/*
Serial.print("ADC: ");
Serial.println(adcOutput);
Serial.print("VOLT: ");
Serial.println(batteryVoltage);
Serial.print("PERCENT: ");
Serial.println(batteryChargePercentage);
Serial.print("PERCENT AVG: ");
Serial.println(average);
*/
// draw the battery outline
display -> drawRect(104, 49, 7, 15);
// fill the battery, 5 steps
// 0, 25, 50, 75, 100%
if (average <= 0){
// 0%
} else if (average > 0){
// 25%
display -> drawRect(106, 60, 3, 2);
if (average >= 25){
// 50%
display -> drawRect(106, 57, 3, 2);
if (average >= 50){
// 75%
display -> drawRect(106, 54, 3, 2);
if (average >= 75){
// 100%
display -> drawRect(106, 51, 3, 2);
}
}
}
}
}
This is how it looks:
File that you can just replace: printermonitor.zip
To expand the battery live, you may can take a look to my night mode ( I started a pull request) with the darker display the battery life expand around 50-100% longer in my tests
When I will have time (if) I will try to understand how the web interface works and try to implement it "properly" with settings etc. Unless someone more knowledgeable is up to the task.
Next week when I’m home I’ll take a look and try to add this function to my monitor. Maybe I need a schematic where I put the resistors...
On Sunday I will try to upload the schematic and a sketch to help calibrate the divider, maybe earlier, don't know as I have a lot of work this week.
Again, I didn't test it too much, just verified that it works for me.
Adding a battery shield for full Wireless use is without a doubt possible. But I'm wondering if you could read the battery level through one of the analog pins every so often and display it on the display?