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

Revision:
0:7e77b4f4582c
--- /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