How fast ist client.wirte() on MEGA

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

PeterH is correct. I said the same in reply#10. The SPI will handily outrun the serial port.

For example, you can't load a dump truck with bricks using a wheel barrow, then complain that the dump truck isn't delivering bricks fast enough.

For example, you can't load a dump truck with bricks using a wheel barrow, then complain that the dump truck isn't delivering bricks fast enough.

You can if you only put one brick in the truck at a time, as OP is (or was) doing.

My request is based on the lots of tutorial and literature out there where people write simple code as this to show, how client.print will work. It seems to me, I got one level higher in integration...

Thanks all for your replay. I will try some code with the buffer.

I see many examples that use client.println() calls in a non-optimized fashion, as I described earlier. If you are sending one character at a time that is input by skinware on a keyboard, both serial and ethernet can handily outrun that. If the serial port is fed by an automated program that can send constantly at the 115200 speed, I recommend optimizing all interface code as I described above. It all counts.

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

No, no, no. I don't understand why you keep bringing SPI into the problem. It is nothing to do with SPI. It is nothing to do with the CPU speed, or anything requiring knowledge of the processor's design. This is purely about your code reading and writing to the hardware serial ports.

You have code that reads from one hardware serial port, Serial3. For each character it reads, it writes multiple characters to a different hardware serial port, Serial.

This means that it will generate more output than input. Assuming (and we have to assume, since you haven't POSTED YOUR CODE) that the two hardware serial ports are configured similarly, the output buffer will soon fill up. The implementation of the Arduino hardware serial library is that when the output buffer for a serial port becomes full attempts to write further output block (stop) until there is space for the output to be buffered. This means that for each character received, the Arduino will stop and wait for three characters to be transmitted before it tries to read the next character. In other words, it's now only capable of processing the incoming serial stream at a third of the speed it's arriving at. As soon as the receive buffer fills up, the excess input will be discarded.