Sample code to interface with TI FDC1004 capacitance-to-digital-converter (CDC), multiplexed in a 8x8 grid array by TI SN74LVC1G3157 SPDT mux
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(); // } // } } }