Interrupt noise in arduino

Hello, I have made two modules, module1 gets HC-12 signal from the module2, and the module2 gets proximity sensor input, when sensor touches something, Interrupt gets ground signal, and it triggers arduino to send a signal to module1.

Using arduino UNO, and HC-12 module.

My problem is that every time module1 is turned ON, Interrupt gets some noise, (I think it is the electromagnetic signal from HC-12) and Interrupt gets activated (LOW), although it is not real.

This has been driving me crazy for the last week.

I am trying to use pulseIn() to filter out, very short noise, but I don’t know why I can’t get correct result.

How can I filter this noise, by using software? for example, software debouncer?

(1) Module1 code

#include <SimpleTimer.h>

#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

#define IDlen 4
#define maxID 5

SoftwareSerial mySerial(2,3);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int upButtonPin = 7;
int selectButtonPin = 6;
int downButtonPin = 5;
int sensors[maxID] = {1001,9999,9999,9999,9999};
int receivedID = 0;
int currentPos = 0;
String rcvMsg = "xxxx";

//void printSensor(int intID);
void menu();
void showAllSensors();
int removeID(int senNumInt);

void setup()
{
  Serial.begin(9600);
  Serial.println("Serial began.");

  mySerial.begin(9600);
//  mySerial.println("0000");
  
  lcd.begin();
  pinMode(upButtonPin,  INPUT_PULLUP);
  pinMode(selectButtonPin, INPUT_PULLUP);
  pinMode(downButtonPin, INPUT_PULLUP);
}

void loop()
{
  rcvMsg = "xxxx";
  lcd.setCursor(1,1);
  lcd.clear();
  lcd.print("Ready");
  if(digitalRead(upButtonPin)==LOW){
    lcd.clear();
    lcd.print("Up btn pressed!");
  }
  if(digitalRead(downButtonPin)==LOW){
    lcd.clear();
    lcd.print("Down btn pressed!");
  }
  if(digitalRead(selectButtonPin)==LOW){
    lcd.clear();
    lcd.print("Registered sensors:");
    delay(1000);
    lcd.clear();
    showAllSensors();
    menu();
  }
  if(mySerial.available()>0){
//    String rcvMsg = mySerial.readStringUntil('\n');
    rcvMsg = mySerial.readStringUntil('\n');
    Serial.print("Received msg: ");
    Serial.print(rcvMsg);
    Serial.print('\n');
    receivedID = rcvMsg.substring(0,4).toInt();
    Serial.println(receivedID);
    delay(50);
    
    for (int i=0;i<maxID;i++){
      if(sensors[i] == receivedID){
        String temp = String(receivedID);
        String ack = String(temp + "01"); // 01: success 02: reject (ID does not exist)
        mySerial.println(ack);
        Serial.print("Ack sent: ");
        Serial.print(ack);
      }
    }
  }
}

void menu(){
  lcd.print("UP: add sensor");
  lcd.setCursor(0,1);
  lcd.print("DOWN: del sensor");
  lcd.setCursor(0,0);
  
  while(1){  
    if(digitalRead(upButtonPin)==LOW){
      lcd.clear();
      lcd.print("Add sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);
      
      while(1){   
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Menu: OK, Down: Cancel");
          //센서 입력값을 받아서, 리스트에 넣어 놓기
          sensors[currentPos] = senNumInt;
          lcd.clear();
          showAllSensors();       
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // up button 누름 메뉴 끝

    if(digitalRead(downButtonPin)==LOW){
      lcd.clear();
      lcd.print("Remove sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);

      while(1){   
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Delete sensor");
          delay(600);
          lcd.clear();
          
          //센서 입력값을 받아서, 리스트에서 찾은 후 삭제
          int result = removeID(senNumInt);
          if(result==1){
            lcd.print("Deleted.");
            showAllSensors();       
          }else{
            lcd.print("No such ID!!");
          };
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // down button 누름 메뉴 끝
    
    
    
    delay(200);
  }
  return;
}

void showAllSensors(){
  char imsi[IDlen];
  for(int i=0;i<maxID;i++){
    Serial.println(sensors[i]);
    sprintf(imsi, "%d", sensors[i]);
    lcd.print(imsi);
    delay(800);
    lcd.clear();
  }
  return;
}

int removeID(int senNumInt){
  int isFound = 0;
  for(int i=0;i<maxID;i++){
    if(sensors[i] == senNumInt){
      sensors[i] = 9999;
      isFound = 1;
    }
  }
  return isFound;
}

(2) module2 code

#include <SoftwareSerial.h>
#include <avr/sleep.h> 
#include <SimpleTimer.h>

SimpleTimer timer;
const int wakeUpPin = 2; // pin of interrupt 0
const int LED = 8;
const int numMsg = 1; // For the safety, send multiple messages, everytime.  
boolean armed = false;
SoftwareSerial mySerial(4,5);
String ID = "1001";
String code = "01";
String msg = "xxxx";
String rcvMsg = "xxxx";
int timerID = 0;
boolean isWaked = false;
int pulseWidth = 0;

/*
  Communication protocol
  01: powered on
  02: Sensor touched (Feed is full)
  03: alive
 */

void setup()
{
  String msg = String(ID + code);
  pinMode(wakeUpPin, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  timerID = timer.setInterval(1000, sendMsg);
  
  Serial.begin(9600);  
  mySerial.begin(9600); 
  Serial.println(msg);
  delay(100);
}

void loop() // 반복
{
  pulseWidth = pulseIn(wakeUpPin, LOW, 100000);
  Serial.println("start loop.");
  armed = true;
  delay(100);
  Serial.println("Now sleeping.."); 
  delay(200);
  sleepNow(); 

  Serial.println(pulseWidth);
  if(armed){
    Serial.println("Waked up. Send Feed full msg.");
    
    delay(200);
    code = "02";
    msg = String(ID + code);
    sendMsg();
    int count = 0;
    while(1){
      count++;
      if(count>200){      //prevent infinite loop
        count = 0;
        break;
      }
      Serial.print('*');
      if(mySerial.available()>0){
        Serial.println("RECEIVED!!!!");
        rcvMsg = mySerial.readStringUntil('\n');
        if(rcvMsg.substring(0,4).equals(ID)){
//          timer.deleteTimer(timerID);
          Serial.println("My msg is received successfully. Now sleep again..\n");
          break;
        }
      }
      delay(50);  
    }
    armed = false;
  }
}  

void wakeUpNow(){
  isWaked = true;
  return;
}

void sleepNow(){
  Serial.println("Entered sleep now()");
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
  sleep_enable(); 
  attachInterrupt(0,wakeUpNow, LOW); 
  sleep_mode(); 
  // When wakes up, resume codes from here. 
  sleep_disable(); 
  
  
  detachInterrupt(0);   
  return;
}

void sendMsg(){
  for (int i=0;i<numMsg;i++){
    mySerial.println(msg);
  }
  return;
}

Most likely the problem is in the wiring (cross talk between long, unshielded wires) or motor/relay noise in the power supply wiring. The diagram is not very informative, so post a picture of your setup, as well as links to the modules and power supply.

Avoid using String objects with the Uno. They cause memory problems and unpredictable program crashes.

Put a 1k pullup resistor on the Interrupt input to give it a stronger pullup. Lower resistances require more current to change their voltage, so they are less sensitive to noise. The built in inputs are quite high resistance, so around a strong source of noise like this is one of the situations where they are not good enough on their own and you need something external.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.