Initial commit

Dependencies:   FastPWM Lamp_Intensity_Lock_withTempCo mbed

Fork of Lamp_Intensity_Lock_withTempCo by Medic

main.cpp

Committer:
laserdad
Date:
2016-12-28
Revision:
0:d4187a097285
Child:
1:2d9d931c8484

File content as of revision 0:d4187a097285:

#include "mbed.h"

#define TMD2772_Addr 0x72 //this is the 8-bit address
const uint8_t ALSDataRegister = 0x14;
const uint8_t waitIntervals = 100; //number of 2.73 ms waits
const int measPeriod_ms = 699;


I2C i2c(I2C_SDA,I2C_SCL);
Serial pc(USBTX,USBRX); //open serial port (optionally add baud rate after specifying TX and RX pins)
Timer t;
PwmOut mypwm(PA_1);

void writeRegister(uint8_t addr, uint8_t reg, uint8_t val) {
 /*writes 1 byte to a single register*/
    char writeData[2];
    writeData[0] = reg | 0x80;
    writeData[1] = val;
    i2c.write(addr,writeData, 2);
}

void writeBlock(uint8_t addr, uint8_t startReg, uint8_t *data, uint8_t numBytes) {
/*writes data from an array beginning at the startReg*/
    char writeData[numBytes+1];
    writeData[0]=startReg | 0x80;
    for(int n=1;n<numBytes;n++) {
        writeData[n]=data[n-1];
    }
    i2c.write(addr,writeData,numBytes+1);
}

void readBlock(uint8_t addr, uint8_t startReg, char *data, int numBytes) {
    char writeData = startReg | 0x80;
    i2c.write(addr,&writeData,1,true);
    i2c.read(addr,data,numBytes);
}

uint16_t LSB_MSB_2uint16(char *data) {
/*returns an unsinged 16 bit integer from a 2 data bytes, where the second byte is the MSB*/
    return ((uint16_t)data[1] << 8) + (uint16_t)data[0];
}

void regDump(uint8_t Addr, uint8_t startByte, uint8_t endByte) {
/*print the values of up to 20 registers*/
    char regData[20];
    int numBytes;
    if (endByte>=startByte) {
        numBytes =  (endByte-startByte+1) < 20 ? (endByte-startByte+1) : 20;
    }
    else {
        numBytes=1;
    }    
        
    regData[0] = startByte | 0x80;
    i2c.write(TMD2772_Addr,regData,1,true);
    i2c.read(TMD2772_Addr, regData, numBytes);
    for(int n=0;n<numBytes;n++) {
      pc.printf("%X \r\n", regData[n]);
    }
}



void initTMD2772(void) {
    writeRegister(TMD2772_Addr,0x00,0x0B);// Set power on, ALS enabled, Wait enabled, Interrupts enabled (register 0)
    writeRegister(TMD2772_Addr,0x01,0x00);//ALS time register - 0x00 is max integration time of 699ms (register 1) 
    writeRegister(TMD2772_Addr,0x03,0xFF-waitIntervals); // Wtime = 2.73 ms * delay peroids (subtract from 0xFF to enter into register)
    writeRegister(TMD2772_Addr,0x0D,0x04); //optionally scale ALS gain by 0.16 by seleting 0x04;
//    writeRegister(TMD2772_Addr,0x0D,0x00); //optionally scale ALS gain by 0.16 by seleting 0x04;

    writeRegister(TMD2772_Addr,0x0F,0x00); //ALS gain is 1x
}

int main() {
    float ratio;
    char data[4];
    uint16_t ch0Data;
    uint16_t ch1Data;
    char reg2write;
    float setpoint = 29500;
    float step = 0.0001; //duty cycle change per sample
    float dutyCycle=0.88;
    float dutyCycleMin =0.8;
    float dutyCycleMax =0.99;
    float pGain = 0.25;
    float err;
    float tol=2.5;
    
    //setup everything
    mypwm.period_ms(5);
    mypwm.write(dutyCycle);
    i2c.frequency(400000); //set I2C frequency to 400kHz
    wait_ms(1000);
    initTMD2772();
    regDump(TMD2772_Addr,0x00,0x0F);
    pc.printf("Done initializing\r\n");
    wait_ms(700);
    
    //get initial filter value
    reg2write=ALSDataRegister | 0x80;
    i2c.write(TMD2772_Addr,&reg2write,1,true); //1 byte of data, repeated start for read
    i2c.read(TMD2772_Addr,data,4);
    ch0Data = LSB_MSB_2uint16(data);
    ch1Data = LSB_MSB_2uint16(data+2);
    ratio = (float)ch0Data/(float)ch1Data;
    wait_ms(699);
    
    while(1) {
        t.start();
        reg2write=ALSDataRegister | 0x80;
//        pc.printf("%X\r\n",reg2write);
        i2c.write(TMD2772_Addr,&reg2write,1,true); //1 byte of data, repeated start for read
        i2c.read(TMD2772_Addr,data,4);
        ch0Data = LSB_MSB_2uint16(data);
        ch1Data = LSB_MSB_2uint16(data+2);
        ratio = (float)ch0Data/(float)ch1Data;
        err = ch0Data - setpoint;
        pc.printf( "%U,%U, %f, %f, %f\r\n",ch0Data,ch1Data,ratio, dutyCycle, mypwm.read());
        if (abs(err)>tol) {
            step = (ch0Data-setpoint)/setpoint * pGain;
            dutyCycle -=step;
            dutyCycle = (dutyCycle < dutyCycleMin) ? dutyCycleMin : dutyCycle;
            dutyCycle = (dutyCycle > dutyCycleMax) ? dutyCycleMax : dutyCycle;
            //update with new settings
            mypwm.write(dutyCycle);
        }
        while(t.read_ms() < measPeriod_ms) {
         //pc.printf("%U \r\n",t.read_ms());   
        }
        t.reset();
    }
    
    
}