Arduino Uno and LTC6803-4 problem with communication using SPI

Good Day everyone!

I have a problem with our Battery management system using LTC6803-4. It will be used to measure 5 series cells. The problem is when I read the configuration of the LTC6803-4, all I receive is 0 0 0 0 0 0, seems like they are not communicating with each other. It doesn't match the configuration that I have sent to it. I don't know what's the problem with the code and schematic. Here is the attach schematic and arduino code and its output in serial monitor. And also, I only copied the getPEC code from other source but I have checked it and seems that it is correct. But if you can double check it for me and point out if that is the wrong code that makes the communication not working, pls I need your help. The datasheet for LTC6803-4 can be found here http://cds.linear.com/docs/en/datasheet/680324fa.pdf

#include "SPI.h"

#define WRCFG 0x01 // Write Configuration Register
#define RDCFG 0x02 // Read Configuration Register
#define RDCV 0x04 // Read all cell voltages
#define STCVAD 0x10 // Start ADC poll status
// #define LTC6804ADDR1 0x80 // Board Address for 1st LTC6803-4
#define LTC6804ADDR2 0x81 // Board Address for 2nd LTC6803-4
#define TOTAL 5 // total connected cells

byte byteHolder;
// configuration for 1st module of LTC6803-4 (negate LTC6803-4)
//byte CFFMVMC[6] = {0x09, 0x00, 0x00, 0x00, 0x00, 0x00};
// configuration for 1st module to assert LTC6803-4
byte asLTC6803[6] = {0x29, 0x00, 0x00, 0xFC, 0xA4, 0xBA};
byte LTC2[1] = {0x81};

byte WRFG[1] = {0x01};

void setup() {
 // put your setup code here, to run once:
 
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, INPUT);
 pinMode(13, OUTPUT);
 digitalWrite(10, HIGH);
 SPI.begin();
 SPI.setClockDivider(SPI_CLOCK_DIV64);
 SPI.setDataMode(SPI_MODE3);
 SPI.setBitOrder(MSBFIRST);
 Serial.begin(9600); 
 writeCFGR();
}

void loop() {
 // put your main code here, to run repeatedly:
 readCFGRtencells();
//  spiStart();
//  SPI.transfer(getPEC(WRFG,1));
//  spiEnd();
 delay(2000);
}

// 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;
}

void spiStart() {
 SPI.begin(); 
 if(digitalRead(10) == LOW) {
   digitalWrite(10,HIGH);
   delayMicroseconds(5); //Ensure a valid pulse
 }
 digitalWrite(10, LOW);
 //delayMicroseconds(20); 
}

void spiEnd(uint8_t flag) { //Wait poll Status
 SPI.end();
 if(flag > 0) {
   delayMicroseconds(10); 
   digitalWrite(10, HIGH);
 }
}

void spiEnd(void) {
 spiEnd(1);
}

// Write Configuration Registers for LTC6803-4 using Broadcast Write
void writeCFGR(){
 Serial.println("Writing configuration for all cells..");
 // Open SPI Communication
 spiStart();
 // Send WRCFG command and its PEC byte (2 bytes)
 SPI.transfer(WRCFG);
 SPI.transfer(0xC7);
 // Send command for CFGR0 up to CFGR5 (6 bytes)
 sendMultiplebyteSPI(asLTC6803, 6);
 // send the computed PEC byte of CFGR0 to CFGR5
//  SPI.transfer(getPEC(asLTC6803,6));
 SPI.transfer(0xF7);
 // Close SPI Communication
 spiEnd();
}

//// Read Cell Configuration Registers for LTC6803-4 using Addressable Read
void readCFGRtencells(){
 Serial.println("Reading configuration for five cells..");
 // Open SPI Communication
 spiStart();
 // Send address and its PEC byte (2 bytes)
 SPI.transfer(LTC6804ADDR2);
 SPI.transfer(getPEC(LTC2,1));
 // Send RDCFG command and its PEC byte (2 bytes)
 SPI.transfer(RDCFG);
 SPI.transfer(0xCE);
 // Gather Read Data for Configuration Registers (6 bytes)
 for(int i = 0; i < 6; i++){
   byteHolder = SPI.transfer(RDCFG);
   Serial.println(byteHolder, HEX);
   }
   
 // Close SPI Communication
 spiEnd();
}

// Send multiple data to LTC
void sendMultiplebyteSPI(byte * data, int n){
 for (int i = 0; i<n; i++){ 
   SPI.transfer(data[i]);
   }
 }

1 Like

That doesn't do what you probably expected:

// Send multiple data to LTC
void sendMultiplebyteSPI(byte * data, int n){
  for (int i = 0; i<n; i++){
    SPI.transfer(data);
    }
  }

To really send the data block you have to change the code to:

// Send multiple data to LTC
void sendMultiplebyteSPI(byte * data, int n){
  for (int i = 0; i<n; i++){
    SPI.transfer(data[i]);
    }
  }

Thank you for your reply sir Pylon, I've already changed the code to what you have said, but still I get the same output. It's kinda confusing since I think that I have followed the correct setup for the LTC6803-4 and still get no output and seems like they are not communicating between each other.

Enclose your code with code tags (the "</>" button in the editor), I guess my last comment is an error that was caused by missing code tags.

Post the schematic of your setup. Your code works only if the wiring between the Arduino and the (multiple?) LTC6803-4s is correct. Did you check if your PEC calculation is correct (calculate the PECs for the commands in the datasheet and check if they match the printed reference value)?

I already checked the PEC code in proteus and verified that the returned PEC is the same as the one in the datasheet. I am wondering if I need to use much faster arduino like Arduino M0? The schematic can be downloaded on my first post although its kinda blurry for the pin names. We based the schematic in the sample diagram on the last page of the datasheet. I really appreciate your help.

The schematic can be downloaded on my first post although its kinda blurry for the pin names.

In that picture I cannot see how you wired to the Arduino. And what is J1? I cannot find any datasheet for the number 282834-4.

You need an pull-Up resistor (about 4k7) from LTC6803 SDO to VREG.

(SDO is an open drain output).

Best regards

Kurtow187