Problem using a ESP32 to measure WiFi internet speed
Posted: Mon May 03, 2021 2:23 pm
I'm trying to program my ESP32 to monitor my home WiFi internet speed, but I am getting strange results and could use your help. (I understand that my ESP32 will be unable to measure my WiFi at speeds much over 20Mbps, but that's fine as long as I can record speeds up to around that number.)
I'm testing the time it takes to do a HTTP.GET() request and fully retrieve a large (600KB-15MB) JSON file I have hosted on Amazon S3. To get the full JSON file, I am using the HTTP Stream example from https://github.com/espressif/arduino-es ... Client.ino. I am simply reading the data into a small memory buffer, piece by piece, and doing nothing with it. When I get to the last piece of data, I stop the timer.
However, on a plenty-fast WiFi connection, I am recording a download speed of only about 0.29 Mbps. My understanding is that in real-world practical tests of the ESP32 people are seeing more like 10-30Mbps. This makes me believe I am doing something wrong. Perhaps the method I have chosen to measure the download speed is bottlenecked by the computing operations I have chosen. Perhaps I should be testing the speed using UDP? Am I currently doing it via TCP/IP? This area is not my strength.
Here's the snippet of relevant code:
I have run this code retrieving various size JSON files, here are the results:
// SMALL FILE
09:44:27.842 -> Payload (bytes): 651.09KB
09:44:27.842 -> Payload (bits): 5.20872Mb
09:44:27.842 -> Payload Delivery Time: 17.847s
09:44:27.842 -> Download Mbps: 0.291854
// MED FILE
09:47:35.855 -> Payload (bytes): 3672.16KB
09:47:35.855 -> Payload (bits): 29.3773Mb
09:47:35.855 -> Payload Delivery Time: 104.666s
09:47:35.855 -> Download Mbps: 0.280677
// LARGE FILE
09:56:22.549 -> Payload (bytes): 14688.6KB
09:56:22.549 -> Payload (bits): 117.509Mb
09:56:22.549 -> Payload Delivery Time: 407.169s
09:56:22.549 -> Download Mbps: 0.288601
I see examples of people seeing much higher speeds on their ESP32 projects:
10-16 Mbps: https://github.com/martin-ger/esp32_nat ... erformance (homepage: https://serverkernel.com/how-to-turn-es ... -repeater/)
20-30 Mbps: https://www.reddit.com/r/esp32/comments ... le_seeing/
Any tips on what I'm doing wrong? And how I can accurately write a script to measure the WiFi speed?
I'm testing the time it takes to do a HTTP.GET() request and fully retrieve a large (600KB-15MB) JSON file I have hosted on Amazon S3. To get the full JSON file, I am using the HTTP Stream example from https://github.com/espressif/arduino-es ... Client.ino. I am simply reading the data into a small memory buffer, piece by piece, and doing nothing with it. When I get to the last piece of data, I stop the timer.
However, on a plenty-fast WiFi connection, I am recording a download speed of only about 0.29 Mbps. My understanding is that in real-world practical tests of the ESP32 people are seeing more like 10-30Mbps. This makes me believe I am doing something wrong. Perhaps the method I have chosen to measure the download speed is bottlenecked by the computing operations I have chosen. Perhaps I should be testing the speed using UDP? Am I currently doing it via TCP/IP? This area is not my strength.
Here's the snippet of relevant code:
Code: Select all
HTTPClient http;
http.begin("http://aws-example.s3.com/file.json");
int httpCode = http.GET();
if(httpCode > 0) {
if(httpCode == HTTP_CODE_OK) {
int remainingFileSize = http.getSize();
// create buffer for read
uint8_t buff[1460] = { 0 };
// get tcp stream
WiFiClient * stream = http.getStreamPtr();
// read all data from server
while(http.connected() && (remainingFileSize > 0 || remainingFileSize == -1)) {
// get available data size
size_t size = stream->available();
// start timer
unsigned long startMillis = millis();
// iteratively read all the data into the buffer, and do nothing with it.
if(size) {
// read up to 1460 byte
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
// do nothing with the data
if(remainingFileSize > 0) {
remainingFileSize -= c;
}
}
}
// end timer
unsigned long endMillis = millis();
}
float download_sec = (float) (endMillis - startMillis) / 1000;
int get_size = http.getSize();
float payload_kbytes = (float) get_size / 1000;
float payload_mbits = payload_kbytes*8 / 1000;
float download_mbps = payload_mbits/download_sec;
Debug.print(DBG_VERBOSE, "Payload (bytes): %gKB", payload_kbytes);
Debug.print(DBG_VERBOSE, "Payload (bits): %gMb", payload_mbits );
Debug.print(DBG_VERBOSE, "Payload Delivery Time: %gs", download_sec);
Debug.print(DBG_INFO, "Download Mbps: %g", download_mbps);
}
// SMALL FILE
09:44:27.842 -> Payload (bytes): 651.09KB
09:44:27.842 -> Payload (bits): 5.20872Mb
09:44:27.842 -> Payload Delivery Time: 17.847s
09:44:27.842 -> Download Mbps: 0.291854
// MED FILE
09:47:35.855 -> Payload (bytes): 3672.16KB
09:47:35.855 -> Payload (bits): 29.3773Mb
09:47:35.855 -> Payload Delivery Time: 104.666s
09:47:35.855 -> Download Mbps: 0.280677
// LARGE FILE
09:56:22.549 -> Payload (bytes): 14688.6KB
09:56:22.549 -> Payload (bits): 117.509Mb
09:56:22.549 -> Payload Delivery Time: 407.169s
09:56:22.549 -> Download Mbps: 0.288601
I see examples of people seeing much higher speeds on their ESP32 projects:
10-16 Mbps: https://github.com/martin-ger/esp32_nat ... erformance (homepage: https://serverkernel.com/how-to-turn-es ... -repeater/)
20-30 Mbps: https://www.reddit.com/r/esp32/comments ... le_seeing/
Any tips on what I'm doing wrong? And how I can accurately write a script to measure the WiFi speed?