Sample code to interface with TI FDC1004 capacitance-to-digital-converter (CDC), multiplexed in a 8x8 grid array by TI SN74LVC1G3157 SPDT mux

Dependencies:   mbed-dsp mbed

main.cpp

Committer:
kkado
Date:
2017-08-02
Revision:
0:7e77b4f4582c

File content as of revision 0:7e77b4f4582c:

//Test code to read from FDC1004
//Kevin Kadooka, April 2017

#include "mbed.h"
#include <ctype.h>
#include "arm_math.h"
#include "arm_const_structs.h"

#define SAMPLES 128                          //# of continuous samples to read
#define DUMMIES 10                           //# of dummy readings to make before actually recording data (sometimes first few readings are bunk)

DigitalOut col1(PA_1);                       //Define the pins used to switch rows & cols
DigitalOut col2(PH_1);
DigitalOut col3(PA_4);
DigitalOut col4(PB_0);
DigitalOut col5(PC_2);
DigitalOut col6(PC_1);
DigitalOut col7(PC_3);
DigitalOut col8(PC_0);

DigitalOut row1(PA_3);
DigitalOut row2(PA_2);
DigitalOut row3(PA_10);
DigitalOut row4(PC_4);
DigitalOut row5(PB_3);
DigitalOut row6(PB_5);
DigitalOut row7(PB_13);
DigitalOut row8(PB_4);

I2C i2c(PB_9, PB_8);                        //Initialize i2c master, where PB_9 is SDA, PB_8 is SCL
Serial pc(SERIAL_TX, SERIAL_RX);            //Init serial connection to PC
Timer t;                                    //Timing and stuff

const static arm_cfft_instance_f32 *S;      //Floating point structure for FFT
const int addr = 0xA0;                      //This is the 8-bit address, 7-bit address is 0x50
float C[SAMPLES];                           //Array to hold capacitance values
float FFTinput[SAMPLES*2];                  //Array to hold FFT input, where [0] is first real value, [1] first imag value, etc...
float FFToutput[SAMPLES];                   //Array to hold FFT output
uint32_t t_now;                             //Timing variable
uint16_t w;                                 //Iter

////////////////////////////////////////////////////////////////////////////////
//                              FUNCTIONS                                     //
////////////////////////////////////////////////////////////////////////////////

void capInit(){
    char cmd[3];            //Configure the FDC1004
    cmd[0] = 0x08;          //Register
    cmd[1] = 0b00010001;    //MSB
    cmd[2] = 0b00100000;    //LSB
    i2c.write(addr,cmd,3);
}

float capRead(){
    int16_t lb1, lb2, lb3;
    uint16_t lbb1, lbb2, lbb3;
    char data[2];
    float result;
    
    char cmd[3];                //Start a single measurement on CIN1 with appropriate CAPDAC settings (bytes 9:5)
    cmd[0] = 0x0C;
    cmd[1] = 0b00000100;
    cmd[2] = 0b10000000;
    i2c.write(addr,cmd,3);
    
    wait_ms(10);                //Wait for measurement to complete. Alternatively we could read the status register, but this is reliable enough
    
    i2c.start();                //Point to 0x00 and read MSB (2)
    i2c.write(addr & 0xFE);
    i2c.write(0x00);
    i2c.stop(); 
    
    i2c.read(addr,data,2);
    lb1 = data[0];
    lb2 = data[1];
    
    i2c.start();                //Point to 0x01 and read LSB (1)
    i2c.write(addr & 0xFE);
    i2c.write(0x01);
    i2c.stop();
    
    i2c.start();
    i2c.write(addr | 0x01);
    lb3 = i2c.read(0);
    i2c.stop();
    
    lbb1 = lb1*256+lb2;         //Reconstruct the 3 bytes into a 24-bit 2's complement value, divide by 2^19 to get cap value
    lbb2 = lbb1 >> 11;
    lbb3 = 0b0000011111111111 & lbb1;
    result = lbb2 + (float)lbb3/2048 + (float)lb3/1048576;
    //pc.printf("lb1 = %d, lb2 = %d, lb3 = %d\n",lb1,lb2,lb3);
    //pc.printf("%f\n",result);
        
    return result;
}

void printCap(){
    for(uint16_t i = 0; i < SAMPLES; i++){
        if(i == SAMPLES-1){
            pc.printf("%f\n",C[i]);
        }
        else{
            pc.printf("%f,",C[i]);
        }
    }
}

void printFFT(){
    for(uint16_t i = 0; i < SAMPLES; i++){
        if(i == SAMPLES-1){
            pc.printf("%f\n",FFToutput[i]);
        }
        else{
            pc.printf("%f,",FFToutput[i]);
        }
    }
}

void makeFFTinput(){
    for(uint16_t i = 0; i < SAMPLES; i++){
        FFTinput[2*i] = C[i];
        FFTinput[2*i+1] = 0;
    }
}

void removeOffset(){
    float sum = 0;
    for(uint16_t i = 0; i < SAMPLES; i++){
        sum = sum + C[i];
    }
    float mean = sum/SAMPLES;
    for(uint16_t i = 0; i < SAMPLES; i++){
        C[i] = C[i] - mean;
    }
}

void sensorSelect(uint8_t row, uint8_t col){                                    //Still need to sanitize inputs to only allow 1 <= row <= 8, 1 <= col <= 8
    uint8_t rowbyte = 2^(row - 1);                                              //For example, when row = 1, rowbyte = 1 = 0b00000001, row = 2, rowbyte = 2 = 0b00000010... etc
    uint8_t colbyte = 2^(col - 1);
    
    row1 = (rowbyte & 0b00000001);                                              //Check value of bit 0, and write to pin
    row2 = (rowbyte & 0b00000010)>>1;                                           //Check value of bit 1, etc.
    row3 = (rowbyte & 0b00000100)>>2;
    row4 = (rowbyte & 0b00001000)>>3;
    row5 = (rowbyte & 0b00010000)>>4;
    row6 = (rowbyte & 0b00100000)>>5;
    row7 = (rowbyte & 0b01000000)>>6;
    row8 = (rowbyte & 0b10000000)>>7;
    
    col1 = (colbyte & 0b00000001);
    col2 = (colbyte & 0b00000010)>>1;
    col3 = (colbyte & 0b00000100)>>2;
    col4 = (colbyte & 0b00001000)>>3;
    col5 = (colbyte & 0b00010000)>>4;
    col6 = (colbyte & 0b00100000)>>5;
    col7 = (colbyte & 0b01000000)>>6;
    col8 = (colbyte & 0b10000000)>>7;
}

////////////////////////////////////////////////////////////////////////////////
//                                   MAIN                                     //
////////////////////////////////////////////////////////////////////////////////

int main(){
    S = &arm_cfft_sR_f32_len128;
    t.start();
    
    
    col1 = 1;
    col2 = 0;
    col3 = 0;
    col4 = 0;
    col5 = 0;
    col6 = 0;
    col7 = 0;
    col8 = 0;
    
    row1 = 0;
    row2 = 0;
    row3 = 0;
    row4 = 0;
    row5 = 0;
    row6 = 0;
    row7 = 0;
    row8 = 1;
    
    
    //sensorSelect(1,1);
    
    pc.baud(115200);
    capInit();
    
    while(1){
    //    for(uint8_t j = 1; j <= 8; j++){
    //        for(uint8_t i = 1; i <= 8; i++){
    //            sensorSelect(i,j);
                
                w = 0;
                t_now = t.read_us();
                while(w < SAMPLES+DUMMIES){
                    if(t.read_us()-t_now >= 16666){
                        //t_now = t.read_us();
                        if(w < DUMMIES){
                            capRead();
                            //printf("dummy measurement %d",w);
                        }
                        else{
                            C[w-DUMMIES] = capRead();
                            //printf("t = %d, C = %f\n",t_now,C[w]);
                        }
                        w++;
                    }
                }
                //removeOffset();
                printCap();
                //pc.printf("Making FFT input...\n");
                //makeFFTinput();
                //pc.printf("Calculating FFT...\n");
                //arm_cfft_f32(S,FFTinput,0,1);
                //pc.printf("Calculating FFT mag...\n");
                //arm_cmplx_mag_f32(FFTinput,FFToutput,SAMPLES);
                //printFFT();
    //        }
    //    }
    }
}