Конфликт на Ардуино Нано между SIMM800L и RFID mfrc522

Дмташ
Offline
Зарегистрирован: 04.10.2021

Мистикой мы называем то, что не можем объяснить с точки зрения логики и здравого смысла.

Друзья, братья, помогите! Я в мистику упёрся и буксую уже несколько дней.

Задача простая - GSM сигнализация. Собрал схемку, написал скетч и тут началось, но по порядку.

Задумка такая: в момент постановки под охрану пьезик издаёт короткий сигнал, отсылается СМС сообщение о принятии под охрану, далее светодиод периодически выдаёт серию вспышек. При снятии с охраны пьезик издаёт два коротких писка, светодиод перестаёт моргать и отсылается СМС о снятии с охраны. Если же в режиме охраны на вход door приходит LOW то пьезик начинает циклично издавать серию писков.

В итоге, при включении всё хорошо, при постановки под охрану, всё отрабатывается, пьезик пищит один раз, светодиод моргает как положено, если в этот момент подать на контрольный вход ноль, включается тревожный сигнал и уже не выключается при возврате единицы на контрольных вход (задумка именно такая), а вот выключить сигнализацию или снять с охраны уже не получается. Плата полностью виснет. При чём не просто виснет, а как будто умирает. Не помогает ни reset, ни даже перезаливка скетча, не работает и все!

Чтобы реанимировать плату, надо залить любой другой скетч, где не используется RFID, а потом можно опять заливать нужный скетч.

Что я только не пробовал. Менял местами блоки постановки и снятия с охраны, то есть при включении сразу встаёт в режим охраны, подношу брелок, с охраны снимается, СМС отсылается, а когда пытаюсь снова включить всё виснет. Получается, что виснет, когда обращаешься к SIMM800 второй раз.

Разъединил по времени работы SPI и SoftwareSerial, то есть исключил их одновременную работу, не помогло.

Когда же отключаю один из модулей и закоменчиваю соответствующую часть кода, второй прекрасно всё что ему положено отрабатывает, что RFID, что SIMM800.

Если бы сброс или хотя бы перезаливка скетча помогали, я бы искал ошибку в коде, но они не помогают.

Кто с подобным сталкивался? У кого идеи есть?

Вот код.

#include <SPI.h>                        //  Библиотека "SPI".
#include <MFRC522.h>                    //  Библиотека "RFID".
MFRC522 mfrc522(10, 9);                 //  Создание экземпляра MFRC522.
#include <SoftwareSerial.h>             //  Библиотека интерфейса UART.

SoftwareSerial mySerial(4, 3);          //  Выводы SIM800L Tx и Rx подключены к выводам Arduino 4 и 3

#define chip  2030766275                //  ID брелка.
#define chipD 3834215466                //  ID карты (дубликат).

#define bus  14                         //  Пин сирены. Выход.
#define led  15                         //  Пин сигнального светодиода. Выход.
#define door 16                         //  Пин тревожного сигнала (освещение салона). Вход.

uint32_t uidDec=0;                      //  Хранения ID считываемой метки в десятичном формате.
uint32_t uidDecTemp;                    //  Временное храниения той же метки.
bool flag = false;                      //  Постановка в дежурный режим, flag == true - cигнализация включена.
bool alrm = false;                      //  Флаг управления тревожным сигналом.
int8_t sig;                             //  Задаёт количество писков.
int16_t N = 2500;                       //  Период серии импульсов светодиода в режиме охраны.
int16_t n = 400;                        //  Период самих импульсов светодиода.
int32_t T;                              //  Отсчёт периода серии вспышек.
int32_t t;                              //  Отсчёт периода вспышек.

void setup()              {
  pinMode(door,INPUT);                  //  Назначение входа тревожного сигнала, сигнал освещения салона.
  pinMode(led,OUTPUT);                  //  Назначение выхода на сигнальный светодиод.
  digitalWrite(led,LOW);                //  Предварительное гашение светодиода.
  pinMode(bus,OUTPUT);                  //  Назначение выхода на тревожный сигнал.
  digitalWrite(bus,LOW);                //  Предварительное выключение сирены.
  Serial.begin(19200);                  //  Включение монитора порта.
  SPI.begin();                          //  Инициализация SPI / Init SPI bus.  
  mfrc522.PCD_Init();     }             //  Инициализация MFRC522 / Init MFRC522 card. 


void loop()                                           {

if (!mfrc522.PICC_IsNewCardPresent()) {IO();return;}        //  Ожидание новой метки.
if (!mfrc522.PICC_ReadCardSerial())   {return;}             //  Чтение метки.
mfrc522.PICC_HaltA();                                       //  Остановка опроса RFID.

for (int8_t i = 0; i < mfrc522.uid.size; i++){              //  Цикл выборки номера ID.
 uidDecTemp = mfrc522.uid.uidByte[i];                       //  Чтение очередного фрагмента номера.
 uidDec = uidDec * 256 + uidDecTemp;         }              //  Формирование полного номера ID.

if(uidDec == chip, chipD)   {                               //  Отождествление прописанных ID
    flag = !flag;                                           //  Если Да,инвертируем flag,

  SPI.end();                            //  Выключение SPI.
  mySerial.begin(19200);                //  Включение последовательной связи Arduino с SIM800L.
  
if(flag)                        {
    mySerial.println("AT+CMGF=1");                        // Выбирает формат SMS
  delay(500);
  mySerial.println("AT+CMGS=\"+79610238941\"");         // Отправка СМС на указанный номер
  delay(500);
  mySerial.print("OXPAHA BKL");              // Тест сообщения  
  mySerial.write(26);
  sig = 1;                       }                   // Если flag установлен, то sig=1.
  
else              {
    mySerial.println("AT+CMGF=1");                        // Выбирает формат SMS
  delay(500);
  mySerial.println("AT+CMGS=\"+79610238941\"");         // Отправка СМС на указанный номер
  delay(500);
    mySerial.print("OXPAHA OTKL");              // Тест сообщения
  mySerial.write(26);
  sig = 2;        }                                  //  Если flag сброшен, то sig=2.
  
  mySerial.end();                //  Выключение последовательной связи Arduino с SIM800L.
  
Signal();               //  Вызов функции писка.

  t = millis();             }  //  Присвоить t текущее значение millis.
  
  SPI.begin();                          //  Включение SPI.
  } 

void IO()                                             {     //  Фун-я обработки входов и выходов.
if(!flag) {alrm = false;}                                   //  Если не дежурный режим, то alrm сброшен.
else  {LedD(); if(!digitalRead(door)) {alrm = true;}}
BusS();                                               }

void LedD()                 {                       //   Функция формирования сейий вспышек светодиода.
if(T + N>millis())        {
  for(;t+n>millis();)  {
digitalWrite(led,HIGH);
delay(10);
digitalWrite(led,LOW);
delay(40);             }  }
else  {T = millis(); t = T;}}

void BusS()                 {                       //  Функция формирования тревожного сигнала пьезика.
    if(alrm)              {
for(int8_t i=0;i<7;i++) {
digitalWrite(bus,HIGH);
delay(50);
digitalWrite(bus,LOW);
delay(50);              } } }

void Signal()             {                   //  Функция коротких писков при изменении режимов.
  for(sig;sig>0;sig--)  {
digitalWrite(bus,HIGH);
delay(10);
digitalWrite(bus,LOW);
delay(70);              } }




    

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Если не работает аппаратный сброс, ошибка не программная, а аппаратная.

Нужна схема.

Дмташ
Offline
Зарегистрирован: 04.10.2021

Простите, первый день на форуме, не могу понять как скинуть сюда картинку.

 

b707
Offline
Зарегистрирован: 26.05.2017

А я все же код посмотрел бы. Думаю что то что ресет не помогает - скорее всего никак не связано с работой программы. А вот то что в коде полно косяков - это видно сразу.
Зачем вы в программе постоянно выключаете софтсериал, а потом обратно включаете и заново инициализируете? Не из-за этого ли виснет? А если сделать как принято - включить софтсериал в сетапе и больше не трогать?

Еще добавка - Форматирование кода крайне неудачное, кто вас научил ставить закрывающие скобки в конце строк, так что на экране их не видно?

Дмташ
Offline
Зарегистрирован: 04.10.2021

Первоначальный вариант был традиционным, т.е. инициализация модулей проводилась однократно в сетапе, это я уже потом в поисках причин, попробовал разделять по времени работу модулей, дабы исключить их взаимовлияние. Но эксперимент получился безрезультатным. эти изменения никак не влияли.

 

Дмташ
Offline
Зарегистрирован: 04.10.2021

Подскажите пожалуйста как закачать картинку. Не могу схему выложить.

 

b707
Offline
Зарегистрирован: 26.05.2017

Читайте прикрепленную тему в песочнице

b707
Offline
Зарегистрирован: 26.05.2017

Дмташ пишет:

Первоначальный вариант был традиционным, т.е. инициализация модулей проводилась однократно в сетапе, это я уже потом в поисках причин, попробовал разделять по времени работу модулей, дабы исключить их взаимовлияние. Но эксперимент получился безрезультатным. эти изменения никак не влияли.

 


верните обратно традиционный, сейчас в коде черти что наворочено

Дмташ
Offline
Зарегистрирован: 04.10.2021

Спасибо, исправлюсь)))

Дмташ
Offline
Зарегистрирован: 04.10.2021

andriano пишет:

Если не работает аппаратный сброс, ошибка не программная, а аппаратная.

Нужна схема.

Вот она

Дмташ
Offline
Зарегистрирован: 04.10.2021

b707 пишет:

кто вас научил ставить закрывающие скобки в конце строк, так что на экране их не видно?

С небольшой натяжкой можно сказать, что ардуинщик я начинающий. Форматирую таким образом я по двум причинам, во-первых, мне тем удобнее читать код чем больше строк помещается на экране, поэтому экономлю строки, пусть даже ценой их удлиннения, во-вторых парные скобки я располагаю на одной линии по вертикали, это облегчает мне ориентирование в случаях множественности вложенных друг в друга скобок.

Но по вашей просьбе привожу код в порядок.

Дмташ
Offline
Зарегистрирован: 04.10.2021

b707 пишет:
Дмташ пишет:

верните обратно традиционный, сейчас в коде черти что наворочено

Вот откорректированный код.

#include <SPI.h>                        //  Библиотека "SPI".
#include <MFRC522.h>                    //  Библиотека "RFID".
MFRC522 mfrc522(10, 9);                 //  Создание экземпляра MFRC522.
#include <SoftwareSerial.h>             //  Библиотека интерфейса UART.

SoftwareSerial mySerial(4, 3);          //  Выводы SIM800L Tx & Rx подключены к выводам Arduino 4 и 3

#define chip  2030766275                //  ID брелка.
#define chipD 3834215466                //  ID карты (дубликат).

#define bus  14                         //  Пин сирены. Выход.
#define led  15                         //  Пин сигнального светодиода. Выход.
#define door 16                         //  Пин тревожного сигнала (освещение салона). Вход.

uint32_t uidDec=0;                      //  Храниения ID считываемой метки в десятичном формате.
uint32_t uidDecTemp;                    //  Временное храниения той же метки.
bool flag = false;                      //  Постановка в дежурный режим, flag == true - cигнализация включена.
bool alrm = false;                      //  Флаг управления тревожным сигналом.
int8_t sig;                             //  
int32_t T;
int32_t t;
int16_t n = 400;
int16_t N = 2500;

void setup()              
{
  pinMode(door,INPUT);                  //  Назначение входа тревожного сигнала, сигнал освещения салона.
  pinMode(led,OUTPUT);                  //  Назначение выхода на сигнальный светодиод.
  digitalWrite(led,LOW);                //  Предварительное гашение светодиода.
  pinMode(bus,OUTPUT);                  //  Назначение выхода на тревожный сигнал.
  digitalWrite(bus,LOW);                //  Предварительное выключение сирены.
  Serial.begin(19200);                  //  Включение монитора порта.
  mySerial.begin(19200);                //  Включение последовательной связи Arduino с SIM800L.
  SPI.begin();                          //  Инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();                   //  Инициализация MFRC522 / Init MFRC522 card.
}

void loop()                                           
{
if (!mfrc522.PICC_IsNewCardPresent()) {IO();return;}        //  Ожидание новой метки.
if (!mfrc522.PICC_ReadCardSerial())   {return;}             //  Чтение метки.
mfrc522.PICC_HaltA();                                       //  Остановка опроса RFID.

for (int8_t i = 0; i < mfrc522.uid.size; i++){              //  Цикл выборки номера ID.
 uidDecTemp = mfrc522.uid.uidByte[i];                       //  Чтение очередного фрагмента номера.
 uidDec = uidDec * 256 + uidDecTemp;                       //  Формирование полного номера ID.
 }
 
if(uidDec == chip, chipD)   {                               //  Отождествление прописанных ID
    flag = !flag;                                           //  Если Да,инвертируем flag,
  
if(flag)  {
  mySerial.println("AT+CMGF=1");                        // Выбирает формат SMS
  delay(500);
  mySerial.println("AT+CMGS=\"+796000000000\"");         // Отправка СМС на указанный номер
  delay(500);
  mySerial.print("OXPAHA BKL");              // Тест сообщения  
  mySerial.write(26);
  sig = 1;                                          // Если flag установлен, то sig=1.
}

else  {
  mySerial.println("AT+CMGF=1");                        // Выбирает формат SMS
  delay(500);
  mySerial.println("AT+CMGS=\"+79600000000\"");         // Отправка СМС на указанный номер
  delay(500);
  mySerial.print("OXPAHA OTKL");              // Тест сообщения
  mySerial.write(26);
  sig = 2;                                          //  Если flag сброшен, то sig=2.
}
Signal();               //  Вызов функции писка.

  t = millis();               //  Присвоить t текущее значение millis.
   } 
 }
 
void IO()  {                                                //  Фун-я обработки входов и выходов.
if(!flag) {alrm = false;}                                   //  Если не дежурный режим, то alrm сброшен.
else  {LedD(); if(!digitalRead(door)) {alrm = true;}}
BusS();                                               
}

void LedD() {                                       //   Функция формирования сейий вспышек светодиода.
if(T + N>millis()) {
  for(;t+n>millis();)  {
digitalWrite(led,HIGH);
delay(10);
digitalWrite(led,LOW);
delay(40);             
}  }
else  {T = millis(); t = T;}
}

void BusS()                 {                       //  Функция формирования тревожного сигнала пьезика.
    if(alrm)              {
for(int8_t i=0;i<7;i++) {
digitalWrite(bus,HIGH);
delay(50);
digitalWrite(bus,LOW);
delay(50);              
} } }

void Signal()             {                   //  Функция коротких писков при изменении режимов.
  for(sig;sig>0;sig--)  {
digitalWrite(bus,HIGH);
delay(10);
digitalWrite(bus,LOW);
delay(70);              
} }

 

b707
Offline
Зарегистрирован: 26.05.2017

на схеме из криминала вижу только питание MFC с ардуины при том что сама ардуина запитана через VIN от 12в. Стаб ардуины будет грется и может сгореть. то же самое про стаб 3.3в

В сигнальных линиях ошибок не нашел

Дмташ
Offline
Зарегистрирован: 04.10.2021

b707 пишет:

на схеме из криминала вижу только питание MFC с ардуины при том что сама ардуина запитана через VIN от 12в. Стаб ардуины будет грется и может сгореть. то же самое про стаб 3.3в

Сейчас уточнил характеристики, Нано на выводе 3,3 В держит до 50 мА, а mfrc522 потребляет 13-26 мА, думаю должно хватить.

Но! Ранее не сказал, считал неважным, а сейчас задумался, дело в том, что в процессе отладки, один модуль mfrc522 у меня окончательно умер. В смысле не восстанавливается после загрузки, как другие.

rkit
Offline
Зарегистрирован: 23.11.2016

Дмташ пишет:

 mfrc522 потребляет 13-26 мА

в пике - гораздо больше

nik182
Offline
Зарегистрирован: 04.05.2015

Дмташ пишет:

Сейчас уточнил характеристики, Нано на выводе 3,3 В держит до 50 мА, а mfrc522 потребляет 13-26 мА, думаю должно хватить.

Позвольте уточнить, где можно посмотреть сколько держит нана на 3.3 выводе? Родная ft232rl может выдать 50 мА по даташиту, а вот сh340, которая стоит в большинстве китайских нан 30мА имеет максимум потребления. Найти сколько можно грузить на 3.3 мне не удалось. Но если полное потребление 30 мА, то сколько из этого приходиться на 3.3?

Дмташ
Offline
Зарегистрирован: 04.10.2021

nik182 пишет:

Дмташ пишет:

Родная ft232rl может выдать 50 мА по даташиту, а вот сh340, которая стоит в большинстве китайских нан 30мА имеет максимум потребления. Найти сколько можно грузить на 3.3 мне не удалось. Но если полное потребление 30 мА, то сколько из этого приходиться на 3.3?

Я об этом не знал, есть повод задуматься. Хотя собирал неоднократно подобные схемы, но без SIMM800 и проблем никогда не было.