Как задать кретическую температуру по смс

_jah_69_
Offline
Зарегистрирован: 31.03.2017

Возникла такая задача.

Имется датчик температуры в программе стоит что при достижении температуры 5С приходило смс о том что котел потух.

Что пытаюсь сделать- Отправляю смс AlarmTemp=10 или 12.....

Как прописать программно что бы он выдергивал 10 или 12 и присваивал эту цифру AlarmTemp=

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

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

А как Вы делали то, что у Вас сейчас есть? 

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

как бы я сделал...

ловим в смс и сохраняем ее в переменную типа String

дальше проверяем эту строку на наличие подстроки "AlarmTemp="

если есть такая подстрока то выдераем число после знака =

и сохраняем ее в глобальную переменную, но так как она пропадет при перезагрузке то пишем еще  в EEPROM

 

следующим шагом надо дописать в сетапе получение этого значения из EEPROM  и сохранить его в ту же глобальную переменную

вот как бы и все....

думаю строчек 10 кода получится

ну а дальше по коду сравнивайте себе пожалуйсто с глобальной переменной что и как хотите.

можно конечно сделать и без глобальной переменной, но я бы сделал с ней)))

это моя идея, и не утверждаю что правельная.. возможно ктото по другому придумает

_jah_69_
Offline
Зарегистрирован: 31.03.2017

Благодарствую. Попробую 

smesharik
Offline
Зарегистрирован: 31.01.2016
 
 if (!gprsSerial.available())
    return;

  char currSymb = gprsSerial.read();
  if ('\r' == currSymb) {
    if (isStringMessage) {
      currStr.toLowerCase();

if (currStr.indexOf(F("AlarmTemp=")) > -1)    {
        currStr = currStr.substring(5, 8);
        AlarmTemp = currStr.toInt();
      }
  isStringMessage = false;
    } else {
      if (currStr.startsWith("+CMT")) {
        isStringMessage = true;
      } }
 currStr = "";
  } else if ('\n' != currSymb) {
    currStr += String(currSymb);
  }

Значения 5 и 8 подобрать, это с какого символа он будет смотреть у вас наверно будет 10 и 13, счет начинается с 0

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

smesharik пишет:

 
 if (!gprsSerial.available())
    return;

  char currSymb = gprsSerial.read();
  if ('\r' == currSymb) {
    if (isStringMessage) {
      currStr.toLowerCase();

if (currStr.indexOf(F("AlarmTemp=")) > -1)    {
        currStr = currStr.substring(5, 8);
        AlarmTemp = currStr.toInt();
      }
  isStringMessage = false;
    } else {
      if (currStr.startsWith("+CMT")) {
        isStringMessage = true;
      } }
 currStr = "";
  } else if ('\n' != currSymb) {
    currStr += String(currSymb);
  }

Значения 5 и 8 подобрать, это с какого символа он будет смотреть у вас наверно будет 10 и 13, счет начинается с 0

Зачем "подбирать значения 5 и 8", если у вас есть точный ответ от оператора  currStr.indexOf(F("AlarmTemp=") ? Используйте его  по назначению. Тогда. кстати, можно будет посылать несколько команд в одном СМС.

Если "подбирать значения", этот код будет работать один раз из десяти

_jah_69_
Offline
Зарегистрирован: 31.03.2017

Спасибо завтра буду имплантировать в скетч

smesharik
Offline
Зарегистрирован: 31.01.2016

b707 пишет:

Зачем "подбирать значения 5 и 8", если у вас есть точный ответ от оператора  currStr.indexOf(F("AlarmTemp=") ?


Как тогда видоизменить код чтоб он понимал сразу, что перед нами данная переменная и присваивал что идет за равно?

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

smesharik][quote=b707 пишет:

Как тогда видоизменить код чтоб он понимал сразу, что перед нами данная переменная и присваивал что идет за равно?

Например, так:


int p =0;
if ( (p = currStr.indexOf(F("AlarmTemp="))) > -1)    {
        currStr = currStr.substring(p+10, p+13);
        AlarmTemp = currStr.toInt();
      }

Разницу понимаете или обьяснить?

А вот так можно вообще никаких индексов вручную не считать:

int p =0;
if ( (p = currStr.indexOf(F("AlarmTemp="))) > -1)    {
        int pp = currStr.indexOf("=", p) ;
        pp += p;
        currStr = currStr.substring(pp+1, pp+4);
        AlarmTemp = currStr.toInt();
      }

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

smesharik
Offline
Зарегистрирован: 31.01.2016

Да, сорри alarmtemp= все нижним, теперь будет работать

Да если можно пояснить эти рр

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

smesharik пишет:
Боюсь вас огорчить, мой код работает и работает в 100%, а как вы говорите в нижний, да, он все СМС переводит в нижний, это для того чтобы если написать хоть какую букву в верхнем, МК не поймет его.

Даже стало интересно :)

Вас, как программиста :).  не смущает, что вы все строки сначала переводите в нижний регистр, а потом ищете в них строки в верхнем регистре? Или вы этот код слепили прямо сейчас, для форума, а реальный код у вас другой?

smesharik
Offline
Зарегистрирован: 31.01.2016

Про регистр написал выше
В вашем первом примере это не одно и тоже 10, 13 и р+10 , р+13 если р=0

_jah_69_
Offline
Зарегистрирован: 31.03.2017

А нужно ли оно реальное время. Заждать полив по  mills. 1 секунда 1000 милисикунд. И пусть себе отсчитывает скок надобно

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

smesharik пишет:
если можно пояснить эти рр

Смотрите, в  чем проблема вашего кода и как я ее решаю в своем. На примере вашего кода из сообщения #4

в 9-ой строке вы ищете во входных данных строку "AlarmTemp". Оператор currStr.indexOf(F("AlarmTemp=") не только ищет заданную строку - он еще и сообщает вам ее положение, если она нашлась. Но вы эту информацию никак не используете, а вместо этого предполагаете, что "AlarmTemp" всегда стоит строго в начале СМС. Достаточно случайно вставить перед "AlarmTemp" один-два пробела - и ваш код перестанет работать.

В моем варианте я не только ищу строку "AlarmTemp" во входных данных - я запоминаю ее положение и потом отсчитываю начало значения температуры от первого символа этой строки. Даже если "AlarmTemp" стоит не в начале СМС и даже если в СМС куча другого текста - код все равно правильно сработает. Этим кодом можно обрабатывать СМС с несколькими командами, типа "Kotel=ON Switch=OFF AlarmTemp=33"

Во втором примере все еще более автоматизировано. Сначала ищем в строке нашу "AlarmTemp", а потом ищем первый знак "=" после "AlarmTemp". При этом нам вообще не надо считать символы в наших строках.

smesharik
Offline
Зарегистрирован: 31.01.2016

А вы правы, надо переделать что имеем

void phone() {

  if (!gprsSerial.available())
    return;

  char currSymb = gprsSerial.read();
  if ('\r' == currSymb) {
    if (isStringMessage) {
      currStr.toLowerCase();


if ( (p = currStr.indexOf(F("poliv"))) > -1)    {
        flag = true;
        currStr = currStr.substring(p+5, p+8);
        timer_on = currStr.toInt();
      }

      isStringMessage = false;
    } else {
      if (currStr.startsWith("+CMT")) {
        isStringMessage = true;
      }
      if (currStr.startsWith("+CLIP")) {
        if (currStr.indexOf(master_phone) > -1) {                        // проверяем номер, если наш.
          gprsSerial.println(F("ATH0"));                  // сбрасываем вызов. свой
        }
        else {
          gprsSerial.println(F("ATH0"));                  // если не наш, сбрасываем его.
        }
      }
    }
    currStr = "";
  } else if ('\n' != currSymb) {
    currStr += String(currSymb);
  }
}

Большущее вам спасибо, работает как часы

smesharik
Offline
Зарегистрирован: 31.01.2016

b707 пишет:

Подскажите еще такой момент

как мне сделать что бы при отправки смс вида time1015, было разделение и запись в EEPROM

 if ( (p = currStr.indexOf(F("time"))) > -1)    {
        currStr = currStr.substring(p+4, p+6);
        setHorClockOn = currStr.toInt();        
        currStr = currStr.substring(p+6, p+8);
        setMinClockOn = currStr.toInt();
        EEPROM.update(0, setMinClockOn);
        EEPROM.update(1, setHorClockOn);
      }