| 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
165 LT_union_int32_4bytes data;
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
216 LT_union_int32_4bytes data;
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
i2c_address
uint8_t i2c_address
adc_command
static uint8_t adc_command
Definition: DC2071AA.ino:111
i2c_read_block_data
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
LT_union_int32_4bytes::LT_byte
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
i2c_read_byte_data
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
LTC2992_code_to_current
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
resistor
const float resistor
resistor value on demo board
Definition: DC1496BB.ino:116
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2992.h
LTC2992: Dual Wide Range Power Monitor.
LTC2992_read
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
LTC2992_write_24_bits
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
adc_voltage
static float adc_voltage
Definition: DC2071AA.ino:115
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
LTC2992_SENSE_code_to_voltage
float LTC2992_SENSE_code_to_voltage(uint16_t adc_code, float LTC2992_SENSE_lsb)
Calculate the LTC2992 SENSE voltage.
Definition: LTC2992.cpp:225
LTC2992_code_to_current_sum
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
LTC2992_write
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
LTC2992_code_to_power_sum
float LTC2992_code_to_power_sum(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
Power LSB Weight.
Definition: LTC2992.cpp:273
i2c_write_word_data
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
i2c_write_byte_data
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
LT_union_int32_4bytes::LT_int32
int32_t LT_int32
32-bit signed integer to be converted to four bytes
Definition: Linduino.h:110
LTC2992_GPIO_code_to_voltage
float LTC2992_GPIO_code_to_voltage(uint16_t adc_code, float LTC2992_GPIO_lsb)
Calculate the LTC2992 GPIO voltage.
Definition: LTC2992.cpp:234
LTC2992_read_16_bits
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
i2c_read_word_data
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.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
i2c_write_block_data
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
LTC2992_read_12_bits
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
LT_union_int32_4bytes
This union splits one int32_t (32-bit signed integer) or uint32_t (32-bit unsigned integer) four uint...
Definition: Linduino.h:108
LTC2992_write_16_bits
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
LTC2992_read_24_bits
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
LTC2992_code_to_power
float LTC2992_code_to_power(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
Calculate the LTC2992 power.
Definition: LTC2992.cpp:263
voltage
static float voltage
Definition: DC2289AA.ino:71
current
static uint16_t current
the current measurement from the LTC3335&#39;s counter test mode.
Definition: DC2343A.ino:114
adc_code
static uint32_t adc_code
Definition: DC2071AA.ino:113