| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

LTC2947.cpp
Go to the documentation of this file.
1 /*!
2 LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting up to 30A
3
4 @verbatim
5
6 The LTC2947 is a high-precision power and energy
7 monitor with an internal sense resistor supporting up
8 to 30A. Three internal No Latency delta sigma ADCs ensure
9 accurate measurement of voltage and current, while high-
10 bandwidth analog multiplication of voltage and current
11 provides accurate power measurement in a wide range of
12 applications. Internal or external clocking options enable
13 precise charge and energy measurements.
14 An internal 300 micro ohms, temperature-compensated sense
15 resistor minimizes efficiency loss and external compo-
16 nents, simplifying energy measurement applications while
17 enabling high accuracy current measurement over the full
18 temperature range. For more details see following URLs:
19
20 @endverbatim
21
22 http://www.linear.com/product/LTC2947
23
24 http://www.linear.com/product/LTC2947#demoboards
25
26
27 Copyright 2018(c) Analog Devices, Inc.
28
29 All rights reserved.
30
31 Redistribution and use in source and binary forms, with or without
32 modification, are permitted provided that the following conditions are met:
33 - Redistributions of source code must retain the above copyright
34 notice, this list of conditions and the following disclaimer.
35 - Redistributions in binary form must reproduce the above copyright
36 notice, this list of conditions and the following disclaimer in
37 the documentation and/or other materials provided with the
38 distribution.
39 - Neither the name of Analog Devices, Inc. nor the names of its
40 contributors may be used to endorse or promote products derived
41 from this software without specific prior written permission.
42 - The use of this software may or may not infringe the patent rights
43 of one or more patent holders. This license does not release you
44 from the requirement that you obtain separate licenses from these
45 patent holders to use this software.
46 - Use of the software either in source or binary form, must be run
47 on or directly connected to an Analog Devices Inc. component.
48
49 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
50 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
51 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
53 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
54 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
55 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
57 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
58 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */
60
61 //! @ingroup Power_Monitors
62 //! @{
63 //! @defgroup LTC2947 LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
64 //! @}
65
66 /*! @file
67 @ingroup LTC2947
68 Library for LTC2947: A high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
69 */
70
71 #include <Arduino.h>
72 #include <Linduino.h>
73 #include <LT_I2C.h>
74 #include <LT_SPI.h>
75 #include "LTC2947.h"
76 #include <SPI.h>
77
78 #ifdef LTC2947_DEBUG
79 #include "UserInterface.h"
80 #endif
81
82 boolean LTC2947_SPI_Mode_Enabled = false;
83 uint8_t LTC2947_I2C_Slave_Addr = LTC2947_I2C_ADDR_LL;
84
85 void LTC2947_InitI2C(uint8_t slvAddr)
86 {
87 LTC2947_SPI_Mode_Enabled = false;
88 LTC2947_I2C_Slave_Addr = slvAddr;
89 }
90
91 void LTC2947_InitSPI()
92 {
93 LTC2947_SPI_Mode_Enabled = true;
94 }
95
96 boolean LTC2947_Abs(uint8_t *bytes, uint8_t length)
97 {
98 if (bitMaskClrChk(*bytes, 0x80))
99 return false;// value is already positive
100
101 // two's complement is generated by inverting all bits and add 1
102
103 length--;
104 bytes += length; // seek to LSB
105 uint16_t cHelp = (~(*bytes)) & 0xFF; // invert LSB
106 cHelp++; // add 1
107 *bytes = cHelp; // store back to buffer
108
109 while (length != 0)
110 {
111 // seek next byte (towards MSB)
112 length--;
113 bytes--;
114 cHelp = cHelp >> 8; // restore carry from previous sum
115 cHelp += (~(*bytes)) & 0xFF; // add inverted byte
116 *bytes = cHelp; // store back
117 }
118 return true;// value inverted
119 }
120
121 double LTC2947_BytesToDouble(uint8_t *bytes, uint8_t length, boolean sig, double lsb)
122 {
123 if (length == 0)
124 return 0.0;
125 else if (length == 1)
126 return sig ? (int8_t)(bytes[0])*lsb : bytes[0] * lsb;
127 else if (length == 2)
128 return sig ? LTC2947_2BytesToInt16(bytes)*lsb : LTC2947_2BytesToUInt16(bytes)*lsb;
129 else if (length == 3)
130 return sig ? LTC2947_3BytesToInt32(bytes)*lsb : LTC2947_3BytesToUInt32(bytes)*lsb;
131 else if (length == 4)
132 return sig ? LTC2947_4BytesToInt32(bytes)*lsb : LTC2947_4BytesToUInt32(bytes)*lsb;
133 else
134 return sig ? LTC2947_SignedBytesToDouble(bytes, length, lsb) : LTC2947_UnsignedBytesToDouble(bytes, length, lsb);
135 }
136
137 double LTC2947_UnsignedBytesToDouble(uint8_t *unsignedBytes, uint8_t length, double lsb)
138 {
139 // NOTE: On Arduino double is 32-bit and NOT 64-bit, thus the returned value
140 // will not reflect the full precission of e.g. C1, C2... which are 48-bit values
141 double ret = (*unsignedBytes); // MSB!
142
143 while (length > 1)
144 {
145 unsignedBytes++; // go to next byte
146 length--;
147 ret = ret * 256.0 + (*unsignedBytes);
148 }
149 return ret*lsb;
150 }
151
152 void LTC2947_SerialPrint8hex(uint8_t val)
153 {
154 if (val < 0x10) Serial.print("0");
155 Serial.print(val, HEX);
156 }
157 void LTC2947_SerialPrint16hex(uint16_t val)
158 {
159 for (uint16_t i = 0x1000L; i >= 0x10L; i = i >> 4)
160 if (val < i) Serial.print("0");
161 Serial.print(val, HEX);
162 }
163 void LTC2947_SerialPrint32hex(uint32_t val)
164 {
165 for (uint32_t i = 0x10000000L; i >= 0x10L; i = i >> 4)
166 if (val < i) Serial.print("0");
167 Serial.print(val, HEX);
168 }
169 void LTC2947_SerialPrint64hex(uint64_t uint64Val)
170 {
171 LTC2947_SerialPrint32hex((uint32_t)(uint64Val >> 32));
172 LTC2947_SerialPrint32hex((uint32_t)(uint64Val));
173 }
174
175 void LTC2947_DoubleToBytes(double value, double lsb, uint8_t *bytes, uint8_t length)
176 {
177 //! on Arduino Uno / Linduino the maximum is 8 bytes
178 if (length > sizeof(int64_t)) //! sizeof(int64_t) = 8
179 return;
180
181 //! revert the scaling with LSB and convert to integer value
182 int64_t int64Val = int64_t(value / lsb);
183
184 #ifdef LTC2947_DEBUG
185 Serial.print(F("int64Val=0x"));
186 LTC2947_SerialPrint64hex((uint64_t)(int64Val));
187 Serial.println();
188 Serial.println(F("bytes:"));
189 #endif
190
191 //! convert the integer value to byte array
192 for (int8_t i = length - 1; i >= 0; i--)
193 {
194 bytes[i] = int64Val & 0xFF;
195 int64Val >>= 8;
196 #ifdef LTC2947_DEBUG
197 Serial.print(i);
198 Serial.print(F(":"));
199 LTC2947_SerialPrint8hex(bytes[i]);
200 if (i == 0)
201 Serial.print(F(" (MSB)"));
202 else if (i == length - 1)
203 Serial.print(F(" (LSB)"));
204 Serial.println();
205 #endif
206 }
207 }
208
209 #ifdef LTC2947_DEBUG
210 //! conversion function test
211 void LTC2947_DoubleToBytes_Test()
212 {
213 Serial.print(F("LSB:"));
214 while (!Serial.available());
215 double lsb = read_float();
216 Serial.println(lsb, 8);
217
218 Serial.print(F("LSBrshift:"));
219 while (!Serial.available());
220 int32_t shift = read_int();
221 Serial.println(shift);
222 while (shift-- > 0)
223 lsb = lsb * 0.5;
224
225 Serial.println(lsb, 16);
226
227 Serial.print(F("VAL:"));
228 while (!Serial.available());
229 double val = read_float();
230 Serial.println(val, 8);
231
232 Serial.print(F("VALlshift:"));
233 while (!Serial.available());
234 shift = read_int();
235 Serial.println(shift);
236 while (shift-- > 0)
237 val = val * 2.0;
238
239 Serial.println(val, 16);
240
241 byte bytes[8];
242 LTC2947_DoubleToBytes(val, lsb, bytes, 8);
243 }
244 #endif
245
246
247 double LTC2947_SignedBytesToDouble(uint8_t *signedBytes, uint8_t length, double lsb)
248 {
249 // reserve memory for unsigned bytes
250 uint8_t *unsignedBytes = (uint8_t *)malloc(length);
251 // copy signed bytes to unsigned bytes
252 memcpy(unsignedBytes, signedBytes, length);
253 // calculate absolute value of the signed bytes and store sign
254 // this function will change the unsigned bytes, for this reason
255 // we copied the original unsigned bytes to a new array
256 boolean sign = LTC2947_Abs(unsignedBytes, length);
257 // convert the unsigned bytes to a double value
258 double absDouble = LTC2947_UnsignedBytesToDouble(unsignedBytes, length, lsb);
259 // free the allocated memory of the copied array
260 free(unsignedBytes);
261 // recover the previously stored sign to return a signed value
262 return sign ? -absDouble : absDouble;
263 }
264
265 int32_t LTC2947_4BytesToInt32(byte *bytes)
266 {
267 int32_t ret;
268
269 ret = *bytes;
270 bytes++;
271 ret = ret << 8;
272 ret |= *bytes;
273 bytes++;
274 ret = ret << 8;
275 ret |= *bytes;
276 bytes++;
277 ret = ret << 8;
278 ret |= *bytes;
279 return ret;
280 }
281
282 int32_t LTC2947_3BytesToInt32(byte *bytes)
283 {
284 int32_t ret;
285 // sign extension
286 if (*bytes & 0x80)
287 ret = 0xFF00;
288 else
289 ret = 0;
290
291 ret |= *bytes;
292 bytes++;
293 ret = ret << 8;
294 ret |= *bytes;
295 bytes++;
296 ret = ret << 8;
297 ret |= *bytes;
298 return ret;
299 }
300
301 int16_t LTC2947_2BytesToInt16(byte *bytes)
302 {
303 int16_t ret;
304 ret = *bytes;
305 bytes++;
306 ret = ret << 8;
307 ret |= *bytes;
308 return ret;
309 }
310
311 uint32_t LTC2947_4BytesToUInt32(byte *bytes)
312 {
313 uint32_t ret;
314
315 ret = *bytes;
316 bytes++;
317 ret = ret << 8;
318 ret |= *bytes;
319 bytes++;
320 ret = ret << 8;
321 ret |= *bytes;
322 bytes++;
323 ret = ret << 8;
324 ret |= *bytes;
325 return ret;
326 }
327
328 uint32_t LTC2947_3BytesToUInt32(byte *bytes)
329 {
330 uint32_t ret;
331
332 ret = *bytes;
333 bytes++;
334 ret = ret << 8;
335 ret |= *bytes;
336 bytes++;
337 ret = ret << 8;
338 ret |= *bytes;
339 return ret;
340 }
341
342 uint16_t LTC2947_2BytesToUInt16(byte *bytes)
343 {
344 uint16_t ret;
345 ret = *bytes;
346 bytes++;
347 ret = ret << 8;
348 ret |= *bytes;
349 return ret;
350 }
351
352 /*
353 * Note on I2C/SPI functions:
354 * i2c_write / i2c_read / spi_write / spi_read block methods from LT_I2C / LT_SPI write / read byte arrays from last to first element
355 * which is not compatible with LTC2947 library that expects the opposite order
356 */
357
358 int8_t LTC2947_SpiWrBlock(uint8_t address, uint8_t length, uint8_t *values)
359 {
360 int8_t i;
361
362 output_low(LTC2947_CS); //! 1) Pull CS low
363
364 SPI.transfer(LTC2947_SPI_WRITE_CMD); // write
365 SPI.transfer(address); // reg addr
366
367 for (i = 0; i < length; i++)
368 SPI.transfer(values[i]); //! 2) send byte array
369
370 output_high(LTC2947_CS); //! 3) Pull CS high
371 return 0;
372 }
373
374 int8_t LTC2947_SpiRdBlock(uint8_t address, uint8_t length, uint8_t *values)
375 {
376 int8_t i;
377
378 output_low(LTC2947_CS); //! 1) Pull CS low
379
380 SPI.transfer(LTC2947_SPI_READ_CMD); // read
381 SPI.transfer(address); // reg addr
382
383 for (i = 0; i < length; i++)
384 values[i] = SPI.transfer(0x00);
385
386 output_high(LTC2947_CS); //! 3) Pull CS high
387 return 0;
388 }
389
390 int8_t LTC2947_SpiWrByte(uint8_t address, uint8_t value)
391 {
392 output_low(LTC2947_CS); //! 1) Pull CS low
393
394 SPI.transfer(LTC2947_SPI_WRITE_CMD); // write
395 SPI.transfer(address); // reg addr
396 SPI.transfer(value); //! 2) send byte
397
398 output_high(LTC2947_CS); //! 3) Pull CS high
399 return 0;
400 }
401
402 int8_t LTC2947_SpiRdByte(uint8_t address, uint8_t *value)
403 {
404 output_low(LTC2947_CS); //! 1) Pull CS low
405
406 SPI.transfer(LTC2947_SPI_READ_CMD); // read
407 SPI.transfer(address); // reg addr
408 value[0] = SPI.transfer(0x00); //! 2) read byte
409
410 output_high(LTC2947_CS); //! 3) Pull CS high
411 return 0;
412 }
413
414 int8_t LTC2947_I2CWrBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
415 {
416 int8_t ret = 0;
417
418 if (i2c_start() != 0) //I2C START
419 return 1; //Stop and return 0 if START fail
420
421 ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
422 ret |= i2c_write(regAddr); // Set register address
423
424 while (length > 0)
425 {
426 ret |= i2c_write(*values); //Write Value
427 length--;
428 values++;
429 }
430
431 i2c_stop(); // I2C STOP
432
433 return ret != 0 ? 1 : 0;
434 }
435
436 int8_t LTC2947_I2CRdBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
437 {
438 int8_t ret = 0;
439
440 if (length == 0 || i2c_start() != 0) //I2C START
441 return 1; //Stop and return 0 if START fail
442
443 ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
444 ret |= i2c_write(regAddr); // Set register address
445 ret |= i2c_repeated_start();
446 ret |= i2c_write((slvAddr << 1) | I2C_READ_BIT); // Write 7 bit address with R bit
447
448 if (ret != 0) //If NACK return 1
449 {
450 i2c_stop(); //I2C STOP
451 return 1;
452 }
453
454 length--;
455 while (length > 0)
456 {
457 *values = i2c_read(WITH_ACK); //Read from bus with ACK
458 values++;
459 length--;
460 }
461
462 *values = i2c_read(WITH_NACK); //Read from bus with NACK for the last one;
463
464 i2c_stop(); //I2C STOP
465
466 return 0; // Success!
467 }
468
469 int8_t LTC2947_I2CWrByte(uint8_t slvAddr, uint8_t regAddr, uint8_t value)
470 {
471 int8_t ret = 0;
472
473 if (i2c_start() != 0) //I2C START
474 return 1; //Stop and return 0 if START fail
475
476 ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
477 ret |= i2c_write(regAddr); // Set register address
478 ret |= i2c_write(value); //Write Value
479
480 i2c_stop(); // I2C STOP
481
482 return ret != 0 ? 1 : 0;
483 }
484
485 int8_t LTC2947_I2CRdByte(uint8_t slvAddr, uint8_t regAddr, uint8_t *value)
486 {
487 int8_t ret = 0;
488
489 if (i2c_start() != 0) //I2C START
490 return 1; //Stop and return 0 if START fail
491
492 ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
493 ret |= i2c_write(regAddr); // Set register address
494 ret |= i2c_repeated_start();
495 ret |= i2c_write((slvAddr << 1) | I2C_READ_BIT); // Write 7 bit address with R bit
496
497 if (ret != 0) //If NACK return 1
498 {
499 i2c_stop(); //I2C STOP
500 return 1;
501 }
502
503 *value = i2c_read(WITH_NACK); //Read from bus with NACK for the last one;
504
505 i2c_stop(); //I2C STOP
506
507 return 0; // Success!
508 }
509
510 void LTC2947_GPIO_PinMode(uint8_t mode)
511 {
512 uint8_t gpiostatcl;
513 LTC2947_RD_BYTE(LTC2947_REG_GPIOSTATCL, &gpiostatcl);
514 bitMaskSetClr(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPOEN, mode != INPUT);
515 LTC2947_WR_BYTE(LTC2947_REG_GPIOSTATCL, gpiostatcl);
516 }
517
518 void LTC2947_GPIO_SetPinState(uint8_t val)
519 {
520 uint8_t gpiostatcl;
521 LTC2947_RD_BYTE(LTC2947_REG_GPIOSTATCL, &gpiostatcl);
522 bitMaskSetClr(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPO, val != LOW);
523 LTC2947_WR_BYTE(LTC2947_REG_GPIOSTATCL, gpiostatcl);
524 }
525
526 boolean LTC2947_GPIO_Read()
527 {
528 uint8_t gpiostatcl;
529 LTC2947_RD_BYTE(LTC2947_REG_GPIOSTATCL, &gpiostatcl);
530 return bitMaskSetChk(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPI);
531 }
532
533 uint8_t LTC2947_Ara(uint8_t *svlAddr)
534 {
535 *svlAddr = 0;
536 //! Send I2C start bit
537 if (i2c_start() != 0)
538 return LTC2947_ARA_ERROR;
539
540 //! send the ALERT RESPONSE ADDRESS with read bit
541 if (i2c_write((LTC2947_ALERT_RESP_ADDR << 1) | I2C_READ_BIT))
542 {
543 //! NACK means no device response!
544 return LTC2947_ARA_NO_RESPONSE;
545 }
546
547 //! Read device address from the responding device
548 *svlAddr = i2c_read(WITH_NACK); //! read with NACK
549 i2c_stop(); //! I2C STOP
550 //! check for the expected write bit of the response
551 boolean response_wr_bit = bitMaskClrChk(*svlAddr, 0x1);
552 //! right shift to get 7-bit slave address
553 *svlAddr = ((*svlAddr) >> 1) & 0x7F;
554 if (response_wr_bit)
555 {
556 //! got expected write bit, compare slave address
557 //! with LTC2947's address
558 return ((*svlAddr) == LTC2947_I2C_Slave_Addr)
559 ? LTC2947_ARA_LTC2947_RESPONSE
560 : LTC2947_ARA_OTHER_RESPONSE;
561 }
562
563 //! missing write bit within response!
564 return LTC2947_ARA_RESPONSE_WO_WR;
565 }
566
567 int16_t LTC2947_wake_up()
568 {
569 byte data[1];
570 unsigned long wakeupStart = millis(), wakeupTime;
571 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0);//! any serial transaction will wakeup LTC2947
572 do
573 {
574 delay(1);
575 LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); //! wake up polling by reading OPCTL
576 wakeupTime = millis() - wakeupStart;
577 if (data[0] == 0) //! check if we are in idle mode
578 {
579 //! wake up successful, return wakeup time in milliseconds
580 return wakeupTime;
581 }
582 if (wakeupTime > 200)
583 {
584 //! failed to wake up due to timeout, return -1
585 return -1;
586 }
587 }
588 while (true);
589 }
590
591 boolean LTC2947_GetCurrentPageSelect()
592 {
593 uint8_t currentPageCtrl;
594 LTC2947_RD_BYTE(LTC2947_REG_PGCTL, &currentPageCtrl);
595 return bitMaskSetChk(currentPageCtrl, LTC2947_BM_PGCTL_PAGE);
596 }
597
598 void LTC2947_SetPageSelect(boolean page)
599 {
600 LTC2947_WR_BYTE(LTC2947_REG_PGCTL, page ? LTC2947_BM_PGCTL_PAGE : 0); // switch page
601 }
602
603 void LTC2947_Read_I_P_V_TEMP_VCC(float *I, float *P, float *V, float *TEMP, float *VCC)
604 {
605 // byte array to store register values
606 byte bytes[12];
607
608 // read measurement results from device
609 LTC2947_RD_BYTES(LTC2947_VAL_I, 6, bytes); // I[23:0] P[23:0] starting at data[0]
610 LTC2947_RD_BYTES(LTC2947_VAL_V, 6, bytes + 6); // V[15:0] TEMP[15:0] VDVCC[15:0] starting at data[6]
611
612 // convert to floating point values
613 // Note: definitions in LTC2947.h are given in mA, mW, mV
614 // so they have to be mutliplied by 1e-3 to get A, W, V respectively
615 *I = LTC2947_3BytesToInt32(bytes) * LTC2947_LSB_I * 1e-3; // calc current in amps
616 *P = LTC2947_3BytesToInt32(bytes + 3) * LTC2947_LSB_P * 1e-3; // calc power in watts
617 *V = LTC2947_2BytesToInt16(bytes + 6) * LTC2947_LSB_V * 1e-3; // calc voltage in volts
618 *TEMP = LTC2947_2BytesToInt16(bytes + 6 + 2) * LTC2947_LSB_TEMP + LTC2947_OFFS_TEMP; // calc temperature in degree celcius
619 *VCC = LTC2947_2BytesToInt16(bytes + 6 + 4) * LTC2947_LSB_VDVCC * 1e-3; // calc supply voltage in volts
620 }
621
622 void LTC2947_Read_Abs_C_E_TB(boolean accuSet1, double *C, boolean *signC, double *E, boolean *signE, double *TB)
623 {
624 // byte array to store register values
625 byte bytes[16];
626
627 // read measurement results from device
628 if (accuSet1)
629 // read accumulated quantities set 1: C1[47:0] E1[47:0] TB1[31:0]
630 LTC2947_RD_BYTES(LTC2947_VAL_C1, 16, bytes);
631 else
632 // read accumulated quantities set 2: C2[47:0] E2[47:0] TB2[31:0]
633 LTC2947_RD_BYTES(LTC2947_VAL_C2, 16, bytes);
634
635 // calculate absolute value of Cx and store sign
636 *signC = LTC2947_Abs(bytes, 6);
637 // convert unsigned bytes to double value in As
638 *C = LTC2947_UnsignedBytesToDouble(bytes, 6, LTC2947_LSB_C1);
639
640 // calculate absolute value of Ex and store sign
641 *signE = LTC2947_Abs(bytes + 6, 6);
642 // convert unsigned bytes to double value in Ws
643 *E = LTC2947_UnsignedBytesToDouble(bytes + 6, 6, LTC2947_LSB_E1);
644
645 // calc time in seconds
646 *TB = LTC2947_4BytesToUInt32(bytes + 12) * LTC2947_LSB_TB1;
647 }
648
649 void LTC2947_Read_C_E_TB(boolean accuSet1, double *C, double *E, double *TB)
650 {
651 // byte array to store register values
652 byte bytes[16];
653
654 // read measurement results from device
655 if (accuSet1)
656 // read accumulated quantities set 1: C1[47:0] E1[47:0] TB1[31:0]
657 LTC2947_RD_BYTES(LTC2947_VAL_C1, 16, bytes);
658 else
659 // read accumulated quantities set 2: C2[47:0] E2[47:0] TB2[31:0]
660 LTC2947_RD_BYTES(LTC2947_VAL_C2, 16, bytes);
661
662 // convert signed bytes to double value in As
663 *C = LTC2947_SignedBytesToDouble(bytes, 6, LTC2947_LSB_C1);
664
665 // convert signed bytes to double value in Ws
666 *E = LTC2947_SignedBytesToDouble(bytes + 6, 6, LTC2947_LSB_E1);
667
668 // calc time in seconds
669 *TB = LTC2947_4BytesToUInt32(bytes + 6 + 6) * LTC2947_LSB_TB1;
670 }
bitMaskSetClr
#define bitMaskSetClr(value, bitMask, setNotClr)
Definition: LTC2947.h:81
I2C_WRITE_BIT
#define I2C_WRITE_BIT
Definition: LT_I2C.h:64
LTC2947_I2C_ADDR_LL
#define LTC2947_I2C_ADDR_LL
Definition: LTC2947.h:102
LTC2947_ARA_ERROR
#define LTC2947_ARA_ERROR
general I2C communication error
Definition: LTC2947.h:1508
ret
long ret
Definition: EVAL-AD7124-8.ino:145
LTC2947_I2CWrBlock
int8_t LTC2947_I2CWrBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
write byte array via I2C interface
Definition: LTC2947.cpp:414
LTC2947_I2CWrByte
int8_t LTC2947_I2CWrByte(uint8_t slvAddr, uint8_t regAddr, uint8_t value)
write single byte via I2C
Definition: LTC2947.cpp:469
LTC2947_LSB_TB1
#define LTC2947_LSB_TB1
Definition: LTC2947.h:920
LTC2947_SPI_READ_CMD
#define LTC2947_SPI_READ_CMD
Definition: LTC2947.h:110
sign
bool sign
Definition: Precision_Voltage_Source.ino:77
LTC2947_Read_I_P_V_TEMP_VCC
void LTC2947_Read_I_P_V_TEMP_VCC(float *I, float *P, float *V, float *TEMP, float *VCC)
Reads current (I), power (P), voltage (V), temperature (TEMP) and supply voltage (VCC) from the devic...
Definition: LTC2947.cpp:603
LTC2947_4BytesToUInt32
uint32_t LTC2947_4BytesToUInt32(byte *bytes)
Converts an array of 4 bytes to 32-bit unsigned integer.
Definition: LTC2947.cpp:311
LTC2947_RD_BYTES
static int8_t LTC2947_RD_BYTES(uint8_t REG_ADDR, uint8_t LENGTH, uint8_t *BYTES)
read multiple bytes via I2C/SPI
Definition: LTC2947.h:1588
LTC2947_Ara
uint8_t LTC2947_Ara(uint8_t *svlAddr)
Sends the Alert Response address to the I2C bus and reads the response If two or more devices on the ...
Definition: LTC2947.cpp:533
LTC2947_InitSPI
void LTC2947_InitSPI()
Initializes the LTC2947 library for SPI mode operation.
Definition: LTC2947.cpp:91
LTC2947_Abs
boolean LTC2947_Abs(uint8_t *bytes, uint8_t length)
Calculates the absolute value of a signed value with arbitrary number of bytes.
Definition: LTC2947.cpp:96
output_high
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
LTC2947_Read_C_E_TB
void LTC2947_Read_C_E_TB(boolean accuSet1, double *C, double *E, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:649
LTC2947_BM_PGCTL_PAGE
#define LTC2947_BM_PGCTL_PAGE
Definition: LTC2947.h:1279
LTC2947_BM_GPIOSTATCL_GPI
#define LTC2947_BM_GPIOSTATCL_GPI
Definition: LTC2947.h:1036
LTC2947_3BytesToInt32
int32_t LTC2947_3BytesToInt32(byte *bytes)
converts an array of 3 bytes to 32-bit signed integer
Definition: LTC2947.cpp:282
LTC2947_Read_Abs_C_E_TB
void LTC2947_Read_Abs_C_E_TB(boolean accuSet1, double *C, boolean *signC, double *E, boolean *signE, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:622
LTC2947_CS
#define LTC2947_CS
Definition: LTC2947.h:117
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2947_BM_GPIOSTATCL_GPO
#define LTC2947_BM_GPIOSTATCL_GPO
Definition: LTC2947.h:1040
LTC2947_ARA_OTHER_RESPONSE
#define LTC2947_ARA_OTHER_RESPONSE
got ARA response from some other I2C slave
Definition: LTC2947.h:1512
LTC2947_VAL_I
#define LTC2947_VAL_I
Definition: LTC2947.h:792
i2c_stop
void i2c_stop()
Write stop bit to the hardware I2C port.
Definition: LT_I2C.cpp:462
LTC2947_I2CRdBlock
int8_t LTC2947_I2CRdBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
read multiple bytes via I2C
Definition: LTC2947.cpp:436
LTC2947_SetPageSelect
void LTC2947_SetPageSelect(boolean page)
write LTC2947&#39;s page control register to selected one of two memory pages
Definition: LTC2947.cpp:598
LTC2947_VAL_C2
#define LTC2947_VAL_C2
Definition: LTC2947.h:753
LTC2947_ARA_NO_RESPONSE
#define LTC2947_ARA_NO_RESPONSE
got NO ARA response
Definition: LTC2947.h:1514
LTC2947_2BytesToUInt16
uint16_t LTC2947_2BytesToUInt16(byte *bytes)
Converts an array of 2 bytes to 16-bit unsigned integer.
Definition: LTC2947.cpp:342
LTC2947_SerialPrint8hex
void LTC2947_SerialPrint8hex(uint8_t val)
Prints a 8-bit value in 2-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:152
i2c_start
int8_t i2c_start()
Write start bit to the hardware I2C port.
Definition: LT_I2C.cpp:425
LTC2947_SignedBytesToDouble
double LTC2947_SignedBytesToDouble(uint8_t *signedBytes, uint8_t length, double lsb)
Converts a signed value of arbitrary number of bytes to a floating point value with the scaling facto...
Definition: LTC2947.cpp:247
LTC2947_VAL_V
#define LTC2947_VAL_V
Definition: LTC2947.h:798
address
static uint8_t address
Definition: DC2091A.ino:83
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
WITH_NACK
#define WITH_NACK
Use with i2c_read(WITH_NACK) to read without an acknowledge.
Definition: LT_I2C.h:91
LTC2947_LSB_C1
#define LTC2947_LSB_C1
Definition: LTC2947.h:916
LTC2947_SerialPrint32hex
void LTC2947_SerialPrint32hex(uint32_t val)
Prints a 32-bit value in 8-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:163
LTC2947_SPI_Mode_Enabled
boolean LTC2947_SPI_Mode_Enabled
controlled by LTC2947_InitI2C / LTC2947_InitSPI to switch between I2C / SPI mode
Definition: LTC2947.cpp:82
i2c_write
int8_t i2c_write(uint8_t data)
Send a data byte to hardware I2C port.
Definition: LT_I2C.cpp:470
output_low
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
LTC2947_2BytesToInt16
int16_t LTC2947_2BytesToInt16(byte *bytes)
converts an array of 2 bytes to 16-bit signed integer
Definition: LTC2947.cpp:301
LTC2947_GPIO_Read
boolean LTC2947_GPIO_Read()
reads the current GPIO pin state Make sure LTC2947&#39;s page 0 is selected before calling this function...
Definition: LTC2947.cpp:526
LTC2947_LSB_TEMP
#define LTC2947_LSB_TEMP
Definition: LTC2947.h:958
bitMaskSetChk
#define bitMaskSetChk(value, bitMask)
Definition: LTC2947.h:75
I2C_READ_BIT
#define I2C_READ_BIT
Definition: LT_I2C.h:63
LTC2947_InitI2C
void LTC2947_InitI2C(uint8_t slvAddr)
Initializes the LTC2947 library for I2C mode operation and configures the slave address see defines L...
Definition: LTC2947.cpp:85
LTC2947_OFFS_TEMP
#define LTC2947_OFFS_TEMP
Definition: LTC2947.h:960
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC2947_I2C_Slave_Addr
uint8_t LTC2947_I2C_Slave_Addr
set by LTC2947_InitI2C to set slave address for I2C operation
Definition: LTC2947.cpp:83
LTC2947_ALERT_RESP_ADDR
#define LTC2947_ALERT_RESP_ADDR
The general alert response address.
Definition: LTC2947.h:1518
LTC2947_VAL_C1
#define LTC2947_VAL_C1
Definition: LTC2947.h:744
LTC2947_LSB_VDVCC
#define LTC2947_LSB_VDVCC
Definition: LTC2947.h:962
LTC2947_GPIO_SetPinState
void LTC2947_GPIO_SetPinState(uint8_t val)
Sets the level of the output driver on the GPIO pin This has only an effect if the output driver is e...
Definition: LTC2947.cpp:518
LTC2947_REG_PGCTL
#define LTC2947_REG_PGCTL
Definition: LTC2947.h:246
LTC2947_LSB_V
#define LTC2947_LSB_V
Definition: LTC2947.h:956
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
LTC2947_SpiRdBlock
int8_t LTC2947_SpiRdBlock(uint8_t address, uint8_t length, uint8_t *values)
read array of bytes from the SPI interface
Definition: LTC2947.cpp:374
bitMaskClrChk
#define bitMaskClrChk(value, bitMask)
Definition: LTC2947.h:76
i2c_repeated_start
int8_t i2c_repeated_start()
Write a repeat start bit to the hardware I2C port.
Definition: LT_I2C.cpp:444
UserInterface.h
LTC2947_REG_OPCTL
#define LTC2947_REG_OPCTL
Definition: LTC2947.h:243
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC2947_wake_up
int16_t LTC2947_wake_up()
Wake up LTC2947 from shutdown mode and measure the wakeup time.
Definition: LTC2947.cpp:567
LTC2947_SerialPrint16hex
void LTC2947_SerialPrint16hex(uint16_t val)
Prints a 16-bit value in 4-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:157
LTC2947_4BytesToInt32
int32_t LTC2947_4BytesToInt32(byte *bytes)
Converts an array of 4 bytes to 32-bit signed integer.
Definition: LTC2947.cpp:265
LTC2947_SerialPrint64hex
void LTC2947_SerialPrint64hex(uint64_t uint64Val)
Prints a 64-bit value in 16-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:169
LTC2947_LSB_I
#define LTC2947_LSB_I
Definition: LTC2947.h:952
read_float
float read_float()
Definition: UserInterface.cpp:78
LTC2947_ARA_LTC2947_RESPONSE
#define LTC2947_ARA_LTC2947_RESPONSE
got ARA response from LTC2947
Definition: LTC2947.h:1510
LTC2947_LSB_P
#define LTC2947_LSB_P
Definition: LTC2947.h:954
LTC2947_SPI_WRITE_CMD
#define LTC2947_SPI_WRITE_CMD
Definition: LTC2947.h:111
LTC2947_I2CRdByte
int8_t LTC2947_I2CRdByte(uint8_t slvAddr, uint8_t regAddr, uint8_t *value)
read single byte via I2C
Definition: LTC2947.cpp:485
i2c_read
uint8_t i2c_read(int8_t ack)
Read a data byte from the hardware I2C port.
Definition: LT_I2C.cpp:491
LTC2947_GPIO_PinMode
void LTC2947_GPIO_PinMode(uint8_t mode)
Enables/disables the output driver on the GPIO pin Make sure LTC2947&#39;s page 0 is selected before call...
Definition: LTC2947.cpp:510
LTC2947_LSB_E1
#define LTC2947_LSB_E1
Definition: LTC2947.h:918
LTC2947_DoubleToBytes
void LTC2947_DoubleToBytes(double value, double lsb, uint8_t *bytes, uint8_t length)
Converts a floating point number that was scaled with a given LSB to an integer representation that w...
Definition: LTC2947.cpp:175
LTC2947_3BytesToUInt32
uint32_t LTC2947_3BytesToUInt32(byte *bytes)
converts an array of 3 bytes to 32-bit unsigned integer
Definition: LTC2947.cpp:328
LTC2947.h
LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting...
E
const int16_t E
Definition: LTC2492_Thermocouple_Meter.ino:101
LTC2947_WR_BYTE
static int8_t LTC2947_WR_BYTE(uint8_t REG_ADDR, uint8_t VALUE)
write single byte via I2C
Definition: LTC2947.h:1626
i
static int i
Definition: DC2430A.ino:184
LTC2947_SpiWrByte
int8_t LTC2947_SpiWrByte(uint8_t address, uint8_t value)
write single byte to SPI interface
Definition: LTC2947.cpp:390
WITH_ACK
#define WITH_ACK
Use with i2c_read(WITH_ACK) to read with an acknowledge.
Definition: LT_I2C.h:90
LTC2947_GetCurrentPageSelect
boolean LTC2947_GetCurrentPageSelect()
reads LTC2947&#39;s page control register to determine the currently selected memory page ...
Definition: LTC2947.cpp:591
LTC2947_BytesToDouble
double LTC2947_BytesToDouble(uint8_t *bytes, uint8_t length, boolean sig, double lsb)
Converts a signed or unsigned value of arbitrary number of bytes to a floating point number...
Definition: LTC2947.cpp:121
LTC2947_UnsignedBytesToDouble
double LTC2947_UnsignedBytesToDouble(uint8_t *unsignedBytes, uint8_t length, double lsb)
Converts an unsigned value of arbitrary number of bytes to a floating point value with the scaling fa...
Definition: LTC2947.cpp:137
LTC2947_REG_GPIOSTATCL
#define LTC2947_REG_GPIOSTATCL
Definition: LTC2947.h:168
LTC2947_BM_GPIOSTATCL_GPOEN
#define LTC2947_BM_GPIOSTATCL_GPOEN
Definition: LTC2947.h:1032
LTC2947_ARA_RESPONSE_WO_WR
#define LTC2947_ARA_RESPONSE_WO_WR
got ARA response from any slave but wihtout the expected WR bit
Definition: LTC2947.h:1516
LTC2947_RD_BYTE
static int8_t LTC2947_RD_BYTE(uint8_t REG_ADDR, uint8_t *RESULT)
read single byte via I2C/SPI
Definition: LTC2947.h:1614
values
static uint8_t values[4]
Definition: DC2218A.ino:117
LTC2947_SpiWrBlock
int8_t LTC2947_SpiWrBlock(uint8_t address, uint8_t length, uint8_t *values)
writes block (array) of bytes to the SPI interface
Definition: LTC2947.cpp:358
LTC2947_SpiRdByte
int8_t LTC2947_SpiRdByte(uint8_t address, uint8_t *value)
read single byte from SPI interface
Definition: LTC2947.cpp:402