ADC performance check
Fork of GR-PEACH_test_wo_rtos by
Revision 7:c87a84872d85, committed 2015-01-11
- Comitter:
- kenjiArai
- Date:
- Sun Jan 11 09:48:17 2015 +0000
- Parent:
- 6:849caec97744
- Commit message:
- ADC performance check
Changed in this revision
diff -r 849caec97744 -r c87a84872d85 L3GD20.lib --- a/L3GD20.lib Fri Jan 09 22:50:07 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/kenjiArai/code/L3GD20/#7d0cec583aa3
diff -r 849caec97744 -r c87a84872d85 LIS3DH.lib --- a/LIS3DH.lib Fri Jan 09 22:50:07 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/kenjiArai/code/LIS3DH/#64dac49da306
diff -r 849caec97744 -r c87a84872d85 TextLCD.lib --- a/TextLCD.lib Fri Jan 09 22:50:07 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/wim/code/TextLCD/#9f5f86dfd44a
diff -r 849caec97744 -r c87a84872d85 main.cpp --- a/main.cpp Fri Jan 09 22:50:07 2015 +0000 +++ b/main.cpp Sun Jan 11 09:48:17 2015 +0000 @@ -6,7 +6,7 @@ * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: November 29th, 2014 - * Revised: January 10th, 2015 + * Revised: January 11th, 2015 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE @@ -17,15 +17,10 @@ // Include --------------------------------------------------------------------------------------- #include "mbed.h" -#include "L3GD20.h" -#include "LIS3DH.h" -#include "TextLCD.h" // Definition ------------------------------------------------------------------------------------ #define USE_COM // use Communication with PC(UART) -#define USE_I2C_LCD -#define USE_I2C_SENSOR - + // Com #ifdef USE_COM #define BAUD(x) pcx.baud(x) @@ -41,114 +36,462 @@ #define READABLE(x) {;} #endif +// Use TL431ACZ-AP +// Akizuki NJM431 (equivalent) +// http://akizukidenshi.com/catalog/g/gI-00431/ +#define VREF (2.478f) // measured data (not Typ. data) + +#if defined(TARGET_RZ_A1H) +//#define ADC_BUF_SIZE (4096 * 40) +#define ADC_BUF_SIZE (1024) +#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) +#define ADC_BUF_SIZE (1024) +#elif defined(TARGET_K64F) +#define ADC_BUF_SIZE (1024) +#endif + + // Object ---------------------------------------------------------------------------------------- -// LED's -DigitalOut LEDs[4] = { - DigitalOut(LED1), DigitalOut(LED2), DigitalOut(LED3), DigitalOut(LED4) -}; -// Swiches -DigitalIn USER_SWITCH[2] = { - #if defined(TARGET_RZ_A1H) - DigitalIn(P6_0), DigitalIn(P6_1) - #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)\ - || defined(TARGET_NUCLEO_L152RE) - DigitalIn(PC_13), DigitalIn(A0) - #elif defined(TARGET_LPC1768) - DigitalIn(A0), DigitalIn(A1) - #elif defined(TARGET_K64F) - DigitalIn(PTA4), DigitalIn(PTC6) - #endif -}; // com #ifdef USE_COM Serial pcx(USBTX, USBRX); // Communication with Host #endif -I2C i2c(D14,D15); -// Gyro -L3GX_GYRO gyro(i2c, L3GD20_V_CHIP_ADDR, L3GX_DR_95HZ, L3GX_BW_HI, L3GX_FS_250DPS); -// Acc -LIS3DH acc(i2c, LIS3DH_G_CHIP_ADDR, LIS3DH_DR_NR_LP_50HZ, LIS3DH_FS_8G); -#ifdef USE_I2C_LCD -// LCD -TextLCD_I2C_N lcd0(&i2c, 0x7c, TextLCD::LCD16x2); // LCD(Akizuki AQM0802A) -#endif +// Analog +AnalogIn adc0(A0); // Connect TL431ACZ-AP +AnalogIn adc1(A1); +AnalogIn adc2(A2); +AnalogIn adc3(A3); +AnalogIn adc4(A4); +AnalogIn adc5(A5); +// timer +Timer timer; // RAM ------------------------------------------------------------------------------------------- -float fa[3]; // Acc 0:X, 1:Y, 2:Z -float fg[3]; // Gyro 0:X, 1:Y, 2:Z +static char linebuf[64]; + +typedef struct { + float adc0; + float adc1; + float adc2; + float adc3; + float adc4; + float adc5; + int a0_time; + int a1_time; + int a2_time; + int a3_time; + int a4_time; + int a5_time; + uint32_t n; +} ADC_DataTypeDef; -uint8_t show_flag; -uint32_t count; +ADC_DataTypeDef data_buffer[ADC_BUF_SIZE]; + +// avarage & max.min +uint32_t d_max_min[2]; + +double ave_adc0; +double ave_adc1; +double ave_adc2; +double ave_adc3; +double ave_adc4; +double ave_adc5; +float d_max_min0[2]; +float d_max_min1[2]; +float d_max_min2[2]; +float d_max_min3[2]; +float d_max_min4[2]; +float d_max_min5[2]; // ROM / Constant data --------------------------------------------------------------------------- +#if defined(TARGET_RZ_A1H) +static char *const mon_msg = "ADC checking program for GR-PEACH mbed, created on "__DATE__""; +#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) +static char *const mon_msg = "ADC checking program for Nucleo mbed, created on "__DATE__""; +#elif defined(TARGET_K64F) +static char *const mon_msg = "ADC checking program for K64F mbed, created on "__DATE__""; +#endif // Function prototypes --------------------------------------------------------------------------- // Function prototypes --------------------------------------------------------------------------- +void msg_hlp (void); +void reset_max_min(uint32_t *bf); +void check_max_min(uint32_t dt, uint32_t *bf); +void reset_f_max_min(void); +void check_f_max_min(float dt, float *bf); +void get_line (char *buff, int len); +void blink(void const *n); +void put_rn ( void ); +void put_r ( void ); +int xatoi (char **str, int32_t *res); //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- -void blink(void const *n) { - LEDs[(int)n] = !LEDs[(int)n]; -} +int main(void) +{ + char *ptr; + float dt; + uint32_t i; + uint32_t t; + + BAUD(9600); + put_rn(); + put_rn(); + PRINTF("%s [Help:'?' key]", mon_msg); + put_rn(); + for (;;) { + put_r(); + PUTC('>'); + ptr = linebuf; + get_line(ptr, sizeof(linebuf)); + switch (*ptr++) { + //--------------------------------------------------------------------------------------------- + // Save ADC data into RAM + //--------------------------------------------------------------------------------------------- + case 's' : + for (i = 0; i < ADC_BUF_SIZE; i++) { + timer.reset(); + timer.start(); + dt = adc0.read(); + t = timer.read_us(); + data_buffer[i].adc0 = dt; + data_buffer[i].a0_time = t; -// Read switch status -int read_sw(uint8_t n){ - if (USER_SWITCH[n] == 0){ return 1; - } else { return 0;} -} + timer.reset(); + timer.start(); + dt = adc1.read(); + t = timer.read_us(); + data_buffer[i].adc1 = dt; + data_buffer[i].a1_time = t; + + timer.reset(); + timer.start(); + dt = adc2.read(); + t = timer.read_us(); + data_buffer[i].adc2 = dt; + data_buffer[i].a2_time = t; + + timer.reset(); + timer.start(); + dt = adc3.read(); + t = timer.read_us(); + data_buffer[i].adc3 = dt; + data_buffer[i].a3_time = t; + + timer.reset(); + timer.start(); + dt =adc4.read(); + t = timer.read_us(); + data_buffer[i].adc4 = dt; + data_buffer[i].a4_time = t; + + timer.reset(); + dt = adc5.read(); + t = timer.read_us(); + data_buffer[i].adc5 = dt; + data_buffer[i].a5_time = t; -// Update sensor data -void update_angle(void){ -#ifdef USE_I2C_SENSOR - // read acceleration data from sensor - acc.read_data(fa); - // read gyroscope data from sensor - gyro.read_data(fg); -#else - fa[0] = fa[1] = fa[2] = 1.11f; - fg[0] = fg[1] = fg[2] = 1.11f; -#endif + data_buffer[i].n = i + 1; + if (i%100 == 0) { + put_rn(); + PRINTF("%d", i); + put_rn(); + } else { + PUTC('.'); + } + if ( READABLE() ) { + put_rn(); + GETC(); + break; + } + } + data_buffer[i + 1].n = 0; + put_rn(); + PRINTF("Finished at %d", i); + put_rn(); + break; + //--------------------------------------------------------------------------------------------- + // Display saved ADC data + //--------------------------------------------------------------------------------------------- + case 'd' : + put_rn(); + PRINTF("Show all saved data"); + put_rn(); + for (i = 0; (i < ADC_BUF_SIZE) && (data_buffer[i].n != 0) ; i++) { + PRINTF("No.%5d, ", i); + PRINTF("A0= %4.4f , A1= %4.4f , ", data_buffer[i].adc0, data_buffer[i].adc1); + PRINTF("A2= %4.4f , A3= %4.4f , ", data_buffer[i].adc2, data_buffer[i].adc3); + PRINTF("A4= %4.4f , A5= %4.4f , ", data_buffer[i].adc4, data_buffer[i].adc5); + PRINTF("Time/0= %d /1= %d /2= %d /3= %d /4= %d /5= %d [uS]", + data_buffer[i].a0_time, data_buffer[i].a1_time, data_buffer[i].a2_time, + data_buffer[i].a3_time, data_buffer[i].a4_time, data_buffer[i].a5_time); + put_rn(); + if ( READABLE() ) { + GETC(); + break; + } + } + break; + //--------------------------------------------------------------------------------------------- + // Check convertion time + //--------------------------------------------------------------------------------------------- + case 't' : + uint32_t time_all = 0; + + put_r(); + reset_max_min(d_max_min); + for (i = 0; (i < ADC_BUF_SIZE) && (data_buffer[i].n != 0) ; i++) { + time_all += (data_buffer[i].a0_time + data_buffer[i].a1_time +data_buffer[i].a2_time + + data_buffer[i].a3_time + data_buffer[i].a4_time + data_buffer[i].a5_time); + check_max_min(data_buffer[i].a0_time, d_max_min); + check_max_min(data_buffer[i].a1_time, d_max_min); + check_max_min(data_buffer[i].a2_time, d_max_min); + check_max_min(data_buffer[i].a3_time, d_max_min); + check_max_min(data_buffer[i].a4_time, d_max_min); + check_max_min(data_buffer[i].a5_time, d_max_min); + } + PRINTF("Conversion time/ave = %f [uS], Number of sample %d, Max %d [uS], Min %d [uS]", + (double)time_all / (i * 6), i, d_max_min[1], d_max_min[0]); + put_rn(); + break; + //--------------------------------------------------------------------------------------------- + // Analysis saved data + //--------------------------------------------------------------------------------------------- + case 'a' : + put_r(); + reset_f_max_min(); + for (i = 0; (i < ADC_BUF_SIZE) && (data_buffer[i].n != 0) ; i++) { + ave_adc0 += data_buffer[i].adc0; + ave_adc1 += data_buffer[i].adc1; + ave_adc2 += data_buffer[i].adc2; + ave_adc3 += data_buffer[i].adc3; + ave_adc4 += data_buffer[i].adc4; + ave_adc5 += data_buffer[i].adc5; + check_f_max_min(data_buffer[i].adc0, d_max_min0); + check_f_max_min(data_buffer[i].adc1, d_max_min1); + check_f_max_min(data_buffer[i].adc2, d_max_min2); + check_f_max_min(data_buffer[i].adc3, d_max_min3); + check_f_max_min(data_buffer[i].adc4, d_max_min4); + check_f_max_min(data_buffer[i].adc5, d_max_min5); + } + PRINTF("Number of sample %d", i); + put_rn(); + PRINTF("ADC0/ave = %f , Max %f , Min %f , Dif %f", + ave_adc0 / i, d_max_min0[1], d_max_min0[0], d_max_min0[1] - d_max_min0[0]); + put_rn(); + PRINTF("ADC1/ave = %f , Max %f , Min %f , Dif %f", + ave_adc1 / i, d_max_min1[1], d_max_min1[0], d_max_min1[1] - d_max_min1[0]); + put_rn(); + PRINTF("ADC2/ave = %f , Max %f , Min %f , Dif %f", + ave_adc2 / i, d_max_min2[1], d_max_min2[0], d_max_min2[1] - d_max_min2[0]); + put_rn(); + PRINTF("ADC3/ave = %f , Max %f , Min %f , Dif %f", + ave_adc3 / i, d_max_min3[1], d_max_min3[0], d_max_min3[1] - d_max_min3[0]); + put_rn(); + PRINTF("ADC4/ave = %f , Max %f , Min %f , Dif %f", + ave_adc4 / i, d_max_min4[1], d_max_min4[0], d_max_min4[1] - d_max_min4[0]); + put_rn(); + PRINTF("ADC5/ave = %f , Max %f , Min %f , Dif %f", + ave_adc5 / i, d_max_min5[1], d_max_min5[0], d_max_min5[1] - d_max_min5[0]); + put_rn(); + break; + //--------------------------------------------------------------------------------------------- + // Buffer information + //--------------------------------------------------------------------------------------------- + case 'b' : + put_r(); + PRINTF("Buffer information", i); + put_rn(); + PRINTF("Start address: 0x%08x", &data_buffer[0]); + put_rn(); + PRINTF("End address: 0x%08x", &data_buffer[ADC_BUF_SIZE - 1]); + put_rn(); + PRINTF("Size of Buf: %d (0x%x)", sizeof(data_buffer), sizeof(data_buffer)); + put_rn(); + break; + //--------------------------------------------------------------------------------------------- + // Check Vcc + //--------------------------------------------------------------------------------------------- + case 'v' : + put_r(); + PRINTF("This is special function only if A0 conneceted 2.5V Shunt reg. e.g. TL431, NJM431."); + put_rn(); + PRINTF("Please make sure #define VREF as your condition."); + put_rn(); + while(true){ + PRINTF("Vcc= %4.4f [v]", VREF / adc0.read()); + put_rn(); + if ( READABLE() ) { + GETC(); + break; + } + wait(0.5); + } + break; + //--------------------------------------------------------------------------------------------- + // help + //--------------------------------------------------------------------------------------------- + case '?' : + put_r(); + msg_hlp(); + break; + } + } } -// Update sensor data -void display(void){ -#ifdef USE_I2C_LCD - lcd0.locate(0, 0); // 1st line top - lcd0.printf(" G=%4.1f ", sqrt(fa[0]*fa[0] + fa[1]*fa[1] + fa[2]*fa[2])); - lcd0.locate(0, 1); // 2nd line top - lcd0.printf("%8d",count++); -#endif +// Help Massage +void msg_hlp (void) +{ + PRINTF(mon_msg); + put_rn(); + PRINTF("s - Save ADC data into RAM"); + put_rn(); + PRINTF("d - Display saved ADC data"); + put_rn(); + PRINTF("t - Check convertion time"); + put_rn(); + PRINTF("a - Analysis saved data"); + put_rn(); + PRINTF("b - Buffer information"); + put_rn(); + PRINTF("v - Check Vcc"); + put_rn(); +} + +void reset_max_min(uint32_t *bf) +{ + *(bf + 1) = 0; + *bf = 0xffffffff; } -void send_pc(void){ - PRINTF("G:%+6.1f,%+6.1f,%+6.1f, ", fg[0], fg[1], fg[2]); - PRINTF("A:%+6.1f,%+6.1f,%+6.1f \r\n", fa[0], fa[1], fa[2]); +void check_max_min(uint32_t dt, uint32_t *bf) +{ + if (dt > *(bf + 1)){ + *(bf + 1) = dt; + } else if (dt < *bf){ + *bf = dt; + } +} + +void reset_f_max_min(void) +{ + d_max_min0[0] = 1.0f; + d_max_min0[1] = 0.0f; + d_max_min1[0] = 1.0f; + d_max_min1[1] = 0.0f; + d_max_min2[0] = 1.0f; + d_max_min2[1] = 0.0f; + d_max_min3[0] = 1.0f; + d_max_min3[1] = 0.0f; + d_max_min4[0] = 1.0f; + d_max_min4[1] = 0.0f; + d_max_min5[0] = 1.0f; + d_max_min5[1] = 0.0f; +} + +void check_f_max_min(float dt, float *bf) +{ + if (dt > *(bf + 1)){ + *(bf + 1) = dt; + } else if (dt < *bf){ + *bf = dt; + } } -int main(void) { - // I2C LCD -#ifdef USE_I2C_LCD - lcd0.locate(0, 0); // 1st line top - lcd0.printf("I2C test"); - lcd0.locate(0, 1); // 2nd line top - lcd0.puts(" JH1PJL "); - lcd0.setContrast(0x14); -#endif - count = 0; - while (true) { - update_angle(); - display(); - send_pc(); - //wait(0.2); - blink((void *)0); - //wait(0.2); - blink((void *)1); - //wait(0.2); - blink((void *)2); - //wait(0.2); - blink((void *)3); - //wait(0.2); +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Get key input data +void get_line (char *buff, int len) +{ + char c; + int idx = 0; + + for (;;) { + c = GETC(); + // Added by Kenji Arai / JH1PJL May 9th, 2010 + if (c == '\r') { + buff[idx++] = c; + break; + } + if ((c == '\b') && idx) { + idx--; + PUTC(c); + PUTC(' '); + PUTC(c); + } + if (((uint8_t)c >= ' ') && (idx < len - 1)) { + buff[idx++] = c; + PUTC(c); + } } + buff[idx] = 0; + PUTC('\n'); } + +// Put \r\n +void put_rn ( void ) +{ + PUTC('\r'); + PUTC('\n'); +} + +// Put \r +void put_r ( void ) +{ + PUTC('\r'); +} + +int xatoi (char **str, int32_t *res) +{ + unsigned long val; + unsigned char c, radix, s = 0; + + while ((c = **str) == ' ') (*str)++; + if (c == '-') { + s = 1; + c = *(++(*str)); + } + if (c == '0') { + c = *(++(*str)); + if (c <= ' ') { + *res = 0; + return 1; + } + if (c == 'x') { + radix = 16; + c = *(++(*str)); + } else { + if (c == 'b') { + radix = 2; + c = *(++(*str)); + } else { + if ((c >= '0')&&(c <= '9')) { + radix = 8; + } else { + return 0; + } + } + } + } else { + if ((c < '1')||(c > '9')) { + return 0; + } + radix = 10; + } + val = 0; + while (c > ' ') { + if (c >= 'a') c -= 0x20; + c -= '0'; + if (c >= 17) { + c -= 7; + if (c <= 9) return 0; + } + if (c >= radix) return 0; + val = val * radix + c; + c = *(++(*str)); + } + if (s) val = -val; + *res = val; + return 1; +}