Nano Every Serial1 does not work without USB Connection. Help needed!

Hi there!

I've recently started working on a project: I am making an LED "Neon Sign" that is controllable using WIFI. This involves the Arduino Nano Every communicating with an ESP8266-01S over UART.

The Code uses the Serial object to communicate with my Computer over USB, for Logging and Debugging purposes. The Serial1 object is used to communicate with the ESP using the UART Protocol on pins D0/D1.

Everything works perfectly so far, to the point where I just want to hang the Sign on the Wall and call it Done. With one Issue:

For some reason the Serial communication with the ESP only seems to work when the Nano Every is connected to my Computer with USB. As soon as I disconnect the USB and Power the Nano Every using an external 12 V Supply connected to Vin, Serial1 just stops working for some reason.

Here's how the ESP is connected to the Nano Every:
-The ESP requires 3.3V and is connected to the 3V3 pin.
-It's connected to the D0/D1 pins, Tx-Rx, Rx-Tx.
-Ground is connected.

This setup, as I mentioned, works perfectly with the Nano Every connected to my computer.

Since I use Serial over USB for Debugging, it is quite hard to Debug what is going on, since the Problem only occurs with the USB disconnected.

Here's what I've done:
-I checked the 3V3 pin for the correct Voltage using a multimeter.
-I've tracked down the Error using the Built-in LED on the Nano Every, to be sure that the problem is with the Serial1 connection, and nothing else.
-I've powered the Nano Every using a Phone charger, to see if the Problem lies with the Power delivery over the USB Port, but that does not fix the problem.

Unfortunately, I do not own an Oscilloscope to probe the Serial communication lines.

In Summary, the Serial1 communication just does not seem to work on my Nano Every when it is not connected to my PC with USB. I am not sure if it is the Sending or the Receiving that's the issue.

I would appreciate any help on this. What else could I try? Does anyone havy any ideas on why this might be happening, or has anyone experienced a similar issue?

Welcome to the forum

Does your code have something like

while (!Serial);

in setup ?

Please post your full sketch, using code tags when you do

No, it does not contain while(!Serial).

Here's the full code:

#include <ArduinoJson.h>
#include <Wire.h>
#include <PCA9685.h>
#include <EEPROM.h>

#define SWITCH 6

PCA9685 driver = PCA9685(0x40, PCA9685_MODE_N_DRIVER, 1500);

char rxBuf[512]; // This is important
size_t rxInd = 0;

bool switchState, state;

bool isOnline = false;
long nextOnlineTest;


int brightness;

int loadRx() { // This function is important
  int count = 0;
  long start = millis();
  while(millis() < start + 50) {
    while(Serial1.available()) {
      if(rxInd == 511) {
        return count;
      }
      char c = Serial1.read();
      rxBuf[rxInd] = c;
      rxInd++;
      rxBuf[rxInd] = 0;
      count++;
      start = millis();
    }
  }
  return count;
}

void clearRx() {
  rxInd = 0;
  *rxBuf = 0;
}

void flushRx() {
  while(Serial1.available()) Serial1.read();
}

void LEDUpdate() {
  showAll(state ? brightness : 0);
}

void showAll(int brightness) {
  for(int i = 0; i < 13; i++) {
    driver.getPin(i).setValueAndWrite(brightness);
  }
}

void setup() {
  // put your setup code here, to run once:

  pinMode(LED_BUILTIN, OUTPUT);
  

  Serial.begin(115200);
  Serial1.begin(115200);
  
  

  pinMode(SWITCH, INPUT_PULLUP);
  Wire.begin();
  driver.setup();

  delay(10);

  
  

  while(!strstr(rxBuf, "OK")) {
    Serial1.println("AT");
    delay(20);
    loadRx();
  }

  digitalWrite(LED_BUILTIN, HIGH);
  //Serial1.println("ATE0");

  nextOnlineTest = 0;

  clearRx();
  flushRx();
  Serial.println("ESP READY");

  switchState = digitalRead(SWITCH);
  state = switchState;
  brightness = (EEPROM.read(1)<<8)+EEPROM.read(2);

  Serial.print("Brightness: ");
  Serial.println(brightness);

  LEDUpdate();

}

void strapd(char* str, char c) {
  size_t len = strlen(str);
  str[len] = c;
  str[len+1] = 0;
}

void processRxBuf() {
  Serial.print("Buffer: ");
  Serial.println(strlen(rxBuf));
  Serial.println("---------------------");
  Serial.println(rxBuf);
  Serial.println("-------------------------");

  char* ptr = rxBuf;
  while(*ptr) {
    if(strncmp(ptr, "+IPD", 4) == 0) {
      ptr += 5;
      char lenStr[4];
      lenStr[0] = 0;
      while(*ptr != ':') {
        strapd(lenStr, *ptr);
        ptr++;
      }
      ptr++;
      int len = atoi(lenStr);
      char message[len + 1];
      message[0] = 0;
      strncpy(message, ptr, len);
      message[len] = 0;
      processMessage(message);
    }
    ptr++;
  }
  clearRx();
}

void executeMessage(char* sender, char* content) {
  if(strcmp(content, "off") == 0) {
    state = false;
    LEDUpdate();
    sendToHub("BROADCAST", "STATE:off");
  } else if(strcmp(content, "on") == 0) {
    state = true;
    LEDUpdate();
    sendToHub("BROADCAST", "STATE:on");
  } else if(strncmp(content, "brightness ", 11) == 0) {
    brightness = atoi(content + 11);
    EEPROM.write(1, brightness >> 8);
    EEPROM.write(2, brightness & 0xFF);
    state = true;
    LEDUpdate();
    sendToHub("BROADCAST", "STATE:on");
  } else if(strcmp(content, "getstate") == 0) {
    char buf[16];
    sprintf(buf, "STATE:%s", state ? "on" : "off");
    sendToHub(sender, buf);
  } else if(strcmp(content, "getbrightness") == 0) {
    char buf[24];
    sprintf(buf, "BRIGHTNESS:%d", brightness);
    sendToHub(sender, buf);
  }
}

void processMessage(char* message) {
  Serial.print("Received Message: ");
  Serial.println(message);

  DynamicJsonDocument doc(512);
  DeserializationError err = deserializeJson(doc, message);
  if(err) {
    Serial.print("Json Deserialization Error: ");
    Serial.println(err.f_str());
    return;
  }

  const char* method = doc["method"];
  if(strcmp(method, "Hub") != 0) return;

  const char* sender = doc["sender"];
  const char* content = doc["content"];

  executeMessage(sender, content);

}

void sendToHub(char* target, char* content) {
  char buf[256];
  sprintf(buf, "{\"method\":\"Hub\",\"target\":\"%s\",\"content\":\"%s\"}", target, content);
  sendUdp(buf);
}

void sendUdp(char* message) {
  Serial.print("Sending: ");
  Serial.print(message);

  char buf[80];
  sprintf(buf, "AT+CIPSEND=%d", strlen(message));
  Serial1.println(buf);
  delay(10);
  Serial1.println(message);
}

void loop() {
  // put your main code here, to run repeatedly:

  if(!isOnline && millis() >= nextOnlineTest) {
    nextOnlineTest = millis() + 500;
    Serial1.println("AT+CIPSTA?");
    delay(10);
    loadRx();
    if(strstr(rxBuf, "192.168.")) {
      isOnline = true;
      Serial1.println("AT+CIPSTART=\"UDP\",\"192.168.0.101\",2444,2444");
      delay(10);
      char buf[16];
      sprintf(buf, "STATE:%s", state ? "on" : "off");
      sendToHub("BROADCAST", buf);
    }
    clearRx();
  }

  while(Serial.available()) Serial1.write(Serial.read());

  int i = loadRx();
  if(i) processRxBuf();

  if(digitalRead(SWITCH) != switchState) {
    switchState = digitalRead(SWITCH);
    state = switchState;
    LEDUpdate();
    sendToHub("BROADCAST", state ? "STATE:on" : "STATE:off");
  }
}

The important Part is in setup():

while(!strstr(rxBuf, "OK")) {
    Serial1.println("AT");
    delay(20);
    loadRx();
  }

The Arduino repeatedly sends "AT" over Serial1.
The ESP should then respond with "OK".
It reads all incoming data in the loadRx() function (defined at the top of the file).
When the "OK" is received, the Built-in LED turns on.

The LED turns on and everything works fine, when a USB Connection is present.
However this does not work without a USB Connection. The LED does not turn on, and it gets stuck in this loop.

Everything after this code is unimportant here, because it never gets executed anyways, so you can ignore all functions except setup() and loadRx().

Hi there again. I have somehow fixed the problem.

I changed the loop to the following:

while(!strstr(rxBuf, "OK")) {
    clearRx();
    Serial1.println("AT");
    delay(20);
    loadRx();
  }

The code now clears the rx Buffer and that has solved the problem, indicating a buffer overflow.

Everything seems to work fine now, even without the USB Connected.

While the problem is solved, I still am a little confused, as this buffer overflow never happened with the usb connected.

I do have one theory:
The ESP takes a while to start. This is enough time to make the buffer overflow.
The Nano Every however, resets after a short while, when the USB Connection is established.
This clears the buffer, and because the ESP is fully running now, the "AT" - "OK" transaction works fine.

This reset does not happen when no USB Connection is established. Therefore the buffer overflow happens before the ESP is fully started, and it gets stuck in the loop, without being reset.

Thank you anyways, UKHeliBob!