library for MAX9611 /9612 Current-Sense Amplifiers
max9611.h@8:1e392bc95666, 2015-01-28 (annotated)
- Committer:
- igbt6
- Date:
- Wed Jan 28 17:53:26 2015 +0000
- Revision:
- 8:1e392bc95666
- Parent:
- 7:012f5b39405e
quick code clean up
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igbt6 | 1:131a836c6b79 | 1 | /* |
igbt6 | 5:6fec24c37e2a | 2 | @file MAX9611.h |
igbt6 | 8:1e392bc95666 | 3 | |
igbt6 | 5:6fec24c37e2a | 4 | @brief MAX9611 High-Side, Current-Sense Amplifiers with |
igbt6 | 8:1e392bc95666 | 5 | 12-Bit ADC and Op Amp/Comparator- Breakout I2C Library |
igbt6 | 1:131a836c6b79 | 6 | |
igbt6 | 1:131a836c6b79 | 7 | @Author lukasz uszko(luszko@op.pl) |
igbt6 | 1:131a836c6b79 | 8 | |
igbt6 | 5:6fec24c37e2a | 9 | Tested on FRDM-KL46Z and FRDM-KL25Z |
igbt6 | 8:1e392bc95666 | 10 | |
igbt6 | 1:131a836c6b79 | 11 | Copyright (c) 2014 luszko |
igbt6 | 1:131a836c6b79 | 12 | Released under the MIT License (see http://mbed.org/license/mit) |
igbt6 | 1:131a836c6b79 | 13 | |
igbt6 | 8:1e392bc95666 | 14 | Documentation regarding the MAX9611 might be found here: |
igbt6 | 5:6fec24c37e2a | 15 | http://datasheets.maximintegrated.com/en/ds/MAX9611-MAX9612.pdf |
igbt6 | 1:131a836c6b79 | 16 | */ |
igbt6 | 1:131a836c6b79 | 17 | |
igbt6 | 7:012f5b39405e | 18 | //DEMO - HOW TO USE: |
igbt6 | 7:012f5b39405e | 19 | // NOTE before first use, do not forget to set mCsaCurrentValueOffset in constructor, it is a value that you can obtain from method: uint16_t readRawCSAOutValue(void), |
igbt6 | 7:012f5b39405e | 20 | // when a current value flowing through shunt resistor equals 0. |
igbt6 | 7:012f5b39405e | 21 | /* |
igbt6 | 7:012f5b39405e | 22 | ---------------------------------------- DEMO: 1 version ---------------------------------------- |
igbt6 | 7:012f5b39405e | 23 | #include "mbed.h" |
igbt6 | 7:012f5b39405e | 24 | #include "max9611.h" |
igbt6 | 7:012f5b39405e | 25 | |
igbt6 | 8:1e392bc95666 | 26 | #define MAX9611_PIN_SDA PTC9 // I2C0 //for example |
igbt6 | 7:012f5b39405e | 27 | #define MAX9611_PIN_SCL PTC8 |
igbt6 | 7:012f5b39405e | 28 | int main() |
igbt6 | 7:012f5b39405e | 29 | { |
igbt6 | 7:012f5b39405e | 30 | MAX9611 max9611(MAX9611_PIN_SDA, MAX9611_PIN_SCL); |
igbt6 | 7:012f5b39405e | 31 | Serial debug(USBTX, USBRX); |
igbt6 | 7:012f5b39405e | 32 | debug.baud(115200); |
igbt6 | 7:012f5b39405e | 33 | while(1) { |
igbt6 | 8:1e392bc95666 | 34 | if(!max9611.readCSAOutputValue()){ |
igbt6 | 7:012f5b39405e | 35 | debug.printf("MAX9611_CSA_Reading ERROR!- check all connections\r\n"); |
igbt6 | 7:012f5b39405e | 36 | } |
igbt6 | 7:012f5b39405e | 37 | else{ |
igbt6 | 7:012f5b39405e | 38 | debug.printf("MAX9611_CSA %5.2f [mA]\r\n", max9611.getCSAOutput()); |
igbt6 | 7:012f5b39405e | 39 | } |
igbt6 | 8:1e392bc95666 | 40 | |
igbt6 | 8:1e392bc95666 | 41 | if(!max9611.readTemp()){ |
igbt6 | 7:012f5b39405e | 42 | debug.printf("MAX9611_TEMP_Reading ERROR!- check all connections\r\n"); |
igbt6 | 7:012f5b39405e | 43 | } |
igbt6 | 7:012f5b39405e | 44 | else{ |
igbt6 | 7:012f5b39405e | 45 | debug.printf("MAX9611_TEMP: %5.2f [C]\r\n", max9611.getTemp()); |
igbt6 | 7:012f5b39405e | 46 | } |
igbt6 | 8:1e392bc95666 | 47 | |
igbt6 | 8:1e392bc95666 | 48 | |
igbt6 | 7:012f5b39405e | 49 | } |
igbt6 | 7:012f5b39405e | 50 | return 0; |
igbt6 | 7:012f5b39405e | 51 | } |
igbt6 | 7:012f5b39405e | 52 | */ |
igbt6 | 7:012f5b39405e | 53 | |
igbt6 | 7:012f5b39405e | 54 | |
igbt6 | 7:012f5b39405e | 55 | |
igbt6 | 1:131a836c6b79 | 56 | |
igbt6 | 1:131a836c6b79 | 57 | |
igbt6 | 5:6fec24c37e2a | 58 | #ifndef MAX9611_H |
igbt6 | 5:6fec24c37e2a | 59 | #define MAX9611_H |
igbt6 | 1:131a836c6b79 | 60 | |
igbt6 | 1:131a836c6b79 | 61 | #include "mbed.h" |
igbt6 | 1:131a836c6b79 | 62 | |
igbt6 | 5:6fec24c37e2a | 63 | #define MAX9611_I2C_ADDRESS 0xE1 //A0 and A1 PIN are conected to GND , Write address 0xE0, Read Address 0xE1 |
igbt6 | 1:131a836c6b79 | 64 | |
igbt6 | 5:6fec24c37e2a | 65 | |
igbt6 | 5:6fec24c37e2a | 66 | |
igbt6 | 8:1e392bc95666 | 67 | |
igbt6 | 8:1e392bc95666 | 68 | |
igbt6 | 8:1e392bc95666 | 69 | |
igbt6 | 8:1e392bc95666 | 70 | class MAX9611 |
igbt6 | 8:1e392bc95666 | 71 | { |
igbt6 | 1:131a836c6b79 | 72 | |
igbt6 | 1:131a836c6b79 | 73 | |
igbt6 | 8:1e392bc95666 | 74 | /**********private members and methods********************************/ |
igbt6 | 8:1e392bc95666 | 75 | private: |
igbt6 | 8:1e392bc95666 | 76 | |
igbt6 | 8:1e392bc95666 | 77 | typedef enum { |
igbt6 | 8:1e392bc95666 | 78 | CHANNEL_A_0=0, /*Read current-sense amplifier output from ADC, gain = 1x*/ |
igbt6 | 8:1e392bc95666 | 79 | CHANNEL_A_1, /*Read current-sense amplifier output from ADC, gain = 4x*/ |
igbt6 | 8:1e392bc95666 | 80 | CHANNEL_A_2, /*Read current-sense amplifier output from ADC, gain = 8x*/ |
igbt6 | 8:1e392bc95666 | 81 | CHANNEL_B, /*Read average voltage of RS+ (input common-mode voltage) from ADC*/ |
igbt6 | 8:1e392bc95666 | 82 | CHANNEL_C, /*Read voltage of OUT from ADC*/ |
igbt6 | 8:1e392bc95666 | 83 | CHANNEL_D, /*Read voltage of SET from ADC*/ |
igbt6 | 8:1e392bc95666 | 84 | CHANNEL_E, /*Read internal die temperature from ADC*/ |
igbt6 | 8:1e392bc95666 | 85 | ALL_CHANNELS /*Read all channels in fast-read mode, sequentially every 2ms. Uses last gain setting.*/ |
igbt6 | 8:1e392bc95666 | 86 | } eCtrlReg1MUX; |
igbt6 | 8:1e392bc95666 | 87 | |
igbt6 | 8:1e392bc95666 | 88 | typedef enum { |
igbt6 | 8:1e392bc95666 | 89 | NORMAL_OPERATION_SHDN=0, |
igbt6 | 8:1e392bc95666 | 90 | SHUTDOWN_MODE |
igbt6 | 8:1e392bc95666 | 91 | } eCtrlReg1SHDN; |
igbt6 | 8:1e392bc95666 | 92 | |
igbt6 | 8:1e392bc95666 | 93 | typedef enum { |
igbt6 | 8:1e392bc95666 | 94 | NORMAL_OPERATION_LR=0, |
igbt6 | 8:1e392bc95666 | 95 | RESET |
igbt6 | 8:1e392bc95666 | 96 | } eCtrlReg1LR; |
igbt6 | 8:1e392bc95666 | 97 | |
igbt6 | 8:1e392bc95666 | 98 | typedef enum { |
igbt6 | 8:1e392bc95666 | 99 | NORMAL_OPERATION_MODE=0, |
igbt6 | 8:1e392bc95666 | 100 | COMPARATOR_MODE=7, |
igbt6 | 8:1e392bc95666 | 101 | OPAMP_MODE=3 |
igbt6 | 8:1e392bc95666 | 102 | } eCtrlReg1MODE; |
igbt6 | 8:1e392bc95666 | 103 | |
igbt6 | 8:1e392bc95666 | 104 | //watchdog delay time |
igbt6 | 8:1e392bc95666 | 105 | typedef enum { |
igbt6 | 8:1e392bc95666 | 106 | _1MS=0, |
igbt6 | 8:1e392bc95666 | 107 | _100US=1 |
igbt6 | 8:1e392bc95666 | 108 | } eCtrlReg2DTIM; |
igbt6 | 8:1e392bc95666 | 109 | |
igbt6 | 8:1e392bc95666 | 110 | //watchdog retry delay time |
igbt6 | 8:1e392bc95666 | 111 | typedef enum { |
igbt6 | 8:1e392bc95666 | 112 | _50MS=0, |
igbt6 | 8:1e392bc95666 | 113 | _10MS=1 |
igbt6 | 8:1e392bc95666 | 114 | } eCtrlReg2RTIM; |
igbt6 | 8:1e392bc95666 | 115 | |
igbt6 | 8:1e392bc95666 | 116 | //watchdog retry delay time |
igbt6 | 8:1e392bc95666 | 117 | typedef enum { |
igbt6 | 8:1e392bc95666 | 118 | CSA_DATA_BYTE_MSB_ADRR= 0x00, |
igbt6 | 8:1e392bc95666 | 119 | CSA_DATA_BYTE_LSB_ADRR= 0x01, |
igbt6 | 8:1e392bc95666 | 120 | RS_DATA_BYTE_MSB_ADRR= 0x02, |
igbt6 | 8:1e392bc95666 | 121 | RS_DATA_BYTE_LSB_ADRR= 0x03, |
igbt6 | 8:1e392bc95666 | 122 | OUT_DATA_BYTE_MSB_ADRR= 0x04, |
igbt6 | 8:1e392bc95666 | 123 | OUT_DATA_BYTE_LSB_ADRR= 0x05, |
igbt6 | 8:1e392bc95666 | 124 | SET_DATA_BYTE_MSB_ADRR= 0x06, |
igbt6 | 8:1e392bc95666 | 125 | SET_DATA_BYTE_LSB_ADRR= 0x07, |
igbt6 | 8:1e392bc95666 | 126 | TEMP_DATA_BYTE_MSB_ADRR= 0x08, |
igbt6 | 8:1e392bc95666 | 127 | TEMP_DATA_BYTE_LSB_ADRR= 0x09, |
igbt6 | 8:1e392bc95666 | 128 | CONTROL_REGISTER_1_ADRR= 0x0A, |
igbt6 | 8:1e392bc95666 | 129 | CONTROL_REGISTER_2_ADRR= 0x0B |
igbt6 | 8:1e392bc95666 | 130 | } eRegAddresses; |
igbt6 | 8:1e392bc95666 | 131 | |
igbt6 | 8:1e392bc95666 | 132 | |
igbt6 | 8:1e392bc95666 | 133 | |
igbt6 | 1:131a836c6b79 | 134 | /** Write data to the given register |
igbt6 | 8:1e392bc95666 | 135 | * |
igbt6 | 1:131a836c6b79 | 136 | * @returns |
igbt6 | 1:131a836c6b79 | 137 | * 1 on success, |
igbt6 | 1:131a836c6b79 | 138 | * 0 on error |
igbt6 | 8:1e392bc95666 | 139 | */ |
igbt6 | 5:6fec24c37e2a | 140 | bool write(uint8_t regAddress, uint8_t* data,int dataLength); |
igbt6 | 8:1e392bc95666 | 141 | |
igbt6 | 2:d12dffd027a8 | 142 | /** Write data to the given register |
igbt6 | 2:d12dffd027a8 | 143 | * @param register Address |
igbt6 | 2:d12dffd027a8 | 144 | * @param data to read |
igbt6 | 8:1e392bc95666 | 145 | * @param length of data to read |
igbt6 | 2:d12dffd027a8 | 146 | * @returns |
igbt6 | 2:d12dffd027a8 | 147 | * 1 on success, |
igbt6 | 2:d12dffd027a8 | 148 | * 0 on error |
igbt6 | 8:1e392bc95666 | 149 | */ |
igbt6 | 5:6fec24c37e2a | 150 | bool read(uint8_t regAddress, uint8_t* data,int length); |
igbt6 | 8:1e392bc95666 | 151 | |
igbt6 | 8:1e392bc95666 | 152 | |
igbt6 | 8:1e392bc95666 | 153 | /** Make 12 bit data from 2 bytes received from thr device data read from Data regiters of Max9611/9612 are laid in the following way : |
igbt6 | 8:1e392bc95666 | 154 | * Byte 1: bit7-MSB12........bit0-MSB05 ; Byte 2: bit7-LSB04.... bit4-LSB00 |
igbt6 | 5:6fec24c37e2a | 155 | * @param MSB byte |
igbt6 | 5:6fec24c37e2a | 156 | * @param 4 bits of LSB bytes |
igbt6 | 5:6fec24c37e2a | 157 | * @returns 1 2bit data |
igbt6 | 8:1e392bc95666 | 158 | * |
igbt6 | 8:1e392bc95666 | 159 | */ |
igbt6 | 8:1e392bc95666 | 160 | inline uint16_t get12BitData(uint8_t msbByte,uint8_t lsbByte) { |
igbt6 | 5:6fec24c37e2a | 161 | uint16_t data12Bit= (msbByte<<4)|((lsbByte>>4)&0x0F); |
igbt6 | 8:1e392bc95666 | 162 | return data12Bit; |
igbt6 | 5:6fec24c37e2a | 163 | } |
igbt6 | 8:1e392bc95666 | 164 | |
igbt6 | 8:1e392bc95666 | 165 | |
igbt6 | 8:1e392bc95666 | 166 | inline uint16_t get9BitData(uint8_t msbByte,uint8_t lsbByte) { |
igbt6 | 5:6fec24c37e2a | 167 | uint16_t data9Bit= (msbByte<<1)|((lsbByte>>6)&0x01); |
igbt6 | 8:1e392bc95666 | 168 | return data9Bit; |
igbt6 | 8:1e392bc95666 | 169 | } |
igbt6 | 8:1e392bc95666 | 170 | |
igbt6 | 6:32b5eb1df932 | 171 | |
igbt6 | 8:1e392bc95666 | 172 | /** Compute a value of current coefficient to be used to mulitiple by rawData obained from CSA output in order to getting real current value in [mA] |
igbt6 | 8:1e392bc95666 | 173 | * @param empty |
igbt6 | 8:1e392bc95666 | 174 | * @returns coefficient that you can used to get real value of measured current depending on muxReg value |
igbt6 | 8:1e392bc95666 | 175 | * |
igbt6 | 8:1e392bc95666 | 176 | */ |
igbt6 | 8:1e392bc95666 | 177 | inline float getCSACurrentCoeffmA(void) { |
igbt6 | 8:1e392bc95666 | 178 | float coeff=1; |
igbt6 | 8:1e392bc95666 | 179 | switch(mMuxReg) { |
igbt6 | 8:1e392bc95666 | 180 | case CHANNEL_A_0: /*gain = 1x*/ |
igbt6 | 8:1e392bc95666 | 181 | coeff=1.075; |
igbt6 | 8:1e392bc95666 | 182 | break; |
igbt6 | 8:1e392bc95666 | 183 | case CHANNEL_A_1: /*gain = 4x*/ |
igbt6 | 8:1e392bc95666 | 184 | coeff=0.269; |
igbt6 | 8:1e392bc95666 | 185 | break; |
igbt6 | 8:1e392bc95666 | 186 | case CHANNEL_A_2: /*gain = 8x*/ |
igbt6 | 8:1e392bc95666 | 187 | coeff=0.134; |
igbt6 | 8:1e392bc95666 | 188 | break; |
igbt6 | 8:1e392bc95666 | 189 | default: |
igbt6 | 8:1e392bc95666 | 190 | break; |
igbt6 | 8:1e392bc95666 | 191 | } |
igbt6 | 8:1e392bc95666 | 192 | return coeff; |
igbt6 | 5:6fec24c37e2a | 193 | } |
igbt6 | 8:1e392bc95666 | 194 | |
igbt6 | 8:1e392bc95666 | 195 | /**********protected members********************************/ |
igbt6 | 8:1e392bc95666 | 196 | protected: |
igbt6 | 8:1e392bc95666 | 197 | |
igbt6 | 8:1e392bc95666 | 198 | I2C mI2c; |
igbt6 | 6:32b5eb1df932 | 199 | int mI2cAddr; |
igbt6 | 8:1e392bc95666 | 200 | float mTemperature; |
igbt6 | 6:32b5eb1df932 | 201 | float mCurrentSenseAmplifierOutput; |
igbt6 | 8:1e392bc95666 | 202 | uint16_t mCsaCurrentValueOffset; //this parameter depends on your sensor |
igbt6 | 8:1e392bc95666 | 203 | uint8_t mMuxReg;// |
igbt6 | 8:1e392bc95666 | 204 | |
igbt6 | 8:1e392bc95666 | 205 | |
igbt6 | 8:1e392bc95666 | 206 | /**********public methods********************************/ |
igbt6 | 8:1e392bc95666 | 207 | public: |
igbt6 | 6:32b5eb1df932 | 208 | |
igbt6 | 6:32b5eb1df932 | 209 | /** Create an MAX9611 instance |
igbt6 | 8:1e392bc95666 | 210 | * @param sda pin |
igbt6 | 8:1e392bc95666 | 211 | * @param scl pin |
igbt6 | 8:1e392bc95666 | 212 | * @param address: I2C slave address |
igbt6 | 6:32b5eb1df932 | 213 | */ |
igbt6 | 8:1e392bc95666 | 214 | MAX9611(PinName sda, PinName scl,int i2cFrequency=100000,int address = MAX9611_I2C_ADDRESS); |
igbt6 | 6:32b5eb1df932 | 215 | |
igbt6 | 6:32b5eb1df932 | 216 | |
igbt6 | 6:32b5eb1df932 | 217 | /** Create a MAX9611 instance |
igbt6 | 6:32b5eb1df932 | 218 | * @param i2c object |
igbt6 | 8:1e392bc95666 | 219 | * @param address: I2C slave address |
igbt6 | 6:32b5eb1df932 | 220 | */ |
igbt6 | 8:1e392bc95666 | 221 | MAX9611(I2C& i2c, int address = MAX9611_I2C_ADDRESS); |
igbt6 | 6:32b5eb1df932 | 222 | |
igbt6 | 6:32b5eb1df932 | 223 | |
igbt6 | 8:1e392bc95666 | 224 | /** Initialization: set member values and configuration registers, ought to be invoked in the body of constructor |
igbt6 | 6:32b5eb1df932 | 225 | * @returns |
igbt6 | 6:32b5eb1df932 | 226 | * true on success, |
igbt6 | 6:32b5eb1df932 | 227 | * false on error |
igbt6 | 6:32b5eb1df932 | 228 | */ |
igbt6 | 8:1e392bc95666 | 229 | bool initMax9611(eCtrlReg1MUX mux= CHANNEL_A_1, |
igbt6 | 8:1e392bc95666 | 230 | eCtrlReg1SHDN shdn= NORMAL_OPERATION_SHDN, |
igbt6 | 8:1e392bc95666 | 231 | eCtrlReg1LR lr=NORMAL_OPERATION_LR, |
igbt6 | 8:1e392bc95666 | 232 | eCtrlReg1MODE mode= NORMAL_OPERATION_MODE, |
igbt6 | 8:1e392bc95666 | 233 | eCtrlReg2DTIM watchdogDelay= _1MS, |
igbt6 | 8:1e392bc95666 | 234 | eCtrlReg2RTIM watchdogRetryDelay=_50MS); |
igbt6 | 6:32b5eb1df932 | 235 | |
igbt6 | 6:32b5eb1df932 | 236 | |
igbt6 | 6:32b5eb1df932 | 237 | /** Read temperature from the MAX9611. |
igbt6 | 6:32b5eb1df932 | 238 | * @param none |
igbt6 | 6:32b5eb1df932 | 239 | * @returns |
igbt6 | 6:32b5eb1df932 | 240 | * 1 on success, |
igbt6 | 6:32b5eb1df932 | 241 | * 0 on error |
igbt6 | 8:1e392bc95666 | 242 | */ |
igbt6 | 6:32b5eb1df932 | 243 | bool readTemp(void); |
igbt6 | 8:1e392bc95666 | 244 | |
igbt6 | 8:1e392bc95666 | 245 | |
igbt6 | 8:1e392bc95666 | 246 | /** Get temperature from the last measurement |
igbt6 | 8:1e392bc95666 | 247 | * |
igbt6 | 6:32b5eb1df932 | 248 | * @returns |
igbt6 | 6:32b5eb1df932 | 249 | * temperature (C) |
igbt6 | 8:1e392bc95666 | 250 | */ |
igbt6 | 8:1e392bc95666 | 251 | inline float getTemp(void) { |
igbt6 | 8:1e392bc95666 | 252 | return mTemperature; |
igbt6 | 8:1e392bc95666 | 253 | } |
igbt6 | 8:1e392bc95666 | 254 | |
igbt6 | 8:1e392bc95666 | 255 | |
igbt6 | 8:1e392bc95666 | 256 | /** Read CSA output value from the MAX9611. |
igbt6 | 8:1e392bc95666 | 257 | * @param none |
igbt6 | 8:1e392bc95666 | 258 | * @returns |
igbt6 | 8:1e392bc95666 | 259 | * 1 on success, |
igbt6 | 8:1e392bc95666 | 260 | * 0 on error |
igbt6 | 8:1e392bc95666 | 261 | */ |
igbt6 | 6:32b5eb1df932 | 262 | bool readCSAOutputValue(void); |
igbt6 | 8:1e392bc95666 | 263 | |
igbt6 | 6:32b5eb1df932 | 264 | |
igbt6 | 8:1e392bc95666 | 265 | /** Get value of CSA output from the last measurement |
igbt6 | 8:1e392bc95666 | 266 | * |
igbt6 | 8:1e392bc95666 | 267 | * @returns |
igbt6 | 8:1e392bc95666 | 268 | * Current Value [mA] |
igbt6 | 8:1e392bc95666 | 269 | */ |
igbt6 | 8:1e392bc95666 | 270 | inline float getCSAOutput(void) { |
igbt6 | 8:1e392bc95666 | 271 | return mCurrentSenseAmplifierOutput; |
igbt6 | 8:1e392bc95666 | 272 | } |
igbt6 | 6:32b5eb1df932 | 273 | |
igbt6 | 8:1e392bc95666 | 274 | //DEBUG |
igbt6 | 8:1e392bc95666 | 275 | uint16_t mRawInt; |
igbt6 | 8:1e392bc95666 | 276 | uint16_t readRawControl(void); |
igbt6 | 8:1e392bc95666 | 277 | uint16_t readRawCSAOutValue(void); |
igbt6 | 8:1e392bc95666 | 278 | uint16_t readRawRsValue(void); |
igbt6 | 8:1e392bc95666 | 279 | uint16_t readRawOutValue(void); |
igbt6 | 8:1e392bc95666 | 280 | |
igbt6 | 8:1e392bc95666 | 281 | |
igbt6 | 8:1e392bc95666 | 282 | |
igbt6 | 1:131a836c6b79 | 283 | }; |
igbt6 | 1:131a836c6b79 | 284 | |
igbt6 | 1:131a836c6b79 | 285 | #endif |