ESP32-S3 powering problems

I’m currently using an ESP32-S3 16mb, 2x 2.8” LCD screens via SPI, 1x 74LS04, SD Card reader, speaker and keypad. Currently the SD Card reader is not connected to power.

When I connect power to my ESP32-S3, it will no longer initialize the screens on its own… unless I connect the usb-c. The setup I’m using is a breadboard power supply, capable of supplying 1A to the circuit. I have the +5v rail of the breadboard connected to the Vin on the ESP32, the 2 screens and the 7404.

When my code was 2500-ish lines and only 150,000 lines in header files (mostly graphics), I had no problems. Turn on the power supply, ESP32 boots and initializes the screens and runs the program no issues. The ESP32 has an onboard green LED that blinks 5 times during boot.

My program currently is about 3500+ lines of code w/ about 250,000 lines in header files (mostly graphics). Now when I turn on the power, the ESP32 still does the 5 blinks on the green LED and boots, but will not initialize the 2 screens. The screens just stay blank white. I know the program is running because the speaker plays a tone when certain keypad buttons are pressed. Sometimes, after pressing the reset several times, it will boot and initialize the screens. But, if I have the USB-c cord plugged in, either to my pc or a USB power supply, it will boot and initialize the screens w/o issue.

I’ve metered the power draw on the circuit and it draws no more that 160mA when booting/running. I’ve tried a delayed reset w/ the 7404 in combination w/ an RC circuit. I’ve tried to delay the initialization of the screens in the code. I’ve tried putting delays in the screen init function. I’ve tried a different ESP32 module. I’ve even gone back several revisions of my program, when the code was about 2500 lines and that old code works w/o having the USB plugged in. Nothing in the screen init functions/code has change from any of the revisions.

Since I can’t actually see the failure via the serial monitor, because with the USB plugged in it works, I can’t tell if the screens just fail to initialize or if it’s the ESP32 or a power problem. Could it be that the increased code/graphics is drawing more power? Wouldn’t think so, since the memory is still there, just not filled. But, what do I know? I guess I could wire an LED light to a spare pin and light it when the screens init…

Does anyone have any suggestions?
Thank you in advance

// LCD Display control signals using Hardware SPI 
#define TFT_S1_CS_PIN        14         // Screen 1 Chip Select
#define TFT_S2_CS_PIN         8         // Screen 2 Chip Select



TFT_eSPI tft = TFT_eSPI();                   // Create instance for TFT Screen(s) -> 1 instance for 2 screens w/ soft /CS



void Initialize_Screens(void) {
    
  pinMode(TFT_S1_CS_PIN, OUTPUT);               // Screen 1 chip select set to output
  pinMode(TFT_S2_CS_PIN, OUTPUT);               // Screen 2 chip select set to output
  
  delay(10);                                    // Let settle

  digitalWrite(TFT_S1_CS_PIN, HIGH);            // Initial /CS setting
  digitalWrite(TFT_S2_CS_PIN, HIGH);            // Initial /CS setting

  digitalWrite(TFT_S1_CS_PIN, LOW);             // Select Screen 1
  digitalWrite(TFT_S2_CS_PIN, LOW);             // Select Screen 2

  Serial.print("Initalizing Both LCDs... ");  
  delay(25);                                    // Give time for /CS setup
  tft.init();                                   // Initialize Screen(s)
    
  digitalWrite(TFT_S2_CS_PIN, HIGH);            // De-Select Screen 2
  tft.setRotation(1);                           // Set rotation of screen 1 
  tft.fillScreen(TFT_BLACK);                    // Clear screen
  digitalWrite(TFT_S1_CS_PIN, HIGH);            // De-Select Screen 1
  digitalWrite(TFT_S2_CS_PIN, LOW);             // Select Screen 2
  delay(25);                                    // Give time for screen setup
  tft.setRotation(1);                           // Rotate
  tft.fillScreen(TFT_BLACK);                    // Set rotation of screen 2
  digitalWrite(TFT_S2_CS_PIN, HIGH);            // De-Select Screen 2
  delay(10);
  dblbuffer.createSprite(DOUBLEBUFFER_X, DOUBLEBUFFER_Y); // Set sprite dimensions

  tft.setTextSize(1);
  tft.setTextColor(TFT_BLACK);
  Serial.println("done");  

}

Note that it could still be powered through the SPI wires.

I have never seen one. Please post a link.
Most breadboard supply top at 700mA with 6volt input, and that drops to 100mA with a 12volt input. Mainly due to thermal limitations.
So what is the input voltage.
Leo..

Leo,

Thank you for the reply.

Note that it could still be powered through the SPI wires.

I will disconnect those and try.

I have never seen one. Please post a link.
Most breadboard supply top at 700mA with 6volt input, and that drops to 100mA with a 12volt input. Mainly due to thermal limitations.
So what is the input voltage.
Leo..

I don’t have a link for the power supply since I’ve had these for over 10yrs. It uses the AM1117 5.0 regulator which is rated for 1A. “While rated for 1A, sustained operation above 500mA–800mA requires good thermal management (heatsinking).” Regardless, the circuit still only draws 160mA max. The breadboard power supply is powered by a 12v 1A wall wart.

But still, I can’t comprehend why more code will cause this issue. I’m not the greatest programmer and my code is strictly procedural and doesn’t currently have any interrupts.

*Side note, I just comprehended the comment you wrote about the 100ma w/ 12v supply.

I have 5v 2A power supplies that I will connect directly to the circuit tomorrow. Thanks

The AMS1117 will BARELY supply 160mA at that input voltage.

At 12v, AMS1117 will output approximately 143mA safely.

What is your reasoning for that choice. Is your house cold?
Drop that input voltage to 7-9volt regulated, or use a buck converter.

A 5volt cellphone charger with USB socket is a good choice.
Leo..

Lol, I literally have over 50 12v power wall warts of varying amps. I can get them for free and it’s just what I happened to have. I’ve never had a problem before, but my projects were limited in scope. I just do this as a hobby for fun. This was the 2nd project I’ve done w/ an ESP32 and the 1st of this size.
I’ve changed out the power supply w/ a direct 5v supply and everything seems to be working as intended.
Thank you for the information about the AMS1117 chip, as I didn’t realize.

Thank you for you help.

Ok, I switched to a USB breakout board for power. I have tried both USB-C and Micro USB breakout boards. Although, it has helped, it still hasn’t fixed the problem. Now the screens initialize about half the time. These are plugged into a USB 2A wall plug, into the Vcc of both screens and to the Vin on the ESP32. When power is applied, the screens stay white and won’t initialize. The ESP32 is doing what it’s suppose to. I can’t tell because I have audio feedback when a button is pressed. Sometimes, if the reset button is pressed, the screens will initialize and sometimes they won’t. But, if I also use the USB-C port on the ESP32 connected to my pc, the initialize w/o any problems 99% of the time. My code to init the screens is above. I’ve tried various delays after each line give the ESP io pins time to “settle” before continuing. Thank you for your help.

Not enough experience with tft screens, some experience with four screens on one S3 and the Adafruit library, but pretty sure you can't have two active at the same time.
Leo..

From my research this is required in order to initialize both screens. The next lines of code…

 tft.init();                                   // Initialize Screen(s)
    
  digitalWrite(TFT_S2_CS_PIN, HIGH);            // De-Select Screen 2
  tft.setRotation(1);                           // Set rotation of screen 1 

calls the init function then de-selects screen 2 to set the parameters for screen 1.

This program/sketch, I work on a specific section, troubleshoot, test and correct any errors and once I’m happy with the results, I save the program. Then I save the program as the next version number. I’m currently on save version 39. I rewrote and finalized the initialize screens function back in version 3 and have been using it since.

I will try to call the tft.init() separately and see what effect that has. But, I don’t think that part of the code is the problem, then again anything could be the problem. In my first post I said that this wasn’t a problem until my code reached a certain size 3500+ lines of code w/ 250,000 lines in header files which was around version 32. So 30 versions of my code and no issues. I can reload one of the prior v32 sketches and no problems. This is why I was thinking it was a power problem due to more code being stored on the ESP32.

For some reason your prior suggestion of getting rid of the AM1117 power module did help for a while. But as my code gets larger this has seemed to arise again.

I do thank you for helping and brainstorming w/ me to resolve this issue.

Hi, @cmndr-brain
I am no TFT or SPI expert but doing this;

  Serial.print("Initalizing Both LCDs... ");  
  delay(25);                                    // Give time for /CS setup
  tft.init();                                   // Initialize Screen(s)

Having both screens on at the same time when you tft.init() , and SPI being bi-directional, means you are not just sending signals to the screens at the sametime, BUT recieving signals from both screens at the same time.
Instead of one at a time.
Can I suggest you move the init command down a few lines to where you have one CS1 pin active only.
Then add the init to further down your code where you have CS2 pin active only.

I understand that tft.init intialises comms with each screen, you cannot intialise comms with both at the same time, there may be subtle reply signals timing from each screen.
That is, one may be slower than the other to respond to commands.

As I said I am no SPI or TFT expert, just thats how it looks to me.

OR
Make two instances of tft if the library will allow.

Thanks.. Tom.... :smiley: :+1: :coffee: :australia:

Part of my research about these screens was reading several articles, code examples and videos. Here are 2 videos that show to select both screens and initialize them at the same time.

Driving 2 Screens (view @ 6:27)

Multiple SPI Displays (view @ 27:10)

I guess there might be a misunderstanding as to what is going on. My code has worked fine with initializing the screens all along, until I’ve reached a certain size in my code (it seems). Keep in mind, I haven’t changed any of the initialization code since version 3, I’ve only added more code using those same functions. It seems that when my code got to a certain size, the screens started having problems initializing. My program is currently on vers. 40 now. Everytime I add new code and test, I save it as a new version. I can go back to vers. 32, upload the sketch and everthing works. Both screens initialize everytime, with or w/o being connected to my pc. But, as I added more code, graphics and images, now the screens don’t init everytime, unless the ESP32 is connected to my pc.

And that’s the strange bit, which is why I’ve reach out for help. I’m using a 5v 2A wall adapter to power the screens AND the ESP32 via the Vin pin. All grounds are common. When I just have the power from the wall adapter, the screens fail to initialize about 90% of the time when I power cycle or press the reset button. BUT… when I have the USB-C cord from my pc connected to the ESP32 also, the screens initialize everytime. This is why I thought it was a power problem and not a coding problem. Eventually, I’d like this project to be able to run on it’s own w/o being plugged into my pc.

Thank you for the suggestions, it’s all appreciated.

SWAG: It could well be a coding problem (two SPI peripherals active at the same time) causing a power problem.

If anything in your code tries to read from the display(s), you're going to have both of them trying to drive the MISO line at the same time. With two peripherals driving the MISO line at the same time, unless both of them are changing the state of the MISO line at the same infitessimal-second (something way way way smaller than a picosecond), you'll be running into the situation where, for a very brief period, but repeated each and every time you do a read, one displays will have its MISO line set HIGH and the other, LOW. Result: current spikes. That's a recipe for wacky behaviour, and not the fun kind either. The kind that manifests itself in weird, impossible to debug, "why is THAT happening all of a sudden" ways.

If that is indeed what's happening (and without seeing the code in question, it's impossible to say) the hack/fix is to disconnect one or both MISO lines. And don't read anything from the displays. Personally, I still wouldn't do that. Writing to two SPI peripherals at once is asking for trouble. It's a bad habit to start. Sooner or later, it'll bite you. But you know, you're the one with the problem, not any of us. So, do as you will, and good luck figuring it out!

Update: So I de-coupled the tft.init function from initializing both screens at the same time to initializing them separately. Screen 1 still wouldn’t initialize 50% of the time unless the USB-C cord was plugged into the device, in which it would initialize every time. But, the 2nd screen would initialize 99% of the time. I added 10k pullup resistors to the screen Chip Select lines as I read a suggestion in another thread. This helped and screen 1 would now initialize 80% of the time. So, I added a loop to initialized the screens twice. If either screen wouldn’t initialize the 1st time, it would always initialize the 2nd time.
With this added code, the ESP32 after being off for a while, wouldn’t boot at all. The red power light would come on, but no green blinky blinky. Manually pressing the reset button or grounding the reset pin would fix the problem and boot. At this point, I’m still thinking its a power problem. So I researched this new problem and ran across this thread (ESP32 runs program only after EN pressed), on the ESP32 forum. I guess I’m not the only one with these problems. Long story short, GPIO pin 0 is tied to the “BOOT” signal. So, per the recommendations of the article, I added a 10k pullup resistor, tied to 3.3v to GPIO 0. So far, this has seemed to fix all the problems. I have a little more testing to do, but I can see both screens initialize twice upon power up or reset. I’m going to remove the double inits and see if the screens still work every time. If not, I just leave the redundant inits and move on.