Общение с SIM900 не перебивая

YaSerg
Offline
Зарегистрирован: 02.03.2017

Всем привет!

Пытаюсь написать скетч отправки смс, так что бы контроллер не пытался ничего отсылать пока идёт информация от шилда.

Пытаюсь реализовать следующий алгоритм: при отправки смс в начале проверяем не пытается ли нам что-то говорить шилд :

if (gprsSerial.available()!=0) { 
      isNosendSms = true;
      return; }

если да, то ставим тру для неотосланной смс, которая формируется в условии

                    String smsText = "I'm started! "+ChekSensorsStatus();
                    sendTextMessage(smsText);

Но по факту если шилд молчит (gprsSerial.available()!=0) смс отправляется нормально, а если  false то вследующем цикле отправляется пустое смс. Подскажите почему, где обнуляется переменная smsText?

Фрагмент скетча:

void setup()
{
.................................................

boolean isNosendSms = false;

.....................................................
}

void loop()
{
.....................................................


// Читаем входящие смс
    if (gprsSerial.available()) {
        
 
    char currSymb = gprsSerial.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение,
            //отреагируем на него соответствующим образом
            if (!currStr.compareTo("Alarm on")) {
                  // Мигаем светодиодом
                  for(int i = 0; i < blinkTime; i++)
                  { //Во время калибровки будет мигать сигнальный диод
                  i % 2 ? digitalWrite(statPin, HIGH) : digitalWrite(statPin, LOW);
                  delay(1000); }
                  countAlarm = 0;
                  //Перед пуском проверяем закрыты ли двери (концевой на пине 2)
                    boolean doorClose = CheckCloseDoors(limSwitch);
                    boolean doorClose2 = CheckCloseDoors(limSwitch2);
                    if (doorClose && doorClose2) {
                    isSendMessage = true;
                    countAlarm = 0;
                    String smsText = "I'm started! "+ChekSensorsStatus();
                    sendTextMessage(smsText); }
                    if (!doorClose || !doorClose2) {
                    String smsText = "No started! Door not closed! "+ChekSensorsStatus();
                    sendTextMessage(smsText); }
.....................................................

.....................................................

        //проверяем есть ли неотосланное смс
  if (isNosendSms) { sendTextMessage(smsText); }

.....................................................
}

void sendTextMessage(String room) {
 
//  Пока идет информация от шилда сохраняем текст смс и прерываем отправку и читаем дальше что говорит шилд
//  Должна быть ф-ция с возвращаемым значением, значение, наверное лучше, текст смс
//      if (!gprsSerial.available())
 
    if (gprsSerial.available()!=0) { 
      isNosendSms = true;
      return; }
    
    else {       
 
    // Устанавливаем адресата: телефонный номер в международном формате
    gprsSerial.println("AT + CMGS = \"+7номер\"");
    delay(200);
    // Пишем текст сообщения
    gprsSerial.println(room);
    delay(200);
    // Отправляем Ctrl+Z, обозначая, что сообщение готово
    gprsSerial.println((char)26);
    // Serial.println("SMS Sended");
    delay(200);
 
    isNosendSms = false; }
 
}
 
void DialVoiceCall(String tel)
{
  digitalWrite(warPin, HIGH);
  gprsSerial.println(tel); //dial the number, must include country code
  gprsSerial.println();
  delay(3000);
  digitalWrite(warPin, LOW);
  delay(3000);
  digitalWrite(warPin, HIGH);
  delay(3000);
  digitalWrite(warPin, LOW);
}
 
boolean CheckCloseDoors(int sensorPin)
{
 if (digitalRead(sensorPin) == HIGH) {
 boolean result = false;
 return result; }
 if (digitalRead(sensorPin) == LOW) {
 boolean result = true;
 return result; }
 }
 
String ChekSensorsStatus() {
  String currSms = "";
  if (digitalRead(pirPin) == HIGH) {
    currSms += "/P1:M/"; }
  else { currSms += "/P1:N/"; }
  
  if (digitalRead(pirPin2) == HIGH) {
    currSms += "P2:M/"; }
  else { currSms += "P2:N/"; }
 
  if (digitalRead(limSwitch) == HIGH) {
    currSms += "L1:O/"; }
  else { currSms += "L1:C/"; }
 
  if (digitalRead(limSwitch2) == HIGH) {
    currSms += "L2:O/"; }
  else { currSms += "L2:C/"; }
 
  return currSms;
 
}

 

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

Вы зачем-то заново обьявляете smsText при каждом использовании, так что smsTextв строках 37, 40 и 47 -это три разные переменные.  Значения, которые вы присваиваете в строках 37 и 40 - не передаются в процедуру sendTextMessage

А на тему, кто кого "перебивает" - поговорим когда вы исправите этот баг. По-моему, блок строк 58-60 вообще лишний

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

Вы зачем-то заново обьявляете smsText при каждом использовании, так что smsTextв строках 37, 40 и 47 -это три разные переменные.  Значения, которые вы присваиваете в строках 37 и 40 - не передаются в процедуру sendTextMessage

А на тему, кто кого "перебивает" - поговорим когда вы исправите этот баг. По-моему, блок строк 58-60 вообще лишний

 

String smsText = ""; обьявить в setup единоразово,  дальше использовать без String, просто smsText?

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

YaSerg пишет:

String smsText = ""; обьявить в setup единоразово,  дальше использовать без String, просто smsText?

да

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707, спасибо! Поправлю, проэксперементирую.

b707 пишет:

А на тему, кто кого "перебивает" - поговорим когда вы исправите этот баг. По-моему, блок строк 58-60 вообще лишний

Почему? Задумка следующая: если прочитан хоть один символ поставить значение не отосланной смс (isNosendSms)  true если смс не отправлено и прервать ф-цию. Дождаться когда из порта молчание и тогда отправить смс с тектом из переменной вышеупомянутой smsText, вернуть флаг в значение false.

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

b707 пишет:

YaSerg пишет:

String smsText = ""; обьявить в setup единоразово,  дальше использовать без String, просто smsText?

да

тьфу! неправильно - обьявлять надо не в setup, а раньше. Если обьявить в setup - это будет локальная переменная процедуры setup. понимаете? а вам нужна глобальная

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

тьфу! неправильно - обьявлять надо не в setup, а раньше. Если обьявить в setup - это будет локальная переменная процедуры setup. понимаете? а вам нужна глобальная

Протупил, да, раньше setup объявлю. Спасибо!

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

YaSerg пишет:

Почему? Задумка следующая: если прочитан хоть один символ поставить значение не отосланной смс (isNosendSms)  true если смс не отправлено и прервать ф-цию. Дождаться когда из порта молчание и тогда отправить смс с тектом из переменной вышеупомянутой smsText, вернуть флаг в значение false.

А если если порт "заговорит" после строки 60 - что делать? ИМХО, пытаться уловить все, что передает модем - довольно трудоемко. Я в своем проекте от этого отказался и читаю только ответы на мои запросы. Все что модем шлет "без спросу" - просто чищу не читая.

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

А если если порт "заговорит" после строки 60 - что делать? ИМХО, пытаться уловить все, что передает модем - довольно трудоемко. Я в своем проекте от этого отказался и читаю только ответы на мои запросы. Все что модем шлет "без спросу" - просто чищу не читая.

Я пока не допёр как это сделать. Всё у меня упирается в большие задержки. Можете пример показать?

Если заговорит после 60 строки это маловероятно, это миллисекунды. Но возможно!

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

YaSerg пишет:

Я пока не допёр как это сделать.

что именно?

YaSerg
Offline
Зарегистрирован: 02.03.2017

читаю только ответы на мои запросы. Все что модем шлет "без спросу" - просто чищу не читая.

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

YaSerg пишет:

читаю только ответы на мои запросы. Все что модем шлет "без спросу" - просто чищу не читая.

я не имел в виду конкретный код - а общий принцип. Как бы два разных подхода к обработке входящих СМС.  Можно постоянно мониторить вывод модема, чтобы увидеть пришедшую СМС. И все равно можете что-то пропустить. Другой подход - не отслеживать вывод из сериала вообще, а просто раз в 5 минут проверять наличие новых СМС соответсвующей командой. (конечно, надо предварительно настроить сохранение СМС в память или на симку)

YaSerg
Offline
Зарегистрирован: 02.03.2017

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

Идея с чтеним смс из памяти мне нравится. Поделитесь примерчиком?

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

YaSerg пишет:

Идея с чтеним смс из памяти мне нравится. Поделитесь примерчиком?

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

YaSerg
Offline
Зарегистрирован: 02.03.2017

Библиотеку пробовал она офигенная! Но проблема всех этих библиотек в моем проекте они ни как не хотят работать в ESP8266 или Wemos D1. 

Ошибка компиляции:

/Users/serg/Documents/Arduino/libraries/GPRS_SIM900-master/GPRS_Shield_Arduino.cpp: In member function 'void GPRS::listen()':

/Users/serg/Documents/Arduino/libraries/GPRS_SIM900-master/GPRS_Shield_Arduino.cpp:792:13: error: 'class SoftwareSerial' has no member named 'listen'
  gprsSerial.listen();
             ^
/Users/serg/Documents/Arduino/libraries/GPRS_SIM900-master/GPRS_Shield_Arduino.cpp: In member function 'bool GPRS::isListening()':
/Users/serg/Documents/Arduino/libraries/GPRS_SIM900-master/GPRS_Shield_Arduino.cpp:797:20: error: 'class SoftwareSerial' has no member named 'isListening'
  return gprsSerial.isListening();
                    ^
exit status 1
Ошибка компиляции для платы WeMos D1(Retired).
 
Нахожу ф-цию в файле GPRS_Shield_Arduino.cpp и не вижу ничего такого, что могло бы вызывать ошибку:
 
#include <stdio.h>
#include "GPRS_Shield_Arduino.h"

GPRS* GPRS::inst;

GPRS::GPRS(uint8_t tx, uint8_t rx, uint32_t baudRate):gprsSerial(tx,rx)
{
    inst = this;
    sim900_init(&gprsSerial, baudRate);
}

bool GPRS::init(void)
{
    if(!sim900_check_with_cmd(F("AT\r\n"),"OK\r\n",CMD)){
		return false;
    }
    
    if(!sim900_check_with_cmd(F("AT+CFUN=1\r\n"),"OK\r\n",CMD)){
        return false;
    }
    
    if(!checkSIMStatus()) {
		return false;
    }
    return true;
}
..........................
void GPRS::listen(void)
{
	gprsSerial.listen();
}

 

 

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

YaSerg пишет:

Библиотеку пробовал она офигенная! Но проблема всех этих библиотек в моем проекте они ни как не хотят работать в ESP8266 или Wemos D1.

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

Что касается приведенной ошибки - попробуйте просто закомментировать функцию void GPRS::listen(void) в файле GPRS_Shield_Arduino.cpp, по моему она вам не нужна для чтения СМС

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

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

Что касается приведенной ошибки - попробуйте просто закомментировать функцию void GPRS::listen(void) в файле GPRS_Shield_Arduino.cpp, по моему она вам не нужна для чтения СМС

Вы дорабатывали эту библиотеку? Т.е. что бы перейти на нее придется немного поработать с ней?

void GPRS::listen(void) isListening() а для чего эта ф-ции? Дело в том что я не весь коды выкладывал, у меня есть еще звонки, проверка доступности модуля и сети.

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

я не имел в виду конкретный код - а общий принцип. Как бы два разных подхода к обработке входящих СМС.  Можно постоянно мониторить вывод модема, чтобы увидеть пришедшую СМС. И все равно можете что-то пропустить. Другой подход - не отслеживать вывод из сериала вообще, а просто раз в 5 минут проверять наличие новых СМС соответсвующей командой. (конечно, надо предварительно настроить сохранение СМС в память или на симку)

Поигрался с рекомендованной Вами библиотекой все работает, кроме чтения смс. Я так понял что надо настроить модем на сохранение смс на сим карту. Подскажете как реализовать?

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

YaSerg пишет:

void GPRS::listen(void) isListening() а для чего эта ф-ции? Дело в том что я не весь коды выкладывал, у меня есть еще звонки, проверка доступности модуля и сети.

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

YaSerg пишет:

Поигрался с рекомендованной Вами библиотекой все работает, кроме чтения смс. Я так понял что надо настроить модем на сохранение смс на сим карту. Подскажете как реализовать?

посмотрите описание команды AT+CPMS

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

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

Может я мало жду, как быстро она должна появиться в мониторе порта в стандартном скетче?

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

YaSerg пишет:

Может я мало жду, как быстро она должна появиться в мониторе порта в стандартном скетче?

"она" - это кто?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Почитайте уже что нибудь про сигналы CTS, RTS... Ну что бы "огород не городить". Умные люди для вас придумали.

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

brokly пишет:

Почитайте уже что нибудь про сигналы CTS, RTS... Ну что бы "огород не городить". Умные люди для вас придумали.

А при чем здесь это?

YaSerg
Offline
Зарегистрирован: 02.03.2017

b707 пишет:

YaSerg пишет:

Может я мало жду, как быстро она должна появиться в мониторе порта в стандартном скетче?

"она" - это кто?

 СМСка отправленная на SIM900

MihaNN52
Offline
Зарегистрирован: 22.01.2017

Делаю примерно тоже самое но на SIM800L, но думаю хрен редки не слаще.

В общем то тоже сталкнулся с такой возможностью что смс не уйдет.

Я так же формирую сообзение в String. Только при объявлении в сетапе ставлю String smsText = "0";

После в какой либо функции которая должена отправить смс она формирует String smsText и все.

Т.е в твоем случае это будет так 

String smsText = "I'm started! "+ChekSensorsStatus();

Все у нас есть строка которая != "0"

И пишем отправку мессаги которая крутится в цикле. Для нее получаем уровень сигнала сети.

if (smsText != "0" && level_gps >= desired_level_gps) { //  если есть сообщение и уровень сигнала сети больше или равно желаемому. тут же можно поставить условия проверки gprsSerial.available()==0
   
    gprsSerial.println(F("AT+CMGF=1\r")); 
    gprsSerial.println("AT+CMGS=\"" + tel1 + "\"");
    delay(30);
    gprsSerial.print(smsText);
    delay(30);
    gprsSerial.print((char)26);
    delay(30);
    send_1 = "0"; // обнуляем текст смс
    delay(30);
   
   }

*на делеи не смотри они от балды

если я правильно понял задачу конечно.

как Миха получал уровень сети)) http://arduino.ru/forum/programmirovanie/sim800l-uroven-signala-seti

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

YaSerg пишет:

b707 пишет:

"она" - это кто?

 СМСка отправленная на SIM900

Странный вопрос :) Если СМС уже в памяти и вы считываете "Непрочитанные сообщения" - то сразу. Если Вы отправили из телефона и ждете - зависит от того, сколько будет идти СМС, может и вообще не придти :)

По Вашим прошлым вопросам - посмотрел, что делает isListening() - это функция "обертка" для одноименной функции класса SoftwareSerial. В принципе она вам не нужна и странно, что на нее возникает ошибка.

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

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

MihaNN52,

я вам у же писал, что у вас формат отправки СМС неверный (или не вполне верный)

Вместо 4-й строки gprsSerial.println("AT+CMGS=\"" + tel1 + "\""); нужно вставить

gprsSerial.print("AT+CMGS=\"" + tel1 + "\"");
gprsSerial.print(char(13));

 

MihaNN52
Offline
Зарегистрирован: 22.01.2017

 

Ни где не видел такого... это точно для sim800l? Не хочется обсуждать мои вопросы в чужой теме. И мая не припомнит общения на эту тему.

 

 

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

MihaNN52 пишет:

Ни где не видел такого... это точно для sim800l? Не хочется обсуждать мои вопросы в чужой теме. И мая не припомнит общения на эту тему.

Ну может я не вам говорил, сорри.

Формат АТ-команд для большинства модемов одинаков, конкретно для SIM800 можете убедиться вот тут: https://www.elecrow.com/download/SIM800%20Series_AT%20Command%20Manual_V...

страница 120, команда AT+CMGS

MihaNN52
Offline
Зарегистрирован: 22.01.2017
Write Command
1) If text mode
(+CMGF=1):
+CMGS=<da>[,
<toda>]
<CR>text is
entered
<ctrl-Z/ESC>
ESC quits without
sending
 
Получается CR не передаем.
Можно ведь так ? 

gprsSerial.println ("AT+CMGS=\"" + tel1 + "\"\r");

спасибо

 

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

b707 пишет:

brokly пишет:

Почитайте уже что нибудь про сигналы CTS, RTS... Ну что бы "огород не городить". Умные люди для вас придумали.

А при чем здесь это?

Читать не умеете ? Или не хотите ?

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

brokly пишет:

Читать не умеете ? Или не хотите ?

Дорогой! На этом форуме никто никому ничего не должен. Не вижу нужды перед вами оправдываться, что я читал, а что нет. В тоже время всегда рад случаю узнать что-то новое. Я прочитал про RTS/CTS и, признаться, не вижу. чем это может быть полезно. Если есть желание - обьясните. Если нет - я и без вас проживу :)

 Салют :)