Used for testing battery sense circuit, looking for max and min levels. Allow for finding true empty, half and full values for driving LEDs for example

Dependencies:   mbed MPL3115A2 TSI WiGo_BattCharger

main.cpp

Committer:
monpjc
Date:
2013-09-03
Revision:
5:4438d5665b4f
Parent:
3:3b88d6ae24f2

File content as of revision 5:4438d5665b4f:

#include "mbed.h"
#include "WiGo_BattCharger.h"
#include "TSISensor.h"
#include "math.h"
#include "MPL3115A2.h"
#include "main.h"
 
MPL3115A2 wigo_sensor1(PTE0, PTE1, MPL3115A2_I2C_ADDRESS);

// Some LEDs for showing status
DigitalOut redLed(LED_RED);
DigitalOut greenLed(LED_GREEN);
DigitalOut blueLed(LED_BLUE);

// test analog input pin
AnalogIn NTC(PTE20);
AnalogIn testPin1(PTE30);
AnalogIn testPin2(PTE22);
AnalogIn testPin3(PTC0);
AnalogIn testPin4(PTE29);
AnalogIn testPin5(PTD1);

// Slide sensor acts as a button
TSISensor tsi;

// I2C used to communicate with sensor
I2C i2c(PTE0, PTE1);

int avgX, avgY, newX, tempXmin, tempXmax, newY, tempYmin, tempYmax;
// Ideally these would be saved in eeprom/flash
struct settings_t {
    long maxX, minX, maxY, minY;
}
settings;

const int addr = MAG_ADDR;

Serial pc(USBTX, USBRX);

WiGo_BattCharger Batt( BATT_LOW, BATT_MED, BATT_FULL, CHRG_EN1, CHRG_EN2, CHRG_SNS_EN, CHRG_SNS, CHRG_POK, CHRG_CHG);

// Read a single byte form 8 bit register, return as int
int readReg(char regAddr)
{
    char cmd[1];

    cmd[0] = regAddr;
    i2c.write(addr, cmd, 1);

    cmd[0] = 0x00;
    i2c.read(addr, cmd, 1);
    return (int)( cmd[0]);
}

// read a register per, pass first reg value, reading 2 bytes increments register
// Reads MSB first then LSB
int readVal(char regAddr)
{
    char cmd[2];

    cmd[0] = regAddr;
    i2c.write(addr, cmd, 1);

    cmd[0] = 0x00;
    cmd[1] = 0x00;
    i2c.read(addr, cmd, 2);
    return (int)( (cmd[1]|(cmd[0] << 8))); //concatenate the MSB and LSB
}

void initMag() {
    char cmd[2];

    cmd[0] = MAG_CTRL_REG2;
    cmd[1] = 0x80;
    i2c.write(addr, cmd, 2);

    cmd[0] = MAG_CTRL_REG1;
    cmd[1] = MAG_3110_SAMPLE80+MAG_3110_OVERSAMPLE2+MAG_3110_ACTIVE; // 0x91;
    i2c.write(addr, cmd, 2);
    }
    
void calXY() //magnetometer calibration: finding max and min of X, Y axis
{
    int tempXmax, tempXmin, tempYmax, tempYmin, newX, newY;
    redLed = ON;

    printf("Waiting for initial press\n");
    // Wait for slider to be pressed
    while( tsi.readDistance() == 0 ) {
        redLed = ON;
        wait(0.2);
        redLed = OFF;
        wait(0.2);
    }
    
    printf("Waiting for release\n");

    // Wait for release
    while( tsi.readDistance() != 0 ) {
        redLed = OFF;
        wait(0.2);
        redLed = ON;
        wait(0.2);
    }
    redLed = OFF;
    wait(0.5);
    
    printf("Rotate\n");
        
    tempXmax = tempXmin = readVal(MAG_OUT_X_MSB);
    tempYmax = tempYmin = readVal(MAG_OUT_Y_MSB);

    while(tsi.readDistance() == 0) {
        greenLed = ON;
        wait(0.1);
        greenLed = OFF;
        wait(0.1);
        newX = readVal(MAG_OUT_X_MSB);
        newY = readVal(MAG_OUT_Y_MSB);
        if (newX > tempXmax) tempXmax = newX;
        if (newX < tempXmin) tempXmin = newX;
        if (newY > tempYmax) tempYmax = newY;
        if (newY < tempYmin) tempYmin = newY;
    }

    settings.maxX = tempXmax;
    settings.minX = tempXmin;
    settings.maxY = tempYmax;
    settings.minY = tempYmin;

    //store new X, Y values in EEPROM/Flash

    // Calculate average from min/max
    avgX=(settings.maxX+settings.minX)/2;
    avgY=(settings.maxY+settings.minY)/2;

    // Wait for release
    while( tsi.readDistance() != 0 ) {
        greenLed = OFF;
        wait(0.2);
        greenLed = ON;
        wait(0.2);
    }
    greenLed = OFF;
    wait(1.0);
}

// ================================ MAIN CODE ================================

float max_batt;
float batt_lvl;
float sensor_data[2];
float testVoltage;

int main()
{
    //unsigned int mode=1;
    
    testVoltage = testPin.read();
    
    Batt.init(CHRG_500MA);
    Batt.sense_en(1);
    wait(0.5);
    max_batt = Batt.read();
    wigo_sensor1.Oversample_Ratio( OVERSAMPLE_RATIO_32);
    wigo_sensor1.Barometric_Mode();

    printf("MAG3110 Test\n");

    redLed = OFF;
    greenLed = OFF;
    blueLed = OFF;
    
    initMag();

    // Get some values
    printf("DR_STATUS %X\n", readReg( MAG_DR_STATUS ));
    printf("WHO_AM_I %X\n", readReg( MAG_WHO_AM_I ));
    printf("SYSMOD %X\n", readReg( MAG_SYSMOD ));
    printf("DIE_TEMP %d\n", readReg( MAG_DIE_TEMP ));

    printf("OFF_X %d\n", readVal( MAG_OFF_X_MSB ));
    printf("OFF_Y %d\n", readVal( MAG_OFF_Y_MSB ));
    printf("OFF_Z %d\n", readVal( MAG_OFF_Z_MSB ));

    printf("CTRL_REG1 %X\n", readReg( MAG_CTRL_REG1 ));
    printf("CTRL_REG2 %X\n", readReg( MAG_CTRL_REG2 ));

    // Mag calibration or store defaults
    //===================================
    //printf("calibrate\n");
    //calXY();
    //printf("....Finished\n");
    //printf("avgX = %d, avgY = %d\n", avgX, avgY);
    avgX = 64366;
    avgY = 1624;

    redLed = OFF;
    greenLed = OFF;
    blueLed = OFF;

    while(1) {

        wait(2);
        int xVal = readVal(MAG_OUT_X_MSB);
        int yVal = readVal(MAG_OUT_Y_MSB);
        int zVal = readVal(MAG_OUT_Z_MSB);
        float heading = (atan2((double)(yVal-avgY),(double)(xVal-avgX)))*180/PI;
        
        // Do something with heading - display direction and turn on blue LED if heading approx north
        if (abs(heading) <= 22.5) { printf("N\n"); blueLed = ON; } else blueLed = OFF;
        if (abs(heading) >= 157.5) printf("S\n");
        if (heading >= 67.5 && heading <= 112.5) printf("E \n");
        if (heading <= -67.5 && heading >= -112.5) printf("W \n");
        if (heading > 22.5 && heading < 67.5) printf("NE\n");
        if (heading < -22.5 && heading > -67.5) printf("NW\n");
        if (heading > 112.5 && heading < 157.5) printf("SE\n");
        if (heading < -112.5 && heading > -157.5) printf("SW\n");

        if (heading < 0) heading += 360.0;
        //printf("xVal - avgX = %d, yVal - avgY = %d  ", xVal-avgX, yVal-avgY);
        //printf("X = %d, Y = %d, Z = %d, Heading %f\n", xVal, yVal, zVal, heading);
        printf("Heading %f\n", heading);

        Batt.LEDupdate(1);

        batt_lvl = Batt.read();
        if( batt_lvl > max_batt ) {
            max_batt = batt_lvl;
        }

        pc.printf("Batt = %f Max:%f %i%\n", batt_lvl, max_batt, Batt.level());
        
        if ( wigo_sensor1.isDataAvailable()) {
            wigo_sensor1.getAllData( &sensor_data[0]);
            pc.printf("Bar: %f\tTemperature: %f\n", sensor_data[0]/100, sensor_data[1]);
        }
        
        //if ( mode & 0x0001) {
        //    pc.printf("\tPressure: %f\tTemperature: %f\r\n", sensor_data[0], sensor_data[1]);
        //    wigo_sensor1.Altimeter_Mode();
        //} else {
        //    pc.printf("\Altitude: %f\tTemperature: %f\r\n", sensor_data[0], sensor_data[1]);
        //    wigo_sensor1.Barometric_Mode();
        //}
        //mode++;
        
        //testVoltage = testPin.read();
        //pc.printf("testVoltage  = %f\n", testVoltage );
        //testVoltage = testPin1.read();
        //pc.printf("testVoltage1 = %f\n", testVoltage );
        //testVoltage = testPin2.read();
        //pc.printf("testVoltage2 = %f\n", testVoltage );
        //testVoltage = testPin3.read();
        //pc.printf("testVoltage3 = %f\n", testVoltage );
        //testVoltage = testPin4.read();
        //pc.printf("testVoltage4 = %f\n", testVoltage );
        pc.printf("------------------------------------------------\n");
        
    }
}