Работа с шумом в прерывании arduino
Я делаю два модуля, модуль 2 получает сигнал датчика и посылает беспроводное сообщение модулю 1 с помощью HC-12. Затем module1 собирается выполнить некоторую работу, которую он должен сделать. Конфигурация схемы изображена на рисунке.
Я проверил связь HC-12, и они хорошо посылают и принимают. Но моя проблема заключается в том, что когда модуль 1 включается, прерывание активируется (НИЗКОЕ), и модуль 2 посылает сигнал, который не должен посылаться. Похоже, это из-за шума электромагнитных волн, исходящих от HC-12.
Как я могу отфильтровать этот шум, используя код ? Теперь я застрял на последние 3 дня.
код
Module1
#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
#include <SoftwareSerial.h>
#include <avr/sleep.h>
#include <SimpleTimer.h>
SimpleTimer timer;
const int wakeUpPin = 2; // вывод прерывания 0
const int LED = 8;
const int numMsg = 1; // Для безопасности каждый раз отправляйте несколько сообщений.
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;
/*
Протокол связи
01: включено питание
02: Сенсор коснулся (Подача полная)
03: живой
*/
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){ //предотвратить бесконечный цикл
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();
// Когда проснется, возобновите коды отсюда.
sleep_disable();
detachInterrupt(0);
return;
}
void sendMsg(){
for (int i=0;i<numMsg;i++){
mySerial.println(msg);
}
return;
}
@Chihyun Ahn, 👍1
Обсуждение1 ответ
Я знаю, это не совсем то, о чем вы просили, но я рекомендую аппаратную фильтрацию. У меня были проблемы с шумом на прерываниях, и я смог решить их с помощью этого компонента: https://www.st.com/content/st_com/en/products/emi-filtering-and-signal-conditioning/integrated-emi-filtering-and-esd-protection/computer-legacy-port-ipad/kbmf.html#overview
Это не дорого и избавит вас от большой головной боли. Если вы не можете использовать SMD-компоненты, вы можете перестроить схему этого фильтра с помощью конденсаторов и резисторов, просто убедитесь, что вы поставили фильтр как можно ближе к контакту прерывания.
- Сброс Arduino Uno в коде
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Как вызвать функции C из скетча ардуино?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Как правильно использовать volatile переменные в Arduino?
- Проблема с Software Serial: нет ответа
- Как прервать функцию цикла и перезапустить ее?
- 4-битный счетчик вверх и вниз
Я не уверен, является ли это диагностическим тестом или ответом, потому что это может быть примерно одно и то же. Я предполагаю, что вы тестируете их в непосредственной близости. Что я бы посоветовал вам сделать, так это сильнее подтянуть штифт 2. Поместите 1 Ком (просто для выбора числа) с контакта 2 на 5 В и переключите "PIN-режим" на "ВХОД", а не "INPUT_PULLUP". Посмотрите, какое это имеет значение, если таковое имеется., @timemage
дроссельные манжеты emi/rfi/ферритовые "бусинки" на vcc и сигнальных проводах могут решить вашу проблему с оборудованием. Попробуйте немного из старого шнура miniUSB и посмотрите, помогут ли они., @dandavis