ADC performance check

Dependencies:  

Fork of GR-PEACH_test_wo_rtos by Kenji Arai

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Sun Jan 11 09:48:17 2015 +0000
Parent:
6:849caec97744
Commit message:
ADC performance check

Changed in this revision

L3GD20.lib Show diff for this revision Revisions of this file
LIS3DH.lib Show diff for this revision Revisions of this file
TextLCD.lib Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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
--- 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
--- 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
--- 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;
+}