Softserial messes up setup when pins are not connected

Hi All,

I am currently prototyping a project to open and close my garage door via RFID and a keypad, in addition to integration with homekit via mqtt.

i have an arduino and an esp8266 (The Thing).
The arduino controls the keypad and the RFID reader. It is basically a "stupid" controller with no authentication logic. All authentication logic is in the ESP8266.

So when the pincode is entered on the keypad or RFID is scanned, the code is sent via SoftSerial from the Arduino to the ESP8266. It works great in a happy flow scenario.
Now i am testing the unhappy paths. I am currently trying to find of if the ESP8266 would still be able to do it's thing then no connection to the arduino can be made via softserial. Because control via Homekit should still be posible, even when keypad and RFID reader are unavailable.

But it doesn't seem to be the case with my current code.
I could try to fix this by not using the serial connection but instead go all the way over mqtt. But i don't want to be dependant of the wifi connection being up. that's also why i chose to store all authentication data in the EEPROM of the ESP. It will only retrieve new codes over the wifi network if it detects a new version of those pincode sets.

Please point me in the right direction on how to "ignore" the software serial until it becomes available.

#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>

// PINS
#define RELAY_TRIGGER_PIN 12
#define BRAIN_RX_PIN 2
#define BRAIN_TX_PIN 14
#define SENSOR_GARAGE_CLOSED_PIN 4
#define SENSOR_GARAGE_OPENED_PIN 0
#define BUTTON_PIN 13
#define LED_PIN 5
//*********

// Timings
#define RELAY_TRIGGER_DELAY 300
#define RFID_IGNORE_TIME 2500
//********

// Communication codes
#define RFIDCODE "1"
#define KEYPADCODE "2"
#define EOT '\4'
//********************

// Variable sizes
#define jsonBufferSize 468
#define RFIDArrayLength 13
#define PincodeArrayLength 5
//***************

// EEPROM Addresses
#define EEPROM_PINCODE_ADDRESS 0
#define EEPROM_RFID_ADDRESS 60
//*****************

const char *ssid = "xxxxxxxxxxxxxxx";
const char *password = "xxxxxxxxxxx";
const char *mqtt_server = "xxxxxxxxxxxx";
const char *device_id = "xxxxxxxxxxxxx";

unsigned long lastRFIDReadTime;
unsigned long lastWifiReconnectTime;
unsigned long lastMQTTReconnectTime;
bool initialWifiConnect = true;
bool initialMQTTConnect = true;

WiFiClient espClient;
PubSubClient client(espClient);

StaticJsonDocument<jsonBufferSize> jsonDoc;

SoftwareSerial brainconnection(BRAIN_RX_PIN, BRAIN_TX_PIN);

char message_buffer[500];

struct {
  int count;
  int version;
  char pincodes[10][PincodeArrayLength];
} pinEEPROM;

struct {
  int count;
  int version;
  char rfids[10][RFIDArrayLength];
} rfidEEPROM;

char pincodes[10][PincodeArrayLength];
int pincode_count = 0;
int pincode_version = 0;

bool setupComplete = false;

char rfids[10][RFIDArrayLength];
int rfid_count = 0;
int rfid_version = 0;

char serial_buffer[500];
char lastIncomingChar = '\0';
String keypadData = "";
int count = 0;

// Button debouncing
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
//******************

// Sensor variables
int lastGarageClosedState = 2;
//*****************

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

  // PIN Setup
  //**********
  Serial.println("PIN setup");
  //setup led pin
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  //setup garage door closed pin
  pinMode(SENSOR_GARAGE_CLOSED_PIN, INPUT_PULLUP);

  //Setup relay
  pinMode(RELAY_TRIGGER_PIN, OUTPUT);
  digitalWrite(RELAY_TRIGGER_PIN, LOW);

  //Setup button pin
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, LOW);

  pinMode(BRAIN_RX_PIN, INPUT);
  pinMode(BRAIN_TX_PIN, OUTPUT);

  // End PIN Setup
  //***************

  delay(1000);
  Serial.println("Brain connection setup");
  brainconnection.begin(9600);

  Serial.println("EEPROM setup");
  EEPROM.begin(200);
  readPincodesFromEEPROM();
  readRFIDsFromEEPROM();

  readKeypadData();

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop()
{
  readKeypadData();
  setup_wifi();
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();

  checkGarageDoorOpen();
  checkOpenGarageDoorButtonPressed();
}

void readKeypadData() {
  // if data is coming from software serial port ==> data is coming from SoftSerial shield
  if (!brainconnection.isListening()) {
    return;
  }
  if (brainconnection.available()) {
    while (brainconnection.available())              // reading data into char array
    {
      count++;
      if (count == 64)
        break;

      lastIncomingChar = (char) brainconnection.read();
      keypadData.concat(lastIncomingChar);
    }
    //Serial.println(keypadData.length());
    count = 0;                      // set counter of while loop to zero
    //if (keypadData.length() == 13) {
    if (lastIncomingChar == EOT) {
      if (keypadData.startsWith(RFIDCODE)) {
        keypadData = keypadData.substring(1, keypadData.length() - 1);
        Serial.println(keypadData);
        keypadData.toCharArray(serial_buffer, 500);

        if (lastRFIDReadTime + RFID_IGNORE_TIME < millis()) {
          client.publish("home/garage/door/rfid/login/request", serial_buffer, false);
          lastRFIDReadTime = millis();

          if (verifyRFID(keypadData)) {
            triggerRelay();
          }
        }

        keypadData = "";
      } else if (keypadData.startsWith(KEYPADCODE)) {
        keypadData = keypadData.substring(1, keypadData.length() - 1);
        Serial.println(keypadData);
        keypadData.toCharArray(serial_buffer, 500);

        client.publish("home/garage/door/keypad/login/request", serial_buffer, false);

        if (verifyPincode(keypadData)) {
          triggerRelay();
        }
      }
      keypadData = "";
    }
  }
}

void setup_wifi() {
  
}

void callback(char *topic, byte * payload, unsigned int length)

}

void deserializeJSONData(char* json) {
  // Deserialize the JSON document
  DeserializationError error = deserializeJson(jsonDoc, json);

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
}

I had to cut down on the code because aparently i can't make posts with more than 9000 characters, so it won't compile because code is missing

tommekevda:
I am currently trying to find of if the ESP8266 would still be able to do it's thing then no connection to the arduino can be made via softserial. Because control via Homekit should still be posible, even when keypad and RFID reader are unavailable.

I don't understand that. Maybe you can re-phrase it?

...R

When i boot the ESP8266 without powering the arduino, the ESP8266 just spews weird characters over the serial interface. I assume this is because the SoftSerial connection between ESP and arduino isn't able to connect. That suspicion is reenforced because everything works perfect if i power the arduino first.

So eventhough the arduino is disconnected, i still want to be able to control the ESP via mqtt (homekit)

I suspect the problem is that the SoftwareSerial Rx pin is floating - meaning it has no guaranteed state and can change from microsecond to microsecond. Try putting a resistor between the Rx pin and Vcc to hold the Rx pin HIGH. The resistor value is probably not critical - anywhere in the range 4k7 to 10k will probably work.

HIGH is the normal idle state for a serial connection and the Tx of the Arduino should be able to override the resistor when necessary to pull the Rx pin LOW as part of a legitimate message.

...R

A wiring diagram will be useful.

There is a difference between not powering the Arduino and fully disconnecting the Arduino.

pulling the RX pin on the ESP high doesn't seem to affect anything

I think i resolved the issue. i hooked up the ground from ESP and arduino together. Once i unplugged the connection between the 2 grounds, everything just worked..
I though you always had to share a common ground, i guess not?

tommekevda:
I think i resolved the issue. i hooked up the ground from ESP and arduino together. Once i unplugged the connection between the 2 grounds, everything just worked..
I though you always had to share a common ground, i guess not?

Yes they do need a common ground. How else will the ESP and Arduino both know what "5 volts" is if they don't have a common point from which to measure it? (yes even digital circuitry "measures")

You actually need to add the power connections (5V, 3.3V, GND) to that wiring diagram.

What I think that happens is that you power the Arduino from the ESP through the TX pin of the Arduino when you disconnect the Arduino's Vcc; you can not do that. When disconnecting the Arduino, you need to disconnect Vcc as well as the signals; GND can stay connected.

You can read up on parasitic power.

As you might be able to tell, I am not trained in electronics. So i am kind of "winging" it, learning along the way. I just hooked up the grounds again (eventhough it now worked with not hooking them up) and the ESP board wouldn't properly boot again. but then i thought. maybe i have to hook up the VCC also? And so i did, now the ESP booted properly without powering the arduino. However, when i plug in the arduino, don't i get 5v to an 3.3v esp8266?

schematic of how it was hooked up here:

tommekevda:
schematic of how it was hooked up here:

Another candidate for the Wall of Shame :slight_smile:

A photo of a schematic drawn with pencil and paper and the pins clearly labelled would be much easier to follow.

...R

yeah... i drew the wires like they were hooked up. just so if there were any mistakes, it would show.

I cleaned up now, here are some images


Imgur

Imgur

Imgur

tommekevda:
I cleaned up now, here are some images

They are evidence of good skill with a camera but they are not a schematic. And a schematic is the only way to form an opinion about the appropriateness of wiring connections.

...R