Once again, I've hit another snag in my project
Basically, I have 2 ATmega328's connected to each other via the serial UART, one uC is measuring cell voltages of a LiPo and spitting them out over serial, and the other is taking that data and displaying it on a LCD.
But for some reason, after a few seconds, the LCD just starts displaying 0.00's, or sometimes numbers like 0.04, 0.03 etc and doesn't seem to update at all any more (Can usually tell it's updating by the LCD flickering).
I am running it over about 2 metres of cat5, however I am monitoring the serial at the LCD end and there is no change in the data when the LCD starts reading 0.00's, so I'm really confused as to what could be going on here?
Code on the measurement uC:
#include "SPI.h"
#define LT_SPI_START digitalWrite(10,LOW)
#define LT_SPI_END digitalWrite(10,HIGH)
byte config[6] = { 0xE9,0x00,0x00,0xFC,0x71,0xC8 }; //Default config
float current_voltages[6];
String serialdata;
#define WRCFG 0x01 // Write config registers
#define RDCFG 0x02 // Read config registers
#define RDCV 0x04 // Read all cell voltages
#define RDCVA 0x06 // Read cells 1-4
#define RDCVB 0x08 // Read cells 5-8
#define LTCADDR 0x80 // LTC's Address - 0000
#define STCVAD 0x10
void setup(){
pinMode(10, OUTPUT);
Serial.begin(115200);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
SPI.setClockDivider(SPI_CLOCK_DIV64);
// Write LTC configs
LT_SPI_START;
sendToSPI(LTCADDR); // Non-broadcast command
sendToSPI(WRCFG); // Write config
sendMultipleToSPI(config, 6);
LT_SPI_END;
// Finish LTC config
}
void loop(){
// STUFF!
beginCellVolt(); // Start cell 1-6 conversion
readCellVolt(current_voltages,LTCADDR);
Serial.print(".");
Serial.print((int)current_voltages[0]/10);
Serial.print(",");
Serial.print((int)current_voltages[1]/10);
Serial.print(",");
Serial.print((int)current_voltages[2]/10);
Serial.print(",");
Serial.print((int)current_voltages[3]/10);
Serial.print(",");
Serial.print((int)current_voltages[4]/10);
Serial.print(",");
Serial.print((int)current_voltages[5]/10);
delay(500);
}
// ---- FUNCTIONS ----
void beginCellVolt() {
LT_SPI_START;
sendToSPI(STCVAD);
delay(11); //Time for conversions
LT_SPI_END;
}
// Reads cell voltage registers
void readCellVolt(float* cell_voltages, byte board) {
LT_SPI_START;
sendToSPI(board); // Board address is selected
sendToSPI(RDCV); // Cell voltages to be read
byte cvr[12]; // Buffer to store unconverted values
getMultipleFromSPI(cvr, RDCV, 12);
LT_SPI_END;
// Converting cell voltage registers to cell voltages
cell_voltages[0] = (cvr[0] & 0xFF) | (cvr[1] & 0x0F) << 8;
cell_voltages[1] = (cvr[1] & 0xF0) >> 4 | (cvr[2] & 0xFF) << 4;
cell_voltages[2] = (cvr[3] & 0xFF) | (cvr[4] & 0x0F) << 8;
cell_voltages[3] = (cvr[4] & 0xF0) >> 4 | (cvr[5] & 0xFF) << 4;
cell_voltages[4] = (cvr[6] & 0xFF) | (cvr[7] & 0x0F) << 8;
cell_voltages[5] = (cvr[7] & 0xF0) >> 4 | (cvr[8] & 0xFF) << 4;
for(int i=0;i<6;i++) {
cell_voltages[i] = (cell_voltages[i]-512)*1.5;
}
}
// Send data to LTC
void sendMultipleToSPI(byte * data, int n) {
for(int i=0; i<n; i++) {
SPI.transfer(data[i]);
}
SPI.transfer(getPEC(data, n));
}
// Get data from LTC
byte * getMultipleFromSPI(byte * data, byte info, int n) {
for(int i=0; i<n; i++) {
data[i] = SPI.transfer(info);
}
byte pec = SPI.transfer(info);
}
void sendToSPI(byte data) {
sendMultipleToSPI(&data, 1);
}
void readConfig(byte*config,byte board) {
LT_SPI_START;
sendToSPI(board); // Board address is selected
sendToSPI(RDCFG); // Configuration is read
getMultipleFromSPI(config, RDCFG, 6);
LT_SPI_END;
}
// Calculate PEC, n is size of DIN
byte getPEC(byte * din, int n) {
byte pec, in0, in1, in2;
pec = 0x41;
for(int j=0; j<n; j++) {
for(int i=0; i<8; i++) {
in0 = ((din[j] >> (7 - i)) & 0x01) ^ ((pec >> 7) & 0x01);
in1 = in0 ^ ((pec >> 0) & 0x01);
in2 = in0 ^ ((pec >> 1) & 0x01);
pec = in0 | (in1 << 1) | (in2 << 2) | ((pec << 1) & ~0x07);
}
}
return pec;
}
And the LCD uC:
String serial_data[6];
float cell_voltages[6];
int varcounter = 0;
boolean newdata = false;
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(9, 8, 7, 4, 2, 5);
void setup() {
pinMode(3, OUTPUT);
analogWrite(3, 128);
lcd.begin(16, 2);
Serial.begin(115200);
}
void loop() {
while (Serial.available() > 0) {
newdata = true;
delay(10); //small delay to allow input buffer to fill
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
varcounter++;
} //breaks out of capture loop to print readstring
if (c != ',' && c != '.'){
serial_data[varcounter] += c;
}
if (c == '.'){
memset(serial_data,0,sizeof(serial_data));
varcounter = 0;
newdata = true;
}
}
if (newdata == true){
lcd.clear();
lcd.setCursor(0,0);
for (int i=0; i < 6; i++){
cell_voltages[i] = serial_data[i].toInt();
cell_voltages[i] = cell_voltages[i] / 100;
if (i == 3){
lcd.setCursor(0,1);
}
lcd.print(cell_voltages[i]);
lcd.print(" ");
delay(10);
}
newdata = false;
}
}
Cheers,
Dan