Sample code to interface with TI FDC1004 capacitance-to-digital-converter (CDC), multiplexed in a 8x8 grid array by TI SN74LVC1G3157 SPDT mux
Diff: main.cpp
- Revision:
- 0:7e77b4f4582c
diff -r 000000000000 -r 7e77b4f4582c main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Aug 02 22:11:11 2017 +0000 @@ -0,0 +1,226 @@ +//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(); + // } + // } + } +} \ No newline at end of file