Maximum Data Rate

Hello Golam,
I am trying to understand how much effective data I can send using 9600 baud rate of arduino uno.
I have written the below code and I get 1028 samples ('s' char) in 1 second. Considering we can only have 960 characters/sec we can send, How is it possible?

unsigned long myTime;
bool flag = 1;
void setup() {
  Serial.begin(9600);
}
void loop() {
  myTime = millis();
  char str = 's';
  while (millis() - myTime <= 1000 && flag == 1) {
    Serial.print(str);
  }
  flag = 0;
}

1. You have 1028 samples/sec; each sample bears 16-bit data (range: 0x0000 - 0x03FF).
2. If you do BINary transmission, you can send 9600/20 = 480 samples in 1-sec.
3. If you do ASCII transmission, you can send 9600/40 = 240 samples in 1-sec.
4. If you want fast transmission, go with hardware UART Port at higher possible Bd.

Thanks for the quick reply.
Can i know why each sample bears 16-bit data? (so each letter is 2 bytes?)
I mean using the above code. In 1 second I got 1028 's' printed to serial. This means that 9600 / 1028 = 9.3 (seems like each sample or 's' is about 9 bits)? How is this possible?

The ADC of UNO converts a sampled signal into 10-bit binary (b9 - b0) and then six 0s are appended for the upper six bit (b15 - b10) to make it 16-bit. 8-bit makes a byte; so, 16-bit will yield 2-byte.

I meant by samples, 's' char that gets printed to the serial terminal.
so 1028 's' got printed, meaning that using a baud rate of 9600, we got 1029 characters in 1 second.
When using baud rate 115200, we got 11848 characters in 1 second got printed.

How are you determining this? If using the timestamps in the Serial Monitor, you should note the timestamp 'granularity', natively seems to be 55 ms(it's the old Windows 'tick' issue), so you might be counting slightly more than a second's worth of output? Better to let it run for 10 seconds, that reduces the error by 10.
C
(correction, 47 ms per jump in the Serial Monitor timestamps.)

At Bd = 115200, it should be (theoretically) 11520 characters in 1-sec as the frame length is 10. However, considering the transmission line delay and the processing time, it is expected to get less characters printed in 1-sec and your 11848 is erroneous.

1 Like

By the way, can you stand a reduction in resolution? Transmitting a single value between 0 and 255 for each measurement would significantly improve your potential bandwidth. That, of course, is up to you, as the receiving end would also need to be able to convert an incoming value between 0 and 255 into whatever your analytical/graphical process would use. If that's not possible, then even transmitting two bytes instead of four would be preferrable. Every second value would be between 0 and 3, so easily synchronized.
Alternately, since every sample is between 0 and 1023, you could break the sample into two 6-bit values and transmit them(consider each value as 5-bits, and add it to )x20). A bit more manipulation, but better than the burden your current ASCII approach uses.

1 Like

The main issue is that we need to send data using Bluetooth LE (RN4020 Module) and to send data through it, we need to send it using UART from a microcontroller.
For example, to send a number to a service characteristic, we need to send this command using UART "SUW,001C,4424", where SUW is the write command, 001C is the service characteristic Handle and 4424 is the data being sent.
I have tried sending it using a 115200 baud rate, and it was printed 790 times (10270 characters).
Does anyone know how to send this data using a more efficient way?

Another question, how do I create a variable that can only hold 6 bits?

Huh? a byte holds 8 bits. A couple of simple math operations can convert the upper 5 bits of your 10-bit ADC result into a character. Ditto with the lower 5 bits. You're really fixated on byte/word lengths, aren't you? Maybe, figure out how ASCII fits into all this?
As an example, a 32-character lookup table could represent your 5-bit value, so receiving two such characters could accurately transfer your 10-bit value. Lots of tricks can be played. You can synchronize that, if necessary, by setting a six bit on one of the two characters so that a single mangled or missing character doesn't destroy your data stream.
You've identified an issue, but not really itemized the constraints. I'm not fishing today, so I'm done. It's not even your thread. Open a new thread, follow the instructions for getting the best out of the forum, and maybe we'll see it there.
C

Ok will open a thread
Thanks for the info

I'm not being deliberately rude, by the way - one of the reasons adding onto old threads is discouraged (it's called "necroing" a thread), is because when someone necros a thread, rarely is enough context given in the new question, because the poster has read through the old thread to figure out what to ask, and just asks a pointed question - like yours. Anyone responding has little chance of answering the right question unless they read the whole thread, and even then there's a lot of missing context, so it's better to push new posters to open their own thread, after reading the guidelines. Looking forward to your improved description of your application and need!
C
C

1 Like

And I'm not on the beach…

a7

@nabil_miri, please do not hijack. Thread split.

9600 baud on UART:

  • a baud is 10 bit: 8 data bits plus a Start and and Stop bit

  • a Stop bit could be also two periods (two stop bits)

So, max. throughput is:

  • 9600 / 10 = 9.6 Kbps

But: any UART transmitter needs time to get the next character, even on a PC. You do not know what the gap between two UART characters sent is.

Also bear in mind:
when you send UART via USB - the USB has a timing; It might send just every 1 ms a new packet (up to 64 characters). If you send single bytes - they might come in very 1 ms only (never mind what the baudrate is - the USB "protocol" sets the speed).
So, USB UART with single characters sent can slow down to:

  • 1 KHz for 8 bits user character = 8000 bps for user UART traffic (even your baudrate is 9,600 which does not matter how fast it is, when USB is involved)

The AVR Arduino code has a 64byte software "transmit buffer", and two bytes of hardware buffering, that can be filled essentially instantly. So when you think you've sent 1028 bytes, you've actually only sent 1028-66 = 962 bytes. Allowing for inaccuracies in timing, that's about right.
See also Serial.flush();

I wouldn't overthink this, gang. He hasn't answered a blessed thing all afternoon, we still don't know where his time values came from, or what he really wants to do, and hasn't started a new thread. I think he's AWOL.
C

USB UART?
1 character every 1ms? (1 KHz)
It ends up in 1000 characters per seconds (you get 960).

When USB is involved - the timing comes from the USB UART "protocol", not anymore from baudrate or UART speed. Check USB CDC or VCP devices...

That is why UARTs always have buffers to remove any gap, :face_with_raised_eyebrow: