Управление переменными через смс SIM800L

Sergio-o
Offline
Зарегистрирован: 18.04.2017

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

Помогите кто сколько сможет!!!!! 

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

1. Я не понял вопроса. Собственно вопроса-то в Вашем тексте как такового нет.

2. Какой именно помощи Вы ожидаете? У Вас же нет скетча, на который можно посмотреть и что-то подсказать. Также, если я правильно понял, у Вас не оборудования га котором Вы можете что-то пробовать (или есть?). Чего Вы ждёте от помогающего?

Sergio-o
Offline
Зарегистрирован: 18.04.2017

оборудование в проекте. 


#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(0, 1, 2, 3, 4, 5);
OneWire oneWire(10);
DallasTemperature ds(&oneWire);
int led = 9;
int up = 13;
DeviceAddress sensor1 = {0x28, 0xFF, 0x14, 0x5F, 0xA3, 0x15, 0x04, 0x09};
void setup() {
  ds.begin();
  lcd.begin(16, 2);
  lcd.clear();
  pinMode(led, OUTPUT);
  pinMode(up, INPUT);
}

void loop() {
 ds.requestTemperatures();
 int h = ds.getTempC(sensor1) * 2;
 int r = 255 - h;
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("Sensor 1: ");
 lcd.print(ds.getTempC(sensor1));
 lcd.print("C");
 delay(700);
 lcd.setCursor(0, 1);
 if (ds.getTempC(sensor1) < 25) { Можно ли через смс изменять значение "<25"?
  lcd.print("Cold");
 } else if (ds.getTempC(sensor1) > 30){  // Можно ли через смс изменять значение ">30"?
  lcd.print("        Critical");
 } else {
  lcd.print("     Normal");
 }
delay(700);

analogWrite(led, r);

}

это первый вопрос. 

Sergio-o
Offline
Зарегистрирован: 18.04.2017

#include <SoftwareSerial.h>
  
SoftwareSerial gprsSerial(2, 3);
  

int greenPin = 4;
int yellowPin = 5;
  
void setup()
{
  Serial.begin(19200);
    gprsSerial.begin(19200);
    pinMode(greenPin, OUTPUT);
    pinMode(yellowPin, OUTPUT);
  
    // Настраиваем приём сообщений с других устройств
    // Между командами даём время на их обработку
    gprsSerial.print("AT+CMGF=1\r");
    delay(300);
    gprsSerial.print("AT+IFC=1, 1\r");
    delay(300);
    gprsSerial.print("AT+CPBS=\"SM\"\r");
    delay(300);
    gprsSerial.print("AT+CNMI=1,2,2,1,0\r");
    delay(500);
}
  
String currStr = "";
// Переменная принимает значение True, если текущая строка является сообщением
boolean isStringMessage = false;
 
void loop()
{
    if (!gprsSerial.available())
        return;
 
    char currSymb = gprsSerial.read();   
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение,
            //отреагируем на него соответствующим образом
            if (!currStr.compareTo("1-1")) {
                digitalWrite(greenPin, HIGH);
            }
            if (!currStr.compareTo("1-0")) {
                digitalWrite(greenPin, LOW);
            }
            if (!currStr.compareTo("2-1")) {
                digitalWrite(yellowPin, HIGH);
            }
            if (!currStr.compareTo("2-0")) {
                digitalWrite(yellowPin, LOW);
            }
            if (!currStr.compareTo("3-0")) {
                digitalWrite(yellowPin, LOW);
                digitalWrite(greenPin, LOW);
            }
            if (!currStr.compareTo("3-1")) {
                digitalWrite(yellowPin, HIGH);
                digitalWrite(greenPin, HIGH);
            }
            isStringMessage = false;
        } else {
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
            }
        }
        currStr = "";
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
    }
    Serial.print(currSymb);
}


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

но вопросы у меня только в этих двух кусках относительно модуля GSM.

команды работают только в формате 1-1 и т.д.

1 команда за 1 смс.

Я видел как кто-то делал 4команды за 1 смс. в формате например в смс 1-0 2-1 3-1 4-2

я как не пытался но повторить не смог.  при отправки команд даж в формате 1-1 2-1 он вообще ничего не делает.

как это сделать?

это второй вопрос

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

Sergio-o пишет:

Можно ли через смс изменять значение ">30"?

это первый вопрос. 

Можно.

Это первый ответ.

Sergio-o пишет:

Я видел как кто-то делал 4команды за 1 смс. в формате например в смс 1-0 2-1 3-1 4-2

я как не пытался но повторить не смог.  при отправки команд даж в формате 1-1 2-1 он вообще ничего не делает.

как это сделать?

это второй вопрос

Рабирать полученную строку. Рабивать её на команды и исполнять их по одной. Т.е. алгоритм примерно такой:

1. Установить "начало команды" на начало строки
2. Идём по строке и сравниваем каждый символ со спец. символом "конец команды"
3. Если найден "конец команды" или строка закончилась, то исполнить одну команду содержащуюся в строке в позициях от "начала команды" до текущего символа
4. Если в п.3 был найдет символ "конец команды", то установить начало команды на следующий символ и перейти к п. 2.
5. Завершить работу.

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

Это второй ответ.

Sergio-o
Offline
Зарегистрирован: 18.04.2017

1. Установить "начало команды" на начало строки

2. Идём по строке и сравниваем каждый символ со спец. символом "конец команды"
3. Если найден "конец команды" или строка закончилась, то исполнить одну команду содержащуюся в строке в позициях от "начала команды" до текущего символа
4. Если в п.3 был найдет символ "конец команды", то установить начало команды на следующий символ и перейти к п. 2.
5. Завершить работу.

Принцип мне понятен. Но как это сделать програмно просто не знаю.

Я по образованию инженер-механик. и обучение по ардуино основано на скачивании чужих скетчей. сидел разбирался. вникал. читал описание библиотек.

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

Sergio-o
Offline
Зарегистрирован: 18.04.2017

начинаю соображать.

char Str3[8] = {'a''r''d''u''i''n''o''\0'};

таким образом мы разбиваем сообщение на символы... вот начало и конец.

и потом их можно обрабативать в виде:

if (a == чему то; r == чему то;) {

сделать это;

}

Я в правильном направлении?

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

Нет. 

Вы получиди строку. Строка состоит из команд (в общем виде они называются лексемами). 1. Вы должны уметь отделять оду лексему от другой. Проще всего это сделать, имея символ разделитель. Например, все команды разделяются символом ';'. Теперь Вы знаете, что первая команда у Вас идёт от начала строки до символа ';' или до конца строки (что вперёд попадётся). Если первая команда закончилась ;, значит есть вторая, которая начинается сразу за ; и идёт до новой ; или до конца строки (что вперёд встретится). И так далее. По этой ; Вы разделяете строку на команды.

Как конкретно это делается - гуглите "примеры использования функции strtok"

stasych
Offline
Зарегистрирован: 16.03.2016

Sergio-o пишет:


#include <SoftwareSerial.h>
  
SoftwareSerial gprsSerial(2, 3);
  

int greenPin = 4;
int yellowPin = 5;
  
void setup()
{
  Serial.begin(19200);
    gprsSerial.begin(19200);
    pinMode(greenPin, OUTPUT);
    pinMode(yellowPin, OUTPUT);
  
    // Настраиваем приём сообщений с других устройств
    // Между командами даём время на их обработку
    gprsSerial.print("AT+CMGF=1\r");
    delay(300);
    gprsSerial.print("AT+IFC=1, 1\r");
    delay(300);
    gprsSerial.print("AT+CPBS=\"SM\"\r");
    delay(300);
    gprsSerial.print("AT+CNMI=1,2,2,1,0\r");
    delay(500);
}
  
String currStr = "";
// Переменная принимает значение True, если текущая строка является сообщением
boolean isStringMessage = false;
 
void loop()
{
    if (!gprsSerial.available())
        return;
 
    char currSymb = gprsSerial.read();   
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение,
            //отреагируем на него соответствующим образом
            if (!currStr.compareTo("1-1")) {
                digitalWrite(greenPin, HIGH);
            }
            if (!currStr.compareTo("1-0")) {
                digitalWrite(greenPin, LOW);
            }
            if (!currStr.compareTo("2-1")) {
                digitalWrite(yellowPin, HIGH);
            }
            if (!currStr.compareTo("2-0")) {
                digitalWrite(yellowPin, LOW);
            }
            if (!currStr.compareTo("3-0")) {
                digitalWrite(yellowPin, LOW);
                digitalWrite(greenPin, LOW);
            }
            if (!currStr.compareTo("3-1")) {
                digitalWrite(yellowPin, HIGH);
                digitalWrite(greenPin, HIGH);
            }
            isStringMessage = false;
        } else {
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
            }
        }
        currStr = "";
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
    }
    Serial.print(currSymb);
}


Извиняюсь за вопросы немного не в тему.

1. Если подобным образом все время принимать и принимать СМС то не переполнится ли на модуле память и не получится ли из-за этого какого-либо конфликта при дальшейней работе с модулем?

2. Если переполнение возможно то как лучше всего почистить память применительно к данному алгоритму?

Спасибо.

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

stasych пишет:

1. Если подобным образом все время принимать и принимать СМС то не переполнится ли на модуле память и не получится ли из-за этого какого-либо конфликта при дальшейней работе с модулем?

2. Если переполнение возможно то как лучше всего почистить память применительно к данному алгоритму?

1. Переполнится. У вас в скетче СМС сохраняются на СИМ-карту - (строка 22, команда gprsSerial.print("AT+CPBS=\"SM\"\r");). Памяти на СИМ-ке обычно хватает на десяток-другой СМС, как только она заполнится, новые СМС приниматься не будут.

2. Командой AT+CMGD нужно стирать ненужные СМС с карты

stasych
Offline
Зарегистрирован: 16.03.2016

Спасибо !

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

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

stasych пишет:

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

Вроде бы не должно влиять, но лучше проверить. Я бы для надежности в начале скетче стирал все СМС с СИМ-карты, а потом принимал СМС и сразу удалял их