Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
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
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.
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; }
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 2018Hi 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>>
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 2018Hi 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>>
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 2018I'm really sorry i couldn't edit the comment and here i'm just paste my code for better clarity.