Voltage reading from 3 sources and activating 3 relays

Hi,

I’m totally new to programming and don’t know much about electronic designing. I’m building a transport pc for hi-fi. For higher quality I’m powering my pc with 12V 10A NIMH cells. I have two 12V power supplys (one is for CPU and HDD, the other is for mainboard - this is again a must for higher sound quality) and four 12V 10A NIMH batteries. My aim is:

While charging one battery, I want to use the other battery for the PSU. When battery voltage drops to 11.2V, I want the relay to be activated and use the other battery.

In the future I’ll add two more batteries for sound card. So I’ll have 6 batteries, which is used for 3 different sources. I need to monitor the voltage of the batteries that are in use and control three relays according the voltage readings.

So, I begin to search and find a voltage reading sketch. Modified it; but failed I guess. The original reading sketch was reading only one voltage. I doubled all of the variables and made it to read two. But when trying to read two batteries with my sketch, the first batteries reading is right, the second batteried reading is wrong.

If I can get the readings right, relay control part of the sketch will be much easier I guess (the rest is simple if phrase, isn’t it?)

Here is my sketch:

#define NUM_SAMPLESA 10
#define NUM_SAMPLESB 10

int sumA = 0; // sum of samples taken
int sumB = 0; // sum of samples taken
unsigned char sample_countA = 0; // current sample number
unsigned char sample_countB = 0; // current sample number
float voltageA = 0.0; // calculated voltage
float voltageB = 0.0; // calculated voltage

void setup()
{
Serial.begin(9600);
}

void loop()
{
// take a number of analog samples and add them up
while (sample_countA < NUM_SAMPLESA) {
sumA += analogRead(A1);
sample_countA++;
delay(10);
}

voltageA = ((float)sumA / (float)NUM_SAMPLESA * 5.015) / 1024.0;

Serial.print(voltageA * 4);
Serial.println (" V");
sample_countA = 0;
sumA = 0;
delay(10);

// take a number of analog samples and add them up
while (sample_countB < NUM_SAMPLESB) {
sumB += analogRead(A2);
sample_countB++;
delay(200);
}

voltageB = ((float)sumB / (float)NUM_SAMPLESB * 5.015) / 1024.0;

Serial.print(voltageB * 1);
Serial.println (" V");
sample_countB = 0;
sumB = 0;
delay(100);

}

Your sum variables are declared int. An int can hold -32768 to 32767. The sum variables can overflow. Use long data types for sums.

Thank you for the fast response. I'll try that today.

But it is interesting that, the first battery's reading is just fine and the others is messed up.

First thing, swap the connections so the first readings are reading the 2nd battery - if the 2nd battery readings are now correct and the 1st battery readings are wrong you can be confident that the problem is with the software, not the hardware.

You should be aware that the Atmega chip has only a single ADC and when you switch to a different analog pin you need to leave a little time for it to settle. The usual advice is to discard the first reading on the new pin. You may find it useful to study the Atmega datasheet.

I don't think there is any need, or any advantage, in using floats for your calculations. Just use unsigned long variables (since the ADC can only return positive values) and watch the order of calculation to see that you don't overflow or underflow in the middle of the calculation.

If you collect a number of samples which is a power of 2 (8, for example) you can get the average by shifting >> 3 is the same as divide by 8.

If you want to maintain precision after the division you could multiply the total beforehand and just remember that the answer is 10 times or 100 times the actual value.

...R

Hi,

Please use code tags.. See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Can you please post a copy of your circuit, in CAD or picture of hand drawn circuit in jpg, png or pdf format.

Thanks Tom...... :)