0

In many development boards the analog voltage data which is sampled by the ADC can be sent to the serial port. But the data speed I see on the serial port by HyperTerminal or Serial monitor is much slower than the sampling rate.

Lets take Arduino as an example. As far as I understand the analogread() function samples an analog input at 10kHz rate. It means 10000 samples taken per second.

But when I use the Serial Monitor it seems the data speed which we see as upcoming/flowing line by line per second on Serial Monitor is much slower.

Is that because the analogread() is averaging the samples before the data is sent to the serial port?

  • analogRead() doesn't send the samples anywhere. I think you need to look at some example code and then revisit your question. – Roger Rowland Dec 1 '16 at 14:47
  • 2
    That function only reads the ADC value, it doesn't do anything else. The 10KHz you mention is related to how often you can call that function, it has nothing to do with what the rest of the code is doing with that data. – Roger Rowland Dec 1 '16 at 14:52
  • 3
    It can sample at 10kHz, doesnt mean it does. When you analogRead and serialPrint, it does it once and prints once. If you want some sort of running average you have to implement it, there's nothing obscure running in the background. – Wesley Lee Dec 1 '16 at 14:52
  • 1
    Given a sample frequency is 10kHz. Assumed the ADC is 8-bit. You'll need to transfer et-least 800kbit or 100kB a second. Because serial is much slower then the ADC you won't get the 10kHz sample rate until the communication can keep up. – JWRM22 Dec 1 '16 at 14:58
  • 1
    We can't tell what you are seeing on the Serial Monitor because that varies from firmware to firmware. I'll repeat myself: if you use analogRead then Serial.print in a loop, you are seeing all the samples. – Wesley Lee Dec 1 '16 at 15:20
4

If you have a loop that calls analogRead() to take a reading, and then serialPrint() to send the reading, each pass through the loop will take at least the sum of the time for those two functions calls together.

When you first call serialPrint(), it returns in uS, as it doesn't actually send data, but puts it into the 64 deep transmit buffer, to be sent in the background. If the transmit buffer is emptying slower than you are filling it (at 9600 baud, it's sending roughly one character per mS, so you can send at most 100 off 10 character messages per second) then eventually when called, it will find not enough space in the transmit buffer for the whole message, and will Block, that is not return, until there is enough space. Each call to serialPrint() will now take 10mS (assuming 10 characters at 9600 baud). That's what slows your loop down.

To send faster, choose a higher baud rate, and reduce the number of characters in the message.

  • void loop() { val = analogRead(analogPin); // read the input pin Serial.println(val); // debug value } – user16307 Dec 1 '16 at 16:24
  • it is sad that using analogread as above code in a loop we will never know the exact sampling rate right? – user16307 Dec 1 '16 at 16:28
  • The sampling period is the time it takes for a loop to complete. So the rate would be 1/looptime. – Wesley Lee Dec 1 '16 at 16:31
  • @WesleyLee last question. can we trust each loop time will ve equal? thanks – user16307 Dec 1 '16 at 17:05
  • 1
    @user16307: “Can we trust each loop time will be equal?” No, you can't. Sending “1000” takes longer than sending “999”: one more byte to send. And then there is the timer 0 interrupting your code roughly every millisecond: each time it's interrupted, the loop takes ≈ 6.25 µs longer to complete (assuming an AVR-based Arduino). If you want constant sampling rate, forget analogRead() and read the datasheet: the ADC can be auto-triggered by a timer, or even by itself (free running mode). – Edgar Bonet Dec 1 '16 at 20:18
4

As far as I understand the analogread() function samples an analog input at 10kHz rate.

No, it samples an analog input at once per invocation. This means that if it is run 10000 times within a second (assuming it can be run that many times within a second) then the code is sampling at 10kHz. But if it's run only twice per second then the code is sampling at 2Hz.

  • Let me ask the same question to you. When I see the readings in Serial Monitor it is much much slower rate. Let me put it this way. If I use a watch and start and stop sampling for 1 second I must have at least 10000 sampled data by the ADC. But the serial monitor shows much much less lines than that. Why is that happening? – user16307 Dec 1 '16 at 14:59
  • 2
    Because your understanding of how analogRead() works is completely and irredeemably broken. – Ignacio Vazquez-Abrams Dec 1 '16 at 15:01
  • 1
    @user16307 -- "If I use a watch and start and stop sampling for 1 second I must have at least 10000 sampled data by the ADC" That assumption is wrong to begin with, any reasoning based on that will be wrong. – Wesley Lee Dec 1 '16 at 15:18
  • 1
    If during that second you call analogRead once, you will have one sample. – Wesley Lee Dec 1 '16 at 15:18
  • 3
    You get one sample per call. Ever. Always. – Ignacio Vazquez-Abrams Dec 1 '16 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.