Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. Noisy inputs..

Noisy inputs..

Scheduled Pinned Locked Moved Hardware
8 Posts 2 Posters 2.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    shabba
    wrote on last edited by
    #1

    Hi all,
    I built a gate controller for myself (https://www.openhardware.io/view/458/Gate-Controller). The relay pins are wrong (N/O and N/C) but that is not relevant here.

    The issue is that when I stop or start the relays when AC is connected my inputs trigger changes. This does not happen when I disconnect the AC. The relays are driving gate motors using starter capacitors.

    #include "PinChangeInterrupt.h"
    #define TINY_GSM_MODEM_A6
    #define RF69_IRQ_NUM          2
    #define MY_NODE_ID 2
    #define MY_DEBUG 
    #define MY_RADIO_RFM69
    #define MY_RFM69_FREQUENCY   RF69_868MHZ
    #include <SPI.h>
    #include <MySensors.h>
    #include <TinyGsmClient.h>
    #define SerialAT Serial1
    #define DELAY 2000
    /////////////////// Gates ///////////////////////
    #define RGC  14
    #define LGO  15
    #define RGO  12 
    #define LGC  18
    //////////////////// Buttons ///////////////////
    #define KEYPAD      20
    #define INTERCOM    19
    #define PHOTOCELLS  23
    #define KEYFOB      21
    #define WALLSWITCH  A7
    #define REEDSWITCH  22
    
    TinyGsm modem(SerialAT);
    
    MyMessage msg(1,V_TRIPPED);
    MyMessage msg2(2,V_TEXT);
    unsigned long const gatesTimeOpenClose = 29000;
    unsigned long const gatesStayOpen = 80000;
    unsigned long movingTime = 0, openTime = 0;
    
    volatile bool keyPad = false, interCom = false, keyFob = false;
    bool gatesOpening = false, gatesClosing = false, gatesOpen = false, stringComplete = false, domoTrigger = false;
    String inputString = "";
    String reason = "";
    int oldsec=0;
    volatile bool startup = true, changeDetected = false;
    
    void openGates() {
      if (gatesOpening) {
        return;
      }
      if (gatesClosing) {
        unsigned long temp = millis() - movingTime; // temp is ms since gate was closing
        movingTime = millis() - (gatesTimeOpenClose - temp) + 1000;
        values();
        Serial.print("OpenGates() :: Reopening:");
        Serial.println(temp/1000);
        stopGates();
      } else {
        movingTime = millis();
      }
      if (gatesOpen) { // Reset open timer
        openTime = millis();
        values();
        Serial.println("OpenGates() : Resetting open timer");
        return;
      }
      gatesOpening = true;
      send(msg2.set(reason.c_str()));
      reason="";
      send(msg.set(0));
      digitalWrite(RGO,LOW);
      values();
      Serial.println("OpenGates() : Right");
      delay(2000);
      digitalWrite(LGO,LOW);
      values();
      Serial.println("OpenGates : Left");
    }
    void stopGates() {
      digitalWrite(LGC,HIGH);
      digitalWrite(LGO,HIGH);
      values();
      Serial.println("StopGates : Stopping Left gate");
      if (gatesClosing) {
        delay(1000);
      }
      digitalWrite(RGC,HIGH);
      digitalWrite(RGO,HIGH);
      Serial.println("StopGates : Stopping Right gate");
      gatesOpen = gatesOpening?true:false;
      if (gatesOpen) {
        values();
        Serial.println("StopGates() : Gates are open");
        openTime = millis();
      }
      gatesOpening = false;
      gatesClosing = false;
    }
    
    void closeGates() {
      while(analogRead(WALLSWITCH) < 615) {
        unsigned long wallOpen = millis();
        if(millis() % 10000 == 0) {
          int sec = (millis() - wallOpen)/1000;
          if (sec != oldsec) {
            values();
            Serial.print("CloseGates() : Wall switch: ");
            Serial.print(sec);
            Serial.println('s');
            oldsec = sec;
          }
        }
      }   
      if (gatesClosing) {
        return;
      }
      movingTime = millis();
      gatesClosing = true;
      gatesOpen = false;
      values();
      keyPad = false, interCom = false, keyFob = false;
      Serial.println("CloseGates() : Closing Left gate");
      digitalWrite(LGC,LOW);
      values();
      delay(2000);
      Serial.println("CloseGates() : Closing Right gate");
      digitalWrite(RGC,LOW);
      values();
    }
    
    void CheckGates() {
      if (gatesOpening || gatesClosing) {
        if((millis() - movingTime) > gatesTimeOpenClose) {
          stopGates();   
        } else {
          if (millis() % 2000 == 0)  {
            values();
            int secs = (millis() - movingTime) / 1000;
            if (secs != oldsec) {
              if (gatesOpening) {
                Serial.print("CheckGates() : Opening:");
              } else {
                Serial.print("CheckGates() : Closing:");
              }
              Serial.print((movingTime + gatesTimeOpenClose - millis()) / 1000);
              Serial.println("s");
              oldsec = secs;
            }
          }
        }
      }
      if (gatesClosing) {
        if (digitalRead(PHOTOCELLS) == HIGH) {
           Serial.println("CheckGates() : Photocells tripped - Reopening");
           openGates();
        }
        if (digitalRead(REEDSWITCH) == LOW) {
           Serial.println("CheckGates() : ReedSwitch tripped");
           send(msg.set(1));
           stopGates();
        }
      }
      if (gatesOpen) {
        if((millis() - openTime) > gatesStayOpen) {
          closeGates();
        } else {
          if (millis() % 5000 == 0)  {
            int secs = (millis() - openTime) / 1000;
            if (secs != oldsec) {
              values();
              Serial.print("CheckGates() : Open ");
              Serial.print(secs);
              Serial.print("s :: ");
              Serial.print((openTime + gatesStayOpen - millis()) / 1000);
              Serial.println("s");
              oldsec = secs;
            }
          }
        }
      }
    }
    
    void setup()  { 
      Serial.println("Setup() : Gate sketch started");
      inputString.reserve(200);
      SerialAT.begin(115200);
      delay(5000); // Give modem a chance.
      Serial.print("Setup() : Initialising Modem...");
      while(!modem.init()) {
        Serial.println("Setup() : ERR: Modem init");
        delay(10000);
      }
      Serial.println("Setup() : Waiting for network..");
      while(!modem.waitForNetwork()) {
        Serial.println("Setup() : ERR: GSM network");
        delay(10000);
      }
      Serial.println("Setup() : Modem ready");
      SerialAT.write("AT+CLIP=1\r\n");
      pinMode(WALLSWITCH, INPUT);
      pinMode(INTERCOM, INPUT_PULLUP);
      pinMode(KEYPAD, INPUT_PULLUP);
      pinMode(KEYFOB, INPUT_PULLUP);
      pinMode(REEDSWITCH, INPUT_PULLUP);
      pinMode(PHOTOCELLS, INPUT_PULLUP);
      attachPCINT(digitalPinToPCINT(INTERCOM), PBChangeIntercom, CHANGE);
      attachPCINT(digitalPinToPCINT(KEYFOB), PBChangeKeyFob, CHANGE);
      attachPCINT(digitalPinToPCINT(KEYPAD), PBChangeKeyPad, CHANGE);
      int gatePins[4] = {LGO,LGC, RGO, RGC};
      for (int x=0;x<4;x++) {
        pinMode(gatePins[x],OUTPUT);
        digitalWrite(gatePins[x],HIGH);
      }
      gatesOpen = (digitalRead(REEDSWITCH))==LOW?false:true;
      if (gatesOpen) {
        Serial.println("Setup() : Gates are open on startup");
        closeGates();  
      }
      values();
      startup = false;
    }
    
    void loop() {
      if (changeDetected) {
        Serial.println("Change detected");
        changeDetected = false;
      }
      if (keyFob) {
        values();
        Serial.println("loop() : Gate open request detected by Key Fob");
        reason="Opened by Key Fob";
        openGates();
        keyFob = false;
      }
      if (interCom) {
        values();
        Serial.println("loop() : Gate open request detected by Intercom");
        reason="Opened by Intercom";
        openGates();
        interCom = false;
      }
      if (keyPad) {
        values();
        Serial.println("loop() : Gate open request detected by key pad");
        reason="Opened by Key Pad";
        openGates();
        keyPad = false;
      } 
      if (stringComplete) {
        inputString.trim();
        if (inputString.length() > 0) {
          Serial.print("loop() : GSM:");
          Serial.println(inputString);
        }
        if(inputString.indexOf("1111111111") > 0 || inputString.indexOf("222222222222") > 0 || inputString.indexOf("333333333333") > 0) {
          String phoneNum = inputString.substring(inputString.indexOf("087"),inputString.indexOf("087")+10);
          Serial.print("loop() : GSM:");
          Serial.print(phoneNum);
          Serial.println(" CALL");
          SerialAT.write("ATH \n\r");
          reason="Opened by " + phoneNum;
          openGates();
        }  
        // clear the string:
        inputString = "";
        stringComplete = false;
      }
      CheckGates();
      reason = "";
    }
    
    void receive(const MyMessage &message) {
      if (message.type == V_STATUS && message.sensor == 1) {
         if (atoi(message.data) == 0) {
            Serial.println("receive() : Open req from domo");
            reason = "Opened from domoticz";
            openGates();
         }
      } 
    }
    
    void serialEvent1() {
      while (SerialAT.available()) {
        char inChar = (char)SerialAT.read();
        inputString += inChar;
        if (inChar == '\n') {
          stringComplete = true;
        }
      }
    }                                                                      
    
    void values() {
      Serial.print("KF: ");
      Serial.print(keyFob);
      Serial.print("| KP: ");
      Serial.print(keyPad);
      Serial.print("| IN: ");
      Serial.println(interCom);
    }
    void presentation() {
      sendSketchInfo("Front Gates", "3.4");
      present(1, S_DOOR, "Front Gates"); 
      present(2, S_INFO, "Gate Open Reason"); 
    }
    
    void PBChangeIntercom() {
      if (startup) return;
      volatile static unsigned long last_interrupt_time = 0;
      unsigned long interrupt_time = millis();
      if (interrupt_time - last_interrupt_time > 1000)  interCom = true;
      last_interrupt_time = interrupt_time;
      changeDetected = true;
    }
    void PBChangeKeyPad() {
      if (startup) return;
      volatile static unsigned long last_interrupt_time = 0;
      unsigned long interrupt_time = millis();
      if (interrupt_time - last_interrupt_time > 1000) keyPad = true;
      last_interrupt_time = interrupt_time;
      changeDetected = true;
    }
    
    void PBChangeKeyFob() {
      if (startup) return;
      volatile static unsigned long last_interrupt_time = 0;
      unsigned long interrupt_time = millis();
      if (interrupt_time - last_interrupt_time > 1000) keyFob = true;
      last_interrupt_time = interrupt_time;
      changeDetected = true;
    }
    

    The code is a bit verbose as I added some debug and extra vars to help me see what was going on. The inputs are:
    Photocells : laser sensor that detects when laser path is broken.
    Wallswitch: Switch inside house to keep gates open. Connected to analog A7 and gnd with a connection from A7 to +5 via a 220 resistor.
    Intercom: Momentary switch in house to open gates.
    Reed: A reed switch that triggers when the gates connect on close.
    KeyFob: A Keyfob :-)
    KeyPad: Keypad switch.
    Phone: A6 module.

    The motors pull about 1.9 A IIRC. Do I need LPFs? Any other ideas?
    Thanks!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      shabba
      wrote on last edited by
      #2

      Bump? :-)

      1 Reply Last reply
      0
      • gohanG Offline
        gohanG Offline
        gohan
        Mod
        wrote on last edited by
        #3

        Are relays opto isolated?

        S 1 Reply Last reply
        0
        • gohanG gohan

          Are relays opto isolated?

          S Offline
          S Offline
          shabba
          wrote on last edited by
          #4

          @gohan said in Noisy inputs..:

          Are relays opto isolated?

          Yes.

          1 Reply Last reply
          0
          • gohanG Offline
            gohanG Offline
            gohan
            Mod
            wrote on last edited by
            #5

            did you try to power the relay with a separate power supply to totally isolate the arduino from the relays circuit?

            1 Reply Last reply
            0
            • S Offline
              S Offline
              shabba
              wrote on last edited by
              #6

              No. I can try that but because I have already received the PCBs I would need to hack it a bit. It is worth mentioning that this does not happen when AC is not passed through the relays but relays are still connected.

              1 Reply Last reply
              0
              • gohanG Offline
                gohanG Offline
                gohan
                Mod
                wrote on last edited by
                #7

                That's why optocoupler are used, but also isolating the rest it could be beneficial as most of the relay boards allow it for a reason

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  shabba
                  wrote on last edited by
                  #8

                  I'm gonna see if I can grab a few ferrite cores and stick then on the AC lines to see if that suppresses the EMI.

                  1 Reply Last reply
                  0

                  Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                  Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                  With your input, this post could be even better 💗

                  Register Login
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  9

                  Online

                  12.0k

                  Users

                  11.2k

                  Topics

                  113.4k

                  Posts


                  Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • MySensors
                  • OpenHardware.io
                  • Categories
                  • Recent
                  • Tags
                  • Popular