How fast ist client.wirte() on MEGA

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:

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());
}

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.

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: 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.

@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 SPI - Arduino Reference. I wonder why my code accumulate the rx buffer. Maybe the serial3.available() takes as much time as serial3.read(). Any ideas?

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.

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.

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.

PeterH:
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.

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.

// 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?

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:

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....

That look almost like mine! :slight_smile:

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.

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

Forget client.write(). It is your serial output which is causing the problem.

PeterH:
Forget client.write(). It is your serial output which is causing the problem.

Are you saying the SPI is to slow? Is it not running a 4Mhz?

Forget client.write().

That is unwise. Both should be taken into account. The serial speed is the limiting factor here, but do not penalize yourself by not optimizing both interfaces.

edit: PeterH is correct about the speed limit. You can't send characters faster over the ethernet than you are receiving them on the serial port.

markuszelg:
Are you saying the SPI is to slow? Is it not running a 4Mhz?

No, I'm saying that SPI is irrelevant to your problem.

Your problem is caused by the fact that the output serial stream is congested, which is preventing you from servicing the input serial stream. Both of these are massively slower than the SPI bus; the SPI bus is not the problem.

Okay, now we are deeply in the processors design.
I understood the protocol speed is not the limit in my use case (stream von NanoSerial->Serial3 on Mega->SPI MegaOut->Ethernet). Limiting is the processors handling of each buffer. And this is in same speed. With the fact of handling spi-transfer for each char, the code requests more processor time for serial out (over SPI) than the serial3.read on input site. Hence, the buffer goes full.

What options do i have? 1. speed up serial out handling in the processors register or 2. speed up serial spi sending with buffer as coded above?