5 years, 11 months ago.

Output data rate of 12bit ADC LPC1768 when the data is written into file using minicom (Teraterm).

Hi, I'm very new to the mbed platform and my question might be very simple for most of them please bear with me.

I'm trying to read three analog inputs from my sensors through 12bit ADC in LPC1768 and stored the output values in a file using minicom(same as teraterm). One of these outputs changes their values suddenly for a certain amount of time, based on their input conditions and what i want to know is the duration of that signals whose data has been changed. That I can get by knowing the time between two data points in the output file. Can you please suggest how to find the time between two data points in the stored output file?

Below are the code and output file. Baud rate used both in code in minicom: 115200

Thank you advance.

#include <FastAnalogIn.h>
#include <mbed.h>
 
AnalogIn ain0(p20);
AnalogIn Vin1(p18);
AnalogIn Vin2(p19);

DigitalOut sysled(LED1); 
Serial pc(USBTX,USBRX); 
unsigned int cont;
 
// define the maximum number of samples
#define BUFFERSIZE 1024

 
int main()
{       
        //Say the System is Ready to Run
         sysled = 1;

        pc.baud(115200);
        float buffer[BUFFERSIZE],Aout,buffer1[BUFFERSIZE],Vout1,buffer2[BUFFERSIZE],Vout2;
  
        pc.printf("Adc value and Vout1 and Vout2.\n\r"); //send an opening text message 
 
        while(1)
        {
                    
                   buffer[0]=ain0.read();    //reading the analog  value form acclerometer
                   buffer1[0]=Vin1.read();   // reading the analog value of vout1
                   buffer2[0]=Vin2.read();   // reading the analog value of vout2

                    Aout=buffer[0];                 //Assgining the acclerometer input values into output variable through buffer
                    Vout1=buffer1[0];          //Assgining the Vout1 input values into output variable through buffer
                    Vout2=buffer2[0];          //Assgining the Vout2 input values into output variable through buffer
                                        
                        pc.printf("%d %1.3f %1.3f %1.3f\n\r",cont,(Aout*3.3),(Vout1*3.3),(Vout2*3.3));
                        cont++;
             
                
        }
}


OUTPUT FILE Cont Aout Vout1 Vout2

0 1.622 3.297 0.000

1 1.626 3.298 0.000

2 1.625 3.298 0.000

3 1.622 3.298 0.000

4 1.612 3.298 0.000

5 1.632 3.297 0.000

6 1.625 3.298 0.000

7 1.618 3.297 0.000

8 1.624 3.300 0.000

9 1.621 3.298 0.000

10 1.630 3.297 0.000

11 1.622 3.298 0.000

A couple of implementation details that the answers seem to have missed:

You define buffers of 1024 samples but then only ever use the first location in the buffer. That's 12k of RAM that you're allocating but not using, a significant portion of the total amount available. You may well have plans to use it at a later stage in which case that's fine but if it's from a copy/paste or an old version of the code then it's best to tidy it up as soon as it's not needed rather than waiting until you run into lack of memory issues.

Secondly by far the slowest part of your loop is going to be the printf. Both printf and serial ports are painfully slow. If you need better timing resolution then run the loop without a printf and it'll go a lot faster. You can then only output text if the values change by over a certain amount.

One other trick is that the serial port has a 16 byte hardware buffer. Any transmissions over 16 bytes will cause the code to stop and wait until there is space. You are outputting about 20 bytes which means those printfs will stall for around 400us waiting for data to be sent out so that the end of the message will fit into the buffer. If you don't need quite so many decimal places then you can reduce your message to under 16 bytes total and speed things up.

posted by Andy A 10 May 2018

Hi Andy, Thank you very much for your valuable comments and now I have one more question puzzling me.

I'm trying to read my signal which is a very high-frequency signal (i mean it usually has abrupt changes and peaks) and store it in the buffer around 2000 samples when it exceeds my threshold value. After that, I'm trying to send the data to my PC using printf outside the loop so that I can gain the sampling time. Here is the problem when I read the time interval between samples it is around 22us i.e 45.5kHz sampling rate but in the user manual, it was mentioned ADC can go up to 200kHz ...Is there any way to increase the sampling rater as I don't need to miss any peaks between these samples. It will be very helpful if u have any idea to resolve that problem.

<<code>>

  1. include <FastAnalogIn.h>
  2. include <mbed.h>
  1. define NUM_SAMPLES 3000 AnalogIn ain0(p20); DigitalOut sysled(LED1); DigitalOut sysled1(LED2); DigitalOut sysled2(LED3); Serial pc(USBTX,USBRX); float interval,final; Timer t1;

int main() { Say the System is Ready to Run sysled = 1; float buffer[NUM_SAMPLES],aout[1],buffer1[NUM_SAMPLES];

unsigned int j;

pc.baud(115200);

t1.start(); run the timer

pc.printf("apply shock to measure"); while(1) {

aout[0]=ain0.read();

storing into buffer if (aout[0]>0.5) value that is scaled to 3.3*my therhold value { sysled1 =1;

while(j<3000)

{ interval=t1.read_us(); t1.reset(); reading next intrval buffer[j]=ain0.read(); buffer1[j]=interval; j=j+1; }

}

sending the data to my PC

if(j>0&&j<3001) { j; sysled2 = 1; final= ((buffer[j]*3.3)-1.625)/0.002; pc.printf("%d %1.3f %1.3f \n\r",j,final,buffer1[j]);

}

sysled2=0;

}

} <<code>>

Regards, Ranga.

posted by RJ Steve 28 Jun 2018

Hi Andy, Thank you very much for your valuable comments and now I have one more question puzzling me.

I'm trying to read my signal which is a very high-frequency signal (i mean it usually has abrupt changes and peaks) and store it in the buffer around 2000 samples when it exceeds my threshold value. After that, I'm trying to send the data to my PC using printf outside the loop so that I can gain the sampling time. Here is the problem when I read the time interval between samples it is around 22us i.e 45.5kHz sampling rate but in the user manual, it was mentioned ADC can go up to 200kHz ...Is there any way to increase the sampling rater as I don't need to miss any peaks between these samples. It will be very helpful if u have any idea to resolve that problem.

<<code>>

  1. include <FastAnalogIn.h>
  2. include <mbed.h>
  1. define NUM_SAMPLES 3000 AnalogIn ain0(p20); DigitalOut sysled(LED1); DigitalOut sysled1(LED2); DigitalOut sysled2(LED3); Serial pc(USBTX,USBRX); float interval,final; Timer t1;

int main() {

sysled = 1; float buffer[NUM_SAMPLES],aout[1],buffer1[NUM_SAMPLES];

unsigned int j;

pc.baud(115200);

t1.start(); run the timer

pc.printf("apply shock to measure"); while(1) {

aout[0]=ain0.read();

storing into buffer if (aout[0]>0.5) { sysled1 =1;

while(j<3000)

{ interval=t1.read_us(); t1.reset(); reading next intrval buffer[j]=ain0.read(); buffer1[j]=interval; j=j+1; }

}

sending the data to my PC if(j>0&&j<3001) { j; sysled2 = 1; final= ((buffer[j]*3.3)-1.625)/0.002; pc.printf("%d %1.3f %1.3f \n\r",j,final,buffer1[j]);

}

sysled2=0;

}

}

<<\code>>

Regards, Ranga.

posted by RJ Steve 28 Jun 2018

I'm really sorry i couldn't edit the comment and here i'm just paste my code for better clarity.

#include <FastAnalogIn.h>
#include <mbed.h>
 
 #define NUM_SAMPLES 3000
AnalogIn ain0(p20);
DigitalOut sysled(LED1); 
DigitalOut sysled1(LED2);
DigitalOut sysled2(LED3);
Serial pc(USBTX,USBRX); 
float interval,final;
 Timer t1;
 
int main()
{       
        //Say the System is Ready to Run
         sysled = 1;
         float buffer[NUM_SAMPLES],aout[1],buffer1[NUM_SAMPLES];
         
         unsigned int  j;
        
         pc.baud(115200);
       
         t1.start(); //run the timer
        
         pc.printf("apply shock to measure");
         while(1)
         {
                       
                      aout[0]=ain0.read();
                      
         //storing into buffer            
          if (aout[0]>0.5)                          //value that is scaled  to 3.3*my therhold value
          { 
                          sysled1 =1;
                          
                         while(j<3000)
                         
                         {
                             interval=t1.read_us();    //get time interval between two sets of measurements
                             t1.reset();               //reading next intrval 
                             buffer[j]=ain0.read();
                             buffer1[j]=interval;
                             j=j+1;
                          }
                    
          }                                       
        
       //sending the data to my PC
        if(j>0&&j<3001)
        {
                                        j--;
                                        sysled2 = 1;
                                        final= ((buffer[j]*3.3)-1.625)/0.002;                //getting the original shock value                                      
                                        pc.printf("%d %1.3f %1.3f \n\r",j,final,buffer1[j]);
                                     
                                      
         }
             
             
              
                              
                sysled2=0;
        
    
        
    }    
        
}        
posted by RJ Steve 28 Jun 2018

2 Answers

5 years, 11 months ago.

Hello Steve,

One option is to use a Timer to measure the interval between two sets of measurements. Then save this info along with data points as below.

#include <FastAnalogIn.h>
#include <mbed.h>

AnalogIn        ain0(p20);
AnalogIn        Vin1(p18);
AnalogIn        Vin2(p19);
DigitalOut      sysled(LED1);
Serial          pc(USBTX, USBRX);
unsigned int    cont;
Timer           timer;
int             interval;

//define the maximum number of samples
#define BUFFERSIZE  1024

int main()
{   //Say the System is Ready to Run
    sysled = 1;

    pc.baud(115200);

    float   buffer[BUFFERSIZE], Aout, buffer1[BUFFERSIZE], Vout1, buffer2[BUFFERSIZE], Vout2;

    pc.printf("Adc value and Vout1 and Vout2 and Iterval.\n\r");    //send an opening text message
    timer.start();  //run the timer
    while (1)
    {
        interval = timer.read_us();   //get time interval between two sets of measurements
        timer.reset();                //start measuring next interval
        buffer[0] = ain0.read();      //reading the analog value form acclerometer
        buffer1[0] = Vin1.read();     //reading the analog value of vout1
        buffer2[0] = Vin2.read();     //reading the analog value of vout2
        Aout = buffer[0];             //Assgining the acclerometer input values into output variable through buffer
        Vout1 = buffer1[0];           //Assgining the Vout1 input values into output variable through buffer
        Vout2 = buffer2[0];           //Assgining the Vout2 input values into output variable through buffer
        pc.printf("%d %1.3f %1.3f %1.3f %d\n\r", cont, (Aout * 3.3), (Vout1 * 3.3), (Vout2 * 3.3), interval);
        cont++;
    }
}

To get the interval, you can call either timer.read_us() or timer.read_ms() depending on the accuracy required.

NOTE: To keep the format after pasting source code into the editing box please enclose it with tags as shown below.

<<code>>
Source code of your program.
<</code>>

If you need more editing options click on Editing tips in bottom-right corner below the editing box.

Accepted Answer

Hello Zoltan Hudak, I really appreciate your help and thank you for your much for editing the code and it really helps me a lot.

posted by RJ Steve 11 May 2018
5 years, 11 months ago.

Hi Steve,

And to expand on Zoltan's answer... if you want to achieve a desired sample rate (as opposed to as fast as you can - which is what you have) you can readily create a sampling event which you schedule to run with your desired period (in msec) as shown below. Note: this was written for a different target.

// includes
#include "mbed.h"

// defines
#define NUM_SAMPLES 0x100
#define NUM_CHANNELS 3

// Hardware stuff
AnalogIn ain0(PA_0);
AnalogIn ain1(PA_1);
AnalogIn ain2(PA_4);
Serial pc(USBTX,USBRX);
Timer timmy;

// Prototypes
void sample (void);

int main() {

    // start timer and set serial baud rate
    timmy.start();
    pc.baud(115200);

    // create a sampling event
    EventQueue q_sampling;

    pc.printf ("program starting...\r\n");
    wait (3);

    // Set the sampling rate and dispatch it
    q_sampling.call_every (5, &sample);       // 5 msec sample rate
    q_sampling.dispatch();
}

void sample (void) {

     int buffer[NUM_CHANNELS][NUM_SAMPLES];
     static int j=0;

     // perform sampling
     buffer[0][j] = ain0.read_u16();
     buffer[1][j] = ain1.read_u16();
     buffer[2][j] = ain2.read_u16();

     // take timer snapshot... checks accuracy of sample rate
     int us_count = timmy.read_us();
     timmy.reset();

     // print results
     pc.printf ("@%d usec:  %d %d %d \r\n", us_count, buffer[0][j], buffer[1][j], buffer[2][j]);

     // circular buffer management
     j+=1;
     if (j == NUM_SAMPLES)
       j = 0;
}