| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

LTC2946.cpp
Go to the documentation of this file.
1 /*!
2 LTC2946: 12-Bit Wide Range Power, Charge and Energy Monitor
3
4 @verbatim
5
6 The LTC®2946 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 LTC2946 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 @endverbatim
23
24 http://www.linear.com/product/LTC2946
25
26 http://www.linear.com/product/ltc2946#demoboards
27
28
29 Copyright 2018(c) Analog Devices, Inc.
30
31 All rights reserved.
32
33 Redistribution and use in source and binary forms, with or without
34 modification, are permitted provided that the following conditions are met:
35 - Redistributions of source code must retain the above copyright
36 notice, this list of conditions and the following disclaimer.
37 - Redistributions in binary form must reproduce the above copyright
38 notice, this list of conditions and the following disclaimer in
39 the documentation and/or other materials provided with the
40 distribution.
41 - Neither the name of Analog Devices, Inc. nor the names of its
42 contributors may be used to endorse or promote products derived
43 from this software without specific prior written permission.
44 - The use of this software may or may not infringe the patent rights
45 of one or more patent holders. This license does not release you
46 from the requirement that you obtain separate licenses from these
47 patent holders to use this software.
48 - Use of the software either in source or binary form, must be run
49 on or directly connected to an Analog Devices Inc. component.
50
51 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
52 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
53 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
55 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
57 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
58 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
59 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62
63 //! @ingroup Power_Monitors
64 //! @{
65 //! @defgroup LTC2946 LTC2946: 12-Bit Wide Range Power, Charge and Energy Monitor
66 //! @}
67
68 /*! @file
69 @ingroup LTC2946
70 Library for LTC2946 12-Bit Wide Range Power, Charge and Energy Monitor
71 */
72
73 #include <Arduino.h>
74 #include <stdint.h>
75 #include "Linduino.h"
76 #include "LT_I2C.h"
77 #include "LTC2946.h"
78 #include <Wire.h>
79
80 // Write an 8-bit code to the LTC2946.
81 int8_t LTC2946_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
82 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
83 {
84 int32_t ack;
85
86 ack = i2c_write_byte_data(i2c_address, adc_command, code);
87
88 return ack;
89
90 }
91
92 // Write a 16-bit code to the LTC2946.
93 int8_t LTC2946_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
94 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
95 {
96 int8_t ack;
97
98 ack = i2c_write_word_data(i2c_address, adc_command, code);
99 return(ack);
100 }
101
102 // Write a 24-bit code to the LTC2946.
103 int8_t LTC2946_write_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
104 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
105 {
106 int8_t ack;
107
108 LT_union_int32_4bytes data;
109 data.LT_int32 = code;
110
111 ack = i2c_write_block_data(i2c_address, adc_command, (uint8_t) 3, data.LT_byte);
112
113 return(ack);
114 }
115
116 int8_t LTC2946_write_32_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
117 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
118 {
119 int8_t ack;
120
121 LT_union_int32_4bytes data;
122 data.LT_int32 = code;
123
124 ack = i2c_write_block_data(i2c_address, adc_command, (uint8_t) 4, data.LT_byte);
125
126 return(ack);
127 }
128
129 // Reads an 8-bit adc_code from LTC2946
130 int8_t LTC2946_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
131 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
132 {
133 int32_t ack;
134
135 ack = i2c_read_byte_data(i2c_address, adc_command, adc_code);
136
137 return ack;
138 }
139
140 // Reads a 12-bit adc_code from LTC2946
141 int8_t LTC2946_read_12_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
142 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
143 {
144 // 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)
145 // Then, shift by 4 bits and return in *adc_code
146 int32_t ack;
147
148 ack = i2c_read_word_data(i2c_address, adc_command, adc_code);
149
150 *adc_code >>= 4;
151 return ack;
152 }
153
154 // Reads a 16-bit adc_code from LTC2946
155 int8_t LTC2946_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
156 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
157 {
158 int32_t ack;
159
160 ack = i2c_read_word_data(i2c_address, adc_command, adc_code);
161
162 return ack;
163 }
164
165 // Reads a 24-bit adc_code from LTC2946
166 int8_t LTC2946_read_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
167 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
168 {
169 int8_t ack;
170
171 LT_union_int32_4bytes data;
172
173 ack = i2c_read_block_data(i2c_address, adc_command, (uint8_t)3, data.LT_byte);
174
175 *adc_code = 0x0FFFFFF & data.LT_int32;
176 return(ack);
177 }
178
179 // Reads a 32-bit adc_code from LTC2946
180 int8_t LTC2946_read_32_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
181 // The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
182 {
183 int8_t ack;
184
185 LT_union_int32_4bytes data;
186
187 ack = i2c_read_block_data(i2c_address, adc_command, (uint8_t) 4, data.LT_byte);
188
189 *adc_code = 0xFFFFFFFF & data.LT_int32;
190 return(ack);
191 }
192
193 // Calculate the LTC2946 VIN voltage
194 float LTC2946_VIN_code_to_voltage(uint16_t adc_code, float LTC2946_VIN_lsb)
195 // Returns the VIN Voltage in Volts
196 {
197 float voltage;
198 voltage = (float)adc_code*LTC2946_VIN_lsb; //! 1) Calculate voltage from code and lsb
199 return(voltage);
200 }
201
202 // Calculate the LTC2946 ADIN voltage
203 float LTC2946_ADIN_code_to_voltage(uint16_t adc_code, float LTC2946_ADIN_lsb)
204 // Returns the ADIN Voltage in Volts
205 {
206 float adc_voltage;
207 adc_voltage = (float)adc_code*LTC2946_ADIN_lsb; //! 1) Calculate voltage from code and ADIN lsb
208 return(adc_voltage);
209 }
210
211 // Calculate the LTC2946 current with a sense resistor
212 float LTC2946_code_to_current(uint16_t adc_code, float resistor, float LTC2946_DELTA_SENSE_lsb)
213 // Returns the LTC2946 current in Amps
214 {
215 float voltage, current;
216 voltage = (float)adc_code*LTC2946_DELTA_SENSE_lsb; //! 1) Calculate voltage from ADC code and delta sense lsb
217 current = voltage/resistor; //! 2) Calculate current, I = V/R
218 return(current);
219 }
220
221 // Calculate the LTC2946 power
222 float LTC2946_code_to_power(int32_t adc_code, float resistor, float LTC2946_Power_lsb)
223 // Returns The LTC2946 power in Watts
224 {
225 float power;
226 power = (float)adc_code*LTC2946_Power_lsb/resistor; //! 1) Calculate Power using Power lsb and resistor
227
228 return(power);
229 }
230
231
232 // Calculate the LTC2946 energy
233 float LTC2946_code_to_energy(int32_t adc_code,float resistor, float LTC2946_Power_lsb, float LTC2946_TIME_lsb)
234 // Returns the LTC2946 energy in Joules
235 {
236 float energy_lsb, energy;
237 energy_lsb=(float)(LTC2946_Power_lsb/resistor)*65536*LTC2946_TIME_lsb; //! 1) Calculate Energy lsb from Power lsb and Time lsb
238 energy = adc_code*energy_lsb; //! 2) Calculate Energy using Energy lsb and adc code
239 return(energy);
240 }
241
242 // Calculate the LTC2946 Coulombs
243 float LTC2946_code_to_coulombs(int32_t adc_code, float resistor, float LTC2946_DELTA_SENSE_lsb, float LTC2946_TIME_lsb)
244 // Returns the LTC2946 Coulombs
245 {
246 float coulomb_lsb, coulombs;
247 coulomb_lsb=(float)(LTC2946_DELTA_SENSE_lsb/resistor)*16*LTC2946_TIME_lsb; //! 1) Calculate Coulomb lsb Current lsb and Time lsb
248 coulombs = adc_code*coulomb_lsb; //! 2) Calculate Coulombs using Coulomb lsb and adc code
249 return(coulombs);
250 }
251
252 //Calculate the LTC2946 Time in Seconds
253 float LTC2946_code_to_time(float time_code, float LTC2946_TIME_lsb)
254 {
255 float seconds;
256 seconds = LTC2946_TIME_lsb * time_code;
257 return seconds;
258 }
259
LTC2946_code_to_energy
float LTC2946_code_to_energy(int32_t adc_code, float resistor, float LTC2946_Power_lsb, float LTC2946_TIME_lsb)
Calculate the LTC2946 energy.
Definition: LTC2946.cpp:233
LTC2946_write_16_bits
int8_t LTC2946_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
Write a 16-bit code to the LTC2946.
Definition: LTC2946.cpp:93
LTC2946_code_to_power
float LTC2946_code_to_power(int32_t adc_code, float resistor, float LTC2946_Power_lsb)
Calculate the LTC2946 power.
Definition: LTC2946.cpp:222
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
LTC2946_ADIN_lsb
const float LTC2946_ADIN_lsb
Typical ADIN lsb weight in volts.
Definition: DC2156.ino:127
resistor
const float resistor
resistor value on demo board
Definition: DC1496BB.ino:116
LTC2946_read
int8_t LTC2946_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
Reads an 8-bit adc_code from LTC2946.
Definition: LTC2946.cpp:130
LTC2946_write_24_bits
int8_t LTC2946_write_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
Write a 24-bit code to the LTC2946.
Definition: LTC2946.cpp:103
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2946_read_16_bits
int8_t LTC2946_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
Reads a 16-bit adc_code from LTC2946.
Definition: LTC2946.cpp:155
LTC2946_read_12_bits
int8_t LTC2946_read_12_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
Reads a 12-bit adc_code from LTC2946.
Definition: LTC2946.cpp:141
LTC2946_VIN_lsb
const float LTC2946_VIN_lsb
Typical VIN lsb weight in volts.
Definition: DC2156.ino:129
adc_voltage
static float adc_voltage
Definition: DC2071AA.ino:115
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
LTC2946_code_to_time
float LTC2946_code_to_time(float time_code, float LTC2946_TIME_lsb)
Calculate the LTC2946 internal time base.
Definition: LTC2946.cpp:253
LTC2946_read_24_bits
int8_t LTC2946_read_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
Reads a 24-bit adc_code from LTC2946.
Definition: LTC2946.cpp:166
LTC2946_ADIN_code_to_voltage
float LTC2946_ADIN_code_to_voltage(uint16_t adc_code, float LTC2946_ADIN_lsb)
Calculate the LTC2946 ADIN voltage.
Definition: LTC2946.cpp:203
LTC2946_write
int8_t LTC2946_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
Write an 8-bit code to the LTC2946.
Definition: LTC2946.cpp:81
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
LTC2946_TIME_lsb
static float LTC2946_TIME_lsb
Static variable which is based off of the default clk frequency of 250KHz.
Definition: DC2156.ino:134
LT_union_int32_4bytes::LT_int32
int32_t LT_int32
32-bit signed integer to be converted to four bytes
Definition: Linduino.h:110
LTC2946_write_32_bits
int8_t LTC2946_write_32_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
Write a 32-bit code to the LTC2946.
Definition: LTC2946.cpp:116
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
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
LTC2946.h
LTC2946: 12-Bit Wide Range Power, Charge and Energy Monitor.
LTC2946_VIN_code_to_voltage
float LTC2946_VIN_code_to_voltage(uint16_t adc_code, float LTC2946_VIN_lsb)
Calculate the LTC2946 VIN voltage.
Definition: LTC2946.cpp:194
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
LTC2946_Power_lsb
const float LTC2946_Power_lsb
Typical POWER lsb weight in V^2 VIN_lsb * DELTA_SENSE_lsb.
Definition: DC2156.ino:130
LTC2946_code_to_current
float LTC2946_code_to_current(uint16_t adc_code, float resistor, float LTC2946_DELTA_SENSE_lsb)
Calculate the LTC2946 current with a sense resistor.
Definition: LTC2946.cpp:212
LTC2946_read_32_bits
int8_t LTC2946_read_32_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
Reads a 32-bit adc_code from LTC2946.
Definition: LTC2946.cpp:180
adc_code
static uint32_t adc_code
Definition: DC2071AA.ino:113
LTC2946_code_to_coulombs
float LTC2946_code_to_coulombs(int32_t adc_code, float resistor, float LTC2946_DELTA_SENSE_lsb, float LTC2946_TIME_lsb)
Calculate the LTC2946 coulombs.
Definition: LTC2946.cpp:243
LTC2946_DELTA_SENSE_lsb
const float LTC2946_DELTA_SENSE_lsb
Typical Delta lsb weight in volts.
Definition: DC2156.ino:128