Переменные сбрасываются.

Nailoren
Offline
Зарегистрирован: 30.10.2018

Здравствуйте, форумчане!

Вообщем возникла небольшая проблемка.

Предыстория: Собираю устройство на базе arduino nano, которое будет по смс сообщениям управлять реле.

Суть проблемы: Допустим, я отправляю на устройство "On1" (включаю свет) получаю ответ, потом отправляю "On2" (включаю обогрев) получаю ответ, далее запрашиваю состояние смской  "sost" и получаю ответ:

"Vkluchen obogrev, Vkluchen svet, Otkluchen nasos, Otklucheno rele, T =  26.63"

Дальше я включаю насос смской "On3", и отключаю свет смской "Off1", всё нормально отключается.

Снова запрашиваю состояние смской  "sost" и получаю ответ: 

"26.63"

Приходит только значение температуры с датчика.

Кто-нибудь знает в чём проблема и как её решить?

Вот кусочек скетча

getsms(); // получаем непрочитанную СМС                 
        
static String sostObogrev="Otkluchen";
static String sostOsv="Otkluchen";
static String sostNasos="Otkluchen";
static String sostRele="Otklucheno";
if (input_string=="Off1"){digitalWrite(Rel1, LOW);sms.SendSMS(n1, "Otkluchen svet");sostOsv="Otkluchen";}
if (input_string=="Off2"){digitalWrite(Rel2, LOW);sms.SendSMS(n1, "Otkluchen obogrev");sostObogrev="Otkluchen";}
if (input_string=="Off3"){digitalWrite(Rel3, LOW);sms.SendSMS(n1, "Otkluchen nasos");sostNasos="Otkluchen";}
if (input_string=="Off4"){digitalWrite(Rel4, LOW);sms.SendSMS(n1, "Otklucheno rele");sostRele="Otklucheno";}
if (input_string=="On1"){digitalWrite(Rel1, HIGH);sms.SendSMS(n1, "Vkluchen svet");sostOsv="Vkluchen";}
if (input_string=="On2"){digitalWrite(Rel2, HIGH);sms.SendSMS(n1, "Vkluchen obogrev");sostObogrev="Vkluchen";}
if (input_string=="On3"){digitalWrite(Rel3, HIGH);sms.SendSMS(n1, "Vkluchen nasos");sostNasos="Vkluchen";}
if (input_string=="On4"){digitalWrite(Rel4, HIGH);sms.SendSMS(n1, "Vklucheno rele");sostRele="Vklucheno";}
// if (input_string=="T"){sms.SendSMS(n1, sendsms);memset(n,0,20);}
if (input_string=="sost")
{
    smsContent=(sostObogrev+" obogrev, "+sostOsv+" svet, "+sostNasos+" nasos, "+sostRele+" rele, T =  "+String(sensors.getTempCByIndex(0)));
    smsContent.toCharArray(sendsms,160);
    sms.SendSMS(n1, sendsms);  
}

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Ой Вы знаете - у меня если тут нажать то там болит а если нажать там то чешется тут. Вот вам фотография мизинца правой ноги подскажите пожалуйста какую таблетку мне пить.

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

1. Скетч нужен полностью.

2. Заодно поставьте проверки выделилась ли память под String'и и печатайте в Serial результат. Протокол (что в сериал печатается) тоже нужен.

Nailoren
Offline
Зарегистрирован: 30.10.2018

inspiritus пишет:

Ой Вы знаете - у меня если тут нажать то там болит а если нажать там то чешется тут. Вот вам фотография мизинца правой ноги подскажите пожалуйста какую таблетку мне пить.

Вроде ясно изложил проблему, что непонятного? 

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

Nailoren пишет:

Вроде ясно изложил проблему, что непонятного? 

Много чего непонятного. Например, как и где описана smsContent? Да и много чего. Код нужен полностью. И про проверку памяти я Вам уже написал. Вставьте сразу, всё равно потом придётся вставлять.

Nailoren
Offline
Зарегистрирован: 30.10.2018
#include <DallasTemperature.h>            
#define DS18B20 4
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
#include "call.h"
SMSGSM sms;
CallGSM call;
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);
int Rel1 = 9;  // для реле 1
int Rel2 = 10; // для реле 2
int Rel3 = 11; // для реле 2
int Rel4 = 12; // для реле 2

int prev_State = 0;
int State;
int numdata;
boolean started=false;
char smsbuffer[160];
char n[20];
String input_string = "";
String smsContent = "";
char pos;


char n1[] = ""; // номер скрыл специально
char sendsms[160]; 



void setup() {
sensors.begin(); 
 
// gprsSerial.begin(4800);
pinMode(7, INPUT_PULLUP);
 pinMode(Rel1, OUTPUT);
 pinMode(Rel2, OUTPUT);
 pinMode(Rel3, OUTPUT);
 pinMode(Rel4, OUTPUT);
 digitalWrite(Rel1, 0);
 digitalWrite(Rel2, 0);
 digitalWrite(Rel3, 0);
 digitalWrite(Rel4, 0);
pinMode(13, OUTPUT);
Serial.begin(9600);

       if (gsm.begin(9600)) {
          Serial.println("\nstatus=READY");
          started=true;
     } else Serial.println("\nstatus=IDLE");
     for(pos=1;pos<=21;pos++) {
    sms.DeleteSMS(pos);
  }
input_string = "";
}
void loop() {
State = !digitalRead(7);
delay(2000);
sensors.requestTemperatures(); 
Serial.println(sensors.getTempCByIndex(0));
if(State == 1  && State != prev_State){ // проверка состояния геркона
  sms.SendSMS(n1, "dver zakryta");
  prev_State = !prev_State;
  digitalWrite(13, 1); 
} 
if(State == 0 && State != prev_State){
  sms.SendSMS(n1, "dver otkryta");
  prev_State = !prev_State;
  digitalWrite(13, 0); 
} 



pos = sms.IsSMSPresent(SMS_UNREAD);
      if (pos) {                   
        
getsms(); // получаем непрочитанную СМС                 
        
static String sostObogrev="Otkluchen";
static String sostOsv="Otkluchen";
static String sostNasos="Otkluchen";
static String sostRele="Otklucheno";
if (input_string=="Off1"){digitalWrite(Rel1, LOW);sms.SendSMS(n1, "Otkluchen svet");sostOsv="Otkluchen";}
if (input_string=="Off2"){digitalWrite(Rel2, LOW);sms.SendSMS(n1, "Otkluchen obogrev");sostObogrev="Otkluchen";}
if (input_string=="Off3"){digitalWrite(Rel3, LOW);sms.SendSMS(n1, "Otkluchen nasos");sostNasos="Otkluchen";}
if (input_string=="Off4"){digitalWrite(Rel4, LOW);sms.SendSMS(n1, "Otklucheno rele");sostRele="Otklucheno";}
if (input_string=="On1"){digitalWrite(Rel1, HIGH);sms.SendSMS(n1, "Vkluchen svet");sostOsv="Vkluchen";}
if (input_string=="On2"){digitalWrite(Rel2, HIGH);sms.SendSMS(n1, "Vkluchen obogrev");sostObogrev="Vkluchen";}
if (input_string=="On3"){digitalWrite(Rel3, HIGH);sms.SendSMS(n1, "Vkluchen nasos");sostNasos="Vkluchen";}
if (input_string=="On4"){digitalWrite(Rel4, HIGH);sms.SendSMS(n1, "Vklucheno rele");sostRele="Vklucheno";}
if (input_string=="sost")
{
    smsContent=(sostObogrev+" obogrev, "+sostOsv+" svet, "+sostNasos+" nasos, "+sostRele+" rele, T =  "+String(sensors.getTempCByIndex(0)));
    smsContent.toCharArray(sendsms,160);
    sms.SendSMS(n1, sendsms);  
}
  

sms.DeleteSMS(pos);
delay(1000);


}
}

void getsms()
{
          sms.GetSMS(pos,n,20,smsbuffer,160);
//          Serial.println(n);
//          Serial.println(smsbuffer);
          input_string = String(smsbuffer);
          Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:--------- " + input_string + "\n");
}    

 

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

А где проверка на то, память выделилась? Я Вам об этом два раза писал! Вот у меня ощущение, Что в строке №94 не хватает памяти. Поставьте наконец проверку, сколько просить-то можно.

И, да, с памятью Вы работаете варварски. Неудивительно, если Вам её впрямь не хватает. Чего только стоит совершенно ненужный глобальный массив sendsms. Он не нужен от слова "совсем", а жрет почти 8% всей имеющейся памяти! Переменная smsContent используется ровно в одном месте, но объявлена она зачем-то глобальной и даже не чистится, а постоянно держит в себе свой огромный контент! Ну и много такого.

В общем ставьте проверку хватило памяти в строке №94

Ох, кстати, а чё за ардуина-то? Сколько хоть у Вас памяти-то? "Понятно он всё написал" :-)

Nailoren
Offline
Зарегистрирован: 30.10.2018

ЕвгенийП, а как проверить, если не секрет, выделилась ли память под String?

Nailoren
Offline
Зарегистрирован: 30.10.2018

Arduino nano

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

Ах, да, сорри - Nano - это я пропустил

Nailoren
Offline
Зарегистрирован: 30.10.2018

Получается, smsContent и sendsms в нужных местах нужно делать static? 

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

Nailoren пишет:

ЕвгенийП, а как проверить, если не секрет, выделилась ли память под String?

if (smsContent) {
   // если истина, то Ок
} else {
   // если ложь, то не хватило
}

 

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

Nailoren пишет:

Получается, smsContent и sendsms в нужных местах нужно делать static? 

1. sendsms не нужен вовсе. Надо только не делать toCharArray, а брать готовый массив символов прямо из самой строки методом c_str

2. smsContent не нужно делать статик. Её нужно просто описать (не статик) в месте использования. Зачем ей сохранять своё значение, если Вы его всё равно каждый раз заново формируете?

Nailoren
Offline
Зарегистрирован: 30.10.2018

Принято, спасибо.