Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTC2992.cpp
Go to the documentation of this file.
1 /*!
2  LTC2992: Dual Wide Range Power Monitor
3 
4 @verbatim
5 
6 The LTC®2992 is a rail-to-rail system monitor that measures
7 current, voltage, power, charge and energy. It features an
8 operating range of 2.7V to 100V and includes a shunt regulator
9 for supplies above 100V. The current measurement common mode
10 range of 0V to 100V is independent of the input supply.
11 A 12-bit ADC measures load current, input voltage and an
12 auxiliary external voltage. Load current and internally
13 calculated power are integrated over an external clock or
14 crystal or internal oscillator time base for charge and energy.
15 An accurate time base allows the LTC2992 to provide measurement
16 accuracy of better than ±0.6% for charge and ±1% for power and
17 energy. Minimum and maximum values are stored and an overrange
18 alert with programmable thresholds minimizes the need for software
19 polling. Data is reported via a standard I2C interface.
20 Shutdown mode reduces power consumption to 15uA.
21 
22 
23 I2C DATA FORMAT (MSB FIRST):
24 
25 Data Out:
26 Byte #1 Byte #2 Byte #3
27 
28 START SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK X X C5 C4 C3 C2 C1 C0 SACK D7 D6 D5 D4 D3 D2 D1 D0 SACK STOP
29 
30 Data In:
31 Byte #1 Byte #2 Byte #3
32 
33 START SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK X X C5 C4 C3 C2 C1 C0 SACK Repeat Start SA6 SA5 SA4 SA3 SA2 SA1 SA0 R SACK
34 
35 Byte #4 Byte #5
36 MSB LSB
37 D15 D14 D13 D12 D11 D10 D9 D8 MACK D7 D6 D5 D4 D3 D2 D1 D0 MNACK STOP
38 
39 START : I2C Start
40 Repeat Start: I2c Repeat Start
41 STOP : I2C Stop
42 SAx : I2C Address
43 SACK : I2C Slave Generated Acknowledge (Active Low)
44 MACK : I2C Master Generated Acknowledge (Active Low)
45 MNACK : I2c Master Generated Not Acknowledge
46 W : I2C Write (0)
47 R : I2C Read (1)
48 Cx : Command Code
49 Dx : Data Bits
50 X : Don't care
51 
52 
53 
54 Example Code:
55 
56 Read power, current and voltage
57 
58  CTRLA = LTC2992_CHANNEL_CONFIG_V_C_3|LTC2992_SENSE_PLUS|LTC2992_OFFSET_CAL_EVERY|LTC2992_ADIN_GND; //! Set Control A register to default value in continuous mode
59  ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_CTRLA_REG, CTRLA); //! Sets the LTC2992 to continuous mode
60 
61  resistor = .02; // Resistor Value On Demo Board
62 
63  ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER_MSB2_REG, &power_code); // Reads the ADC registers that contains V^2
64  power = LTC2992_code_to_power(power_code, resistor, LTC2992_Power_lsb); // Calculates power from power code, resistor value and power lsb
65 
66  ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE_MSB_REG, &current_code); // Reads the voltage code across sense resistor
67  current = LTC2992_code_to_current(current_code, resistor, LTC2992_DELTA_SENSE_lsb); // Calculates current from current code, resistor value and current lsb
68 
69  ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE_MSB_REG, &SENSE_code); // Reads SENSE voltage code
70  SENSE = LTC2992_SENSE_code_to_voltage(SENSE_code, LTC2992_SENSE_lsb); // Calculates SENSE voltage from SENSE code and lsb
71 
72  ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_ENERGY_MSB3_REG, &energy_code); // Reads energy code
73  energy = LTC2992_code_to_energy(energy_code,resistor,LTC2992_Power_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates Energy in Joules from energy_code, resistor, power lsb and time lsb
74 
75  ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_CHARGE_MSB3_REG, &charge_code); // Reads charge code
76  charge = LTC2992_code_to_coulombs(charge_code,resistor,LTC2992_DELTA_SENSE_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates charge in coulombs from charge_code, resistor, current lsb and time lsb
77 
78 
79 
80 @endverbatim
81 
82 http://www.linear.com/product/LTC2992
83 
84 http://www.linear.com/product/LTC2992#demoboards
85 
86 
87 Copyright 2018(c) Analog Devices, Inc.
88 
89 All rights reserved.
90 
91 Redistribution and use in source and binary forms, with or without
92 modification, are permitted provided that the following conditions are met:
93  - Redistributions of source code must retain the above copyright
94  notice, this list of conditions and the following disclaimer.
95  - Redistributions in binary form must reproduce the above copyright
96  notice, this list of conditions and the following disclaimer in
97  the documentation and/or other materials provided with the
98  distribution.
99  - Neither the name of Analog Devices, Inc. nor the names of its
100  contributors may be used to endorse or promote products derived
101  from this software without specific prior written permission.
102  - The use of this software may or may not infringe the patent rights
103  of one or more patent holders. This license does not release you
104  from the requirement that you obtain separate licenses from these
105  patent holders to use this software.
106  - Use of the software either in source or binary form, must be run
107  on or directly connected to an Analog Devices Inc. component.
108 
109 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
110 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
111 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
112 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
113 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
114 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
115 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
116 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
117 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
118 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119 */
120 
121 //! @ingroup Power_Monitors
122 //! @{
123 //! @defgroup LTC2992 LTC2992: Dual Wide Range Power Monitor
124 //! @}
125 /*! @file
126  @ingroup LTC2992
127  Header for LTC2992: Dual Wide Range Power Monitor
128 */
129 
130 #include <Arduino.h>
131 #include <stdint.h>
132 #include "Linduino.h"
133 #include "LT_I2C.h"
134 #include "LTC2992.h"
135 #include <Wire.h>
136 
137 // Write an 8-bit code to the LTC2992.
138 int8_t LTC2992_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
139 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
140 {
141  int32_t ack;
142 
143  ack = i2c_write_byte_data(i2c_address, adc_command, code);
144 
145  return ack;
146 
147 }
148 
149 // Write a 16-bit code to the LTC2992.
150 int8_t LTC2992_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
151 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
152 {
153  int8_t ack;
154 
155  ack = i2c_write_word_data(i2c_address, adc_command, code);
156  return(ack);
157 }
158 
159 // Write a 24-bit code to the LTC2992.
160 int8_t LTC2992_write_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
161 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
162 {
163  int8_t ack;
164 
166  data.LT_int32 = code;
167 
168  ack = i2c_write_block_data(i2c_address, adc_command, (uint8_t) 3, data.LT_byte);
169 
170  return(ack);
171 }
172 
173 
174 // Reads an 8-bit adc_code from LTC2992
175 int8_t LTC2992_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
176 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
177 {
178  int32_t ack;
179 
180  ack = i2c_read_byte_data(i2c_address, adc_command, adc_code);
181 
182  return ack;
183 }
184 
185 // Reads a 12-bit adc_code from LTC2992
186 int8_t LTC2992_read_12_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
187 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
188 {
189  // Use union type defined in Linduino.h to combine two uint8_t's (8-bit unsigned integers) into one uint16_t (unsigned 16-bit integer)
190  // Then, shift by 4 bits and return in *adc_code
191  int32_t ack;
192 
193  ack = i2c_read_word_data(i2c_address, adc_command, adc_code);
194 
195  *adc_code >>= 4;
196  return ack;
197 }
198 
199 // Reads a 16-bit adc_code from LTC2992
200 int8_t LTC2992_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
201 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
202 {
203  int32_t ack;
204 
205  ack = i2c_read_word_data(i2c_address, adc_command, adc_code);
206 
207  return ack;
208 }
209 
210 // Reads a 24-bit adc_code from LTC2992
211 int8_t LTC2992_read_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
212 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
213 {
214  int8_t ack;
215 
217 
218  ack = i2c_read_block_data(i2c_address, adc_command, (uint8_t)3, data.LT_byte);
219 
220  *adc_code = 0x0FFFFFF & data.LT_int32;
221  return(ack);
222 }
223 
224 // Calculate the LTC2992 SENSE voltage
225 float LTC2992_SENSE_code_to_voltage(uint16_t adc_code, float LTC2992_SENSE_lsb)
226 // Returns the SENSE Voltage in Volts
227 {
228  float voltage;
229  voltage = (float)adc_code*LTC2992_SENSE_lsb; //! 1) Calculate voltage from code and lsb
230  return(voltage);
231 }
232 
233 // Calculate the LTC2992 GPIO voltage
234 float LTC2992_GPIO_code_to_voltage(uint16_t adc_code, float LTC2992_GPIO_lsb)
235 // Returns the GPIO Voltage in Volts
236 {
237  float adc_voltage;
238  adc_voltage = (float)adc_code*LTC2992_GPIO_lsb; //! 1) Calculate voltage from code and ADIN lsb
239  return(adc_voltage);
240 }
241 
242 // Calculate the LTC2992 current with a sense resistor
243 float LTC2992_code_to_current(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
244 // Returns the LTC2992 current in Amps
245 {
246  float voltage, current;
247  voltage = (float)adc_code*LTC2992_DELTA_SENSE_lsb; //! 1) Calculate voltage from ADC code and delta sense lsb
248  current = voltage/resistor; //! 2) Calculate current, I = V/R
249  return(current);
250 }
251 
252 // Calculate the LTC2992 current with a sense resistor
253 float LTC2992_code_to_current_sum(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
254 // Returns the LTC2992 current in Amps
255 {
256  float voltage, current;
257  voltage = (float)(adc_code<<1)*LTC2992_DELTA_SENSE_lsb; //! 1) Calculate voltage from ADC code and delta sense lsb
258  current = voltage/resistor; //! 2) Calculate current, I = V/R
259  return(current);
260 }
261 
262 // Calculate the LTC2992 power
263 float LTC2992_code_to_power(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
264 // Returns The LTC2992 power in Watts
265 {
266  float power;
267  power = (float)adc_code*LTC2992_Power_lsb/resistor; //! 1) Calculate Power using Power lsb and resistor
268 
269  return(power);
270 }
271 
272 // Calculate the LTC2992 power
273 float LTC2992_code_to_power_sum(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
274 // Returns The LTC2992 power in Watts
275 {
276  float power;
277  power = (float)(adc_code<<1)*LTC2992_Power_lsb/resistor; //! 1) Calculate Power using Power lsb and resistor
278 
279  return(power);
280 }
281 
uint8_t i2c_address
static uint8_t adc_command
Definition: DC2071AA.ino:111
int8_t i2c_read_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
Read a block of data, starting at register specified by "command" and ending at (command + length - 1...
Definition: LT_I2C.cpp:244
uint8_t LT_byte[4]
4 bytes (unsigned 8-bit integers) to be converted to a 32-bit signed or unsigned integer ...
Definition: Linduino.h:112
int8_t i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value)
Read a byte of data at register specified by "command", store in "value".
Definition: LT_I2C.cpp:124
float LTC2992_code_to_current(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
Calculate the LTC2992 current with a sense resistor.
Definition: LTC2992.cpp:243
const float resistor
resistor value on demo board
Definition: DC1496BB.ino:116
Header File for Linduino Libraries and Demo Code.
LTC2992: Dual Wide Range Power Monitor.
int8_t LTC2992_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
Reads an 8-bit adc_code from LTC2992.
Definition: LTC2992.cpp:175
int8_t LTC2992_write_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
Write a 24-bit code to the LTC2992.
Definition: LTC2992.cpp:160
static float adc_voltage
Definition: DC2071AA.ino:115
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
float LTC2992_SENSE_code_to_voltage(uint16_t adc_code, float LTC2992_SENSE_lsb)
Calculate the LTC2992 SENSE voltage.
Definition: LTC2992.cpp:225
float LTC2992_code_to_current_sum(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
Calculate the LTC2992 current sum with a sense resistor.
Definition: LTC2992.cpp:253
int8_t LTC2992_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
Write an 8-bit code to the LTC2992.
Definition: LTC2992.cpp:138
float LTC2992_code_to_power_sum(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
Power LSB Weight.
Definition: LTC2992.cpp:273
int8_t i2c_write_word_data(uint8_t address, uint8_t command, uint16_t value)
Write a 16-bit word of data to register specified by "command".
Definition: LT_I2C.cpp:216
int8_t i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value)
Write a byte of data to register specified by "command".
Definition: LT_I2C.cpp:155
int32_t LT_int32
32-bit signed integer to be converted to four bytes
Definition: Linduino.h:110
float LTC2992_GPIO_code_to_voltage(uint16_t adc_code, float LTC2992_GPIO_lsb)
Calculate the LTC2992 GPIO voltage.
Definition: LTC2992.cpp:234
int8_t LTC2992_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
Reads a 16-bit adc_code from LTC2992.
Definition: LTC2992.cpp:200
int8_t i2c_read_word_data(uint8_t address, uint8_t command, uint16_t *value)
Read a 16-bit word of data from register specified by "command".
Definition: LT_I2C.cpp:172
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
int8_t i2c_write_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
Write a block of data, starting at register specified by "command" and ending at (command + length - ...
Definition: LT_I2C.cpp:321
int8_t LTC2992_read_12_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
Reads a 12-bit adc_code from LTC2992.
Definition: LTC2992.cpp:186
This union splits one int32_t (32-bit signed integer) or uint32_t (32-bit unsigned integer) four uint...
Definition: Linduino.h:108
int8_t LTC2992_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
Write a 16-bit code to the LTC2992.
Definition: LTC2992.cpp:150
int8_t LTC2992_read_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
Reads a 24-bit adc_code from LTC2992.
Definition: LTC2992.cpp:211
float LTC2992_code_to_power(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
Calculate the LTC2992 power.
Definition: LTC2992.cpp:263
static float voltage
Definition: DC2289AA.ino:71
static uint16_t current
the current measurement from the LTC3335&#39;s counter test mode.
Definition: DC2343A.ino:114
static uint32_t adc_code
Definition: DC2071AA.ino:113