Arduino SPI Problems - Page 1
Forum section: electronics / general

author: aep9690
author_rank: Regular Contributor
timestamp: November 17, 2013, 10:21:34 pm
content: I am trying to create a BMS using an Arduino Uno and the LTC6802-2 (Datasheet Here:http://cds.linear.com/docs/en/datasheet/68022fa.pdf). I was able to get a free demo board from Linear (Schematic Here:http://cds.linear.com/docs/en/demo-board-schematic/1393bsch.pdf) along with the USB interface board and can talk to the demo board just fine using the USB interface board. I have also been able to read from the devices registers through the SPI bus on the Arduino.The problem is that I can't seem to be able to write to the registers at all. I send a write command and then send out the data one byte at a time but when I go to read from it afterwards it doesn't update. Here is the code I wrote:Code:#include <SPI.h>#define READ 0x02#define WRITE 0x01#define CS 10byte result;byte address = B10000000;byte transmit1 = {244, 1, 1, 1, 125, 181};byte transmit2 = {0xE0, 1, 1, 1, 1, 1};void setup(){pinMode(CS, OUTPUT);digitalWrite(CS, HIGH);Serial.begin(9600);SPI.begin();SPI.setDataMode(SPI_MODE3);SPI.setClockDivider(SPI_CLOCK_DIV16);SPI.setBitOrder(MSBFIRST);}void loop() {// Read 1digitalWrite(CS, LOW);SPI.transfer(address);SPI.transfer(READ);for(int i = 0; i < 7; i++){result = SPI.transfer(0x00);}digitalWrite(CS, HIGH);Serial.println("READ 1");for(int i = 0; i < 7; i++){Serial.print(result, HEX);Serial.print(' ');}Serial.println(' ');delay(100);// Write 1digitalWrite(CS, LOW);SPI.transfer(address);SPI.transfer(WRITE);for(int i = 0; i < 6; i++){SPI.transfer(transmit1);}digitalWrite(CS,HIGH);Serial.println("WRITE1");for(int i = 0; i < 6; i++){Serial.print(transmit1, HEX);Serial.print(' ');}Serial.println(' ');delay(100);// Read 2digitalWrite(CS, LOW);SPI.transfer(address);SPI.transfer(READ);for(int i = 0; i < 7; i++){result = SPI.transfer(0x00);}digitalWrite(CS, HIGH);Serial.println("READ 2");for(int i = 0; i < 7; i++){Serial.print(result, HEX);Serial.print(' ');}Serial.println(' ');delay(100);// Write 2digitalWrite(CS, LOW);SPI.transfer(address);SPI.transfer(WRITE);for(int i = 0; i < 6; i++){SPI.transfer(transmit2);}digitalWrite(CS, HIGH);Serial.println("WRITE 2");for(int i = 0; i < 6; i++){Serial.print(transmit2, HEX);Serial.print(' ');}Serial.println(' ');delay(2000);}There shouldn't be anything wrong with the SPI bus because I can read from the device just fine, so I think there has to be something wrong with the software but it is so basic I don't see any problems. I have hooked up my oscilliscope to the bus lines and the only thing that seems like it light cause this problem is that the CS line is pulled high about 5us after the data transmission has finished. The datasheet says the devices latches the data on the rising edge of the CS line so if it is low for too long it might cause problems. The thing is I don't know how to reduce the time between after the transmission has finished and before the CS line is pulled high.I know other people have used the Arduino and this chip to make a BMS but one of the people isn't going open source on it and hasn't returned my messages and the other person published code that doesn't work and hasn't returned my messages either.I would really appreciate any help I can get. I'm ready to throw my workbench out a window.

author: Maxlor
author_rank: Frequent Contributor
timestamp: November 18, 2013, 12:05:43 am
content: Try not sending the address byte. I didn't read all of the data sheet, but it seems that command 1, WRCFG, is a broadcast command. See also page 24 of the datasheet you linked.

author: aep9690
author_rank: Regular Contributor
timestamp: November 18, 2013, 12:17:00 am
content: I tried using both the address command and the broadcast command but neither worked. I also wrote the code using the examples on page 24.

author: dannyf
author_rank: Super Contributor
timestamp: November 18, 2013, 12:26:31 am
content: QuoteWhat output did you get from your code that made you think that way?

author: aep9690
author_rank: Regular Contributor
timestamp: November 18, 2013, 12:37:26 am
content: I'm not at the lab now so I can't get the exact print out but it was along these lines.Code:READ 1E0 0 0 0 0 0 A1 (This is the original values in the register according to the PC software, the A1 is the PEC packet)WRITE 1F4 1 1 1 7D B5 ( I am not writing any 1's because the Arduino SPI library interprets a byte of 0's as a read)READ 2F4 1 1 1 7D B5 CD (I think the PEC packet was CD in this, I will need to double check.)WRITE 2E0 1 1 1 1 1 ( I wanted to write again to make sure it was repeatable)READ 1E0 0 0 0 0 0 A1The last line is why I think it isn't working, if the write was successful then the values in the last read should be E0 1 1 1 1 1, not E0 0 0 0 0 0.

author: dannyf
author_rank: Super Contributor
timestamp: November 18, 2013, 12:43:00 am
content: QuoteIt is probably more helpful to you if you post the exact and actual print out from the terminal.

author: aep9690
author_rank: Regular Contributor
timestamp: November 18, 2013, 12:55:54 am
content: Here is the exact readout:Code:READ 1E0 0 0 0 0 0 A1WRITE1F4 1 1 1 7D B5READ 2F4 1 1 1 7D B5 CDWRITE 2E0 1 1 1 1 1READ 1E0 0 0 0 0 0 A1WRITE1F4 1 1 1 7D B5READ 2F4 1 1 1 7D B5 CDWRITE 2E0 1 1 1 1 1

author: dannyf
author_rank: Super Contributor
timestamp: November 18, 2013, 01:14:26 am
content: 1) there are only 6 CFG registers;2) WRITE1 and READ2 are identical -> the code is working;3) WRITE2 and READ1 are not working -> maybe the data written is invalid; maybe you are trying to write too many registers, etc. Check the datasheet to see if the data are indeed valid.To be safe, I would have pack the write / read process into functions.

author: aep9690
author_rank: Regular Contributor
timestamp: November 18, 2013, 01:22:18 am
content: I know there are only 6 CFG registers, the 7th bit is for checking the PEC.I can't really find any information in the datasheet that restricts the values in the CFG registers.Byte 1 I am not changing, byte 2, 3, and 4 handle the discharge and interrupts for the cells, each bit is for a specific cell, byte 5 specifies the undervoltage, which defaults to 0, and byte 6 handles the overvoltage, which defaults to 0.I don't see a problem with the values I am writing.I plan on packing the functions once I get them working.

author: dannyf
author_rank: Super Contributor
timestamp: November 18, 2013, 01:35:31 am
content: QuoteRight there in the datasheet.Also the wdt expires in 2.5 seconds. After that, the CFGs are reset to default values. The long delay at end of the loop runs quite close to that, especially if you factor in the time to send the strings. What if you shorten it?

author: aep9690
author_rank: Regular Contributor
timestamp: November 18, 2013, 01:51:22 am
content: It looks like reducing the delays fixed the problem. I will just need to figure out a way to make sure the watchdog timer never expires. Thanks a lot for the help everyone.

author: dannyf
author_rank: Super Contributor
timestamp: November 18, 2013, 11:30:16 am
content: Or form a habit of reading the datasheet thoroughly before attempting to code to it. Or you will always end of spending more time trying to debug your code.