Go Down

Topic: breaking at 115200bps (Read 1 time) previous topic - next topic

ars

Hello,
Is it not possible to obtain continuous values from an analog pin using analogRead at 115200 bps without any breaking taking place? At lower rates like 38400 , the readings are continuous. Is this a core problem?

Coding Badly

Is it not possible to obtain continuous values from an analog pin using analogRead at 115200 bps


analogRead does not have a "bps".  Are you referring to Serial?

Quote
without any breaking taking place?


What breaking would that be?

Quote
At lower rates like 38400 , the readings are continuous. Is this a core problem?


What problem?

ars

I meant while performing : Serial.print(analogRead(A0)); command....by breaking I mean that , the values come continuously for about maybe 10 times, then a small delay happens and then the next 10 values come one after the other, this happens again and again while at lower bps the values are obtained continuously one after the other.

Coding Badly

Quote
the values come continuously


Into what?

ars

I am just experiencing a delay between the readings on the serial monitor at 115200 bps whereas there is no delay in case of lower bps like 38400 . How can I prevent this?

Nikarus

I've never had a problem with not getting data in the serial monitor.
Perhaps theres something happening in your code? Perhaps you could post it.

robtillaart


@16Mhz you can do about 8000 analog reads per second. => 8000 ints (x2 bytes)

1 analogRead takes 125 micros.
to send it @115200 takes ~200 micros minimal
to send it @38400 it takes ~600 micros miminal

so at 115200 it takes at least 325 micros to send one reading
and at 38400 it takes at leasr 725 micros

So on average 115200 will be showing twice++ as many samples per second as the 38400 does.

I assume the delay you see is caused at the receiving end, as that end is probably a multitasking box that is mostly busy with switching threads ...

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

ars

This is my code:
void setup() {
  Serial.begin(115200);
}

void loop() {

int valp=map(analogRead(A0),0,1023,0,1600);
float valp1 = (float)valp/100.00;
int vali=map(analogRead(A1),0,1023,0,4000);
float vali1 = (float)vali/1000.00;
int vald=map(analogRead(A2),0,1023,-45,45);

Serial.print(valp1);Serial.print("\t");Serial.print(vali1);Serial.print("\t");Serial.print(vald);Serial.println("");
}


Here, it's almost as if I am missing out some of the data at 115200 bps . A bulk of data comes then a delay then a next bulk of data and so on...however lower bps does not result like this.

PeterH


the values come continuously for about maybe 10 times, then a small delay happens and then the next 10 values come one after the other,


What do you call a 'small delay' and where is this apparent?
I only provide help via the forum - please do not contact me for private consultancy.

michael_x

Quote
where is this apparent

Just out of curiosity:

What happens when you flood the output buffer with Serial.write() ? (without reading it - fast enough / not at all)

How does Serial.flush() detect the output buffer being read ?
Is the Tx LED permanently on ?
Is Serial.println() blocking ?

I understand there's no hardware handshake signal, correct ?

stevonavich

This is likely caused by the output buffer on the arduino. Most of the time the buffer will only write it's contents out over serial (flush) when it is full or finds a newline. So in your case, since there are no newlines, the first 10 or so values get written to the buffer, but not written over serial, so they write very quickly, then the buffer gets full so it flushes out all 10 values (the 11th read has to wait so there is a delay), the now empty buffer will gather 10 more values.... cycle continues. This should give you much more consistent times:

Code: [Select]
Serial.write(analogRead(A0));
Serial.flush();


AWOL

Quote
Most of the time the buffer will only write it's contents out over serial (flush) when it is full or finds a newline.

How do you figure that?
"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.

stevonavich


Quote
Most of the time the buffer will only write it's contents out over serial (flush) when it is full or finds a newline.

How do you figure that?


Well I suppose it's not quite true, not that you made me look for it. I assumed the output would be line buffered, like stdout on most UNIX systems, though I now suppose that is not the case.

Unfortunately I can't find much documentation on the actual implementation of the serial functions so I looked in HardwareSerial.cpp and it seems that the output gets written whenever a certain interrupt handler gets called and pushes it out. I can't find the definition of that interrupt handler, and I also am not sure what causes that interrupt, so I can only guess that at a large baud rates the variation caused by using asynchronous writing becomes noticeable, so perhaps it simply is not interrupted often enough and that 10 or so values enter the buffer before the interrupt handler is called and flushes them out. They then write so quickly that the time it takes to write is comparable to the time it takes for the interrupt to be called again. At low baud rates this waiting for the interrupt may be negligible, but not at high rates.

Does this sound reasonable? If you have any more information on how the serial writing actually happens it would be very welcomed.

SirNickity

The idea of the interrupt handler is that your print call dumps the contents into a ring buffer and returns immediately.  Then an ISR checks the ring buffer, and if non-empty, writes a byte via serial I/O until empty.

I don't remember for sure, but I think Serial.write sidesteps this and just does a blocking write to serial right there and then.

gerg

From time to time I read posts like this and would like to remind everyone that you have an 8 bit safe serial interface. If performance is critical, requiring 7-bit ASCII data is silly for several reasons.

  • Value expansion - a single value (16-bit value; large enough to hold a 12-bit sample) will expand up to four bytes on output.

  • Separator - To know the start and stop of each digit, one needs a separator sentinel of some type (tab, space, coma, etc.) - add a byte.

  • Conversion overhead -  It takes time to convert a binary value into ASCII representation. The bigger the number, the more time it requires.



As a result, a simple two byte integer can expand up to five bytes on output. Available, effective bandwidth, on the serial interface is now 1/5 of the selected baud rate. Clearly not a high performance solution.

I hope more people start trying to transfer binary data on their 8-bit serial interface. As you can see, it can be a serious win to save bandwidth and CPU time.

Great, so now you have a bunch of garbage which isn't exactly human readable. There are lots of tools which will display binary data as hex, decimal, and ASCII. With little code in python, its not terribly difficult to then dump a binary stream into ASCII on your computer, where you have tons of computing power relative to the Arduino.

Go Up