OLIMEX / ESP32-EVB

ESP32 WiFi / BLE Development board with Ethernet interface, Relays, microSD card
Apache License 2.0
248 stars 107 forks source link

External power supply via barrel connector not stable #57

Closed fredlcore closed 3 months ago

fredlcore commented 5 months ago

I'm maintaining a hardware project (https://www.bsb-lan.de) where probably half of the installations run on an Olimex (either EVB or POE). About a dozen users using the official Olimex power supply have now reported back to me that when they use WiFi on the Olimex, the system becomes unstable which shows in disconnects or slow WiFi connections. The matter immediately changes when powering the Olimex via a stable USB power supply (a laptop's USB for example) and the issues are gone.

I'm not sure whether this is a (external) power supply or (internal) voltage shifting issue. At least It seems that it's not the ampere rating of the power supply because similar problems have also occurred with cheap USB power supplies which rate 2-3A. With these, it seems to be rather the case that the voltage level is not stable enough.

We will now add a recommendation to only power the Olimex via a reliable USB power supply, but since an external power supply is often a good choice, I wanted to let you know about this problem, so that hopefully you can fix it in the next hardware revision.

fredlcore commented 3 months ago

Ok, that would be great, but our serial is pointing to Serial1 which we map to pins 36 and 17 respectively – how is it possible that the invalid data coming from the not completely unpowered CH340T comes in at Serial1? Shouldn't it be coming in on Serial which is on pins 1 and 3? Maybe I haven't really understood the problem on a hardware level, but I would have expected such issues on the Serial Monitor (which is connected to Serial's pins 1 and 3 via the CH340T), not on our board's serial communication.

Last but not least: If that while loop is exited via a timeout, the not completely unpowered CH340T would continue to send data when that function is called in the next loop() iteration. So if there is always invalid data coming in on the same serial input stream that we are polling for new, valid data, our code won't be able to do its job even if it's not crashing, right?

fredlcore commented 3 months ago

One more thing: Could you change line 26 (serial = &Serial1;) in bsb.cpp from Serial1 to just Serial and try it again without your bugfix? If other code using Serial does not have this problem, the problem should go away when we move from Serial1, attached to pins 36 and 17, to Serial (attached to pins 1 and 3). Alternatively, you could also change the RX pin in line 48 in bsb.cpp: Serial1.begin(4800, SERIAL_8O1, rx_pin, tx_pin); If you set rx_pin to 1 (which should be the RX pin for Serial) and the problem goes away, it would be another proof that pin 36 is the issue.

@osro, could you also try this? The connection to the heater won't work then, of course, but just to check whether the ESP32 no longer hangs?

DanKoloff commented 3 months ago

@fredlcore Yeah that also works changing &Serial1 to &Serial

fredlcore commented 3 months ago

Ok, just to confirm, could you go back to Serial1 and replace rx_pin in line 48 with 1? If that also fixes the problem (provided you have removed your bugfixes), we know that pin 36 is the problem. Would you have any idea why pin 36 is affected by the not completely unpowered CH340T?

DanKoloff commented 3 months ago

Again it works. But now I can't get serial output on pin #2 of the EXT1 header. I had only that pin and GND attached to external USB-serial adapter.

No idea about GPI36 (it can't be output by definition btw).

fredlcore commented 3 months ago

One other way to test this would be using one of the webserver/serial sketches that you tried above and worked (presumably because they use Serial) and change these to Serial1 using pin 36 for RX and see if a similar problem occurs.

DanKoloff commented 3 months ago

Other code doesn't hang if I change Serial with Serial1. I did it here:


/*
 WiFi Web Server LED Blink

 A simple web server that lets you blink an LED via the web.
 This sketch will print the IP address of your WiFi Shield (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to turn on and off the LED on pin 5.

 If the IP address of your shield is yourAddress:
 http://yourAddress/H turns the LED on
 http://yourAddress/L turns it off

 This example is written for a network using WPA2 encryption. For insecure
 WEP or WPA, change the Wifi.begin() call and use Wifi.setMinSecurity() accordingly.

 Circuit:
 * WiFi shield attached
 * LED attached to pin 5

 created for arduino 25 Nov 2012
 by Tom Igoe

ported for sparkfun esp32
31.01.2017 by Jan Hendrik Berlin

 */

#include <WiFi.h>

const char *ssid = "Olimex";
const char *password = "Hardware";

NetworkServer server(80);

void setup() {
  Serial1.begin(115200);
  pinMode(4, OUTPUT);  // set the LED pin mode

  delay(10);

  // We start by connecting to a WiFi network

  Serial1.println();
  Serial1.println();
  Serial1.print("Connecting to ");
  Serial1.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial1.println("");
  Serial1.println("WiFi connected.");
  Serial1.println("IP address: ");
  Serial1.println(WiFi.localIP());

  server.begin();
}

void loop() {
  NetworkClient client = server.accept();  // listen for incoming clients

  if (client) {                     // if you get a client,
    Serial1.println("New Client.");  // print a message out the serial port
    String currentLine = "";        // make a String to hold incoming data from the client
    while (client.connected()) {    // loop while the client's connected
      if (client.available()) {     // if there's bytes to read from the client,
        char c = client.read();     // read a byte, then
        Serial1.write(c);            // print it out the serial monitor
        if (c == '\n') {            // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn the LED on pin 5 on.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn the LED on pin 5 off.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {  // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(4, HIGH);  // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(4, LOW);  // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial1.println("Client Disconnected.");
  }
}
fredlcore commented 3 months ago

Strange. Can you set the RX pin to 36 explicitly to make sure it isn't using any other pin? So just to confirm again: Our code works fine if you either assign serial to Serial instead of Serial1, or if you keep Serial1 but set the RX pin to something other than pin 36?

@osro: Could you use the bsb.cpp that @DanKoloff linked above and see if that also fixes the problem for you? Most importantly, could you also look whether you can access the heater? If there is continuously invalid data being generated when the EVB is powered via the barrel connector, then I wonder if the messages from the heater actually get through this "noise"...

DanKoloff commented 3 months ago

Unfortunately, I'm overwhelmed with other tasks and I can't debug this project anymore. That's all I could do. It is really tedious with these 20 minute uploads after changing one variable and my other work is falling behind. My advice is to first recommend powering ESP32-EVB from USB.

fredlcore commented 3 months ago

Ok, understood. We'll do as you suggest and thanks a lot for all the work you put into it. I hope I can figure out more with @osro, and if we come to more conclusive findings, we'll let you know.