I have a resistor divider to measure voltage. The values of both the resistors are 10k. My battery voltage is 8.4 volts that provides the voltage for my motors and servos outputting 6v via a linear regulator. A separate battery with a switching regulator provides 5v for the micros .etc.
The regulator for the motors/servos will no longer output 6v when the voltage is lower than 7v. Thus, I turn off the regulator if that happens with my Arduino.
The issue I am facing is that if the actual voltage of the battery is around 7.4 and I am drawing current from 5 servos simultaneously, and 2 motors, the voltage display goes quickly down to ~7 and then the system shuts off.
The issue is that there is a discrepancy between the voltage under high load (all motors/servos working) and the voltage under minimal load (maybe 2-3 servos working) causing the system to shutdown prematurely. I check the voltage every 6 seconds, and the running total gets added to an array via the function digital_smooth to sort of, well, smooth out the actual ADC values.
This function actually I think helps with some of the load spikes, but if the spikes are consistent than it drops quickly.
Is there anyway I can minimize the load drops or account for it in some non-arbitrary way? Or is that just par for the course when dealing with massive simultaneous current draws?
If the latter is true, I guess I could implement some current sensing to see when the draw is high and to somehow account for that with the voltage readings.
I guess I'm curious to see if anyone has faced an issue like this before when doing voltage measurements, and if so, how they dealt with it.
float check_motor_batt() {
int raw = digital_smooth(analogRead(motor_batt_div), motor_batt_array);
return voltage_divider(raw);
}
int digital_smooth(int rawIn, int *sensSmoothArray) { // "int *sensSmoothArray" passes an array to the function - the asterisk indicates the array name is a pointer
int j, k, temp, top, bottom;
long total;
static int i;
// static int raw[filterSamples];
static int sorted[filterSamples];
boolean done;
i = (i + 1) % filterSamples; // increment counter and roll over if necc. - % (modulo operator) rolls over variable
sensSmoothArray[i] = rawIn; // input new data into the oldest slot
// Serial.print("raw = ");
for (j = 0; j < filterSamples; j++) { // transfer data array into anther array for sorting and averaging
sorted[j] = sensSmoothArray[j];
}
done = 0; // flag to know when we're done sorting
while (done != 1) { // simple swap sort, sorts numbers from lowest to highest
done = 1;
for (j = 0; j < (filterSamples - 1); j++) {
if (sorted[j] > sorted[j + 1]) { // numbers are out of order - swap
temp = sorted[j + 1];
sorted [j + 1] = sorted[j] ;
sorted [j] = temp;
done = 0;
}
}
}
/*
for (j = 0; j < (filterSamples); j++) { // print the array to debug
Serial.print(sorted[j]);
Serial.print(" ");
}
Serial.println();
*/
// throw out top and bottom 15% of samples - limit to throw out at least one from top and bottom
bottom = max(((filterSamples * 15) / 100), 1);
top = min((((filterSamples * 85) / 100) + 1 ), (filterSamples - 1)); // the + 1 is to make up for asymmetry caused by integer rounding
k = 0;
total = 0;
for ( j = bottom; j < top; j++) {
total += sorted[j]; // total remaining indices
k++;
// Serial.print(sorted[j]);
// Serial.print(" ");
}
//Serial.println();
//Serial.print("average = ");
//Serial.println(total / k);
return total / k; // divide by number of samples
}