Кормушка для птиц по СМС на 8266

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Доброе время! Решил сделать кормушку, чтоб при отправке СМС срабатывал серво, который сыпал корм.

Взял Wemos Di mini (NodeMCU) и SIM800l (все самое дешевое, естественно). Вставил симку, срабатывает при отправке - но только 1 раз, второй раз не срабатывает. Если контроллер перезагрузить нажатием кнопки - то можно опять активировать один раз. Хотя, даже иногда срабатывает два раза (но редко). В чем может быть ошибка? Питание модулей и сервы отдельное, думаю что хорошее. Может есть ошибка в скетче?

#include <SoftwareSerial.h>
#include <Servo.h>

#define DEBUG 1
#define SIM800_TX_PIN D6 // TX pin of SIM800L
#define SIM800_RX_PIN D5 // RX pin of SIM800L

SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);
char responseBuffer[256];

Servo servo;

char *checkPhone    = {
                          (char *)"79", // Phone number to check
                        };

char *checkSms[]    = {
                          (char *)"CMT:", // Sms string
                        };

char *initSim[]       = {
                          (char *)"AT", // Ping module
                        };


char *initTextMode[]   = {
                          (char *)"AT+CMGF=1\r\n", // Mobile network status
                        };


char *initSmsMode[]    = {
                          (char *)"AT+CNMI=1,2,0,0,0\r\n", // Mobile network status
                        };



void setup() {
  Serial.begin(115200);
  while(!Serial);

  servo.attach(2); //D4
  servo.write(0);

  if(DEBUG) Serial.println("Connecting GSM module");
  if (!connectModule()) {
    delay(1000);
    reboot();
  }

  writeToSim(initTextMode, sizeof(initTextMode)/sizeof(*initTextMode));
  readSim(responseBuffer, 2000);
  Serial.println(responseBuffer);
  delay(1000);

  writeToSim(initSmsMode, sizeof(initSmsMode)/sizeof(*initSmsMode));
  readSim(responseBuffer, 2000);
  Serial.println(responseBuffer);
  delay(1000);
}

void loop() {
  readSim(responseBuffer, 2000);
  Serial.println(responseBuffer);

  if(strstr(responseBuffer,  (char *)"CMT:")) {
    if(strstr(responseBuffer, checkPhone)) {
      Serial.println("SMS detected!");
      servo.write(145);
      delay(1000);
      servo.write(0);
      delay(1000);
   
    }
  }
}


bool connectModule() {
  serialSIM800.begin(57600);
  Serial.print("Trying 57600 ...");
  writeToSim(initSim, sizeof(initSim)/sizeof(*initSim));
  readSim(responseBuffer, 2000);
  if (isResponseOk(responseBuffer)) {
    Serial.println("Connected to mobile");
    return true;
  }
  Serial.println("Bad");
  return false;
}


void writeToSim(char *commands[], int size) {
  for(int i = 0; i < size; i++) {
    serialSIM800.println(commands);
    if(DEBUG) { Serial.print("Writing: "); Serial.println(commands); }
    delay(1000);
  }
}

// Read Sim response until timeout
char* readSim(char* buffer, int timeout) {
  unsigned long timeStart = millis();
  int charCount = 0;

  while(charCount < 256) {
    if(serialSIM800.available()) {
      buffer[charCount++] = serialSIM800.read();
    }
    if(millis() - timeStart > timeout) break;
    delay(10);
  }

  buffer[charCount++] = 0;
  return buffer;
}


bool isResponseOk(char* buffer) {
  // 1. Get buflen
  int buflen = 0;
  for(int i = 0; i < 256; i++) {
    if(int(buffer) == 0) {
      buflen = i;
      break;
    }
  }
  if(DEBUG) { Serial.print("Buflen: " ); Serial.println(buflen, DEC); }

  // 2. Is last ok? buffer[buflen] == 0
  while (buflen > 0) {
    buflen--;
    if (int(buffer[buflen]) == 10) {
      continue;
    }
    if (int(buffer[buflen]) == 13) {
      continue;
    }
    if (int(buffer[buflen]) == 75 && int(buffer[buflen-1]) == 79) {
      if(DEBUG) { Serial.println("Response is OK"); }
      return true;
    }
      if(DEBUG) { Serial.println("Response is BAD"); }
    return false;
  }
  return false;
}

void reboot() {
  wdt_disable();
  wdt_enable(WDTO_15MS);
  while (1) {}
}

Заранее благодарен за ответ!

 
 

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Буфер не очищается после успешного запуска сервы и чтения смс.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

andycat пишет:
Буфер не очищается после чтения. Судя по всему писали не сами - обратиться к автору.

Вы правы, писал не сам - но с автором сейчас связаться проблематично. Может какая-то мелкая помарка, которая сразу бросится в глаза специалисту - я исправлю и все. Хотелось бы надеяться на такой расклад. Заранее благодарен!

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

Автор взял деньги и сбежал? Тут весь код - сплошная помарка.

sadman41
Offline
Зарегистрирован: 19.10.2016

Сдается мне, что на #113 выход за границы массива.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

rkit пишет:

Автор взял деньги и сбежал? Тут весь код - сплошная помарка.

не сбежал, но у него не хватает компетенции понять причину нестабильной работы. А меня поджимает время, проект стоит.

Может есть более простой код, который позволит управлять сервой или шаговым мотором по СМС?

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Интересно.. Как это решить? Переместить строку в другое место?

dimabeliy
Offline
Зарегистрирован: 11.11.2019

sadman41 пишет:

Сдается мне, что на #113 выход за границы массива.

 

Гм.. Как это решить? Переместить строку в другое место?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

А вот это, вообще, про что?

dimabeliy пишет:

bool isResponseOk(char* buffer) {
  // 1. Get buflen
  int buflen = 0;
  for(int i = 0; i < 256; i++) {
    if(int(buffer) == 0) {
      buflen = i;
      break;
    }
  }

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Это лишнее? Попробую удалить!

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Господи, ....

Откуда взялся этот код? Вы его нашли на какой-то помойке или сами написали?

dimabeliy
Offline
Зарегистрирован: 11.11.2019

ЕвгенийП пишет:

Господи, ....

Откуда взялся этот код? Вы его нашли на какой-то помойке или сами написали?

 

Попросил человека - он написал, хотя не очень горел желанием это делать. Возможно, он не супер профи - соединил пару кусков кодов из интернета. Вроде все работало - но оказалось, что работает не стабильно. Вот, надо либо искать новый код - либо править этот. Для некоторых это довольно просто - для меня нет, вот и обратился за помощью к спецам. Заранее благодарен!

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Не знаю, как он у Вас работал. Тот кусок, что я привёл является бредом. И там много такого. По мне, так надо выбросить и переписать заново.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

ЕвгенийП пишет:

Не знаю, как он у Вас работал. Тот кусок, что я привёл является бредом. И там много такого. По мне, так надо выбросить и переписать заново.

 

Есть простой скетч, который управляет реле по СМС - но мне надо именно серву: то есть поменять пару строк (наверное) - но для меня такая операция пока недоступна. Если сможете помочь - буду благодарен!)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

sadman41 пишет:

Сдается мне, что на #113 выход за границы массива.

Выходит, но если тупо после принятия смс в начала буфера ноль записать, то может ещё поработает.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

andycat пишет:
sadman41 пишет:

Сдается мне, что на #113 выход за границы массива.

Выходит, но если тупо после принятия смс в начала буфера ноль записать, то может ещё поработает.

Та-ак, в какой это строке? В 113? А как ноль записать?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

dimabeliy, этот код не жиснеспособен, пинайте автора или изучайте программирование.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

andycat пишет:
dimabeliy, этот код не жиснеспособен, пинайте автора или изучайте программирование.

Хороший совет - но мне нужно все исправить сегодня.

sadman41
Offline
Зарегистрирован: 19.10.2016

Прям сегодня - только за большие деньги. andycat вон специализируется на модемных скетчах.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

sadman41 пишет:

Прям сегодня - только за большие деньги. andycat вон специализируется на модемных скетчах.

Большие - это сколько?

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не могу оценить трудозатраты, не моя область. andycat ждите.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Птички голодные, хотят жрать - а вам бы все привередничать )

dimabeliy
Offline
Зарегистрирован: 11.11.2019

А если взять этот код, но вместо реле вписать туда серво, а тот кусок, который отвечает за ответную отправку СМС просто удалить?

/* 
 Тестировалось на Arduino IDE 1.8.5
 Дата тестирования 14.06.2019г.
 */ 
 #include <SoftwareSerial.h> 
 SoftwareSerial mySerial(3, 2);              // Выводы SIM800L Tx & Rx подключены к выводам Arduino 3 и 2
 char incomingByte; 
 String inputString;
 int relay_1 = A0;                           // Вывод управления реле 1
 int relay_2 = A1;                           // Вывод управления реле 2
 void setup() 
 {
   pinMode(relay_1, OUTPUT);                 // Установим вывод как выход
   digitalWrite(relay_1, HIGH);              // Устанавливаем высокий уровень
   pinMode(relay_2, OUTPUT);                 // Установим вывод как выход
   digitalWrite(relay_2, HIGH);              // Устанавливаем высокий уровень
   Serial.begin(9600);                   
   mySerial.begin(9600); 
 while(!mySerial.available()){             // Зацикливаем и ждем инициализацию SIM800L
    mySerial.println("AT");                  // Отправка команды AT
    delay(1000);                             // Пауза
    Serial.println("Connecting…");         // Печатаем текст
    }
    Serial.println("Connected!");            // Печатаем текст
    mySerial.println("AT+CMGF=1");           // Отправка команды AT+CMGF=1
    delay(1000);                             // Пауза
    mySerial.println("AT+CNMI=1,2,0,0,0");   // Отправка команды AT+CNMI=1,2,0,0,0
    delay(1000);                             // Пауза
    mySerial.println("AT+CMGL=\"REC UNREAD\"");
 }
 void loop()
 {  
   if(mySerial.available()){                  // Проверяем, если есть доступные данные
       delay(100);                            // Пауза
      while(mySerial.available()){            // Проверяем, есть ли еще данные.   
      incomingByte = mySerial.read();         // Считываем байт и записываем в переменную incomingByte   
      inputString += incomingByte;            // Записываем считанный байт в массив inputString   
    }   
       delay(10);                             // Пауза        
       Serial.println(inputString);           // Отправка в "Мониторинг порта" считанные данные
       inputString.toUpperCase();             // Меняем все буквы на заглавные   
       if (inputString.indexOf("ON_1") > -1){ // Проверяем полученные данные, если ON_1 включаем реле 1 
        digitalWrite(relay_1, LOW);       
        sms(String("Relay 1 - ON"), String("+7xxxxxxxxxx"));} // Отправка SMS      
       if (inputString.indexOf("OFF_1") > -1){ // Проверяем полученные данные, если OFF_1 выклюем реле 1  
        digitalWrite(relay_1, HIGH);       
        sms(String("Relay 1 - OFF"), String("+7xxxxxxxxxx"));}// Отправка SMS      
       if (inputString.indexOf("ON_2") > -1){ // Проверяем полученные данные, если ON_2 включаем реле 2 
        digitalWrite(relay_2, LOW);       
        sms(String("Relay 2 - ON"), String("+7xxxxxxxxxx"));}  // Отправка SMS    
       if (inputString.indexOf("OFF_2") > -1){     // Проверяем  полученные  данные, если OFF_2 выключаем реле 2 
        digitalWrite(relay_2, HIGH);       
        sms(String("Relay 2 - OFF"), String("+7xxxxxxxxxx"));} // Отправка SMS    
        delay(50); 
       if (inputString.indexOf("OK") == -1){    
        mySerial.println("AT+CMGDA=\"DEL ALL\"");      
        delay(1000);}     
        inputString = "";}
 }
 void sms(String text, String phone)  // Процедура Отправка SMS
 {
   Serial.println("SMS send started");
   mySerial.println("AT+CMGS=\"" + phone + "\"");
   delay(500);
   mySerial.print(text);
   delay(500);
   mySerial.print((char)26);
   delay(500);
   Serial.println("SMS send complete");
   delay(2000);
 } 

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

dimabeliy пишет:

Хороший совет - но мне нужно все исправить сегодня.

Значит, Вам не повезло. Бывает.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

ЕвгенийП пишет:

dimabeliy пишет:

Хороший совет - но мне нужно все исправить сегодня.

Значит, Вам не повезло. Бывает.

У меня "сегодня" длятся часов до трех-четырех, так что у меня не все потеряно!

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Ну, удачи.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Все довольно просто: sim800 ловит импульс от поступившего СМС, отдает контроллеру, контроллер дает логическую команду серве, чтобы она повернулась на 145 град, пауза 1000 потом вернулась в 0. Затем удаление смс и все. Скетч на 30-40 строк. Не думал, что это может составить хоть какую-то проблему... Можт у кого-то все же есть простая идея?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

У меня все на работе, а рабочее утро по МСК начинается в 9:00,так что не ко мне вопрос.

ЗЫ. Вообще охреневаю с людей, непонятно кому заказывают скетч и даже не оттестируют, платят, потом страдают....

dimabeliy
Offline
Зарегистрирован: 11.11.2019

andycat пишет:
У меня все на работе, а рабочее утро по МСК начинается в 9:00,так что не ко мне вопрос. ЗЫ. Вообще охреневаю с людей, непонятно кому заказывают скетч и даже не оттестируют, платят, потом страдают....

Я не страдаю, не переживайте Вы так) Автор говорит - приезжай, будем думать что там и как, а это потеря времени. Поскольку я считаю, что это задача довольно пустячная - возникло предположение, что спец может найти ошибку за пару минут. 

А Вы можете набросать скетч без оборудования?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

dimabeliy
Offline
Зарегистрирован: 11.11.2019

andycat пишет:
Я нет, не настолько спец чтоб виртуальные проги писать. Купите какую нибудь управляемую смс железку в радио магазине и кран примитивный с двумя положениями и все будет

Я уже думал, взять дешевый телефон, подключить к аудио разъему джек и отправить сигнал на аналоговый пин или типа того, чтобы звук от входящей смски активировал серву. Но потом подумал - зачем этот "велосипед", когда есть стардартные шилды и все такое... А можете глянуть код из 22 поста, он рабочий, только управляет двумя реле, а не сервой. Может можно вместо этих реле вписать серву?

Densl
Offline
Зарегистрирован: 28.11.2018

Мне тоже птичек жалко, подбираю обычно больных, кормлю голодных. Но тоже с этим жсм никогда не имел дело, поэтому ни чем не помогу.

dimabeliy
Offline
Зарегистрирован: 11.11.2019

Densl пишет:

Мне тоже птичек жалко, подбираю обычно больных, кормлю голодных. Но тоже с этим жсм никогда не имел дело, поэтому ни чем не помогу.

А ЛЮДЕЙ ВАМ НЕ ЖАЛКО??? 

Да, шучу) Мне на другом форуме набросали простенький скетч - но пока что коннекта нет...

dimabeliy
Offline
Зарегистрирован: 11.11.2019

УРА, ЗАРАБОТАЛА! Добрый человек с другого форума переделал скетч, который легко встал на ардуино нано, и в общем все работает. 

ВСем спасибо, тему можно закрыть.