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@0:7e77b4f4582c, 2017-08-02 (annotated)
- Committer:
- kkado
- Date:
- Wed Aug 02 22:11:11 2017 +0000
- Revision:
- 0:7e77b4f4582c
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kkado | 0:7e77b4f4582c | 1 | //Test code to read from FDC1004 |
kkado | 0:7e77b4f4582c | 2 | //Kevin Kadooka, April 2017 |
kkado | 0:7e77b4f4582c | 3 | |
kkado | 0:7e77b4f4582c | 4 | #include "mbed.h" |
kkado | 0:7e77b4f4582c | 5 | #include <ctype.h> |
kkado | 0:7e77b4f4582c | 6 | #include "arm_math.h" |
kkado | 0:7e77b4f4582c | 7 | #include "arm_const_structs.h" |
kkado | 0:7e77b4f4582c | 8 | |
kkado | 0:7e77b4f4582c | 9 | #define SAMPLES 128 //# of continuous samples to read |
kkado | 0:7e77b4f4582c | 10 | #define DUMMIES 10 //# of dummy readings to make before actually recording data (sometimes first few readings are bunk) |
kkado | 0:7e77b4f4582c | 11 | |
kkado | 0:7e77b4f4582c | 12 | DigitalOut col1(PA_1); //Define the pins used to switch rows & cols |
kkado | 0:7e77b4f4582c | 13 | DigitalOut col2(PH_1); |
kkado | 0:7e77b4f4582c | 14 | DigitalOut col3(PA_4); |
kkado | 0:7e77b4f4582c | 15 | DigitalOut col4(PB_0); |
kkado | 0:7e77b4f4582c | 16 | DigitalOut col5(PC_2); |
kkado | 0:7e77b4f4582c | 17 | DigitalOut col6(PC_1); |
kkado | 0:7e77b4f4582c | 18 | DigitalOut col7(PC_3); |
kkado | 0:7e77b4f4582c | 19 | DigitalOut col8(PC_0); |
kkado | 0:7e77b4f4582c | 20 | |
kkado | 0:7e77b4f4582c | 21 | DigitalOut row1(PA_3); |
kkado | 0:7e77b4f4582c | 22 | DigitalOut row2(PA_2); |
kkado | 0:7e77b4f4582c | 23 | DigitalOut row3(PA_10); |
kkado | 0:7e77b4f4582c | 24 | DigitalOut row4(PC_4); |
kkado | 0:7e77b4f4582c | 25 | DigitalOut row5(PB_3); |
kkado | 0:7e77b4f4582c | 26 | DigitalOut row6(PB_5); |
kkado | 0:7e77b4f4582c | 27 | DigitalOut row7(PB_13); |
kkado | 0:7e77b4f4582c | 28 | DigitalOut row8(PB_4); |
kkado | 0:7e77b4f4582c | 29 | |
kkado | 0:7e77b4f4582c | 30 | I2C i2c(PB_9, PB_8); //Initialize i2c master, where PB_9 is SDA, PB_8 is SCL |
kkado | 0:7e77b4f4582c | 31 | Serial pc(SERIAL_TX, SERIAL_RX); //Init serial connection to PC |
kkado | 0:7e77b4f4582c | 32 | Timer t; //Timing and stuff |
kkado | 0:7e77b4f4582c | 33 | |
kkado | 0:7e77b4f4582c | 34 | const static arm_cfft_instance_f32 *S; //Floating point structure for FFT |
kkado | 0:7e77b4f4582c | 35 | const int addr = 0xA0; //This is the 8-bit address, 7-bit address is 0x50 |
kkado | 0:7e77b4f4582c | 36 | float C[SAMPLES]; //Array to hold capacitance values |
kkado | 0:7e77b4f4582c | 37 | float FFTinput[SAMPLES*2]; //Array to hold FFT input, where [0] is first real value, [1] first imag value, etc... |
kkado | 0:7e77b4f4582c | 38 | float FFToutput[SAMPLES]; //Array to hold FFT output |
kkado | 0:7e77b4f4582c | 39 | uint32_t t_now; //Timing variable |
kkado | 0:7e77b4f4582c | 40 | uint16_t w; //Iter |
kkado | 0:7e77b4f4582c | 41 | |
kkado | 0:7e77b4f4582c | 42 | //////////////////////////////////////////////////////////////////////////////// |
kkado | 0:7e77b4f4582c | 43 | // FUNCTIONS // |
kkado | 0:7e77b4f4582c | 44 | //////////////////////////////////////////////////////////////////////////////// |
kkado | 0:7e77b4f4582c | 45 | |
kkado | 0:7e77b4f4582c | 46 | void capInit(){ |
kkado | 0:7e77b4f4582c | 47 | char cmd[3]; //Configure the FDC1004 |
kkado | 0:7e77b4f4582c | 48 | cmd[0] = 0x08; //Register |
kkado | 0:7e77b4f4582c | 49 | cmd[1] = 0b00010001; //MSB |
kkado | 0:7e77b4f4582c | 50 | cmd[2] = 0b00100000; //LSB |
kkado | 0:7e77b4f4582c | 51 | i2c.write(addr,cmd,3); |
kkado | 0:7e77b4f4582c | 52 | } |
kkado | 0:7e77b4f4582c | 53 | |
kkado | 0:7e77b4f4582c | 54 | float capRead(){ |
kkado | 0:7e77b4f4582c | 55 | int16_t lb1, lb2, lb3; |
kkado | 0:7e77b4f4582c | 56 | uint16_t lbb1, lbb2, lbb3; |
kkado | 0:7e77b4f4582c | 57 | char data[2]; |
kkado | 0:7e77b4f4582c | 58 | float result; |
kkado | 0:7e77b4f4582c | 59 | |
kkado | 0:7e77b4f4582c | 60 | char cmd[3]; //Start a single measurement on CIN1 with appropriate CAPDAC settings (bytes 9:5) |
kkado | 0:7e77b4f4582c | 61 | cmd[0] = 0x0C; |
kkado | 0:7e77b4f4582c | 62 | cmd[1] = 0b00000100; |
kkado | 0:7e77b4f4582c | 63 | cmd[2] = 0b10000000; |
kkado | 0:7e77b4f4582c | 64 | i2c.write(addr,cmd,3); |
kkado | 0:7e77b4f4582c | 65 | |
kkado | 0:7e77b4f4582c | 66 | wait_ms(10); //Wait for measurement to complete. Alternatively we could read the status register, but this is reliable enough |
kkado | 0:7e77b4f4582c | 67 | |
kkado | 0:7e77b4f4582c | 68 | i2c.start(); //Point to 0x00 and read MSB (2) |
kkado | 0:7e77b4f4582c | 69 | i2c.write(addr & 0xFE); |
kkado | 0:7e77b4f4582c | 70 | i2c.write(0x00); |
kkado | 0:7e77b4f4582c | 71 | i2c.stop(); |
kkado | 0:7e77b4f4582c | 72 | |
kkado | 0:7e77b4f4582c | 73 | i2c.read(addr,data,2); |
kkado | 0:7e77b4f4582c | 74 | lb1 = data[0]; |
kkado | 0:7e77b4f4582c | 75 | lb2 = data[1]; |
kkado | 0:7e77b4f4582c | 76 | |
kkado | 0:7e77b4f4582c | 77 | i2c.start(); //Point to 0x01 and read LSB (1) |
kkado | 0:7e77b4f4582c | 78 | i2c.write(addr & 0xFE); |
kkado | 0:7e77b4f4582c | 79 | i2c.write(0x01); |
kkado | 0:7e77b4f4582c | 80 | i2c.stop(); |
kkado | 0:7e77b4f4582c | 81 | |
kkado | 0:7e77b4f4582c | 82 | i2c.start(); |
kkado | 0:7e77b4f4582c | 83 | i2c.write(addr | 0x01); |
kkado | 0:7e77b4f4582c | 84 | lb3 = i2c.read(0); |
kkado | 0:7e77b4f4582c | 85 | i2c.stop(); |
kkado | 0:7e77b4f4582c | 86 | |
kkado | 0:7e77b4f4582c | 87 | lbb1 = lb1*256+lb2; //Reconstruct the 3 bytes into a 24-bit 2's complement value, divide by 2^19 to get cap value |
kkado | 0:7e77b4f4582c | 88 | lbb2 = lbb1 >> 11; |
kkado | 0:7e77b4f4582c | 89 | lbb3 = 0b0000011111111111 & lbb1; |
kkado | 0:7e77b4f4582c | 90 | result = lbb2 + (float)lbb3/2048 + (float)lb3/1048576; |
kkado | 0:7e77b4f4582c | 91 | //pc.printf("lb1 = %d, lb2 = %d, lb3 = %d\n",lb1,lb2,lb3); |
kkado | 0:7e77b4f4582c | 92 | //pc.printf("%f\n",result); |
kkado | 0:7e77b4f4582c | 93 | |
kkado | 0:7e77b4f4582c | 94 | return result; |
kkado | 0:7e77b4f4582c | 95 | } |
kkado | 0:7e77b4f4582c | 96 | |
kkado | 0:7e77b4f4582c | 97 | void printCap(){ |
kkado | 0:7e77b4f4582c | 98 | for(uint16_t i = 0; i < SAMPLES; i++){ |
kkado | 0:7e77b4f4582c | 99 | if(i == SAMPLES-1){ |
kkado | 0:7e77b4f4582c | 100 | pc.printf("%f\n",C[i]); |
kkado | 0:7e77b4f4582c | 101 | } |
kkado | 0:7e77b4f4582c | 102 | else{ |
kkado | 0:7e77b4f4582c | 103 | pc.printf("%f,",C[i]); |
kkado | 0:7e77b4f4582c | 104 | } |
kkado | 0:7e77b4f4582c | 105 | } |
kkado | 0:7e77b4f4582c | 106 | } |
kkado | 0:7e77b4f4582c | 107 | |
kkado | 0:7e77b4f4582c | 108 | void printFFT(){ |
kkado | 0:7e77b4f4582c | 109 | for(uint16_t i = 0; i < SAMPLES; i++){ |
kkado | 0:7e77b4f4582c | 110 | if(i == SAMPLES-1){ |
kkado | 0:7e77b4f4582c | 111 | pc.printf("%f\n",FFToutput[i]); |
kkado | 0:7e77b4f4582c | 112 | } |
kkado | 0:7e77b4f4582c | 113 | else{ |
kkado | 0:7e77b4f4582c | 114 | pc.printf("%f,",FFToutput[i]); |
kkado | 0:7e77b4f4582c | 115 | } |
kkado | 0:7e77b4f4582c | 116 | } |
kkado | 0:7e77b4f4582c | 117 | } |
kkado | 0:7e77b4f4582c | 118 | |
kkado | 0:7e77b4f4582c | 119 | void makeFFTinput(){ |
kkado | 0:7e77b4f4582c | 120 | for(uint16_t i = 0; i < SAMPLES; i++){ |
kkado | 0:7e77b4f4582c | 121 | FFTinput[2*i] = C[i]; |
kkado | 0:7e77b4f4582c | 122 | FFTinput[2*i+1] = 0; |
kkado | 0:7e77b4f4582c | 123 | } |
kkado | 0:7e77b4f4582c | 124 | } |
kkado | 0:7e77b4f4582c | 125 | |
kkado | 0:7e77b4f4582c | 126 | void removeOffset(){ |
kkado | 0:7e77b4f4582c | 127 | float sum = 0; |
kkado | 0:7e77b4f4582c | 128 | for(uint16_t i = 0; i < SAMPLES; i++){ |
kkado | 0:7e77b4f4582c | 129 | sum = sum + C[i]; |
kkado | 0:7e77b4f4582c | 130 | } |
kkado | 0:7e77b4f4582c | 131 | float mean = sum/SAMPLES; |
kkado | 0:7e77b4f4582c | 132 | for(uint16_t i = 0; i < SAMPLES; i++){ |
kkado | 0:7e77b4f4582c | 133 | C[i] = C[i] - mean; |
kkado | 0:7e77b4f4582c | 134 | } |
kkado | 0:7e77b4f4582c | 135 | } |
kkado | 0:7e77b4f4582c | 136 | |
kkado | 0:7e77b4f4582c | 137 | void sensorSelect(uint8_t row, uint8_t col){ //Still need to sanitize inputs to only allow 1 <= row <= 8, 1 <= col <= 8 |
kkado | 0:7e77b4f4582c | 138 | uint8_t rowbyte = 2^(row - 1); //For example, when row = 1, rowbyte = 1 = 0b00000001, row = 2, rowbyte = 2 = 0b00000010... etc |
kkado | 0:7e77b4f4582c | 139 | uint8_t colbyte = 2^(col - 1); |
kkado | 0:7e77b4f4582c | 140 | |
kkado | 0:7e77b4f4582c | 141 | row1 = (rowbyte & 0b00000001); //Check value of bit 0, and write to pin |
kkado | 0:7e77b4f4582c | 142 | row2 = (rowbyte & 0b00000010)>>1; //Check value of bit 1, etc. |
kkado | 0:7e77b4f4582c | 143 | row3 = (rowbyte & 0b00000100)>>2; |
kkado | 0:7e77b4f4582c | 144 | row4 = (rowbyte & 0b00001000)>>3; |
kkado | 0:7e77b4f4582c | 145 | row5 = (rowbyte & 0b00010000)>>4; |
kkado | 0:7e77b4f4582c | 146 | row6 = (rowbyte & 0b00100000)>>5; |
kkado | 0:7e77b4f4582c | 147 | row7 = (rowbyte & 0b01000000)>>6; |
kkado | 0:7e77b4f4582c | 148 | row8 = (rowbyte & 0b10000000)>>7; |
kkado | 0:7e77b4f4582c | 149 | |
kkado | 0:7e77b4f4582c | 150 | col1 = (colbyte & 0b00000001); |
kkado | 0:7e77b4f4582c | 151 | col2 = (colbyte & 0b00000010)>>1; |
kkado | 0:7e77b4f4582c | 152 | col3 = (colbyte & 0b00000100)>>2; |
kkado | 0:7e77b4f4582c | 153 | col4 = (colbyte & 0b00001000)>>3; |
kkado | 0:7e77b4f4582c | 154 | col5 = (colbyte & 0b00010000)>>4; |
kkado | 0:7e77b4f4582c | 155 | col6 = (colbyte & 0b00100000)>>5; |
kkado | 0:7e77b4f4582c | 156 | col7 = (colbyte & 0b01000000)>>6; |
kkado | 0:7e77b4f4582c | 157 | col8 = (colbyte & 0b10000000)>>7; |
kkado | 0:7e77b4f4582c | 158 | } |
kkado | 0:7e77b4f4582c | 159 | |
kkado | 0:7e77b4f4582c | 160 | //////////////////////////////////////////////////////////////////////////////// |
kkado | 0:7e77b4f4582c | 161 | // MAIN // |
kkado | 0:7e77b4f4582c | 162 | //////////////////////////////////////////////////////////////////////////////// |
kkado | 0:7e77b4f4582c | 163 | |
kkado | 0:7e77b4f4582c | 164 | int main(){ |
kkado | 0:7e77b4f4582c | 165 | S = &arm_cfft_sR_f32_len128; |
kkado | 0:7e77b4f4582c | 166 | t.start(); |
kkado | 0:7e77b4f4582c | 167 | |
kkado | 0:7e77b4f4582c | 168 | |
kkado | 0:7e77b4f4582c | 169 | col1 = 1; |
kkado | 0:7e77b4f4582c | 170 | col2 = 0; |
kkado | 0:7e77b4f4582c | 171 | col3 = 0; |
kkado | 0:7e77b4f4582c | 172 | col4 = 0; |
kkado | 0:7e77b4f4582c | 173 | col5 = 0; |
kkado | 0:7e77b4f4582c | 174 | col6 = 0; |
kkado | 0:7e77b4f4582c | 175 | col7 = 0; |
kkado | 0:7e77b4f4582c | 176 | col8 = 0; |
kkado | 0:7e77b4f4582c | 177 | |
kkado | 0:7e77b4f4582c | 178 | row1 = 0; |
kkado | 0:7e77b4f4582c | 179 | row2 = 0; |
kkado | 0:7e77b4f4582c | 180 | row3 = 0; |
kkado | 0:7e77b4f4582c | 181 | row4 = 0; |
kkado | 0:7e77b4f4582c | 182 | row5 = 0; |
kkado | 0:7e77b4f4582c | 183 | row6 = 0; |
kkado | 0:7e77b4f4582c | 184 | row7 = 0; |
kkado | 0:7e77b4f4582c | 185 | row8 = 1; |
kkado | 0:7e77b4f4582c | 186 | |
kkado | 0:7e77b4f4582c | 187 | |
kkado | 0:7e77b4f4582c | 188 | //sensorSelect(1,1); |
kkado | 0:7e77b4f4582c | 189 | |
kkado | 0:7e77b4f4582c | 190 | pc.baud(115200); |
kkado | 0:7e77b4f4582c | 191 | capInit(); |
kkado | 0:7e77b4f4582c | 192 | |
kkado | 0:7e77b4f4582c | 193 | while(1){ |
kkado | 0:7e77b4f4582c | 194 | // for(uint8_t j = 1; j <= 8; j++){ |
kkado | 0:7e77b4f4582c | 195 | // for(uint8_t i = 1; i <= 8; i++){ |
kkado | 0:7e77b4f4582c | 196 | // sensorSelect(i,j); |
kkado | 0:7e77b4f4582c | 197 | |
kkado | 0:7e77b4f4582c | 198 | w = 0; |
kkado | 0:7e77b4f4582c | 199 | t_now = t.read_us(); |
kkado | 0:7e77b4f4582c | 200 | while(w < SAMPLES+DUMMIES){ |
kkado | 0:7e77b4f4582c | 201 | if(t.read_us()-t_now >= 16666){ |
kkado | 0:7e77b4f4582c | 202 | //t_now = t.read_us(); |
kkado | 0:7e77b4f4582c | 203 | if(w < DUMMIES){ |
kkado | 0:7e77b4f4582c | 204 | capRead(); |
kkado | 0:7e77b4f4582c | 205 | //printf("dummy measurement %d",w); |
kkado | 0:7e77b4f4582c | 206 | } |
kkado | 0:7e77b4f4582c | 207 | else{ |
kkado | 0:7e77b4f4582c | 208 | C[w-DUMMIES] = capRead(); |
kkado | 0:7e77b4f4582c | 209 | //printf("t = %d, C = %f\n",t_now,C[w]); |
kkado | 0:7e77b4f4582c | 210 | } |
kkado | 0:7e77b4f4582c | 211 | w++; |
kkado | 0:7e77b4f4582c | 212 | } |
kkado | 0:7e77b4f4582c | 213 | } |
kkado | 0:7e77b4f4582c | 214 | //removeOffset(); |
kkado | 0:7e77b4f4582c | 215 | printCap(); |
kkado | 0:7e77b4f4582c | 216 | //pc.printf("Making FFT input...\n"); |
kkado | 0:7e77b4f4582c | 217 | //makeFFTinput(); |
kkado | 0:7e77b4f4582c | 218 | //pc.printf("Calculating FFT...\n"); |
kkado | 0:7e77b4f4582c | 219 | //arm_cfft_f32(S,FFTinput,0,1); |
kkado | 0:7e77b4f4582c | 220 | //pc.printf("Calculating FFT mag...\n"); |
kkado | 0:7e77b4f4582c | 221 | //arm_cmplx_mag_f32(FFTinput,FFToutput,SAMPLES); |
kkado | 0:7e77b4f4582c | 222 | //printFFT(); |
kkado | 0:7e77b4f4582c | 223 | // } |
kkado | 0:7e77b4f4582c | 224 | // } |
kkado | 0:7e77b4f4582c | 225 | } |
kkado | 0:7e77b4f4582c | 226 | } |