Canberk Sönmez
/
LTC2945_Monitor
LTC2945 ported
Diff: main.cpp
- Revision:
- 3:2ab78e7e8518
- Parent:
- 2:7e390bcce297
--- a/main.cpp Fri Aug 25 07:46:48 2017 +0000 +++ b/main.cpp Fri Aug 25 14:42:14 2017 +0000 @@ -1,63 +1,121 @@ -#include "mbed.h" +/** + * Canberk Sönmez, + * code is taken from the official tutorial for Linduino platform. + * + * I couldn't get power measurement working. + */ + +#include <mbed.h> #include <I2C.h> #include "LT_I2C.h" #include "LTC2945.h" -I2C i2c(p9, p10); -// sda, scl +/* initialize I2C communications object */ +I2C i2c(p28, p27); +/* sda, scl */ -extern I2C* i2c_object; - -Serial pc(USBTX, USBRX); - +/* LTC2945 I2C address, it's shifted 1 bit right, + * as it's given in 8-bit form in the datasheet, + * and the library does shifting again, causing + * communication problems + * 0xDE, since ADR0 and ADR1 are both grounded. */ const int ltc2945_addr = 0xDE>>1; -int test_write(int byte) { - return i2c_object->write(byte); -} +/* ASSERT macro, reports debugging information if + * the condition inside paranthesis is not satisfied. */ +#define ASSERT(x) if (! (x)) { printf("%s:%d %s failed!\n", \ + __FILE__, __LINE__, #x); } -#define ASSERT(x) if (! (x)) { printf("%s:%d %s failed!\n", __FILE__, __LINE__, #x); } -#define DEBUG_LINE printf("DEBUG: %s:%d\n", __FILE__, __LINE__); +/* + * Program entry point. + */ +int main() { + /* initialize ported LT_I2C library and check if it's fine */ + ASSERT(lt_i2c_init_attach(&i2c) == LT_I2C_INIT_FINE); -int main() { - ASSERT(lt_i2c_init_attach(&i2c) == LT_I2C_INIT_FINE); - i2c.frequency(10000); + /* change I2C frequency, to have it working with optocoupled circuit */ + i2c.frequency(1000); - const float LTC2945_DELTA_SENSE_lsb = 2.5006105E-05; //!< Typical Delta lsb weight in volts - const float LTC2945_VIN_lsb = 2.5006105E-02; //!< Typical VIN lsb weight in volts - const float LTC2945_Power_lsb = 6.25305E-07; //!< Typical POWER lsb weight in V^2 + /* typical LSB values, LSB is the smallest change in the value per least + * significant bit. */ + // typical deltaSense LSB weight in volts + const float LTC2945_DELTA_SENSE_lsb = 2.5006105E-05; + // typical Vin LSB in volts + const float LTC2945_VIN_lsb = 2.5006105E-02; + // typical POWER LSB in V^2 + const float LTC2945_Power_lsb = 6.25305E-07; + // power code, which is read as an integer and converted later int32_t power_code; + // current code (same as above) uint16_t current_code; + // Vin code (same as above) uint16_t VIN_code; + // adc command is constructed and sent to the LTC2945 uint8_t adc_command; + // ACKnowledge bit, received if the operation is successful int8_t ack; + // resistance value float resistor; + // calculated power value float power; + // calculated current value float current; + // calculated VIN value float VIN; + // the resistance value (calibrate if necessary) + resistor = 0.26518f; + + // we are in an infinite loop, continuously print values while (true) { - ack = 0; - adc_command = LTC2945_SENSE_MONITOR | LTC2945_CONTINUOUS_MODE; // Builds commands to set LTC2945 to continuous mode - ack |= LTC2945_write(ltc2945_addr, LTC2945_CONTROL_REG, adc_command); // Sets the LTC2945 to continuous mode - ASSERT(ack == 0); - resistor = .0182445; // Resistor Value On Demo Board + ack = 0; // never forget resetting ack + // build adc_command, set LTC2945 in continuous mode + adc_command = LTC2945_SENSE_MONITOR | LTC2945_CONTINUOUS_MODE; + /* send command by LTC2945_write command. + * we use |= here not &= to accumulate success state + * as in the API 0 means successful, and 1 means failure. + * if we have ACKnowledge, then we are successful */ + ack |= LTC2945_write(ltc2945_addr, LTC2945_CONTROL_REG, adc_command); - ack |= LTC2945_read_24_bits(ltc2945_addr, LTC2945_POWER_MSB2_REG, &power_code); // Reads the ADC registers that contains V^2 - ASSERT(ack == 0); - power = LTC2945_code_to_power(power_code, resistor, LTC2945_Power_lsb); // Calculates power from power code, resistor value and power lsb + /* read LTC2945_POWER_MSB2_REG register, containing power code + * (it's a 24-bit register) */ + ack |= LTC2945_read_24_bits( + ltc2945_addr, + LTC2945_POWER_MSB2_REG, + &power_code); + /* and convert it to power, using LTC2945_code_to_power */ + power = LTC2945_code_to_power(power_code, resistor, LTC2945_Power_lsb); - ack |= LTC2945_read_12_bits(ltc2945_addr, LTC2945_DELTA_SENSE_MSB_REG, ¤t_code); // Reads the voltage code across sense resistor + /* read LTC2945_DELTA_SENSE_MSB_REG register, containing deltaSENSE + * voltage code (it's a 12-bit register) */ + ack |= LTC2945_read_12_bits( + ltc2945_addr, + LTC2945_DELTA_SENSE_MSB_REG, + ¤t_code); + /* and convert it to current using resistance + * via LTC2945_code_to_current */ + current = LTC2945_code_to_current( + current_code, + resistor, + LTC2945_DELTA_SENSE_lsb); + + /* read LTC2945_VIN_MSB_REG register, containing Vin voltage code + * (it's a 12-bit register) */ + ack |= LTC2945_read_12_bits( + ltc2945_addr, + LTC2945_VIN_MSB_REG, + &VIN_code); + /* and convert it to voltage directly */ + VIN = LTC2945_VIN_code_to_voltage(VIN_code, LTC2945_VIN_lsb); + + /* we must have ack = 0 if all the operations above are successful! */ ASSERT(ack == 0); - current = LTC2945_code_to_current(current_code, resistor, LTC2945_DELTA_SENSE_lsb); // Calculates current from current code, resistor value and current lsb - - ack |= LTC2945_read_12_bits(ltc2945_addr, LTC2945_VIN_MSB_REG, &VIN_code); // Reads VIN voltage code - ASSERT(ack == 0); - VIN = LTC2945_VIN_code_to_voltage(VIN_code, LTC2945_VIN_lsb); // Calculates VIN voltage from VIN code and lsb - - printf("power: %f, current: %f, Vin: %f\n", power, current, VIN); + /* print it, only 2 digits after dot */ + printf("power: %.2f, current: %.2f, Vin: %.2f\n", power, current, VIN); + + /* wait 500 ms */ wait_ms(500); } }