Pages: [1] 2   Go Down
Author Topic: beginner needs some advice on ADC sampling rate and wifi module  (Read 2310 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't used Arduino till now.
For my project, I need 5 ADCs with 10 bit resolution and sampling speed of 1kSps for each channel. Then I need to transfer these values to a PC via Wifi. For Wifi, I found RN-131 wifi module which can communicate with a microcontroller (aurduino) via Tx, Rx pins. My setup will be like Arduino -> RN-131 -> PC

Considering my required sampling rate of ADCs, baud rate for trasmitting data to RN131, can I choose arduino for my project?
Have people already worked on RN131 with arduino?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino is sampling at about 15 kSps (the 6 input are multiplexed so you may get about 3 kSps with 5 inputs used).

I already use a RN-XV XBee from Roving Networks which is based on the RN-171 module. The two modules are probably similar enough to tell you that this will work for you. I get transfer rates of about 1Mbit/s (not from the MCU to the WiFi but direct network traffic) so your 100kbit/s (5 integer values 1000 times per second) should not pose a problem if your WiFi network is robust enough to allow that speed.
« Last Edit: May 21, 2012, 07:11:06 am by pylon » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The 16 MHz Arduino clock has to be divided down to 125 KHz to get full 10-bit resolution.  In auto-trigger mode it takes 13.5 cycles to get each value. That's a little over 9000 samples per second so using Timer/Counter1 to auto-trigger an analog conversion every 200 microseconds (5000 samples per second) should not be a problem.

Getting 50,000 bits per second to your PC should be no problem if the WiFi module supports 115200 baud or higher.

Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The 16 MHz Arduino clock has to be divided down to 125 KHz to get full 10-bit resolution.  In auto-trigger mode it takes 13.5 cycles to get each value. That's a little over 9000 samples per second so using Timer/Counter1 to auto-trigger an analog conversion every 200 microseconds (5000 samples per second) should not be a problem.
Be aware though, that there is a single shared ADC and that with back to back use of it, the previous reading may impact the current. A workaround for this is to read twice, discarding the first reading. If you were to do this though, you would need to be doing 10K samples/s which, from the foregoing, won't be achievable.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Be aware though, that there is a single shared ADC and that with back to back use of it, the previous reading may impact the current. A workaround for this is to read twice, discarding the first reading. If you were to do this though, you would need to be doing 10K samples/s which, from the foregoing, won't be achievable.

So what is the maximum usable sampling rate one can get for 10bits? Has anyone already tested it?
Thanx
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 602
Posts: 33362
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Be aware though, that there is a single shared ADC and that with back to back use of it, the previous reading may impact the current.
That is only true if the input impedance to the ADC is significantly higher than 10K.
Keep it at 10K and you can sample at the maximum rate.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As I recall the normal sample time is 104 uS. What you can do is sample and keep processing (an interrupt will tell you when the sample is ready). Then you can be sending the previous sample while you start the next one. That way you don't have to sample, send, sample, send and so on, where the sending time will slow down the sample rate.

I would have thought that the WiFi was the limiting thing here, but perhaps not. Can you send the results in about 200 uS via WiFi?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just checked the sampling rate by transferring via serial. With this code (below), I could get sampling rate of ~530 sps for each channel. If I read just 1 channel I get ~2100 sps.
void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(analogRead(A0));
  Serial.println(analogRead(A1));
  Serial.println(analogRead(A2));
  Serial.println(analogRead(A3));
}


Is there anyway I can improve this code for better sampling rate?

What you can do is sample and keep processing (an interrupt will tell you when the sample is ready). Then you can be sending the previous sample while you start the next one. That way you don't have to sample, send, sample, send and so on, where the sending time will slow down the sample rate.

How do I implement this interrupt. Could give me some more hints?

thanx
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Be aware though, that there is a single shared ADC and that with back to back use of it, the previous reading may impact the current.
That is only true if the input impedance to the ADC is significantly higher than 10K.
Keep it at 10K and you can sample at the maximum rate.

If you need to sample a with a source resistance greater than 10K, patching the analogRead code to add a short delay between switching the multiplexer and starting the conversion avoids the need to take 2 readings and is more effective. For example, a delay of 10us (increasing the overall anologRead time from 110us to 120us) is good for source resistance up to 100K.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How do I implement this interrupt. Could give me some more hints?

Here:

http://www.gammon.com.au/interrupts

Scroll down to "Read the Analog-to-Digital converter asynchronously".
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My problem is more with the serial transfer. I am getting a very slow transfer speed. Here is my code:

Serial.begin(115200) ;
start = millis() ;
  for (i = 0 ; i < 1000 ; i++)
    Serial.println(analogRead(A1)) ;
  }

The output is 418 msec (1000 calls) .

I tested to transfer without reading from ADCs:
Serial.println(1);      gives: 248 msec (1000 calls)
Serial.println(111);   gives: 418 msec (1000 calls)

which is far less than baud rate of 115200.

If I have to read 5 ADC pins and transfer via serial in every loop, that means to call Serial.println 5 times a loop, it will take more than a second to complete 200 loops. It will decrease my sampling frequency for each channel to less than 200Hz

How can I solve this problem?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The theoretical minimum time to transfer 4000 bytes (3 digits plus newline) using a 115200 baud line is 347ms. An overhead of 70ms is not that bad at all.

You could make that a lot faster by using binary transfer instead of ASCII. A 10 bit reading of an analog input doesn't have to use up to 50 bits on the line (4 digits plus newline, all times 10 bits).
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25768
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could overlap reading with sending; initiate a conversion then send the result of the previous conversion.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Serial.println(1);      gives: 248 msec (1000 calls)
Serial.println(111);   gives: 418 msec (1000 calls)

which is far less than baud rate of 115200.

The println adds a carriage-return and a newline. That's another two bytes.

Since there are 10 bits per byte (8 + start + stop bits) you can transfer 11520 bytes per second, that is one per 86.8 uS.

To transfer "1" + cr + newline (3 bytes) will take 260 uS (you got 248 so you are doing well).

To transfer "111" + cr + newline (5 bytes) will take 434 uS (you got 418 so you are doing well again).

As others suggested, sending the "raw" data could be faster, although it would be important to stay in sync.

You could overlap reading with sending; initiate a conversion then send the result of the previous conversion.

...

What you can do is sample and keep processing (an interrupt will tell you when the sample is ready). Then you can be sending the previous sample while you start the next one.

Yes, good idea.

But you can see that sending 4 bytes is going to take 347 uS which is about 3 times the time it takes to take a sample. You may have to revise your expectations. Or change your design. Send one full sample and then a difference.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just tried sending the binary, but I think I am doing the wrong way.
Serial.println(111, BIN);  gives 759 msec (1000 calls)
Logged

Pages: [1] 2   Go Up
Jump to: