Go Down

Topic: How fast ist client.wirte() on MEGA (Read 2078 times) previous topic - next topic

Feb 11, 2013, 11:20 am Last Edit: Feb 11, 2013, 03:14 pm by markuszelg Reason: 1
Hi

I try to send a Serial stream from Serial3 (MEGA) direct to the Ethernet BreakOut in a while loop. It turns out, the serial3.read() is much more faster (serial.begin(115200)); than the SPI attached client.wirte() function. The 63 Byte buffer on Serial3 is full after 3 while cycles. Does anyone know how fast the client.print(c); function shifts data out over SPI to the ethernet chip?
I used to have a client.write(HEADERSTRING) with the F() function. But this takes me directly to a full rx buffer.

Here's my template code:
Code: [Select]

EthernetClient client.
serial3.begin(115200);
char c;

//SEND REQUEST
serial3.print(REQUESTSTRING);
while (do wait until CHARSTART is arriving) {}

// SREAM RESPONSE TO ETHNERT SHIELD
while (serial3.available()) {
c=serial3.read();
if (c==CHAREND) break;
else client.print(c);
//for debug over serial 1 to my pc only:
serial.println(serial3.available());
}

Nick Gammon

I don't see any SPI transmission there, and I doubt that even that snippet would compile, as it is "write" not "wirte".

Read this before posting a programming question

Please post all your code.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PaulS

In addition, the fact that you are Serial.print()ing in the loop will slow down the loop.

You are better off collecting the data from the serial port into an array, and client.print()ing the whole array.

@PaulS: whole array: hmm.. may by my architecture is wrong: I do a external eeprom dump from a attached nano over serial to the MEGA. this will take me up to 1KB of data. buffing this amount of data is hard with MEGA. right?

@Nick: client.write() will write over SPI, no? I was not looking into #include <SPI.h> #include <Ethernet.h>. But one may find out, the SPI will go this way.

Does anyone know how fast the SPI port communication speed. I was once (a long time ago) reading 10Mhz.

PaulS

Quote
@PaulS: whole array: hmm.. may by my architecture is wrong: I do a external eeprom dump from a attached nano over serial to the MEGA. this will take me up to 1KB of data. buffing this amount of data is hard with MEGA. right?

Yes, and no. Yes, a 1K buffer is a real challenge.

But, why not establish handshaking with the remote device? Send it a request for data, say 64 bytes. Collect those 64 bytes. Send them to the client. Ask the remote device for 64 more bytes. Collect them, send them, lather, rinse, repeat.

There is no reason that the remote device has to tell its whole life store without pausing to breathe.

#5
Feb 11, 2013, 12:34 pm Last Edit: Feb 11, 2013, 01:02 pm by markuszelg Reason: 1
@PaulS: you're right. When my direct streaming design cannot handly timing issues, I do need to switch to this 64byte-sample approach. However, I will need to redisign my protocol. That's to say, it's only sending full information today.

Knowing the speed of ethernet SPI, I could go down one step with my serial speed. Does anyone knows about the speeds?

Update: default for SPI is 4 Mhz see http://arduino.cc/en/Reference/SPI. I wonder why my code accumulate the rx buffer. Maybe the serial3.available() takes as much time as serial3.read(). Any ideas?

PeterH

Why do you mention SPI at all? I don't see any SPI I/O happening here.

You're reading characters from a hardware serial port Serial3. For every received character, you print several characters on a different serial port Serial1.

Since you HAVEN'T SHOWN US ALL YOUR CODE we can't see how those serial ports were configured but I will guess they're running at the same speed. So naturally you will find that the output stream is the limiting factor and prevents your sketch from processing the input stream at its full speed.

This could be made to work if you change your sketch to only print one output character per input character, although it wouldn't be very resilient. For a more robust solution you would ensure that the output stream was at less than 100% capacity when the inputs were at 100% capacity. The best way to do that would be to run the output port at a higher speed.
I only provide help via the forum - please do not contact me for private consultancy.

SurferTim

#7
Feb 11, 2013, 02:33 pm Last Edit: Feb 11, 2013, 02:45 pm by SurferTim Reason: 1
Quote
Does anyone know how fast the client.print(c); function shifts data out over SPI to the ethernet chip?

If this is an ethernet shield, I see SPI I/O. Should I point it out to everyone?

edit: Listen to PaulS. This will certainly help. Send the array as one packet, instead of each character in its own packet.
Quote
You are better off collecting the data from the serial port into an array, and client.print()ing the whole array.


Yes, the ethernet shield. as in http://arduino.cc/en/Main/ArduinoEthernetShield.
I still have no clue how fast the SPI is in respect to the Serial.read() when setting up the serial.begin(115200). Any ideas.


For a more robust solution you would ensure that the output stream was at less than 100% capacity when the inputs were at 100% capacity. The best way to do that would be to run the output port at a higher speed.

That's exactly what I'm asking for. What's the speed of client.write() in respect to serial3.read() setting up by 115200bps.

SurferTim

I think you are limited to 4MHz on the SPI bus with the w5100. However, sending an array of characters is much more efficient that one character per packet. The overhead becomes a real speed problem.
Code: [Select]
// this takes 6 packets
client.print('h');
client.print('e');
client.print('l');
client.print('l');
client.print('o');
client.println();

// this takes one packet
client.println("hello");


The w5100 4MHz SPI speed should handily outrun the serial port's 115200.

!! UPDATE in code on the top of this post with some general settings to clearify my request.

@SurferTim: Just for be clear: You're saying the function call to 'client.print' is takeing more cpu runtime than it would be with serial3.read(). In my case: jumping during the while-loop every time to client.print will take more time (@16Mhz ATmega2560) than the serial3 will shift into rx buffer?

SurferTim

That could be the case. Every call to the following functions generates a separate packet.
client.print()
client.println()
client.write()

There are at least 48 bytes of overhead with each packet, plus the time required to send them individually.

What about this:
Code: [Select]

byte counter=0;
char buffer[15];

while (serial3.available()) {
c=serial3.read();
if (c==CHAREND) break;
else {
   buffer[counter]=c;
   if (counter==15) {
    client.print(buffer);
    counter=0;
   }
   else counter++;
}

Then of course I need the handle the half empty buffer with a '\0' char at the end....

SurferTim

That look almost like mine!  :)

edit: Insure you empty that after you have received all the serial data. The last buffer may not fill up, so transmit what you have before closing the connection.

Go Up