False reading from input sensors

I am having trouble with random false readings from my input pins. The project is an indicator for the state of the garage doors (his and her). There is a set of leds that are visible inside the house to show if they're open or closed. I had the sketch running flawlessly on the final hardware sitting on my desk but without the wire leads used to connect to the magnetic door sensors. After I installed everything in the garage, the leds did not match the door state consistently. I suspected the magnetic switches might be the issue but removing the switches completely (leaving wires completely disconnected) is still generating erroneous values. I used an exact between the terminals on the board in case there was residue conducting current. It seems like it works if I remove the wire completely. I think the pull up resistors are enabled correctly (although using older code). Board is an ESP-32 (Elegoo).

General functions - check wifi and flash leds if not connected

Check time and turn off leds after 11pm local time (using very rough dst calculation)

Check sensors and turn leds on/off as appropriate - problem area in final install

My first wifi project so i am really bummed i couldn't cross the line with it.

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/af63c06b-c7b8-4f1e-ace1-7f30240c4d10 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  String timeStringCloud;
  bool ledHerCloud;
  bool ledHisCloud;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"
#include "time.h"

int sensorLeft = 34;
int sensorRight = 23;
int ledHerRed = 12;
int ledHerGreen = 27;
int ledHisRed = 18;
int ledHisGreen = 21;
int wifiCounter = 0;
String timeString = "Daytime";
struct tm timeinfo;  // time related...
int dstBeginMonth = 3; // DST Starts March 8th (on or about) - using DST begins in March and ends in November
int dstEndMonth = 11; // DST Ends November 1st (on or about)


void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 
  
  // My Adds:
  pinMode(sensorLeft, INPUT);
  digitalWrite(sensorLeft, HIGH); // enable pull up resistor
  pinMode(sensorRight, INPUT);
  digitalWrite(sensorRight, HIGH); // enable pull up
  pinMode(ledHerRed, OUTPUT);
  pinMode(ledHerGreen, OUTPUT);
  pinMode(ledHisRed, OUTPUT);
  pinMode(ledHisGreen, OUTPUT);
  
  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
    
  wifiCounter ++;  // counter for wifi connection test

  if (timeString == "Daytime") {
      ledUpdate(sensorLeft);
      ledUpdate(sensorRight);
      }
     else {
      ledsOff();
      }

  if (!getLocalTime(&timeinfo)) {
    Serial.println("No time available (yet)");
    }
    else {
      timeString = timeChecker();
      Serial.println("time check:");
      Serial.println(timeString);
      }

    
  cloudUpdates();  // set the cloud variables for the dashboard
   
  delay(500);

  Serial.println(ledHisCloud);
  Serial.println(ledHerCloud);
  Serial.println(WiFi.status());
  
  if (wifiCounter >= 20) {
    if (WiFi.status() != WL_CONNECTED) {
      noWiFiConnection();
      }
    wifiCounter = 0;
    }
}

void ledUpdate(int x) {    // Based on the sensor state, we set the led lights
  if (x == sensorLeft) {
    digitalWrite(ledHerGreen, digitalRead(x));
    digitalWrite(ledHerRed, !digitalRead(x));
    }
  if (x == sensorRight){
    digitalWrite(ledHisGreen, digitalRead(x));
    digitalWrite(ledHisRed, !digitalRead(x));
    }
}

void ledsOff() {  // to turn off the physical leds overnight
    digitalWrite(ledHerGreen, LOW);
    digitalWrite(ledHerRed, LOW);
    digitalWrite(ledHisGreen, LOW);
    digitalWrite(ledHisRed, LOW);
}

void cloudUpdates() {  // Based on sensor state, update cloud variables, update time value
    ledHerCloud = digitalRead(sensorLeft);
    ledHisCloud = digitalRead(sensorRight);
    timeStringCloud = timeString;
}

void noWiFiConnection() {
  for (int i = 0; i < 10; i++)
    {
    Serial.println("no_wifi");
    digitalWrite(ledHerGreen, HIGH); 
    digitalWrite(ledHisGreen, HIGH);
    digitalWrite(ledHerRed, LOW);
    digitalWrite(ledHisRed, LOW);
    delay(500);
    digitalWrite(ledHerGreen, LOW); 
    digitalWrite(ledHisGreen, LOW);
    digitalWrite(ledHerRed, HIGH);
    digitalWrite(ledHisRed, HIGH);
    delay(500);
    }
}

String timeChecker() {
    String t;
    int timeOffset = 0; // vs UTC
    int myHour = 0; // local hour
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    if ((timeinfo.tm_mon >= dstBeginMonth) && (timeinfo.tm_mon < dstEndMonth)) {
      Serial.println("it's Daylight Savings Time");
      timeOffset = 4;
      }  
    else if ((timeinfo.tm_mon < dstBeginMonth) || (timeinfo.tm_mon >= dstEndMonth)) {
      Serial.println("it's not Daylight Savings Time");
      timeOffset = 5;
      }
    if (timeinfo.tm_hour > timeOffset) {
      myHour = timeinfo.tm_hour - timeOffset;
      Serial.println("Hour is " + String(myHour));
      } 
    else {
      myHour = timeinfo.tm_hour + 24 - timeOffset;
      Serial.println("Hour is " + String(myHour));
      }
    if ((myHour >= 23) || (myHour < 8)) {  // hours for overnight - 11 pm - 8 am
      t = "Overnight";
      } 
      else {
        t = "Daytime";
        }
  return t;
}
  
    










As an electronics instructor of mine once said, "all electronics are analog, and every wire is an antenna".

Neither of your sensor inputs has the internal pullup enabled. Not that it would be likely to help much if your wiring is of any length; they're simply too high a value to suppress electrical noise that a significant length of wire is going to pick up.

Since you haven't said otherwise, I'll assume your wiring is unshielded, isn't using twisted pair, or any other precautions against picking up noise?

I thought I was enabling pullup resistor with: digitalWrite(sensorRight, HIGH);

I saw that there is a newer/preferred alternative using pinMode(x, INPUT_HIGH), but only after completing final install. Is first method no longer an option?

Wires are stranded, not twisted, “bell wire”.

Wires are also running next to Lan cable and are not separated.

I wouldn't count on that on anything save the ATmega chips. And maybe not even all of them.

In any case, 20K-50K isn't going to do diddly for lengths of unprotected wire.

  • I always use pinMode(sensorRight, INPUT_PULLUP);

Gives me some thoughts for testing. I will remove the sensor wires from the terminals at the Board (replicating version that was sitting on my desk) and see if there are fluctuations. See if I can't find some shielded wire. And, thanks for your help! I have been discouraged.

Not your current most important problem, but this can be done exactly and easily with no code. The Arduino ESP32 core has this built-in already.

Off the top of my head, I'd try having the reed switch drive an optoisolator (which would be located with the processor) and use the output to drive the processor's input. Maybe a cap across the isolator's input if things are really bad. I'm sure there are better ideas, but that was the first thing that popped into my head.

More than happy to take the suggestion, based on what I could find in samples and such, this was my closest approximation. How would you go about finding the time with esp32?

I'm not sure exactly how to achieve the same thing with Arduino Cloud, but this:

should return your local time, including dst adjustment, but it isn't doing that because it doesn't know what time zone you are in.

I'm not sure, but it might be as simple as saving this line at the top of your code

#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03" 

with whatever string is appropriate for for location from here

and also adding these lines in setup()

  setenv("TZ", MY_TZ, 1);            // Set environment variable with your time zone
  tzset();

Hello,

Just a small mention of your cable types. Twisted pair refers to two independent cables twisted together. They are purchased like that.

An interesting project. I like “His and Hers”. Good luck…………

I suggest you use pull up resistors in the 2.2K range, that will give you just over 1mA through the contacts. That will help keep them clean and the lower impedance of the switch circuit will help reduce noise. Leaving the wires disconnected assuming they are connected to the ESP tells me you have some great antennas.

For my garage sensor I simply bought a cheep photo eye designed for garage doors, mounted it and used that. The one I has uses a modulated power source which I monitored with a 150 Ohm resistor. The one for the alarm system was a simple magnet on the door and a reed switch on the door frame. I used a 4.7K resistor with a UNO. No problems so far, about 7 years working.

Changed the pin used for sensorLeft to 32 as there is no internal resistor available on the original (34) pin. Using pinMode(sensorLeft, INPUT_PULLUP); (and making adjustments to ledUpdate() ) didn’t improve the experience.

Ended up with adding two 4.7k pull Down resistors which seems to have done the trick.

Circuit diagramming is new to me, but I thought I would try here. The leds are smd and are in the hall above the garage where we can see them before going to bed. Had to make them small enough and dim enough so my other half wasn’t upset. They (leds) fit in a 1.5 inch long strip that is above the smoke detector. Very unobtrusive.

Switches are magnetic reeds. This was a fun project for me (now that it’s working). Thank you all for helping!

As the saying goes, "Well, there's your problem".

The usual way of doing things is to have the switch to ground, with either a discrete or built in pullup to 3.3V.

When you just had the switch to 3.3V, and the switch was open, the input was either floating (pinMode(pin, INPUT)) or pulled high (pinMode(pin,INPUT_PULLUP)). It was never, ever, low. That's why adding the pull downs changed things. The input pins are now in a known state (low) when the switches are open.