Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1652A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1652A Demonstration Board.
3 LTC6803-2: Battery stack monitor
4 
5 @verbatim
6 
7 NOTES
8  Setup:
9  Set the terminal baud rate to 115200 and select the newline terminator.
10  Ensure all jumpers on the demo board are installed in their default positions from the factory.
11  Refer to Demo Manual DC1652.
12 
13 
14  Menu Entry 1: Write Configuration
15  Writes the configuration register of the LTC6803s on the stack. This command can be used to turn on
16  the reference and shorten ADC conversion Times.
17 
18  Menu Entry 2: Read Configuration
19  Reads the configuration register of the LTC6803, the read configuration can differ from the written configuration.
20  The GPIO pins will reflect the state of the pin
21 
22  Menu Entry 3: Start Cell voltage conversion
23  Starts a LTC6803 cell channel adc conversion.
24 
25  Menu Entry 4: Read cell voltages
26  Reads the LTC6803 cell voltage registers and prints the results to the serial port.
27 
28  Menu Entry 5: Start Auxiliary voltage conversion
29  Starts a LTC6803 Temp channel adc conversion.
30 
31  Menu Entry 6: Read Auxiliary voltages
32  Reads the LTC6803 Temp registers and prints the Temp voltages to the serial port.
33 
34  Menu Entry 7: Start cell voltage measurement loop
35  The command will continuously measure the LTC6803 cell voltages and print the results to the serial port.
36  The loop can be exited by sending the MCU a 'm' character over the serial link.
37 
38 USER INPUT DATA FORMAT:
39  decimal : 1024
40  hex : 0x400
41  octal : 02000 (leading 0)
42  binary : B10000000000
43  float : 1024.0
44 @endverbatim
45 
46 http://www.linear.com/product/LTC6803-2
47 
48 http://www.linear.com/product/LTC6803-2#demoboards
49 
50 
51 Copyright 2018(c) Analog Devices, Inc.
52 
53 All rights reserved.
54 
55 Redistribution and use in source and binary forms, with or without
56 modification, are permitted provided that the following conditions are met:
57  - Redistributions of source code must retain the above copyright
58  notice, this list of conditions and the following disclaimer.
59  - Redistributions in binary form must reproduce the above copyright
60  notice, this list of conditions and the following disclaimer in
61  the documentation and/or other materials provided with the
62  distribution.
63  - Neither the name of Analog Devices, Inc. nor the names of its
64  contributors may be used to endorse or promote products derived
65  from this software without specific prior written permission.
66  - The use of this software may or may not infringe the patent rights
67  of one or more patent holders. This license does not release you
68  from the requirement that you obtain separate licenses from these
69  patent holders to use this software.
70  - Use of the software either in source or binary form, must be run
71  on or directly connected to an Analog Devices Inc. component.
72 
73 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
74 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
75 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
76 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
77 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
78 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
79 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
80 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
81 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
82 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 
84 Copyright 2015 Linear Technology Corp. (LTC)
85  */
86 
87 
88 /*! @file
89  @ingroup LTC68032
90 */
91 
92 #include <Arduino.h>
93 #include <stdint.h>
94 #include "Linduino.h"
95 #include "LT_SPI.h"
96 #include "UserInterface.h"
97 #include "LTC68032.h"
98 #include <SPI.h>
99 
100 const uint8_t TOTAL_IC = 1;//!<number of ICs in the daisy chain
101 
102 /******************************************************
103  *** Global Battery Variables received from 6803 commands
104  These variables store the results from the LTC6803
105  register reads and the array lengths must be based
106  on the number of ICs on the stack
107  ******************************************************/
108 uint16_t cell_codes[TOTAL_IC][12];
109 /*!<
110  The cell codes will be stored in the cell_codes[][12] array in the following format:
111 
112  | cell_codes[0][0]| cell_codes[0][1] | cell_codes[0][2]| ..... | cell_codes[0][11]| cell_codes[1][0] | cell_codes[1][1]| ..... |
113  |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
114  |IC1 Cell 1 |IC1 Cell 2 |IC1 Cell 3 | ..... | IC1 Cell 12 |IC2 Cell 1 |IC2 Cell 2 | ..... |
115 ****/
116 
117 uint16_t temp_codes[TOTAL_IC][3];
118 /*!<
119  The Temp codes will be stored in the temp_codes[][3] array in the following format:
120 
121  | temp_codes[0][0]| temp_codes[0][1]|temp_codes[0][2] | temp_codes[1][0]| temp_codes[1][1]| ..... |
122  |------------------|-----------------|-----------------|-----------------|-----------------|-----------|
123  |IC1 Temp1 |IC1 Temp2 |IC1 ITemp |IC2 Temp1 |IC2 Temp2 | ..... |
124 */
125 
126 uint8_t tx_cfg[TOTAL_IC][6];
127 /*!<
128  The tx_cfg[][6] stores the LTC6803 configuration data that is going to be written
129  to the LTC6803 ICs on the daisy chain. The LTC6803 configuration data that will be
130  written should be stored in blocks of 6 bytes. The array should have the following format:
131 
132  | tx_cfg[0][0]| tx_cfg[0][1] | tx_cfg[0][2]| tx_cfg[0][3]| tx_cfg[0][4]| tx_cfg[0][5]| tx_cfg[1][0] | tx_cfg[1][1]| tx_cfg[1][2]| ..... |
133  |--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|-----------|
134  |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC2 CFGR0 |IC2 CFGR1 | IC2 CFGR2 | ..... |
135 
136 */
137 
138 uint8_t rx_cfg[TOTAL_IC][7];
139 /*!<
140  the rx_cfg[][8] array stores the data that is read back from a LTC6803-2 daisy chain.
141  The configuration data for each IC is stored in blocks of 7 bytes. Below is an table illustrating the array organization:
142 
143 |rx_config[0][0]|rx_config[0][1]|rx_config[0][2]|rx_config[0][3]|rx_config[0][4]|rx_config[0][5]|rx_config[0][6] |rx_config[1][0]|rx_config[1][1]| ..... |
144 |---------------|---------------|---------------|---------------|---------------|---------------|-----------------|---------------|---------------|----------|
145 |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC1 PEC |IC2 CFGR0 |IC2 CFGR1 | ..... |
146 */
147 
148 
149 //! Inititializes hardware and variables
150 void setup()
151 {
152  Serial.begin(115200);
153  LTC6803_initialize(); //Initialize LTC6803 hardware
154  init_cfg(); //initialize the 6803 configuration array to be written
155  print_menu();
156 }
157 
158 
159 //! main loop
160 void loop()
161 {
162 
163  if (Serial.available()) // Check for user input
164  {
165  uint32_t user_command;
166  user_command = read_int(); // Read the user command
167  Serial.println(user_command);
168  run_command(user_command);
169  }
170 }
171 
172 
173 /*!*****************************************
174  \brief executes the user inputted command
175 
176  Menu Entry 1: Write Configuration \n
177  Writes the configuration register of the LTC6803. This command can be used to turn on the reference
178  and increase the speed of the ADC conversions.
179 
180  Menu Entry 2: Read Configuration \n
181  Reads the configuration register of the LTC6803, the read configuration can differ from the written configuration.
182  The GPIO pins will reflect the state of the pin
183 
184  Menu Entry 3: Start Cell voltage conversion \n
185  Starts a LTC6803 cell channel adc conversion.
186 
187  Menu Entry 4: Read cell voltages \n
188  Reads the LTC6803 cell voltage registers and prints the results to the serial port.
189 
190  Menu Entry 5: Start Temp voltage conversion \n
191  Starts a LTC6803 Temp channel adc conversion.
192 
193  Menu Entry 6: Read Temp voltages \n
194  Reads the LTC6803 axiliary registers and prints the GPIO voltages to the serial port.
195 
196  Menu Entry 7: Start cell voltage measurement loop \n
197  The command will continuously measure the LTC6803 cell voltages and print the results to the serial port.
198  The loop can be exited by sending the MCU a 'm' character over the serial link.
199 
200 *******************************************/
201 void run_command(uint32_t cmd)
202 {
203  int8_t error = 0;
204 
205  char input = 0;
206  switch (cmd)
207  {
208 
209  case 1:
210 
212  print_config();
213  break;
214 
215  case 2:
216 
217  error = LTC6803_rdcfg(TOTAL_IC,rx_cfg);
218  if (error == -1)
219  {
220  Serial.println(F("A PEC error was detected in the received data"));
221  }
222  print_rxconfig();
223  break;
224 
225  case 3:
226 
227  LTC6803_stcvad();
228  delay(3);
229  Serial.println(F("cell conversion completed"));
230  Serial.println();
231  break;
232 
233  case 4:
234 
235  error = LTC6803_rdcv(TOTAL_IC,cell_codes); // Set to read back all cell voltage registers
236  if (error == -1)
237  {
238  Serial.println(F("A PEC error was detected in the received data"));
239  }
240  print_cells();
241  break;
242 
243  case 5:
244 
245  LTC6803_sttmpad();
246  delay(3);
247  Serial.println(F("aux conversion completed"));
248  Serial.println();
249  break;
250 
251  case 6:
252 
253  error = LTC6803_rdtmp(TOTAL_IC,temp_codes); // Set to read back all aux registers
254  if (error == -1)
255  {
256  Serial.println(F("A PEC error was detected in the received data"));
257  }
258  print_temp();
259  break;
260 
261  case 7:
262  Serial.println(F("transmit 'm' to quit"));
263 
265  while (input != 'm')
266  {
267  if (Serial.available() > 0)
268  {
269  input = read_char();
270  }
271 
272 
273  LTC6803_stcvad();
274  delay(10);
275 
277  if (error == -1)
278  {
279  Serial.println(F("A PEC error was detected in the received data"));
280  }
281  print_cells();
282 
283 
284  if (error == -1)
285  {
286  Serial.println(F("A PEC error was detected in the received data"));
287  }
288  // print_rxconfig();
289 
290  delay(500);
291  }
292  print_menu();
293  break;
294 
295  default:
296  Serial.println(F("Incorrect Option"));
297  break;
298  }
299 }
300 
301 
302 //! Initializes the configuration array
303 void init_cfg()
304 {
305  for (int i = 0; i<TOTAL_IC; i++)
306  {
307  tx_cfg[i][0] = 0xF1;
308  tx_cfg[i][1] = 0x00 ;
309  tx_cfg[i][2] = 0x00 ;
310  tx_cfg[i][3] = 0x00 ;
311  tx_cfg[i][4] = 0x00 ;
312  tx_cfg[i][5] = 0x00 ;
313  }
314 
315 }
316 
317 
318 //! Prints the main menu
320 {
321  Serial.println(F("Please enter LTC6803 Command"));
322  Serial.println(F("Write Configuration: 1"));
323  Serial.println(F("Read Configuration: 2"));
324  Serial.println(F("Start Cell Voltage Conversion: 3"));
325  Serial.println(F("Read Cell Voltages: 4"));
326  Serial.println(F("Start Aux Voltage Conversion: 5"));
327  Serial.println(F("Read Aux Voltages: 6"));
328  Serial.println(F("loop cell voltages: 7"));
329  Serial.println(F("Please enter command: "));
330  Serial.println();
331 }
332 
333 
334 
335 
336 //! Prints cell coltage codes to the serial port
338 {
339 
340 
341  for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
342  {
343  Serial.print(" IC ");
344  Serial.print(current_ic+1,DEC);
345  for (int i=0; i<12; i++)
346  {
347  Serial.print(" C");
348  Serial.print(i+1,DEC);
349  Serial.print(":");
350  Serial.print(cell_codes[current_ic][i]*0.0015,4);
351  Serial.print(",");
352  }
353  Serial.println();
354  }
355  Serial.println();
356 }
357 
358 
359 //! Prints GPIO voltage codes and Vref2 voltage code onto the serial port
361 {
362 
363  for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
364  {
365  Serial.print(" IC ");
366  Serial.print(current_ic+1,DEC);
367  for (int i=0; i < 2; i++)
368  {
369  Serial.print(" Temp-");
370  Serial.print(i+1,DEC);
371  Serial.print(":");
372  Serial.print(temp_codes[current_ic][i]*0.0015,4);
373  Serial.print(",");
374  }
375  Serial.print(" ITemp");
376  Serial.print(":");
377  Serial.print((temp_codes[current_ic][2]*0.1875)-274.15,4);
378  Serial.println();
379  }
380  Serial.println();
381 }
382 
383 //! Prints the configuration data that is going to be written to the LTC6803 to the serial port.
385 {
386  int cfg_pec;
387 
388  Serial.println("Written Configuration: ");
389  for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
390  {
391  Serial.print(" IC ");
392  Serial.print(current_ic+1,DEC);
393  Serial.print(": ");
394  Serial.print("0x");
395  serial_print_hex(tx_cfg[current_ic][0]);
396  Serial.print(", 0x");
397  serial_print_hex(tx_cfg[current_ic][1]);
398  Serial.print(", 0x");
399  serial_print_hex(tx_cfg[current_ic][2]);
400  Serial.print(", 0x");
401  serial_print_hex(tx_cfg[current_ic][3]);
402  Serial.print(", 0x");
403  serial_print_hex(tx_cfg[current_ic][4]);
404  Serial.print(", 0x");
405  serial_print_hex(tx_cfg[current_ic][5]);
406  Serial.print(", Calculated PEC: 0x");
407  cfg_pec = pec8_calc(6,&tx_cfg[current_ic][0]);
408  serial_print_hex((uint8_t)(cfg_pec));
409  Serial.println();
410  }
411  Serial.println();
412 }
413 
414 
415 //! Prints the configuration data that was read back from the LTC6803 to the serial port.
417 {
418  Serial.println("Received Configuration ");
419  for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
420  {
421  Serial.print(" IC ");
422  Serial.print(current_ic+1,DEC);
423  Serial.print(": 0x");
424  serial_print_hex(rx_cfg[current_ic][0]);
425  Serial.print(", 0x");
426  serial_print_hex(rx_cfg[current_ic][1]);
427  Serial.print(", 0x");
428  serial_print_hex(rx_cfg[current_ic][2]);
429  Serial.print(", 0x");
430  serial_print_hex(rx_cfg[current_ic][3]);
431  Serial.print(", 0x");
432  serial_print_hex(rx_cfg[current_ic][4]);
433  Serial.print(", 0x");
434  serial_print_hex(rx_cfg[current_ic][5]);
435  Serial.print(", Received PEC: 0x");
436  serial_print_hex(rx_cfg[current_ic][6]);
437 
438  Serial.println();
439  }
440  Serial.println();
441 }
442 
443 //! Print Data Byte in Hex Format
444 void serial_print_hex(uint8_t data)
445 {
446  if (data < 16)
447  {
448  Serial.print("0");
449  Serial.print((byte)data,HEX);
450  }
451  else
452  Serial.print((byte)data,HEX);
453 }
static void print_config()
Prints the configuration data that is going to be written to the LTC6803 to the serial port...
Definition: DC1652A.ino:384
static void print_menu()
Prints the main menu.
Definition: DC1652A.ino:319
unsigned char user_command
static void loop()
main loop
Definition: DC1652A.ino:160
static uint8_t tx_cfg[TOTAL_IC][6]
The tx_cfg[][6] stores the LTC6803 configuration data that is going to be written to the LTC6803 ICs ...
Definition: DC1652A.ino:126
LTC6803-2 Multicell Battery Monitor.
Header File for Linduino Libraries and Demo Code.
static void setup()
Inititializes hardware and variables.
Definition: DC1652A.ino:150
static void init_cfg()
Initializes the configuration array.
Definition: DC1652A.ino:303
static uint8_t rx_cfg[TOTAL_IC][7]
the rx_cfg[][8] array stores the data that is read back from a LTC6803-2 daisy chain.
Definition: DC1652A.ino:138
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
static void run_command(uint32_t cmd)
Definition: DC1652A.ino:201
static void serial_print_hex(uint8_t data)
Print Data Byte in Hex Format.
Definition: DC1652A.ino:444
static uint16_t cell_codes[TOTAL_IC][12]
The cell codes will be stored in the cell_codes[][12] array in the following format: ...
Definition: DC1652A.ino:108
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
uint8_t pec8_calc(uint8_t len, uint8_t *data)
Function that calculates PEC byte.
Definition: LTC68031.cpp:305
static void print_rxconfig()
Prints the configuration data that was read back from the LTC6803 to the serial port.
Definition: DC1652A.ino:416
const uint8_t TOTAL_IC
number of ICs in the daisy chain
Definition: DC1652A.ino:100
static int error
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
static void print_cells()
Prints cell coltage codes to the serial port.
Definition: DC1652A.ino:337
int32_t read_int()
void LTC6803_sttmpad()
Function to start Temp channel voltage measurement.
Definition: LTC68031.cpp:184
void LTC6803_wrcfg(uint8_t total_ic, uint8_t config[][6])
Function that writes configuration of LTC6803-1/-3.
Definition: LTC68031.cpp:90
int8_t LTC6803_rdtmp(uint8_t total_ic, uint16_t temp_codes[][3])
Function that reads Temp Voltage registers.
Definition: LTC68031.cpp:195
void LTC6803_initialize()
Initializes the SPI port.
Definition: LTC68031.cpp:79
static int i
Definition: DC2430A.ino:184
uint8_t LTC6803_rdcv(uint8_t total_ic, uint16_t cell_codes[][12])
Function that reads Cell Voltage registers.
Definition: LTC68031.cpp:246
static void print_temp()
Prints GPIO voltage codes and Vref2 voltage code onto the serial port.
Definition: DC1652A.ino:360
int8_t read_char()
int8_t LTC6803_rdcfg(uint8_t total_ic, uint8_t r_config[][7])
Function that reads configuration of LTC6803-1/-3.
Definition: LTC68031.cpp:126
static uint16_t temp_codes[TOTAL_IC][3]
The Temp codes will be stored in the temp_codes[][3] array in the following format: ...
Definition: DC1652A.ino:117
void LTC6803_stcvad()
Function to start Cell Voltage measurement.
Definition: LTC68031.cpp:174