LTC2945 ported

Dependencies:   mbed

main.cpp

Committer:
odtulumbedder
Date:
2017-09-20
Revision:
4:d32eaca53504
Parent:
3:2ab78e7e8518

File content as of revision 4:d32eaca53504:

/**
 * 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"

/* initialize I2C communications object */
I2C i2c(p28, p27);
/*      sda, scl */

/* 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;

/* 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); }

/*
 * 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);

    /* change I2C frequency, to have it working with optocoupled circuit */
    i2c.frequency(1000);

    /* 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;    // 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);

        /* 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);

        /* 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,
            &current_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);

        /* print it, only 2 digits after dot */
        printf("power: %.2f, current: %.2f, Vin: %.2f\n", power, current, VIN);
        
        /* wait 500 ms */
        wait_ms(500);        
    }
}