I just can not figure out where the bottleneck is.
The data received from the client is transmitted with the speed of normal serial communication, 115200 baud and therefore 115200 bits/s. Am I right?
But when I try to receive large packets or decrease the delay time to increase transfer speed the ethernet connection seems to slow as data gets lost?
I can not get it faster than ~35 seconds for a 10kb file.
Has someone dealt with a similiar problem?
My whole sketch:
#include <SPI.h>
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include "SdFat.h"
#include "SdFatUtil.h"
//#include "WaveSD.h"
// HTTP TEXT
prog_char string_0[] PROGMEM = "HTTP/1.1 200 OK"; // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "Content-Type: text/html";
prog_char string_2[] PROGMEM = "<HTML><HEAD></HEAD>";
prog_char string_3[] PROGMEM = "<BODY>";
prog_char string_4[] PROGMEM = "<form method='post' enctype='multipart/form-data'>";
prog_char string_5[] PROGMEM = "<input type='file' name='data'><input type='submit'></form>";
prog_char string_6[] PROGMEM = "</BODY></HTML>";
PROGMEM const char *httpText[] =
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5,
string_6 };
#define packetBufSize 128
char buf[packetBufSize+1];
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile logfile;
SdFile soundfile;
//WaveSD wave;
// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
PgmPrint("error: ");
SerialPrintln_P(str);
if (card.errorCode()) {
PgmPrint("SD error: ");
Serial.print(card.errorCode(), HEX);
Serial.print(',');
Serial.println(card.errorData(), HEX);
}
while(1);
}
const int SDchipSelect = 8;
const int EthernetChipSelect = 10;
bool bPlayedSound = false;
bool httpPostDetected = false;
bool httpPostStart = false;
int byteCount = 0;
int saveCount = 0;
String received="";
String boundary="";
// Ethernet Configuration
Server server(80);
static uint8_t mac[] = {
0x90, 0xA2, 0xDA, 0x00, 0x22, 0x2F };
static uint8_t ip[] = {
192, 168, 178, 100};
static uint8_t gateway[] = {
192, 168, 178, 1};
//////////////////////////////////// SETUP
void setup(void) {
Serial.begin(115200);
pinMode(EthernetChipSelect, OUTPUT);
pinMode(SDchipSelect, OUTPUT);
useSD();
PgmPrint("Free RAM: ");
Serial.println(FreeRam());
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
// breadboards. use SPI_FULL_SPEED for better performance.
if (!card.init(SPI_FULL_SPEED, 8)) error("card.init failed");
// initialize a FAT volume
if (!volume.init(&card)) error("volume.init failed");
// open the root directory
if (!root.openRoot(&volume)) error("openRoot failed");
logfile.remove(&root, "playlog.txt");
useEthernet();
Ethernet.begin(mac, ip, gateway);
server.begin();
}
void loop(void)
{
useEthernet();
// listen for incoming clients
Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank && !httpPostDetected) {
sendHtml(client, server);
break;
}
else if (c == '\n' && httpPostDetected && !httpPostStart) {
if (boundary == "") {
PgmPrint("TEST1\n");
Serial.print(received);
int search = received.indexOf("boundary=");
if (search!=-1)
{
boundary = received.substring(search+9);
PgmPrint("BOUNDARY READ\n");
}
}
else {
int search = received.indexOf(boundary);
if (search!=-1)
{
PgmPrint("BOUNDARY DETECTED\n");
PgmPrint("POST DATA START\n");
PgmPrint("AVAILABLE BYTES: ");
Serial.println(client.available());
delay(1);
useSD();
if (!logfile.open(&root, "playlog.txt", O_WRONLY | O_APPEND | O_CREAT))
error("can't open log file");
useEthernet();
httpPostStart = true;
}
}
received = "";
byteCount = 0;
}
else if (c == '\n' && !httpPostDetected) {
PgmPrint("NEW LINE\n");
// you're starting a new line
currentLineIsBlank = true;
int search = received.indexOf("POST");
if (search!=-1)
{
httpPostDetected = true;
PgmPrint("POST DETECTED\n");
}
received = "";
} /*
else if (c == '\n' && httpPostStart) {
currentLineIsBlank = true;
received.concat(c);
Serial.print(c);
if (httpPostStart) {
++byteCount;
if (byteCount==packetBufSize) {
PgmPrint("PACKET END\n");
save(received);
received = "";
byteCount = 0;
}
}
}*/
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
received.concat(c);
Serial.print(c);
if (httpPostStart) {
while (client.available() > 0) {
c = client.read();
buf[byteCount] = c;
++byteCount;
if (byteCount==packetBufSize) {
//PgmPrint("PACKET END\n");
save(buf);
byteCount = 0;
}
}
}
}
}
else if (httpPostStart){
PgmPrint("Free RAM: ");
Serial.println(FreeRam());
useSD();
// IMPORTANT: close log file to flush any unwritten changes
logfile.close();
useEthernet();
PgmPrint("LAST POSTED DATA: ");
Serial.println(buf);
httpPostDetected = false;
httpPostStart = false;
boundary = "";
sendHtml(client, server);
break;
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
void sendHtml(Client client, Server server)
{
PgmPrint("SEND SERVER HTML");
char buffer[65]; // make sure this is large enough for the largest string it must hold
// send a standard http response header
for (int i = 0; i < 2; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(httpText[i]))); // Necessary casts and dereferencing, just copy.
client.println( buffer );
}
client.println();
for (int i = 2; i < 7; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(httpText[i]))); // Necessary casts and dereferencing, just copy.
server.print( buffer );
}
}
void save(char* data)
{
++saveCount;
useSD();
logfile.write(data);
delay(500);
if (saveCount==5) {
logfile.sync();
saveCount=0;
}
useEthernet();
}
void useEthernet()
{
digitalWrite(EthernetChipSelect, LOW);
digitalWrite(SDchipSelect, HIGH);
}
void useSD()
{
digitalWrite(SDchipSelect, LOW);
digitalWrite(EthernetChipSelect, HIGH);
}