Serial not working on Nano ESP32

Hello. I got a new Arduino Nano ESP32 and I am using it for a project. I wanted to use Serial to test but nothing comes up in the Serial Monitor. After uploading, the nano disconnects from the computer making the reconnecting longer because I have to press the reset button multiple times for it to reconnect. Simple codes work and I think my code may have things that block it from continuing.

Here is part of the setup function:

void setup() {
  i2s_set_pin(I2S_NUM_0, &pin_config);
  Serial.begin(9600);
  GPRS.begin(9600, SERIAL_8N1, 5, 6);
  u8g2.begin();
  u8g2.setFont(u8g2_font_6x10_tf);
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  delay(3000);
  Serial.print("a");
  if (!SD.begin(10)) {
    u8g2.clearBuffer();
    u8g2.drawStr( 0, 0, "SD CONNECTION FAIL");
    u8g2.sendBuffer();
    while (!SD.begin(10)) {delay(100);}
  }
  Serial.print("b");

Please post your full sketch

String pversion = "PAN version 2.0.0.0";

#include <WiFi.h>
#include <esp_wifi.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <U8g2lib.h>
#include <HardwareSerial.h>
#include "AudioFileSourceID3.h"
#include "AudioOutputI2S.h"
#include "AudioGeneratorWAV.h"
#include "AudioFileSourceSD.h"
#include <driver/i2s.h>
#include <ArduinoBLE.h>

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define SELECT 4
#define CNTRLA 5
#define CNTRLB 6
#define CNTRLX 7

int curLine = 0;
int ls;
bool button[8];
int batteryState = 0;
String vtype;
String sec[10] = {"0","0","0","0","0","0","0","0","0","0"};
String line;

const int dataPin = 8;
const int clockPin = 7;
const int latchPin = 4;

static const i2s_pin_config_t pin_config = {
  .bck_io_num = 8,
  .ws_io_num = 9,
  .data_out_num = 18,
  .data_in_num = I2S_PIN_NO_CHANGE
};

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
HardwareSerial GPRS(1);

AudioFileSourceSD *source = NULL;
AudioGeneratorWAV *wav = NULL;
AudioOutputI2S *out = NULL;
AudioFileSourceID3 *id3 = NULL;

File sysFile;
File varFile;
File mapFile;
File spkFile;

void stopLoop() {while(true) {delay(100);}}

void error(int ec) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setCursor(0,0);
  u8g2.print("INTERNAL ERROR " + String(ec));
  u8g2.setCursor(0,10);
  u8g2.print("LINE: " + String(curLine));
  u8g2.setCursor(128 - (pversion.length() * 6), 54);
  u8g2.print(pversion);
  u8g2.sendBuffer();
  sysFile.close();
  mapFile.close();
  varFile.close();
  stopLoop();
}

void cvar() {
  SD.remove("/sys/ram.txt");
  varFile = SD.open("/sys/ram.txt", FILE_WRITE);
}

void playwav(String path) {
  source = new AudioFileSourceSD();
  source->open(path.c_str());
  id3 = new AudioFileSourceID3(source);
  out = new AudioOutputI2S();
  wav = new AudioGeneratorWAV();
  wav->begin(id3, out);
  while (wav->isRunning()) {
    if (!wav->loop()) wav->stop();
  }
  source->close();
}

void updateButtons() {
  digitalWrite(latchPin, LOW);
  digitalWrite(latchPin, HIGH);
  for (int i = 0; i < 8; i++) {
    if (digitalRead(dataPin) == HIGH) {button[i] = true;} else {button[i] = false;}
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
}

void checkPowerLevel() {
  int rledd = analogRead(A0);
  int bledd = analogRead(A1);
  bool rled;
  bool bled;
  if (rledd >= 512) {rled = true;} else {rled = false;}
  if (bledd >= 512) {bled = true;} else {bled = false;}
  if (rled && !bled) {batteryState = 1;}
  else if (!rled && bled) {batteryState = 2;}
  else if (!rled && !bled) {batteryState = 3;}
}

void splitLine() {
  int index = 0;
  int wn = 0;
  while (index >= 0) {
    int spaceIndex = line.indexOf(' ', index);
    if (spaceIndex >= 0) {
      sec[wn] = line.substring(index, spaceIndex);
      wn++;
      index = spaceIndex + 1;
    } else {
      sec[wn] = line.substring(index, spaceIndex);
      wn++;
      break;
    }
  }
}

String getVar(String var) {
  int lineNumber = 0;
  String bar;
  varFile.seek(0);
  while (varFile.available()) {
    bar = varFile.readStringUntil('\n');
    lineNumber++;
    if (bar.substring(0, bar.indexOf(",") - 1) == var) {break;}
  }
  return bar.substring(bar.indexOf(",") + 1, bar.indexOf("#") - 1);
}

void mkVar(String varn, String val, String t) {
  varFile.seek(varFile.size());
  varFile.print(varn);
  varFile.print(",");
  varFile.print(val);
  varFile.print("#");
  varFile.println(t);
}

void setVar(String varn, String val) {
  String varll = getVar(varn);
  varFile.seek(0);
  String d = "";
  while (varFile.available()) {
    d += char(varFile.read());
  }
  varFile.close();
  cvar();
  d.replace(varn + "," + varll, varn + "," + val);
  varFile.print(d);
}

String getVarType(String var) {
  int lineNumber = 0;
  String line;
  varFile.seek(0);
  while (varFile.available()) {
    line = varFile.readStringUntil('\n');
    lineNumber++;
    if (line.substring(0, line.indexOf(",") - 1) == var) {break;}
  }
  return line.substring(line.indexOf("#") + 1, line.length());
}

String val(String inp) {
  if (inp.substring(0, 1) == "$") {vtype = getVarType(inp.substring(1,inp.length())); return getVar(inp.substring(1,inp.length()));}
  else if (inp.substring(0, 1) == "\"") {vtype = "s"; return inp.substring(1,inp.length() - 1);}
  else {vtype = "i"; return inp;}
}

String operators(String argo) {
  String partv[3];
  String part[3];
  String partt;
  int index = 0;
  int wn = 0;
  while (index >= 0) {
    int spaceIndex = argo.indexOf(' ', index);
    if (spaceIndex >= 0) {
      partv[wn] = argo.substring(index, spaceIndex);
      wn++;
      index = spaceIndex + 1;
    } else {
      partv[wn] = argo.substring(index, spaceIndex);
      wn++;
      break;
    }
  }
  part[0] = val(partv[0]);
  partt = vtype;
  part[2] = val(partv[2]);
  if (partt == "i") {
    if (part[2].substring(0,1) == "~") {part[2] = String(~part[2].toInt());}
    if (part[1] == "=") {setVar(partv[0], part[2]); return "";}
    else if (part[1] == "+") {return String(part[0].toInt() + part[2].toInt());}
    else if (part[1] == "-") {return String(part[0].toInt() - part[2].toInt());}
    else if (part[1] == "/") {return String(part[0].toInt() / part[2].toInt());}
    else if (part[1] == "*") {return String(part[0].toInt() * part[2].toInt());}
    else if (part[1] == "%") {return String(part[0].toInt() % part[2].toInt());}
    else if (part[1] == "==") {if (part[0].toInt() == part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == ">") {if (part[0].toInt() > part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == ">=") {if (part[0].toInt() >= part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == "<") {if (part[0].toInt() < part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == "<=") {if (part[0].toInt() <= part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == "!=") {if (part[0].toInt() != part[2].toInt()) {return "true";} else {return "false";}}
    else if (part[1] == "&&") {if (part[0] == "true" && part[2] == "true") {return "true";} else {return "false";}}
    else if (part[1] == "||") {if (part[0] == "true" || part[2] == "true") {return "true";} else {return "false";}}
    else if (part[1] == "+=") {setVar(partv[0], String(part[0].toInt() + part[2].toInt())); return "";}
    else if (part[1] == "-=") {setVar(partv[0], String(part[0].toInt() - part[2].toInt())); return "";}
    else if (part[1] == "*=") {setVar(partv[0], String(part[0].toInt() * part[2].toInt())); return "";}
    else if (part[1] == "/=") {setVar(partv[0], String(part[0].toInt() / part[2].toInt())); return "";}
    else if (part[1] == "&=") {setVar(partv[0], String(part[0].toInt() & part[2].toInt())); return "";}
    else if (part[1] == "|=") {setVar(partv[0], String(part[0].toInt() | part[2].toInt())); return "";}
    else if (part[1] == "^=") {setVar(partv[0], String(part[0].toInt() ^ part[2].toInt())); return "";}
    else if (part[1] == "%=") {setVar(partv[0], String(part[0].toInt() % part[2].toInt())); return "";}
    else if (part[1] == "<<") {return String(part[0].toInt() << part[2].toInt());}
    else if (part[1] == ">>") {return String(part[0].toInt() >> part[2].toInt());}
    else if (part[1] == "&") {return String(part[0].toInt() & part[2].toInt());}
    else if (part[1] == "|") {return String(part[0].toInt() | part[2].toInt());}
    else if (part[1] == "^") {return String(part[0].toInt() ^ part[2].toInt());}
    else if (part[1] == "<<") {return String(part[0].toInt() << part[2].toInt());}
  }
  else if (partt == "s") {
    if (part[1] == "+") {return part[0] + part[2];}
    else if (part[1] == "==") {if (part[0] == part[2]) {return "true";} else {return "false";}}
    else if (part[1] == "!=") {if (part[0] != part[2]) {return "true";} else {return "false";}}
    else if (part[1] == "+=") {setVar(partv[0], part[0] += part[2]); return "";}
  }
  else if (partt == "b") {
    bool partb[2] = {"true", "true"};
    if (part[0] == "true") {partb[0] = true;}
    if (part[2] == "true") {partb[1] = true;}
    if (part[0] == "false") {partb[0] = false;}
    if (part[2] == "false") {partb[1] = false;}
    if (part[2].substring(0,1) == "!") {partb[2] = !partb[2];}
    if (part[1] == "==") {if (partb[0] == partb[1]) {return "true";} else {return "false";}}
    else if (part[1] == "&&") {if (partb[0] == true && partb[2] == true) {return "true";} else {return "false";}}
    else if (part[1] == "||") {if (partb[0] == true || partb[2] == true) {return "true";} else {return "false";}}
  }
}

void getLine(int lineNumber) {
  // Get //
  mapFile.seek(lineNumber * 10);
  sysFile.seek(mapFile.readStringUntil('\n').toInt());
  line = sysFile.readStringUntil('\n');
  // Compress //
  while (!line.indexOf("(") >= 0) {
    int maxin = 0;
    int j = 0;
    int cur = 0;
    String arg;
    for (int i = 0; i < line.length(); i++) {
      int now = 0;
      if (line.substring(i, i + 1) == "(") {now++;}
      else if (line.substring(i, i + 1) == ")") {now--;}
      if (now < maxin) {now = maxin;}
    }
    while (j >= line.length()) {
      if (line.substring(j, j + 1) == "(") {cur++;}
      else if (line.substring(j, j + 1) == ")") {cur--;}
      if (cur == maxin) {
        while (true) {
          if (line.substring(j, j + 1) == ")") {
            String newarg = operators(arg.substring(1, arg.length()));
            line.replace(arg + ")", newarg);
            break;
          }
          arg += line.substring(j, j + 1);
          j++;
        }
      }
      j++;
    }
  }
  // Split //
  int index = 0;
  int wn = 0;
  while (index >= 0) {
    int spaceIndex = line.indexOf(' ', index);
    if (spaceIndex >= 0) {
      sec[wn] = line.substring(index, spaceIndex);
      wn++;
      index = spaceIndex + 1;
    } else {
      sec[wn] = line.substring(index, spaceIndex);
      wn++;
      break;
    }
  }
}

void setup() {
  i2s_set_pin(I2S_NUM_0, &pin_config);
  Serial.begin(9600);
  GPRS.begin(9600, SERIAL_8N1, 5, 6);
  u8g2.begin();
  u8g2.setFont(u8g2_font_6x10_tf);
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  delay(3000);
  Serial.print("a");
  if (!SD.begin(10)) {
    u8g2.clearBuffer();
    u8g2.drawStr( 0, 0, "SD CONNECTION FAIL");
    u8g2.sendBuffer();
    while (!SD.begin(10)) {delay(100);}
  }
  Serial.print("b");
  u8g2.clearBuffer();
  u8g2.drawStr( 0, 0, "OK");
  u8g2.sendBuffer();
  delay(500);
  // Load Screen //
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_logisoso32_tr);
  u8g2.drawStr(35, 0, "PAN");
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setCursor(128 - (pversion.length() * 6), 53);
  u8g2.print(pversion);
  // Load Screen //
  u8g2.clearBuffer();
  u8g2.sendBuffer();
  sysFile = SD.open("/sys/boot/test.txt");
  mapFile = SD.open("/sys/boot/map.txt");
  cvar(); // Clears varFile then opens
}

void loop() {
  ///////////////////////////////////////////////////////
  /////////////////// System Commands ///////////////////
  ///////////////////////////////////////////////////////
  getLine(curLine);
  curLine++;
  updateButtons();
  //if ((mapFile.size() / 10) == curLine) {}
  if (sec[0] == "ls") {ls = curLine + 1;}
  else if (sec[0] == "le") {curLine = ls; return;}
  ///////////////////////////////////////////////////////
  ////////////////// Arduino Commands ///////////////////
  ///////////////////////////////////////////////////////
  /*if (sec[0] == "if") {
    if (sec[2] == "{") {op(1, sec[1], NULL, NULL);}
    else {op(3, sec[1], sec[2], sec[3]);
    op();
    //if (isAlpha(sec[1])) {}
  }
  */
  else if (sec[0] == "int") {mkVar(sec[1], val(sec[2]), "i");}
  else if (sec[0] == "str") {mkVar(sec[1], val(sec[2]), "s");}
  else if (sec[0] == "bool") {mkVar(sec[1], val(sec[2]), "b");}
  else if (sec[0].substring(0,1) == "$") {setVar(sec[0].substring(1, sec[0].length()), operators(line.substring(1, line.length())));}
  else if (sec[0] == "delay") {delay(val(sec[1]).toInt());}
  else if (sec[0] == "Serial.print") {Serial.print(val(sec[1]));}
  ///////////////////////////////////////////////////////
  //////////////////// U8G2 Commands ////////////////////
  ///////////////////////////////////////////////////////
  else if (sec[0] == "u8g2.clearBuffer") {u8g2.clearBuffer();}
  else if (sec[0] == "u8g2.sendBuffer") {u8g2.sendBuffer();}
  else if (sec[0] == "u8g2.drawBox") {u8g2.drawBox(val(sec[1]).toInt(), val(sec[2]).toInt(), val(sec[3]).toInt(), val(sec[4]).toInt());}
  //if (sec[0] == "u8g2.drawCircle") {u8g2.drawCircle(val(sec[0]).toInt(), val(sec[1]).toInt(), val(sec[2]).toInt(), val(sec[3]).toInt());}
  //if (sec[0] == "u8g2.drawDisc") {u8g2.drawDisc(val(sec[0]).toInt(), val(sec[1]).toInt(), val(sec[2]).toInt(), val(sec[3]).toInt());}
  //if (sec[0] == "u8g2.drawEllipse") {u8g2.drawEllipse(val(sec[0]).toInt(), val(sec[1]).toInt(), val(sec[2]).toInt(), val(sec[3]).toInt());}
/*
drawFilledEllipse
drawFrame
drawGlyph
drawHLine
drawLine
drawPixel
drawRBox
drawRFrame
drawTriangle
drawUTF8
drawVLine
drawXBM
enableUTF8Print
firstPage
getAscent
getDescent
getDisplayHeight
getDisplayWidth
getMaxCharHeight
getMaxCharWidth
getMenuEvent
getStrWidth
getUTF8Width
home
initDisplay
initInterface
nextPage
print
sendBuffer
sendF
setAutoPageClear
setBitmapMode
setBusClock
setClipWindow
setContrast
setCursor
setDisplayRotation
setDrawColor
setFlipMode
setFont
setFontDirection
setFontMode
setFontPosBaseline
setFontPosBottom
setFontPosTop
setFontPosCenter
setFontRefHeightAll
setFontRefHeightExtendedText
setFontRefHeightText
setI2CAddress
setMaxClipWindow
setPowerSave
updateDisplay
updateDisplayArea
*/
  ///////////////////////////////////////////////////////
  //////////////////// UBOOT Commands ///////////////////
  ///////////////////////////////////////////////////////
  else {error(2);}
}

Things are still being setup here but it is able to compile.

HardwareSerial GPRS(1);

What does the parameter 1 do here ?

IDK. I found it in a tutorial. Shall I remove it?

I know very little about serial comms on the board but found this

https://docs.arduino.cc/tutorials/nano-esp32/cheat-sheet/

There is a section on using serial on the board

I tried replacing Serial with Serial0 but it didn't do anything. The simple code works fine without the zero. I am testing the code by removing single lines before the setup.

When my Arduino disconnects, I need to press the reset button a few times to connect. I found out that it actually enters bootloader mode because the led is pulsing green and there are 2 connections to the board. I am guessing that the Arduino cannot print to Serial in bootloader mode. There might be something that makes the Arduino crash and I actually once was able to print in Serial by removing the I2S pin config set but am unable to do it again. I am still working on fixing it.

While in bootloader mode, i reconnected the Arduino to the computer and the connection was successful. The Serial started working and the code was running fine. I am still working on seeing if there were lines blocking it because i2s pin config set was commented out.

Hi, @kinghappy
Did you write your code in stages, and test as you go?
OR
Did you write it all at once and then try to get it to work?

If in stages, at what stage did the serial problem occur?

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

I did them in big stages so I know that some things work. I did a few more tests and found out that without the i2s pin config set command, reinserting the plug in the Arduino will make it run fine. With the command it does not connect automatically to the computer. Does anyone know if the command blocks it?

After tests I have proven that this line is causing the program to reset. I am working on fixing it.

I found out that my Audio Library (uses I2S) can change the pin setup for I2S meaning I don't have to use the faulty line.

1 Like

Hi,

I'm currently feeling the same situation.
The Nano ESP32 is currently making me crazy.

When I reconnect it, I can't open the serial monitor and can't use it.
I must press the reset button twice, reflash the program so that I can use the serial. After that I can use it normally. The serial then always works.
As long as I don't press reset or disconnect and reconnect.
That makes me crazy.
The handling of the Nano ESP32 is making me crazy.

Is there any secret recipe to make it work as soon as I plug it in again?

Arduino IDE 2.3.4 with ESP32 Core Package 3.1.1.
However, I had this behavior long before.
Only now it's getting annoying in the long run.

is just a sketch to test things out
#include <Streaming.h>

// ------ User Konfiguration ------------------------------------------------------------------------------
Stream &cout {Serial};
// -----------------------------------------------------------------------------------------------------------------

namespace MeineLed {
  struct TimerName {enum {Between, End, ToRight, ToLeft, Up, Down, HoldUp, HoldDown, HoldRight, HoldLeft, ANZAHL}; } constexpr tName;
}
// -----------------------------------------------------------------------------------------------------------------

struct ConfigDaten {
  uint32_t zeit [MeineLed::tName.ANZAHL] {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
  uint8_t maxBrightness {123};
  enum MODUS {CROSSFADE, CHANGEUPDOWN} mode {CHANGEUPDOWN};
};
ConfigDaten configDaten [2];

// -----------------------------------------------------------------------------------------------------------------

class MyEyePair
{
  private:
    struct ConfigDaten &config;     // Referenz 'config' ist Alias auf das original struct {zeit, maxBrightness, mode} ('struct' kann auch weggelassen werden)
    const size_t zeitAnzahl;

  public:   
    MyEyePair (auto &list, size_t length): // ReferenzĂĽbergabe 'list'
      config {list},
      zeitAnzahl {sizeof(config.zeit) / sizeof(config.zeit[0])} // 10 Zeiten mal 4 Byte = 40 Bytes
    { } 

    void add (void) {
      for (unsigned i=0; auto &d : config.zeit){
        d++; d++;
        ++i;
      }
      Serial.println(); 
    }

    uint8_t getBrightness (void) { return config.maxBrightness; }
    uint32_t getZeit (void) { return sizeof(config.zeit); }
    uint32_t getZeitAnzahl (void) { return zeitAnzahl; }  // 10 Zeiten mal 4 Byte = 40 Bytes
    unsigned getMode (void) { return static_cast<unsigned>(config.mode); }
}; // Ende class 'MyEye'

constexpr size_t singleObjectZeitAnzahl { sizeof(configDaten[0].zeit) / sizeof(configDaten[0].zeit[0]) };  // 10 Zeiten mal 4 Byte = 40 Bytes
constexpr size_t lengthBuffer { sizeof(configDaten) };                                  // 48 Bytes

MyEyePair myEyePair { configDaten[1], lengthBuffer };
  
void setup()
{
  Serial.begin(115200);
  delay(5000);
  Serial.println("\nESP32 RESET\n");
  Serial.println( lengthBuffer );
  Serial.println( myEyePair.getBrightness() );
  Serial.println( myEyePair.getZeit() );
  Serial.println( myEyePair.getZeitAnzahl() );
    
  for(auto &config : configDaten) {
    for(auto &zeit : config.zeit) {
      cout.print(zeit); cout.print(F(" "));
    }  
    cout.println();
  }
  cout.println();

  Serial.println("add+2");
  myEyePair.add();
  
  for(auto &config : configDaten) {
    for(auto &zeit : config.zeit) {
      cout.print(zeit); cout.print(F(" "));
    }  
    cout.println();
  }
  cout.println();

}

void loop()
{

}

If the serial is working, I have COM4.

After reconnecting I have COM3 which does not work.

When plugging in the Arduino Nano ESP32 without pressing reset, does your RGB light flash rainbow/pulse green/do nothing/other?

Hi,

after plugging in, the RGB changes from purple to green and is off. Only the green power LED lights on.

Can you post your full code?

Hi,

the full code is in post #14.

This is the reduced code without pins that still shows the problem.

In the meantime, I have continued writing my main program. Now I have succeeded :grimacing: in getting the RGB to flash green and purple alternately.

Flashing in programmer mode does not work at the moment either.
I must first think about what to do now.

Click where the arrow points in post #14.

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

Hi,

I was able to bring the Nano back to life, my program is working again. But now the RGB in blue is permanently lit. Does the color blue have a special meaning?
I have only replaced the old analogWrite with LedC. I am still working with Arduino Pin Numbers.
I use only Pin, D2, D4, D7, D9.