Кормушка для птиц по СМС на 8266
- Войдите на сайт для отправки комментариев
Пнд, 11/11/2019 - 19:25
Доброе время! Решил сделать кормушку, чтоб при отправке СМС срабатывал серво, который сыпал корм.
Взял 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) {}
}
Буфер не очищается после успешного запуска сервы и чтения смс.
Вы правы, писал не сам - но с автором сейчас связаться проблематично. Может какая-то мелкая помарка, которая сразу бросится в глаза специалисту - я исправлю и все. Хотелось бы надеяться на такой расклад. Заранее благодарен!
Автор взял деньги и сбежал? Тут весь код - сплошная помарка.
Сдается мне, что на #113 выход за границы массива.
Автор взял деньги и сбежал? Тут весь код - сплошная помарка.
не сбежал, но у него не хватает компетенции понять причину нестабильной работы. А меня поджимает время, проект стоит.
Может есть более простой код, который позволит управлять сервой или шаговым мотором по СМС?
Интересно.. Как это решить? Переместить строку в другое место?
Сдается мне, что на #113 выход за границы массива.
Гм.. Как это решить? Переместить строку в другое место?
А вот это, вообще, про что?
bool isResponseOk(char* buffer) { // 1. Get buflen int buflen = 0; for(int i = 0; i < 256; i++) { if(int(buffer) == 0) { buflen = i; break; } }Это лишнее? Попробую удалить!
Господи, ....
Откуда взялся этот код? Вы его нашли на какой-то помойке или сами написали?
Господи, ....
Откуда взялся этот код? Вы его нашли на какой-то помойке или сами написали?
Попросил человека - он написал, хотя не очень горел желанием это делать. Возможно, он не супер профи - соединил пару кусков кодов из интернета. Вроде все работало - но оказалось, что работает не стабильно. Вот, надо либо искать новый код - либо править этот. Для некоторых это довольно просто - для меня нет, вот и обратился за помощью к спецам. Заранее благодарен!
Не знаю, как он у Вас работал. Тот кусок, что я привёл является бредом. И там много такого. По мне, так надо выбросить и переписать заново.
Не знаю, как он у Вас работал. Тот кусок, что я привёл является бредом. И там много такого. По мне, так надо выбросить и переписать заново.
Есть простой скетч, который управляет реле по СМС - но мне надо именно серву: то есть поменять пару строк (наверное) - но для меня такая операция пока недоступна. Если сможете помочь - буду благодарен!)
Сдается мне, что на #113 выход за границы массива.
Выходит, но если тупо после принятия смс в начала буфера ноль записать, то может ещё поработает.
Сдается мне, что на #113 выход за границы массива.
Та-ак, в какой это строке? В 113? А как ноль записать?
dimabeliy, этот код не жиснеспособен, пинайте автора или изучайте программирование.
Хороший совет - но мне нужно все исправить сегодня.
Прям сегодня - только за большие деньги. andycat вон специализируется на модемных скетчах.
Прям сегодня - только за большие деньги. andycat вон специализируется на модемных скетчах.
Большие - это сколько?
Я не могу оценить трудозатраты, не моя область. andycat ждите.
Птички голодные, хотят жрать - а вам бы все привередничать )
А если взять этот код, но вместо реле вписать туда серво, а тот кусок, который отвечает за ответную отправку СМС просто удалить?
/* Тестировалось на 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); }Хороший совет - но мне нужно все исправить сегодня.
Значит, Вам не повезло. Бывает.
Хороший совет - но мне нужно все исправить сегодня.
Значит, Вам не повезло. Бывает.
У меня "сегодня" длятся часов до трех-четырех, так что у меня не все потеряно!
Ну, удачи.
Все довольно просто: sim800 ловит импульс от поступившего СМС, отдает контроллеру, контроллер дает логическую команду серве, чтобы она повернулась на 145 град, пауза 1000 потом вернулась в 0. Затем удаление смс и все. Скетч на 30-40 строк. Не думал, что это может составить хоть какую-то проблему... Можт у кого-то все же есть простая идея?
У меня все на работе, а рабочее утро по МСК начинается в 9:00,так что не ко мне вопрос.
ЗЫ. Вообще охреневаю с людей, непонятно кому заказывают скетч и даже не оттестируют, платят, потом страдают....
Я не страдаю, не переживайте Вы так) Автор говорит - приезжай, будем думать что там и как, а это потеря времени. Поскольку я считаю, что это задача довольно пустячная - возникло предположение, что спец может найти ошибку за пару минут.
А Вы можете набросать скетч без оборудования?
Я нет, не настолько спец чтоб виртуальные проги писать. Купите какую нибудь управляемую смс железку в радио магазине и кран примитивный с двумя положениями и все будет
Я уже думал, взять дешевый телефон, подключить к аудио разъему джек и отправить сигнал на аналоговый пин или типа того, чтобы звук от входящей смски активировал серву. Но потом подумал - зачем этот "велосипед", когда есть стардартные шилды и все такое... А можете глянуть код из 22 поста, он рабочий, только управляет двумя реле, а не сервой. Может можно вместо этих реле вписать серву?
Мне тоже птичек жалко, подбираю обычно больных, кормлю голодных. Но тоже с этим жсм никогда не имел дело, поэтому ни чем не помогу.
Мне тоже птичек жалко, подбираю обычно больных, кормлю голодных. Но тоже с этим жсм никогда не имел дело, поэтому ни чем не помогу.
А ЛЮДЕЙ ВАМ НЕ ЖАЛКО???
Да, шучу) Мне на другом форуме набросали простенький скетч - но пока что коннекта нет...
УРА, ЗАРАБОТАЛА! Добрый человек с другого форума переделал скетч, который легко встал на ардуино нано, и в общем все работает.
ВСем спасибо, тему можно закрыть.