Self-educated 60+ hobby-coder here, so don't bite my head off.
Trying to design a lead/acid battery cell voltmeter with relays/flying caps. Just for fun and learning.
Eight DPDT relays and a TPIC6C596 shift register on a small board. Three boards for 24 cells (48volt battery) for now.
Boards are designed and parts are ordered, so time to think software.
This is what I have so far, but I'm not sure about the nested for loop on line 53.
'rawValue' exists inside the main for loop, but can it also exist inside the nested for loop.
Or should I do it as in the second sketch ('total' is an unsigned int).
Maybe there are also other mistakes.
Leo..
// TPIC6C596 lead/acid battery cell monitor
// 6k8 resistor between Aref and 3.3volt pins to make a ~2.725volt Aref
// user input
float Aref = 2.731; // Aref used | ***calibrate voltage here***
const byte cells = 24; // number of battery cells | max 32
const byte numReadings = 45; // for averaging | max 64
const byte inputPin = A0;
const byte latchPin = 8;
const byte dataPin = 11;
const byte clockPin = 12;
unsigned int rawValue[cells]; // cell arrays | each can hold 64 A/D readings
float voltage[cells]; // voltage arrays
long data = 0; // 4 bytes | 32 relays max
int preRead; // this A/D value is not used
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
// start with all relays off
digitalWrite(latchPin, LOW);
digitalWrite(dataPin, 0);
for (int i = 0; i < 32; i++) { // clock in LOWs
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
digitalWrite(latchPin, HIGH); // transfer to outputs
digitalWrite(latchPin, LOW);
// three control lines are now low
analogReference(EXTERNAL); // an external reference voltage is used
Serial.begin(115200); // ***set serial monitor to this value***
Serial.println(F("Lead/Acid Battery Cell Voltmeter"));
Serial.println(F("--------------------------------"));
delay(5000); // wait for cell sample caps to charge.
}
void loop() {
// read the voltage on the flying caps
for (int i = 0; i < cells; i++) { // step through the rawValue arrays
data = 1 << i; // shifts a single HIGH bit across the bytes of a 4-byte long | one relay on at the time
digitalWrite(latchPin, LOW); // so the relays don't chatter while sending data
shiftOut(dataPin, clockPin, MSBFIRST, (data >> 24)); // send
shiftOut(dataPin, clockPin, MSBFIRST, (data >> 16)); // the
shiftOut(dataPin, clockPin, MSBFIRST, (data >> 8)); // four
shiftOut(dataPin, clockPin, MSBFIRST, data); // bytes
digitalWrite(latchPin, HIGH); // activate relay
delay(10); // wait for contact bounce
preRead = analogRead(inputPin); // one unused reading to clear any ghost charges
//Serial.println(preRead); // test bouncing
for (int x = 0; x < numReadings; x++) { // multiple analogue readings for averaging
rawValue[i] = rawValue[i] + analogRead(inputPin); // add each value
}
// all relays off
digitalWrite(latchPin, LOW);
digitalWrite(dataPin, 0);
for (int j = 0; j < 32; j++) { // clock in 32 LOWs
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
digitalWrite(latchPin, HIGH); // transfer to outputs
digitalWrite(latchPin, LOW);
delay(10); // wait for relay to turn off
// calculate voltage and clear rawValue arrays
voltage[i] = rawValue[i] * (Aref / 1023) / numReadings; // calculate voltage and store in voltage array
if ((rawValue[i] / numReadings) == 1023) voltage[i] = 9.999; // crude overflow indicator
rawValue[i] = 0; // clear raw array
}
// print the values
Serial.print(F("Battery 1 = "));
Serial.print(voltage[0] + voltage[1] + voltage[2] + voltage[3] + voltage[4] + voltage[5]);
Serial.print(F("volt Cells: "));
for (int i = 0; i < 6; i++) {
Serial.print(voltage[i], 3); // three decimal places
Serial.print(F(" "));
}
Serial.println(F(""));
Serial.print(F("Battery 2 = "));
Serial.print(voltage[6] + voltage[7] + voltage[8] + voltage[9] + voltage[10] + voltage[11]);
Serial.print(F("volt Cells: "));
for (int i = 6; i < 12; i++) {
Serial.print(voltage[i], 3); // three decimal places
Serial.print(F(" "));
}
Serial.println(F(""));
Serial.print(F("Battery 3 = "));
Serial.print(voltage[12] + voltage[13] + voltage[14] + voltage[15] + voltage[16] + voltage[17]);
Serial.print(F("volt Cells: "));
for (int i = 12; i < 18; i++) {
Serial.print(voltage[i], 3); // three decimal places
Serial.print(F(" "));
}
Serial.println(F(""));
Serial.print(F("Battery 4 = "));
Serial.print(voltage[18] + voltage[19] + voltage[20] + voltage[21] + voltage[22] + voltage[23]);
Serial.print(F("volt Cells: "));
for (int i = 18; i < 24; i++) {
Serial.print(voltage[i], 3); // three decimal places
Serial.print(F(" "));
}
Serial.println(F(""));
Serial.println(F("---------------------"));
delay(5000); // time between scanning all cells
}
for (int x = 0; x < numReadings; x++) { // multiple analogue readings for averaging
total = total + analogRead(inputPin); // add each value
}
rawValue[i] = total; // transfer to rawValue array
total = 0; // reset
