Skip to content

Difference in esp-01 and esp-12e while implementing serial to wifi bridge #4428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DeshmukhAkshay opened this issue Feb 24, 2018 · 23 comments
Closed

Comments

@DeshmukhAkshay
Copy link

DeshmukhAkshay commented Feb 24, 2018

I am having a project where I use ESP8266 as a serial-to-wifi bridge. I send data serially from a python code running on windows7 to esp8266(esp-01) which it sends to a wifi client running on windows7 again. While sending a pdf file (79 KBs) in a similar fashion, I (due to limiting RAM), opted for a method where i receive serially chunks of file and send it to wifi immediately after receiving. This keeps on happening inside the loop until all the bytes of file are successfully transferred from serial to wifi. Doing this, initially esp8266(esp-01) was loosing some bytes sometimes. I figured there is somehow a mismatch between wifi transfer speed and serial baudrate which results in overflow of serial buffer and thus, loss of few bytes rendering final output file corrupt. So, I reduced baudrate from 500000 to 250000 and things worked fine confirming my theory. The issue is when I am running same code in esp8266(esp-12e), the baudrate 250000 is not enough and it still looses bytes. Further, reducing baudrate to 115200 makes things work almost fine (9 times success and one time lost bytes) while with 9600 baudrate file transfer is 100% success. But baudrate below 250000 is already slower as per my requirement.
My questions are:
1- Is my theory correct? Theory that serially data is coming too fast while receiving it and sending to wifi immediately takes some time, combined with a little slower wifi speed is resulting in overflow of serial buffer sometimes and thus, loss of bytes. (decreasing of baudrate did worked in both hardwares which sort of proves this point but I am not sure)

2- Why the same code do not work fine in esp-12e? Is there any difference in there wifi controller or handling or something else? I created a hotspot in both hardwares and checked their speed which is same (54 Mbps), so it may not be wifi speed but then what?

3- How to overcome this?

A simple version of code i used for testing is as follows:

python code on windows7 (python 3.6):

import serial
import time

ser = serial.Serial('COM4', 250000, timeout=300) 
time.sleep(1)
with open("C:/Users/aatibui/Desktop/current/output.pdf", "rb") as f:
	read_done = f.read()
	ser.write(read_done)

time.sleep(5)

ESP8266 code:

#include <ESP8266WiFi.h>

const char* ssid = "atomic";
const char* password = "int1234";

WiFiServer server(23);
WiFiClient client;

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  Serial.print("\nConnecting to ");
  Serial.println(ssid);

  while (WiFi.status() != WL_CONNECTED) delay(500);
  server.begin();

  Serial.print("Ready! Use 'telnet ");
  Serial.print(WiFi.localIP());
  Serial.println(" 23' to connect");

}

void loop() {
  if (server.hasClient()) {
    if (!client || !client.connected()) {
      if (client) client.stop();
      client = server.available();
      while (client.connected()) {
        while (Serial.available()) {
          size_t len = Serial.available();
          uint8_t sbuf[len];
          Serial.readBytes(sbuf, len);
          client.write(sbuf,len);
          delay(1);
        }
      }
    }
  }
}

Wifi Client code (jdk7):

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.io.DataInputStream;


public class ClientArduinoFile_1 {
     
     public static final int BUFFER_SIZE = 20*1024;
     private byte[] buffer;
     
     public ClientArduinoFile_1() {
          buffer = new byte[BUFFER_SIZE];
     }

     public void startClient() throws Exception {
          Socket socket = new Socket("192.168.0.8", 23);
		  BufferedInputStream in = 
               new BufferedInputStream(socket.getInputStream());

		  BufferedOutputStream out = 
               new BufferedOutputStream(new FileOutputStream("C:/Users/aatibui/Desktop/test123.pdf"));
          
		
          int len = 0;
		  int counter = 0;
		  int bytes = 0;
		  System.out.println("here");
          while ((len = in.read(buffer)) > 0) {
			   
			   System.out.print("bytes: "+len);
			   bytes += len;
			   System.out.print(" ; total: "+bytes);
			   
			   out.write(buffer, 0, len);
               System.out.print(" # ");
			   System.out.println(counter++);
			   if(bytes>=79965){
				   System.out.println("reached end of file");
				   break;
			   }
		}
          in.close();
          out.flush();
          out.close();
          socket.close();
          System.out.println("\nDone!");
     }


     public static void main(String[] args) throws Exception {
          ClientArduinoFile_1 test = new ClientArduinoFile_1();
          test.startClient();
     }

}

The circuit diagram of connection for esp-01 and esp-12e:
ckt dia

@WereCatf
Copy link
Contributor

WereCatf commented Feb 24, 2018

I cannot answer as to if there's physically some difference that causes this issue, but there's a reasonably simple workaround you could use: only transfer, say, how much data it's going to send to the ESP, the data, and then a CRC, have the ESP check the CRC and reply with either a "CRC OK" or "CRC not OK", and in the case of "CRC not OK" have the app resend the payload.

@d-a-v
Copy link
Collaborator

d-a-v commented Feb 24, 2018

In your serial-wifi transfer, don't read more serial data bytes than client.availableForWrite() before writing them to the client.

@devyte
Copy link
Collaborator

devyte commented Feb 24, 2018

Try pr #4328 .

@ghost
Copy link

ghost commented Mar 13, 2018

Before I add to this thread with my similar issue, it looks like that PR has now been merged, and since I downloaded the latest GIT yesterday, AFAIK I've got the new code.

I'm also doing a similar thing, using an ESP-01 (80MHz CPU, 40MHz Flash) and implementing an FTP server using another (much faster) MCU controller that talks to the 8266 via Serial. The master MCU claims to have zero serial-error/drift @ 250KHz, 1MHz & 2MHz. The whole project works perfectly @ 500KHz but quickly fails at anything greater (the next step I tried being 750KHz, but 1MHz does too, and 2MHz, which would be my ideal speed if it worked). I'm fairly [very] sure I lose a byte due to some long WiFi interrupt (the only library I use) that puts the two units out of sync. CRC may well be a solution, if sync. can be re-established, but that's easier to say than it is to implement.

I also tried increasing the 8266 HW/Serial receive buffer size from 256 bytes to 2048. It didn't make a difference.

Given there are 40 clock cycles (80MHz/2MHz) for an interrupt to complete - given the buffer change I mentioned didn't work so I expect it's being blocked, I kind of understand that running the devices at this speed isn't going to work without some ESP experts (not I!) doing something special here... But that's where I'm at... Left with a device that processes files at 40KB/s when it could be going close to 160KB/s.

I feel that's the difference between a nice solution and one that would be rarely used.

@d-a-v
Copy link
Collaborator

d-a-v commented Mar 13, 2018

Can you try reading Serial then sending to WiFi client not more than client.availableForWrite()
(and similarly the other way around, not reading tcp / writing serial not more than Serial.availableForWrite()).
Also, keeping the variable-length-buffer in stack can lead to issues (well, the other way around especially, sizes can be big, stack overflow, exception, all that).

@drmpf
Copy link

drmpf commented Mar 13, 2018

A Serial to WiFi bridge is a common function,
see my projects which include buffering for WiFi transmits
https://www.forward.com.au/pfod/CheapWifiShield/ESP2866_01_WiFi_Shield/index.html
and
https://www.forward.com.au/pfod/CheapWifiShield/index.html
But you still need to limit the serial speed to prevent buffer overrun and loss of data

@devyte
Copy link
Collaborator

devyte commented Mar 13, 2018

Pr #4328 has been merged (post 2.4.1 release), it fixes an issue with the HardwareSerial rx buffering, and is reportedly working up to 2MHz.

@ghost
Copy link

ghost commented Mar 14, 2018

My solution has serial handshaking (data lengths and wait signals) between the two MCUs and the buffer is in global memory.. availableForWrite() should not be needed because Serial comms is fully completed and the other side set to "wait" before WiFi is used (both transmit and receive). Having said that, I expect WiFi interrupts are firing fairly constantly no matter what state the system is in. I also have PR #4328.

My calculation of 40 clocks was wrong, since there's 10 bits in each byte transferred - it's 400 clocks before Serial will possibly lose a byte @ 2MHz.

Questions I might ask the ESP people in the know are, can the Serial interrupt fire when the WiFi Interrupt is running (priority and nesting), if not then what is the max. latency the WiFi interrupt needs (this can be used to calculate the appropriate serial baud setting) and also, if the WiFi interrupt needs to loop and consume >400 clocks, can it service the Serial hardware as a side task while/if interrupts are blocked (so my larger serial buffer is effective).

Thanks everyone.

@ghost
Copy link

ghost commented Mar 15, 2018

I downloaded the tech. specs. for the ESP8266 and I see the hardware serial has 128 byte receive and transmit FIFOs. The uart_start_isr function configures RX for "full" as 100 (giving 28 characters extra to clear the FIFO - 11200 clocks) but I changed this so "full" was just 25 and it did seem to work a bit longer - but still failed.

Sadly, the specs. say little to nothing about how WiFi works. I did read the doco for this project and they say WiFi is serviced at the end of loop() and when you call delay()/yield(). My project has no delays but does exit loop() regularly and I think I saw code in Serial.available() that "optimistically" yields when empty, which I use.

Since I was able to transfer files at a higher speed for bit longer, I ran a diff on the original file each time I uploaded and downloaded it. The files were the same size, but in one case there were two characters different, one about 100KB in to the file and another at about 1.2MB in - the file was 2MB in size. I had not lost a character, but there is a signal problem for me at high speed. That makes me wonder if the upload speed option of 921600 is because the ESP-01 can't reliably do 1000000?

On another attempt, the file transfer didn't complete and I saw this at the end of the short file: (the file is basically 2MB of c++ source code full of text hex values)

	0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, 0x88A2, 0xE5D9,	0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, 0x88B0, 0xE5DC,
	0x88B1, 0xception (28):
epc1=0x402024b4 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000030 depc=0x00000000

ctx: cont 
sp: 3fff3a70 end: 3fff3cb0 offset: 01a0

>>>stack>>>
3fff3c10:  00000200 00000217 3fff2bc8 402024a6  
3fff3c20:  40107028 00000000 00001388 40201414  
3fff3c30:  00000000 3fff59dc 40107028 00000000  
3fff3c40:  00001388 0000001c 3ffee974 00000000  
3fff3c50:  401070d0 00000000 feefeffe 3fff2c88  
3fff3c60:  00000004 0000000b 00000001 0000000a  
3fff3c70:  00000000 0000001c 00000000 feefeffe  
3fff3c80:  00000000 00000000 00000001 3fff2c88  
3fff3c90:  3fffdad0 00000000 3fff2c80 40203f44  
3fff3ca0:  feefeffe feefeffe 3fff2c90 401006ed  
<<<stack<<<
                                                                                                                                                      , 0xE2E8,	0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, 0x7CB1, 0xE2EB,
	0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, 0x7CBD, 0xE2EE,	0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, 0x7CC5, 0xE2F0,
...

Notice the ESP8266 write exception occurred in the middle of my receive from WiFi function (WiFiClient.read() already completed because I'm in the loop that sends back the result over Serial. And, more confusing, my loop has then continued to send 1725 bytes from my buffer (I've not shown it all here) after the exception happened. My 16KB buffer accesses are protected by a limit check:

                if (len > 1024 * 16)
                    len = 1024 * 16;
                l = WFC [sockindex].read (buf, len);
                if (l < 0)
                    l = 0;
                len = l;
                Serial.write (len >> 8);
                Serial.write (len & 0xFF);
                i = 0;
                while (i < len)
                    Serial.write (buf [i++]);

My FTP code doesn't request anywhere near 16KB in these calls as I've limited it in trying to fix this issue. The two MCUs are completely out of sync. at this point too with the master getting back the exception data in the file payload.

The FTP code is hammering this function at this point (all it's doing it asking for data and checking if still connected in a loop - as a disconnect on the data socket signals the FTP file transfer is complete).

Edit: Should say read exception.

@ghost
Copy link

ghost commented Mar 15, 2018

Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
Decoding 9 results
0x40203688: Print at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\libraries\ESP8266WiFi\src/WiFiServer.cpp line 168
:  (inlined by) Server at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/Server.h line 25
:  (inlined by) WiFiServer::WiFiServer(unsigned short) at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\libraries\ESP8266WiFi\src/WiFiServer.cpp line 54
0x40203dd4: operator new(unsigned int) at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/abi.cpp line 84
0x40202414: loop at C:\Users\NoMyth\AppData\Local\Temp\arduino_build_184233\sketch/FTPd3f.h line 113
0x401070d0: gdb_init at ?? line ?
0x40201414: __pinMode at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 34
0x40107028: gdb_init at ?? line ?
0x401070d0: gdb_init at ?? line ?
0x40203f50: loop_wrapper at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 58
0x401006ed: cont_wrapper at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 81

@ghost
Copy link

ghost commented Mar 15, 2018

The one above occurred in the control thread while waiting for a new command from the FTP client.

This one is the data in the file that is mentioned above:

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 8 results
0x402024b8: loop at C:\Users\NoMyth\AppData\Local\Temp\arduino_build_184233\sketch/FTPd3f.h line 139
0x402024aa: loop at C:\Users\NoMyth\AppData\Local\Temp\arduino_build_184233\sketch/FTPd3f.h line 139
0x40107028: gdb_init at ?? line ?
0x40201414: __pinMode at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 34
0x40107028: gdb_init at ?? line ?
0x401070d0: gdb_init at ?? line ?
0x40203f54: loop_wrapper at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 58
0x401006ed: cont_wrapper at C:\Jason\arduino-1.8.5\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 81

The FTPd3f (firmware) has this on line 113:

                WFS = new WiFiServer (port);

The firmware has this on line 139:

                Serial.write (WFC [sockindex].connected ());

For line 139, I expect a byte corruption in sockindex being sent has made it go out of bounds?

@d-a-v
Copy link
Collaborator

d-a-v commented Mar 15, 2018

It is hard to debug the esp-arduino core without a sketch and setup we don't have access to, this is why we need MCVE to reproduce locally and track the bug down.
There are debug options in menu that could help, especially the OOM one. You could also monitor ESP.getFreeHeap(). and it is also needed that ::write(data,len) always returns the len parameter (or take actions if that's not the case).

@ghost
Copy link

ghost commented Mar 15, 2018

I understand. I'm not sure what problem there would be with line 113 but it has only happened once (unlike many other exceptions I've now seen, now that I know where to look and have modified my master sketch to dump serial when something odd happens) but I wasn't expecting it to restart the server listener while I was connected with the FTP client. I suspect the control byte was corrupt and it entered the wrong function in that instance, even though it shouldn't have crashed. I am monitoring heap and it has always been above 25KB too.

What I can now say is, as I increase the Serial baud rate between the two devices, I see more and more serial communication corruptions. I've changed the code to only make WiFi function calls on array members that are instantiated and the exceptions are now all gone. Any bogus sockindex values fail-safe to return values that keep the transfer going. The file transfers however, although always the correct number of bytes transmitted/received in either direction, have more and more data corruptions (detected by running diff) no matter which direction the file is sent.

I'm now confident the software is rock solid. The hardware however isn't. The thing is, I've rewired it 3 times now and there's no difference. Currently the RX on the 8266 is a 5mm long solder trace to master, and the TX is a 12mm wire. Neither are close to any other signal - and I'm not sure I can improve this any further. I had thought maybe the 3.3v regulator isn't up to it, but Serial is the only thing not working while WiFi seems fine. I don't think that is the problem, and it's certainly spec'd for the job.

Adding CRC now seems like the best thing to do, but at 2MHz, the number of corruptions I can see is huge. It also makes the project twice as complicated and not really guaranteed to be any faster with repeat packet sends. I might opt for a couple of test-sketches that test the full range of baud rates to see if there's a fast one both MCUs like. I just can't find any details on this for the 8266.

But, thanks for helping!

@d-a-v
Copy link
Collaborator

d-a-v commented Mar 15, 2018

At this point, we need a MCVE sketch.
If you can try to reproduce this bug with RX bound to TX (like with Serial.swap() and GPIO13+15 linked), we can try and help.

@ghost
Copy link

ghost commented Mar 16, 2018

Sure.. The following sketch is a minimal example, use whatever other MCU with two serial ports you have for master. With twifi=0 you see occasional output like "EL~~-" (E means error but a single byte wasn't lost, L means a single byte was, but EL together just means it's resynchronising after an error followed by two more characters and a minus in the resync). With twifi=1 you get much more output, but I'm not sure if attempting to connect with an FTP client makes it worse - but it does output "Disconnect" and then resyncs with the usual 3 bytes ~~-.

#ifdef ESP8266
#define tmode 0 // 0=Slave 8266, 1=Master for uploading
#else
#define tmode 1
#endif

#define twifi 0 // 0=None, 1=Add WiFi Testing

#define SPEED 2000000 // Test baud rate

#if ((twifi == 1) && (tmode == 0))
#include "ESP8266WiFi.h"
WiFiServer WFS (21);
#endif

unsigned char nexts = 0;
unsigned char nextr = 0;

unsigned char limit = 0;

void setup () {
#if (tmode == 0)
    Serial.begin (SPEED);
    delay (1000);
    Serial.print ("Start1");
    delay (100);
    #if (twifi == 1)
        WiFi.mode (WIFI_STA);
        WiFi.begin ("Network", "Password");
    #endif
    Serial.print ("Start2");
    delay (100);
#else
    Serial.begin (115200); // For Arduino monitor output
    delay (1000);
    Serial2.begin (SPEED);
#endif
}

void loop () {
    int i;
#if (tmode == 0)
    i = Serial.available ();
    while (i--) {
        unsigned char b = Serial.read ();
        if (b != nextr++) {
            if (b == nextr) {
                Serial.write ('L'); // Byte Loss
                nextr = ++b;
            } else {
                Serial.write ('E'); // Bit Error (or multi byte loss, but that's too hard for a minimal sketch)
                nextr = b;
            }
        }
    }

    #if (twifi == 1)
        static int WiFiState = 0;
        if (WiFi.status() != WL_CONNECTED) {
            if (WiFiState) {
                //WFS.end(); // Where did this method go?
                WiFiState = 0;
            }
        } else if (WiFiState == 0) {
            Serial.write ("Start3");
            WFS.begin();
            WiFiState = 1;
        }
        WiFiClient WFC_temp = WFS.available ();
        if (WFC_temp) {
            WFC_temp.stop (); // FTP go away
            Serial.write ("Disconnect");
        }
    #endif
    
    // Comment out for testing receive only
    i = Serial.availableForWrite ();
    while (i--)
        Serial.write (nexts++);
        
#else

    i = Serial2.availableForWrite ();
    while (i--)
        Serial2.write (nexts++);
        
    i = Serial2.available ();
    while (i--) {
        unsigned char b = Serial2.read ();
        if (b != nextr++) {
            
            if (b == 0)
                Serial.write ('Z');
            else if ((b < ' ') || (b > '~'))
                Serial.write ('~');
            else
                Serial.write (b);
            
            if (b == nextr) {
                Serial.write ('-'); // Byte Loss
                nextr = ++b;
            } else
                nextr = b;
                
            if (++limit >= 40) {
                limit = 0;
                Serial.write ('\n');
            }
        }
    }

#endif
}

@ghost
Copy link

ghost commented Mar 17, 2018

Some observations:

1/ Increasing the RX software buffer (to 2KB) does nothing to help the problem in this sketch.

2/ Since RX and TX Serial hardware FIFOs are the same size, I doubt very much you could reproduce this problem with only one module with RX bound to TX.

3/ Even with WiFi off, which reduces errors considerably, I'm seeing one error every ~15MBs transferred on average. I added a byte match success counter to the sketch for that estimate. With WiFi enabled, it's pretty much like I wrote above about my file transfer, one error for every MB transferred. Sometimes you get 3-5MBs or so without errors, but that's rate.

E.G. Master sketch now uses a global unsigned long "checks" variable and says: if (b != nextr++) { ... } else checks++; if (checks >= 1000000) {Serial.write ("MB!\n"); checks = 0;}

@ghost
Copy link

ghost commented Mar 18, 2018

@DeshmukhAkshay : I agree with your initial findings in the OP, my test sketch above still shows regular errors at 500000 baud when WiFi is on, but they almost all go away at 250000 baud on an ESP-01. I don't have a '12e to test with and I'm unlikely to buy one in the future (or any other 8266 based devices now) to test given I can still see errors at 250000 baud. I also agree with you, anything below 250000 makes file transferring via WiFi too slow to be useful for anything but tiny files.

At 250000 baud, I see one error every ~30MBs transferred on average when WiFi is on.

I also did a microsecond-difference test on the two MCUs I'm using, the result (where 1000000 is a perfect match of the two clocks) was 999993. 0.000007us drift per second, since Serial is meant to handle up to 2.5% difference in baud rates, I don't think this difference in clocks used to generate the baud rate is related to the errors.

(Oh, I also meant to write "rare" in my post just above, not "rate".)

EDIT: I tried turning off all WiFi devices in my home except the ESP-01 and the WiFi-Router, it's done 80MB without an error so far on Serial, but that's not useful except to demonstrate where the problem lies.

@ghost
Copy link

ghost commented Mar 25, 2018

@DeshmukhAkshay : I believe there's a bug in the ESP8266 uart.c file that wrongly calculates there are no characters available if the uart isr runs at precisely the "wrong" time. The wrong time being, when moving the FIFO data due to being full or by time-out, and if the software buffer is already completely empty then the two components of "available()" can be 0 if the isr fires in the middle of the addition operation it does. If this is the case while read() has been called (because available() had already told you there was data in the FIFO) it will return -1 as the next character and corrupt your file.

Can you modify your esp library files in the Arduino directory and add this extra line of code and re-try your tests? You may want to get the latest files from here, they have some other fixes to the uart library. You may also want to change your tests to include suggestions made by others here...

In file: uart.c

int uart_peek_char(uart_t* uart)
{
...
  if (!uart_rx_available(uart)) {
    // Since the uart-int may have fired, double check the software buffer again now
    if (uart->rx_buffer->rpos == uart->rx_buffer->wpos)
      return -1;
  }
...
}

Also, if you are going to use faster baud rates, increase the rx buffer size to 512 or 1024:
Use "Serial.setRxBufferSize(1024);" after calling "Serial.begin(...);" (at 2MHz baud, I needed 1024).

@DeshmukhAkshay
Copy link
Author

DeshmukhAkshay commented Apr 3, 2018

Hey, I had also tried same tests on NodeMCU1.0 board just to confirm previous hardware design was correct. It is also giving me same behaviour.
@jasoroony : I tried your suggestions mentioned in above comment(change in uart.c & Serial.setRxBufferSize(1024) with baud rate 250000), it partially solve my problem. Previously, I was not able to transfer file once, but now with NodeMCU1.0(which uses esp-12e) I can transfer the same file which i was trying to transfer previously. But it failed after 4-5 attempts.
Also, I am trying to find out pattern of failure cases.
Can anyone suggest me any other actions?

@ghost
Copy link

ghost commented Apr 3, 2018

Download the latest files from here. They have fixed some issues with the uart.

Other than that, I would say your original analysis was correct, the uart is overflowing (there's now a new Serial method you can use to find out if it has: bool hasOverrun() so you can verify it for sure with that).

If that's true, only send from the PC RxBufferSize (1024) bytes and then make the PC wait for a continue control byte to come back, create a counter in your sketch and when it reaches RxBufferSize and you have passed all the data to the WiFi methods, send back the control byte to tell the PC to resume now you know the Rx buffer is empty.

That's basically what my solution does, and it works now.

@DeshmukhAkshay
Copy link
Author

DeshmukhAkshay commented Apr 4, 2018

@jasoroony can you brief me about how you used hasOverrun() method in your sketch or any other URL/reference.
I had tried searching for its way to used it in sketch, but not yet succeed.

@ghost
Copy link

ghost commented Apr 5, 2018

if (Serial.hasOverrun()) { }

It resets the internal flag every-time you call the hasOverrun method, so you only get a true result once until it overruns again. If you do turn an LED on, you could turn it off after some short time period...

unsigned int t0 = 0;

void loop () {
  // add your code

  // check uart
  if (Serial.hasOverrun()) {
    turn_led_on();
    t0 = millis();
  }
  if (millis() - t0 > 500) {
    turn_led_off();
  }
}

@earlephilhower
Copy link
Collaborator

Looks like a solution to the initial problem was found. The UART code has also been significantly upgraded (esp. relating to overflow) since the opening. Closing for now, but if there is still something please do open a new issue and fill out the requested fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants