Skip to content

Instantly share code, notes, and snippets.

@durlabhjain
Last active August 24, 2020 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save durlabhjain/b9310ed5c5b4d213ce4c8f333d8ea3c9 to your computer and use it in GitHub Desktop.
Save durlabhjain/b9310ed5c5b4d213ce4c8f333d8ea3c9 to your computer and use it in GitHub Desktop.
NodeMCU Upload speed Test
#include <ESP8266WiFi.h>
#define ssid "test"
#define password "test"
#define SERVER "linux.stream4.tech"
#define SERVER_PORT 8000
#define MAX_WIFI_RETRY 10
#define WIFI_RETRY_DELAY 500
#define INITIAL_WIFI_CONNECT_TIMEOUT 2000
#define DEBUG_PRINT(x) Serial.println(x)
#define KB 1000
#define MB 1000000
#define BUFFER_TYPE_INITIAL 0
#define BUFFER_TYPE_HEADER 1
#define BUFFER_TYPE_IMAGE 2
#define IMAGE_DATA_BUFFER_SIZE 1460
long lastDebugMessageTime;
long startTime;
WiFiClient client;
bool flash_read_data(uint8_t *data, uint32_t size, uint32_t address) // Read Data From Flash
{
return true;
}
class ImageStream : public Stream
{
protected:
uint32_t imageSizes[2];
uint32_t imageAddresses[2];
uint32_t totalSize;
uint8_t *imageHeader;
uint32_t imageRemaining;
int8_t currentImage;
uint32_t headerSize;
uint8_t bufferType;
uint32_t remaining;
uint8_t *image_data_buffer;
int bufferPosition;
int bufferSize;
public:
ImageStream(uint32_t size1, uint32_t size2, uint8_t *image_header, uint32_t imageHeaderSize)
{
imageSizes[0] = size1;
imageSizes[1] = size2;
headerSize = imageHeaderSize;
totalSize = headerSize + size1 + size2;
remaining = totalSize;
bufferSize = -1;
imageHeader = image_header;
bufferType = BUFFER_TYPE_INITIAL;
currentImage = -1;
imageRemaining = 0;
bufferPosition = 0;
int bufferSize = IMAGE_DATA_BUFFER_SIZE;
image_data_buffer = (uint8_t *)malloc(sizeof(uint8_t) * IMAGE_DATA_BUFFER_SIZE);
}
virtual void setAddresses(uint32_t address1, uint32_t address2)
{
imageAddresses[0] = address1;
imageAddresses[1] = address2;
}
virtual int available()
{
return remaining;
}
virtual int read()
{
int value = peek();
bufferPosition++;
remaining--;
if (remaining == 0)
{
DEBUG_PRINT("Releasing buffer");
free(image_data_buffer);
}
return value;
}
virtual int peek()
{
if (!remaining)
{
return -1;
}
if (bufferPosition > bufferSize)
{
if (bufferType == BUFFER_TYPE_INITIAL)
{
DEBUG_PRINT("Starting header");
bufferSize = headerSize;
bufferType = BUFFER_TYPE_HEADER;
}
else if (bufferType == BUFFER_TYPE_HEADER || bufferType == BUFFER_TYPE_IMAGE)
{
if (bufferType == BUFFER_TYPE_HEADER)
{
bufferType = BUFFER_TYPE_IMAGE;
}
// if no more of current image is pending, move to next image
if (imageRemaining == 0)
{
DEBUG_PRINT("Starting Image");
currentImage++;
DEBUG_PRINT(currentImage);
DEBUG_PRINT(totalSize - remaining);
imageRemaining = imageSizes[currentImage];
DEBUG_PRINT("Image size");
DEBUG_PRINT(imageRemaining);
}
DEBUG_PRINT("Doing flash read");
bufferSize = imageRemaining > IMAGE_DATA_BUFFER_SIZE ? IMAGE_DATA_BUFFER_SIZE : (int)imageRemaining;
DEBUG_PRINT(bufferSize);
uint32_t address = imageAddresses[currentImage];
if (!flash_read_data(image_data_buffer, bufferSize, address))
{
DEBUG_PRINT("Flash read failed");
return -1;
}
imageRemaining -= (int)bufferSize;
DEBUG_PRINT("Image remaining");
DEBUG_PRINT(imageRemaining);
}
bufferPosition = 0;
}
// notify nrf
// todo: why do we need to notify
// send_data_to_nrf(chk_image_indicator_buffer, 2);
if(bufferType == BUFFER_TYPE_HEADER)
{
return imageHeader[bufferPosition];
}
return image_data_buffer[bufferPosition];
}
virtual void flush()
{
DEBUG_PRINT("Releasing buffer again");
if(remaining > 0) {
free(image_data_buffer);
}
remaining = 0;
};
virtual size_t write(uint8_t data)
{
(void)data;
return 1;
}
size_t size()
{
DEBUG_PRINT("Total");
return totalSize;
}
const char *name()
{
return "5a";
}
};
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
startTime = millis();
lastDebugMessageTime = startTime;
DEBUG_PRINT("starting wifi connection....");
WiFi.begin(ssid, password);
delay(INITIAL_WIFI_CONNECT_TIMEOUT);
}
bool connectWiFi() {
DEBUG_PRINT("Connecting to WiFi");
for(int trial = 0; trial < MAX_WIFI_RETRY; trial++) {
if(trial > 0) {
delay(WIFI_RETRY_DELAY);
DEBUG_PRINT("retrying...");
}
if (WiFi.status() == WL_CONNECTED) {
DEBUG_PRINT("WiFi connected");
// Print the IP address
//DEBUG_PRINT(WiFi.localIP());
return true;
}
}
DEBUG_PRINT("Error connecting to wifi. Aborting...");
return false;
}
uint32_t connectToServer()
{
uint8_t maxRetries = 2;
uint8_t retry_counter = 0;
bool canContinue = false;
for (uint8_t attempt = 0; attempt < maxRetries; attempt++)
{
if(client.connect(SERVER, SERVER_PORT))
{
client.setNoDelay(true);
canContinue = true;
break;
}
}
if (!canContinue)
{
return false;
}
return true;
}
//ImageStream imageStream = ImageStream(200 * KB, 200 * KB,
void loop()
{
uint8_t image_header[40];
uint32_t image1size = 200 * KB;
uint32_t image2size = 200 * KB;
if(connectWiFi())
{
DEBUG_PRINT("creating image stream");
ImageStream imageStream = ImageStream(image1size, image2size, image_header, 40);
uint32_t image1_address = 0;
uint32_t image2_address = 0;
imageStream.setAddresses(image1_address, image2_address);
DEBUG_PRINT("starting upload");
DEBUG_PRINT(imageStream.size());
if (connectToServer())
{
client.println("POST /Handler.ashx HTTP/1.1");
client.println("Host: linux.stream4.tech");
client.println("Content-Type: application/octet-stream");
client.println("Content-Length: " + String(imageStream.size()));
client.println();
client.write(imageStream);
client.stop();
DEBUG("Http Response Code");
}
else
{
DEBUG_PRINT("Error connecting");
}
}
timeTaken();
delay(5000);
timeTaken();
}
void DEBUG(const int number) {
Serial.print(number);
Serial.print("\t");
Serial.println(timeTaken(), DEC);
}
void DEBUG(const String& message) {
Serial.print(message);
Serial.print("\t");
Serial.println(timeTaken(), DEC);
}
long timeTaken() {
long time = millis() - lastDebugMessageTime;
lastDebugMessageTime = millis();
return time;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment