"пропадают" данные в диаграмме

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Здравствуйте

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

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

Если продолжать слать команды в хаотичной последовательности - в какой-то момент снова появляется полное смс в ответ на ту же команду, на которую отвечало с потерей данных.

В терминале это выглядит так:

ROP  (команда)
 
AT+CMGS="+380957314297"
 
> Yes, Capitan!!! Humi: 45.00  Temp:   22.00 Voltage: 0.00  Cool OFF  Vent OFF  Light OFF  (ответ полный, как надо)
 
COOL ON  (команда)
 
AT+CMGS="+380957314297"
 
> Yes, Capitan!  Humi: 45.00  Temp: 22.00 Voltage: 0.00  Cool ON  Vent OFF  Light OFF (ответ полный, как надо)
COOL OFF (команда)
 
AT+CMGS="+380957314297"
 
>  (ответ пустой, никаких данных)
 
COOL ON (команда)
 
 
AT+CMGS="+380957314297"
 
> Yes, Capitan!  Humi: 45.00  Temp: 22.00 Voltage: 0.00  Cool ON  Vent OFF  Light OFF (ответ полный, как надо)
 
ROP   (команда)
 
AT+CMGS="+380957314297"
 
> Vent OFF  Light OFF  (ответ неполный, потеряны данные о температуре, влажности, напряжению, статусе)
 
COOL OFF
 
AT+CMGS="+380957314297"
 
>    (пустой ответ вообще)
COOL ON
 
AT+CMGS="+380957314297"
 
> Yes, Capitan!  Humi: 46.00  Temp: 22.00 Voltage: 0.00  Cool ON  Vent OFF  Light OFF (снова все ок)
 
ROP
AT+CMGS="+380957314297"
 
> Vent OFF  Light OFF
VENT OFF
 
AT+CMGS="+380957314297"
 
> 45.00     Temp: 22.00
LIGHT OFF
 
AT+CMGS="+380957314297"
 
> Yes! Capitan!  voltage: 0.00  Cool ON  Vent OFF  Light OFF Humi: 45.00     Temp: 22.00
 
LIGHT ON
 
AT+CMGS="+380957314297"
 
>      Temp: 22.00
 
ROP
 
AT+CMGS="+380957314297"
 
> Vent OFF  Light ON
 
Ну и дальше в том же духе.
 
Это мои первые шаги в освоении, прошу отнестись с пониманием.
Буду очень благодарен за подсказки - что не так? Куда и почему пропадают данные?
Вот сам текст скетча:
 
void setup()
 
 { 
 
 analogReference(INTERNAL); // выбираем внутреннее опорное напряжение 1.1
 pinMode(6, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);
 pinMode(13, INPUT); // вход массы 
 pinMode(4, INPUT); // вход датчика движения
  statusCool = "Cool OFF";
  statusVent = "Vent OFF";
  statusLight = "Light OFF";
 
 
 Serial.begin(9600);
 Serial.println("ROP Progect");
 
  dht.begin();  // DHT11 
  mySerial.begin(9600);                //подключаем порт модема на скорости по умолчанию (можно менять AT-командой)
  mySerial.println("ATI");              //вывести в терминал иноформацию о модеме
  delay(100);
  mySerial.println("AT+CSQ");          //вывести в терминал уровень сигнала (если 99, то связи нет)
  delay(100);
  mySerial.println("AT+CLIP=1");        //включаем АОН
  delay(100);
  mySerial.println("AT+CMGF=1");        //режим кодировки СМС - обычный (для англ.)
  delay(100);
  mySerial.println("AT+CSCS=\"GSM\"");  //режим кодировки текста
  delay(100);
  mySerial.println("AT+CNMI=2,2");      //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память)
  delay (5000);
 }
 
 
 
void sms(String text, String phone){  //процедура отправки СМС
if (Smsoff==false)
{
  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);
}
}
 
 
 
 void loop() {
    float humi = dht.readHumidity();
    float temp = dht.readTemperature();
    int analogValue = analogRead(analogPin); // читаем значение на аналоговом входе 3         
    float volt  = (analogValue * 12.40) / 1023; // пересчет измерения в вольты
 
 if (mySerial.available()) {          //если есть данные от GSM модуля
 
    delay(400);                        //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
    while (mySerial.available()) {      //сохраняем входную строку в переменную val
    ch = mySerial.read();
    val += char(ch);
    delay(10);
    }
 
    Serial.println(val);                    // дублируем сообщение в терминал
 
     
      
      if (val.indexOf("SMS OFF") > -1) {      // если обнаружено кодовое слово SMS OFF  
          smsoffStr = "Yes, Capitan! SMS OFF";
          Serial.println("sms disabled");      // сообщаем об этом в терминал 
          sms(smsoffStr, MASTER);            // отвечаем смской смс отключены
          Smsoff = true;                    // отключаем смс
        }
//else
    
        if (val.indexOf("ROP") > -1) {      // если обнаружено кодовое слово ROP
        ropStr = "Yes, Capitan!!! Humi: "+ String (humi)+"  "  +  "Temp: "+"  " +String (temp)+ " "+ "Voltage: " +String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight); // ответ на запрос смс РОП
        Smsoff = false;
        Serial.println("ROP request");      // сообщаем об этом в терминал
        sms(ropStr, MASTER);            // отвечаем смской температура, влажность, напряжение, статусы
          }
//else
     if (val.indexOf("COOL ON") > -1) {      // если обнаружено кодовое слово Cool On
              statusCool = "Cool ON";  
              coolStr = "Yes, Capitan!  Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
              Serial.println("Cool ON");      // сообщаем об этом в терминал
              sms(coolStr, MASTER);            // отвечаем смской
              digitalWrite(LED12Pin, HIGH); //включаем 12 пин плюс
                                      }
 
 //else 
        if (val.indexOf("COOL OFF") > -1) {      // если обнаружено кодовое слово Cool off
               statusCool = "Cool OFF" ;
               cooloffStr = "Yes, Capitan!  Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
               Serial.println("COOL OFF");      // сообщаем об этом в терминал (если нужно)
               sms(cooloffStr, MASTER);            // отвечаем смской
               digitalWrite(LED12Pin, LOW);
                                          }
 
//else
     if (val.indexOf("VENT ON") > -1) {      // если обнаружено кодовое слово Vent On
              statusVent = "Vent ON" ;     
              ventStr = String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight)+"  " + "Humi: "+ String (humi)+"    "  +  "Temp: "+String (temp)+"  "+  "Voltage: " +String (volt);
              Serial.println("VENT ON");      // сообщаем об этом в терминал
              sms(ventStr, MASTER);            // отвечаем смской
              digitalWrite(LED11Pin, HIGH); //включаем 11 пин плюс
                                       }
 
// else 
        if (val.indexOf("VENT OFF") > -1) {      // если обнаружено кодовое слово vent off
               statusVent = "Vent OFF" ;  
               ventoffStr = "VENT OFF Voltage: " +String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight)+" Humi: "+ String (humi)+"     "  +  "Temp: "+String (temp);
               Serial.println("Vent OFF");      // сообщаем об этом в терминал
               sms(ventoffStr, MASTER);            // отвечаем смской
               digitalWrite(LED11Pin, LOW);
                                          }
    
//else
     if (val.indexOf("LIGHT ON") > -1) {      // если обнаружено кодовое слово Light On
              statusLight = "Light ON" ;
              lightStr = "Yes! Capitan!  voltage: " +String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight)+" " +"Humi: "+ String (humi)+"     "  +  "Temp: "+String (temp);
              Serial.println("Light ON");      // сообщаем об этом в терминал 
              sms(lightStr, MASTER);            // отвечаем смской
              digitalWrite(LED10Pin, HIGH);
                                       }
   
 //else 
        if (val.indexOf("LIGHT OFF") > -1) {      // если обнаружено кодовое слово light off
               statusLight = "Light OFF";
               lightoffStr = "Yes! Capitan!  voltage: " +String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight)+" " +"Humi: "+ String (humi)+"     "  +  "Temp: "+String (temp);
               Serial.println("Light OFF");      // сообщаем об этом в терминал 
               sms(lightoffStr, MASTER);            // отвечаем смской
               digitalWrite(LED10Pin, LOW);
                                           }
 
      
       val = "";
     
 }
 
 
               
 
 }
 
 
Всем спасибо!!!
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Прочитайте вот эту тему, а потом попробуйте зайти на второй заход.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019
Спасибо. Разбираюсь потихоньку. Код вставил. 
Уровень знаний - начинающий в программировании. С паяльником дружу.
Если вас не затруднит - подкажите еще где "косяки" при оформлении вопроса. 
В коде много лишнего, изначально скетч больше, чем приведенный кусок. Но проблема моя пока на этом участке. 
Закоментированные //else на ситуацию не влияют.
Устройство - ардуино нано с атмегой 328. Модем Neoway 900. 
 
Я был бы рад хотя-бы теоретическому ответу - что и как может "удалить" из моих строк, формирующих содержимое ответных смс, определенные компоненты. Причем "выпадают" как текст в кавычках, так и значения переменных. А потом снова могут появиться. 
             
 
 

 


#include <DHT.h>
#include <SoftwareSerial.h>
#define MASTER "+380957314297"          //укажите  телефон хозяина
SoftwareSerial mySerial(2, 3);          // номера дискретных входов-выходов контроллера в качестве RX, TX

int ch = 0;
long previousMillis = 0;//счетчики времени, прошлое время
long interval = 1000;//интервал 
long previousMillis2 = 0;//счетчики времени, прошлое время
long interval2 = 8000;//интервал 

int buttonPushCounter;   // счётчик нажатия кнопки
int groundcount=0;
int groundcount_old=1;
int movebuttonPushCounter;   // счётчик нажатия кнопки
int movecount=0;
int movecount_old=1;
boolean LowVolt /* = true*/;
boolean SmsVolt /* = true*/;
boolean Smsoff;
boolean groundsms;
boolean movesms;
String val = "";
String tempStr;
String ropStr;
String humiStr;
String moveStr;
String voltStr;
String coolStr;
String ventStr;
String lightStr;   
String cooloffStr;
String ventoffStr;
String lightoffStr;  
String smsoffStr;
String groundStr;
String ground_Str;
String statusCool;
String statusVent;
String statusLight;
String Str;


int groundPin = 13; // вход 13
int LED6Pin = 6; // диод 6 
int LED8Pin = 8; // диод 8 
int LED9Pin = 9; // диод 9
int LED10Pin = 10; // диод 10 light
int LED11Pin = 11; // диод 11 vent
int LED12Pin = 12; // диод 12 cooler
int Move = 6; // датчик движения
int pin=5;
DHT dht(5, DHT11);
int analogPin = 3; // входной аналоговый пин
int analogValue=0; // значение аналогового сигнала

void setup()

 { 

 analogReference(INTERNAL); // выбираем внутреннее опорное напряжение 1.1
 pinMode(6, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);
 pinMode(13, INPUT); // вход массы 
 pinMode(4, INPUT); // вход датчика движения
  statusCool = "Cool OFF";
  statusVent = "Vent OFF";
  statusLight = "Light OFF";

 
 Serial.begin(9600);
 Serial.println("ROP Progect");
 
  dht.begin();  // DHT11 
  mySerial.begin(9600);                //подключаем порт модема на скорости по умолчанию (можно менять AT-командой)
  mySerial.println("ATI");              //вывести в терминал иноформацию о модеме
  delay(100);
  mySerial.println("AT+CSQ");          //вывести в терминал уровень сигнала (если 99, то связи нет)
  delay(100);
  mySerial.println("AT+CLIP=1");        //включаем АОН
  delay(100);
  mySerial.println("AT+CMGF=1");        //режим кодировки СМС - обычный (для англ.)
  delay(100);
  mySerial.println("AT+CSCS=\"GSM\"");  //режим кодировки текста
  delay(100);
  mySerial.println("AT+CNMI=2,2");      //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память)
  delay (5000);
 }
 


void sms(String text, String phone){  //процедура отправки СМС
if (Smsoff==false) // разрешение на отправку смс
{
  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);
}
}



 void loop() {
    float humi = dht.readHumidity(); // влажность с датчика
    float temp = dht.readTemperature(); // температура с датчика
    int analogValue = analogRead(analogPin); // читаем значение на аналоговом входе 3         
    float volt  = (analogValue * 12.40) / 1023; // пересчет измерения в вольты
    unsigned long currentMillis = millis();

      




 if (mySerial.available()) {          //если есть данные от GSM модуля
    delay(400);                        //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
    while (mySerial.available()) {      //сохраняем входную строку в переменную val
    ch = mySerial.read();
    val += char(ch);
    delay(10);
    }

    Serial.println(val);                    // дублируем сообщение в терминал
   
      
      if (val.indexOf("SMS OFF") > -1) {      // если обнаружено кодовое слово SMS OFF  
          smsoffStr = "Yes, Capitan! SMS OFF";
          Serial.println("sms disabled");      // сообщаем об этом в терминал 
          sms(smsoffStr, MASTER);            // отвечаем смской смс отключены
          Smsoff = true;                    // отключаем смс
        }
else
    
        if (val.indexOf("ROP") > -1) {      // если обнаружено кодовое слово ROP
        ropStr = "Yes, Capitan!!! Humi: "+ String (humi)+"  "  +  "Temp: "+"  " +String (temp)+ " "+ "Voltage: " +String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight); // ответ на запрос смс РОП
        Smsoff = false; // включаем разрешение на передачу смс
        Serial.println("ROP request");      // сообщаем об этом в терминал
        sms(ropStr, MASTER);            // отвечаем смской температура, влажность, напряжение, статусы реле
          }
else
     if (val.indexOf("COOL ON") > -1) {      // если обнаружено кодовое слово Cool On
              statusCool = "Cool ON";  
              coolStr = "Yes, Capitan! coolonsms Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
              Serial.println("Cool ON");      // сообщаем об этом в терминал
              sms(coolStr, MASTER);            // отвечаем смской
              digitalWrite(LED12Pin, HIGH); //включаем 12 пин плюс
                                      }

 else 
        if (val.indexOf("COOL OFF") > -1) {      // если обнаружено кодовое слово Cool off
               statusCool = "Cool OFF" ;
               cooloffStr = "Yes, Capitan! cooloffsms  Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
               Serial.println("COOL OFF");    
               sms(cooloffStr, MASTER);            // отвечаем смской
               digitalWrite(LED12Pin, LOW);
                                          }

else
     if (val.indexOf("VENT ON") > -1) {      // если обнаружено кодовое слово Vent On
              statusVent = "Vent ON" ;     
              ventStr = "Yes, Capitan! ventonsms Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
              Serial.println("VENT ON");      
              sms(ventStr, MASTER);            // отвечаем смской
              digitalWrite(LED11Pin, HIGH); //включаем 11 пин плюс
                                       }
 
 else 
        if (val.indexOf("VENT OFF") > -1) {      // если обнаружено кодовое слово vent off
               statusVent = "Vent OFF" ;  
               ventoffStr = "Yes, Capitan! ventoffsms  Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
               Serial.println("Vent OFF");      
               sms(ventoffStr, MASTER);            // отвечаем смской
               digitalWrite(LED11Pin, LOW);
                                          }
    
else
     if (val.indexOf("LIGHT ON") > -1) {      // если обнаружено кодовое слово Light On
              statusLight = "Light ON" ;
              lightStr = "Yes, Capitan! lightonsms Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
              Serial.println("Light ON");      
              sms(lightStr, MASTER);            // отвечаем смской
              digitalWrite(LED10Pin, HIGH);
                                       }
   
 else 
        if (val.indexOf("LIGHT OFF") > -1) {      // если обнаружено кодовое слово light off
               statusLight = "Light OFF";
               lightoffStr = "Yes, Capitan! lightoffsms Humi: "+ String (humi)+"  "  +  "Temp: "+String (temp)+" "+  "Voltage: "+ String (volt)+"  "+String (statusCool)+"  "+String (statusVent)+"  " +String (statusLight);
               Serial.println("Light OFF");     
               sms(lightoffStr, MASTER);            // отвечаем смской
               digitalWrite(LED10Pin, LOW);
                                           }

      
       val = "";
            
 }


 }
 
Из терминала это выглядит так:

ROP (команда)

AT+CMGS="+380957314297"

> Yes, Capitan!!! Humi: 32.00  Temp:   22.00 Voltage: 0.00  Cool OFF  Vent OFF  Light OFF  (ответ правильный)
 
LIGHT ON (команда)
 
AT+CMGS="+380957314297"
 
> Yes, Capitan! lightonsms Humi: 31.00  Temp: 22.00 Voltage: 0.00  Cool OFF  Vent OFF  Light ON (ответ правильный)
 
LIGHT OFF (команда)
 
AT+CMGS="+380957314297"
 
> Yes, Capitan! lightoffsms Humi: 31.00  Temp: 22.00 Voltage: 0.00  Cool OFF  Vent OFF  Light OFF(ответ правильный)
 
VENT ON (команда)
 
AT+CMGS="+380957314297"
 
> Yes, Capitan! ventonsms Humi: 31.00  Temp: 22.00 Voltage: 0.00  Cool OFF  Vent ON  Light OFF (ответ правильный)
VENT OFF(команда)
 
AT+CMGS="+380957314297"
 
>   (ответ неправильный, пустая смс)
 
VENT ON(команда)
 
AT+CMGS="+380957314297"
 
> Vent ON  Light OFF  (ответ неправильный, смс не полная. потеря данных)
 
VENT OFF(команда)
 
AT+CMGS="+380957314297"
 
> Cool OFF  Vent OFF  Light OFF (ответ неправильный, смс не полная. потеря данных)
 
VENT ON(команда)
 
AT+CMGS="+380957314297"
 
>   Light OFF   (ответ неправильный, смс не полная. потеря данных)
 
ROP(команда)
 
АT+CMGS="+380957314297"
 
> Vent ON  Light OFF (ответ неправильный, смс не полная. потеря данных) 
 
COOL ON(команда)
 
AT+CMGS="+380957314297"
 
>   Light OFF  (ответ неправильный, смс не полная. потеря данных)
 
COOL OFF (команда) 
 
AT+CMGS="+380957314297"
 
>   (ответ неправильный, пустая смс)
 
LIGHT ON(команда) 
 
AT+CMGS="+380957314297"
 
> Yes, Capitan! lightonsms Humi: 33.00  Temp: 22.00 Voltage: 0.00  Cool OFF  Vent ON  Light ON (правильный ответ, все данные и статусы снова есть)
 

Благодарю за участие.

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

думаю, что проблема с памятью, но это надо проверить.

Попробуйте сделать такую вещь:

1. откройте файл <место, ге установлено IDE>\hardware\arduino\avr\cores\arduino\WString.cpp
2. В этом файле найдите строку содержащую слово realloc. Выглядит она примерно вот так

	char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
	if (newbuffer) {
		buffer = newbuffer;
		capacity = maxStrLen;
		return 1;
	}

3. В строке 6 после } добавьте elsle Serial.println("BEDA!!!");

Попробуйте скомпилировать. Если будет ругаться нв Serial, то добавьте в начале файла #include <arduino.h>

В общем, скомпилируйте.

Запустите и смотрите. Если сообщение о "беде" будет вылетать перед проблемами, то виноваты проблемы с памятью.

Если нет, будем дальше думать.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019
Благодарю вас.
Файл нашел, пробую добавить такой кусочек в свой код:
unsigned char String::changeBuffer(unsigned int maxStrLen) 
{
  char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
  if (newbuffer) {
    buffer = newbuffer;
    capacity = maxStrLen;
    return 1;
  }
  else    
  Serial.println (BEDA!!!);
  //return 0;
}

Компиляция не проходит. Ругаться начинает так:

 
Arduino: 1.8.9 (Windows XP), Плата:"Arduino Nano, ATmega328P (Old Bootloader)"
 
C:\Documents and Settings\Администратор\Рабочий стол\sms0705_sms_good__status\sms0705_sms_good__status.ino: In function 'void loop()':
 
sms0705_sms_good__status:122:38: error: qualified-id in declaration before '(' token
 
sms0705_sms_good__status:357:2: error: expected '}' at end of input
 
Несколько библиотек найдено для "DHT.h"
 Используется: C:\Program Files\Arduino\libraries\DHT
Не используется: C:\Documents and Settings\Администратор\Мои документы\Arduino\libraries\DHT_sensor_library-1.3.4
Не используется: C:\Documents and Settings\Администратор\Мои документы\Arduino\libraries\DHT_sensor_library
Не используется: C:\Program Files\Arduino\libraries\DHT_sensor_library-1.3.4
Не используется: C:\Program Files\Arduino\libraries\DHT_sensor_library
exit status 1
qualified-id in declaration before '(' token
 
Без этого кусочка - все ок. Что-то не так сделал? Скопировал один в один из файла.
Спасибо за участие
Feofan
Offline
Зарегистрирован: 28.05.2017

Сообщение #3 читайте внимательнее.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Если я правильно понял намек - речь идет о подключении arduino.h библиотеки?

#include <Arduino.h>
#include <DHT.h>
#include <SoftwareSerial.h>
#include <arduino.h>

Просто дописать строку не дало результата. Символы слова "arduino" не выделяются цветом, это значит, что библиотека не найдена?

В списке библиотек такой нет. Гуглом тоже не нашел, чтобы скачать. 

Поиском нашел файл arduino.h но нет нигде arduino.cpp.  Если я верно понял инструкции из сети по библиотекам - эти файлы должны быть в паре. Просто подложив в список библиотек один файл arduino.h в папке - тоже результата не добился.

Мне продолжать решать вопрос с библиотекой или я опять не туда ?

Благодарю за подсказки

sadman41
Offline
Зарегистрирован: 19.10.2016

Не туда. Сообщение #3, п.3.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Туплю :(

unsigned char String :: changeBuffer(unsigned int maxStrLen) 
{
  char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
  if (newbuffer) {
    buffer = newbuffer;
    capacity = maxStrLen;
    return 1;
  }

  else    
  Serial.println ("BEDA!!!");
  //return 0;

}

Ругается почему-то на первую строчку (124:37)unsigned char String :: changeBuffer(unsigned int maxStrLen)

C:\Documents and Settings\Администратор\Рабочий стол\sms0705_sms_good__status\sms0705_sms_good__status.ino: In function 'void loop()':
 
sms0705_sms_good__status:124:37: error: qualified-id in declaration before '(' token
 
sms0705_sms_good__status:360:2: error: expected '}' at end of input
 
Надо что-то дообъявить из этой строки в самом начале? 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SHA_MAN пишет:

Туплю :(

Тупите.

НИЧЕГО не добавляёте в свой файл. Просто поменяйте ОДНУ строку в системном файле (потом вернёте как было).

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Все получилось. Благодарю вас.

"беда" в мониторе появляется регулярно, иногда по паре сообщений подряд :(

Мой скетч слишком кривой? Или "нано" надо заменить на что-то мощнее? 

При этом всем команда по активизации реле выполняется четко и всегда. Вопрос пока только с содержимым ответных смс. 

Спасибо.

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

SHA_MAN пишет:

"беда" в мониторе появляется регулярно, иногда по паре сообщений подряд :(

Каждое появление этого сообщения означает, что система попыталась запросить память, а ей не дали - кончилась. Вот Вам и пустые или полупустые сообщения.

Т.е. причина установлена.

теперь про то как быть. Взять что-то помощнее нано, конечно, можно, но это порочный путь. У Вас ужасно написана программа ( с точки зрения работы с памятью). Не плохо, а именно ужасно. Если её переписать по-человечески, то и наны хватит за глаза. А если оставить как есть и не научиться нормально работать с памятью, то завтра Вы ещё пару сообщений добавите и может случиться, что Вам и Меги не хватит.

В разделе "программирование" вверху есть три мои статьи о работе с памятью Прочитайте все три (они там пронумерованы, соблюдайте порядок) и после этого попробуйте переписать то, что у Вас написано. Например, сделайте свои многочисленные String локальными.

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

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Спасибо большое за объяснение.

Я новичок в этих вопросах, поэтому был рад что вообще хоть как-то заработало. Буду изучать, причесывать.

Еще раз спасибо

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

Ну, просто перенесите описания своих переменных в те блоки, где они нужны и заработает.

stepan_sotnikov
Offline
Зарегистрирован: 06.04.2019

Вопрос к Гуру. Часто вижу обявление пинов и др. через переменные:
 

int groundPin = 13; // вход 13
int LED6Pin = 6; // диод 6
int LED8Pin = 8; // диод 8
int LED9Pin = 9; // диод 9
int LED10Pin = 10; // диод 10 light
int LED11Pin = 11; // диод 11 vent
int LED12Pin = 12; // диод 12 cooler
int Move = 6; // датчик движения
int pin=5;
DHT dht(5, DHT11);
int analogPin = 3; // входной аналоговый пин
int analogValue=0; // значение аналогового сигнала

 

Ведь это все можно сделать препроцессором

 

# define groundPin  13 // вход 13
# define LED6Pin  6 // диод 6
# define LED8Pin  8 // диод 8
# defineLED9Pin  9 // диод 9
# define LED10Pin 10 // диод 10 light
# define LED11Pin 11 // диод 11 vent
# define LED12Pin 12 // диод 12 cooler
# defineMove  6 // датчик движения
# define pin 5
# define analogPin 3 // входной аналоговый пин
# defineanalogValue 0 // значение аналогового сигнала

И данное действо так же осовободит память? И не будет держать эти переменные у себя в памяти НАВЕКА?

sadman41
Offline
Зарегистрирован: 19.10.2016

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

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Еще один вопрос возник.

Как-то можно создать индикатор "загруженности" памяти? Какую-то величину контролировать через терминал, чтобы понимать насколько легче (тяжелее) становится после моих поправок кода? 

Спасибо

sadman41
Offline
Зарегистрирован: 19.10.2016

Теоретически, через это: http://robocraft.ru/blog/arduino/531.html

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

sadman41 пишет:

переменные типа const 

Они ещё константами называются :)

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

SHA_MAN пишет:

Как-то можно создать индикатор "загруженности" памяти? Какую-то величину контролировать через терминал, чтобы понимать насколько легче (тяжелее) становится после моих поправок кода? 

Здесь, на этом форуме, лежит библиотека MemoryExplorer с кучей примеров использования!! И чего вас всех в поиске-то забанили? Небось много видео со срамными девками искали? :)

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Благодарю. Ушел в чтение. Как говорится - чем дальше в лес....  

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

Так я ж вроде сегодня же Вам давал эти ссылки (ну, их описание) и Вы тогда ещё почитать собирались :)

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Бытовая рутина выходного дня отняла время. "Между строк" читать - себе во вред, а вдумчиво получится уже только с понедельника. 

Зато уже точно знаю где проблема и в какую сторону копать. А благодаря вашим ссылкам - где копать тоже знаю.

Спасибо за участие

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

sadman41 пишет:

переменные типа const 

Они ещё константами называются :)

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

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Признаюсь честно - собрался с духом, читать начал (и статьи и обсуждения ниже). Сказать, что понял хотя бы 10% написанного - нагло соврать :(

Тем не менее, какие-то горизонты обозначились. 

Спасибо за подсказки.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Снова здравствуйте. Благодаря вашим подсказкам, предыдущая задумка воплотилась таки в рабочую версию. Спасибо еще раз.

Эксперементы продолжаются, снова вопрос связанный с ресурсами ардуино и использованием памяти.

Задача банальная - с помощью GPS модуля NEO6 получить и передать в смс координаты и время.

Нашел в сети массу примеров, запустил скетч - работает. Но, судя по сообщению при компиляции

(Скетч использует 11398 байт (37%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 805 байт (39%) динамической памяти, оставляя 1243 байт для локальных переменных. Максимум: 2048 байт.)

- скетч слишком "тяжелый" для моей нано 328. Если я пробую добавить его к части скетча с смс и остальным - получаю предупреждение о нехватке памяти и возможной нестабильности работы программы.

//https://eax.me/arduino-gps/
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

SoftwareSerial gps_serial(8, 9);
TinyGPSPlus gps_parser;

void setup()
{
    Serial.begin(9600);
    gps_serial.begin(9600);
    
}

String twoDigits(int x) {
  if(x < 10) return "0" + String(x);
  else return String(x);
}



void loop() {
    while(gps_serial.available() > 0) {
        char temp = gps_serial.read();
        Serial.write(temp);
        gps_parser.encode(temp);
        }

    String lat  = "Unknown         ";
    String lng  = "location        ";
    if(gps_parser.location.isValid()) {
        lat = "Lat: " + String(gps_parser.location.lat(), 6);
        lng = "Lng: " + String(gps_parser.location.lng(), 6);
    }

    String date = "Unknown date    ";
    if(gps_parser.date.isValid()) {
        date = twoDigits(gps_parser.date.day()) + "/" +
               twoDigits(gps_parser.date.month()) + "/" +
               String(gps_parser.date.year()) + "      ";
    }

    String time = "Unknown time    ";
    if(gps_parser.time.isValid()) {
        time = twoDigits(gps_parser.time.hour()+3) + ":" +
               twoDigits(gps_parser.time.minute()) + ":" +
               twoDigits(gps_parser.time.second()) + " UTC    ";
    }

  }

 

Все, что мне надо - lat, lng, date, time. На это "уходит" почти половина всей мощности контроллера. 

Как можно, если можно в принципе, оптимизировать это? 

Я почитал (и перепроверил) что подключении соотв. библиотек сразу занимает место в памяти. #include <TinyGPS++.h> - может быть как-то "урезана" (находил такой текст в сети, но по неопытности не могу судить о достоверности), чтобы она "обслуживала" только мои четыре переменные и не занимала столько ресурсов?

Или выход только в поиске более производетельного контроллера? Если да - посоветуйте какого. 

Я уже даже начал рассматривать вторую нано+neo, которая будет на первую нано+GSM слать данные. Но даже на этапе шальных мыслей это очень тупо выглядит...

Спасибо всем. 

 
sadman41
Offline
Зарегистрирован: 19.10.2016

"В принципе" оптимизировать можно, но если Вы сами понимаете, что неопытны, то проще поменять МК. Следующий по "моще" и популярности из линейки Ардуино - Mega2560.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Благодарю вас.

Я могу как-то предварительно оценить хватит ли мне 2560? Сейчас мой "полный" скетч до 80% нано328 "кушает". Если я возьму мегу2560 - то сколько от ее ресурса это будет в процентах?

Что следующее после 2560 по производительности? Задумок масса, пока буду "шифовать" навычки создания скетчей, хотелось бы под рукой иметь аппаратную возможность запустить хоть в каком-то виде.

Спасибо!

 

sadman41
Offline
Зарегистрирован: 19.10.2016

 Mega 2560 PRO MINI

Флеш память 256Кб
Тип ОЗУ/ Размер 8Кб
Тип ПЗУ/ Размер 4Кб

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Благодарю, джентельмены.

Пока попробую во время ожидания 2560 "попричесывать" скетч.

Имеет ли право на жизнь такой путь - открыть файл библиотеки, пробовать удалять оттуда "ненужные" мне строки, и проверять работает ли еще мой скетч после этого? 

Спасибо

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

канпилятор сам выкинет "ненужные тебе строчки"

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Благодарю. Походу я неверно представил себе это. 

Стало быть надо искать готовую библиотеку с похожим функционалом но с меньшим "аппетитом"  или увеличивать аппаратные ресурсы.

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

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

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

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Вы абсолютно правы. Скетч достаточно кривой, его даже не сразу удалось заставить работать. Но пока я не пробую туда добавить ЖПС - он свое выполняет.

#include <DHT.h>
#include <SoftwareSerial.h>
#define MASTER "+380957314297" //укажите  телефон хозяина
SoftwareSerial mySerial(2, 3); // номера дискретных входов-выходов контроллера в качестве RX, TX
DHT dht(5, DHT11);
int ch = 0;

long previousMillis = 0;	//счетчики времени, прошлое время
long interval = 1000;			//интервал

int buttonPushCounter; // счётчик нажатия кнопки
int groundcount = 0;
int groundcount_old = 1;
int movebuttonPushCounter; // счётчик нажатия кнопки
int movecount = 0;
int movecount_old = 1;
boolean LowVolt /* = true*/;
boolean SmsVolt /* = true*/;
boolean groundSms;
boolean moveSms;
boolean smsOn;
boolean lightOn;
boolean ventOn;
boolean coolOn;
boolean balsmsOn;

String val = "";

int groundPin = 13; // вход 13
//int LED6Pin = 6;		// диод 6
//int LED8Pin = 8;		// диод 8
//int LED9Pin = 9;		// диод 9
int LED10Pin = 10;	// диод 10 light
int LED11Pin = 11;	// диод 11 vent
int LED12Pin = 12;	// диод 12 cooler
int Move = 6;				// датчик движения
int pin = 5;
int analogPin = 3;	 // входной аналоговый пин
int analogValue = 0; // значение аналогового сигнала

boolean statusChanged;
String statusText;

void setup()
{
	analogReference(INTERNAL); // выбираем внутреннее опорное напряжение 1.1
	pinMode(6, OUTPUT);
	pinMode(8, OUTPUT);
	pinMode(10, OUTPUT);
	pinMode(11, OUTPUT);
	pinMode(12, OUTPUT);
	pinMode(13, INPUT); // вход массы
	pinMode(4, INPUT);	// вход датчика движения

	// Ititialize default state
	ventOn = false;
	lightOn = false;
	coolOn = false;
  balsmsOn =false;
	Serial.begin(9600);
  gps_serial.begin(9600);
	Serial.println("ROP Progect");

	dht.begin();						 // DHT11
	mySerial.begin(9600);		 //подключаем порт модема на скорости по умолчанию (можно менять AT-командой)
	mySerial.println("ATI"); //вывести в терминал иноформацию о модеме
	delay(100);
	mySerial.println("AT+CSQ"); //вывести в терминал уровень сигнала (если 99, то связи нет)
	delay(100);
	mySerial.println("AT+CLIP=1"); //включаем АОН
	delay(100);
	mySerial.println("AT+CMGF=1"); //режим кодировки СМС - обычный (для англ.)
	delay(100);
	mySerial.println("AT+CSCS=\"GSM\""); //режим кодировки текста
	delay(100);
	mySerial.println("AT+CNMI=2,2"); //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память)
	delay(5000);
}

void sms(String text, String phone)//процедура отправки СМС
{ 
	if (!smsOn)
	{
		return;
	}

	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);
}


void loop(){ // LOOP

   

	statusChanged = true;
  float humi = dht.readHumidity();
	float temp = dht.readTemperature();
	int analogValue = analogRead(analogPin);	 // читаем значение на аналоговом входе 3
	float volt = (analogValue * 12.40) / 1023; // пересчет измерения в вольты
	unsigned long currentMillis = millis();

	if (mySerial.available())
	{							                         //если есть данные от GSM модуля
		delay(100);                         //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
		while (mySerial.available())        //сохраняем входную строку в переменную val
		{ 
			ch = mySerial.read();
			val += char(ch);
			}

		Serial.println(val); // дублируем сообщение в терминал
	}
	if (val.indexOf("SMS OFF") > -1)
	{ // если обнаружено кодовое слово SMS OFF
		Serial.println("sms disabled"); // сообщаем об этом в терминал
    statusText = "Yes, Capitan! SMS OFF";
    sms(statusText, MASTER);
		smsOn = false;									// отключаем смс
	}


   if (val.indexOf("+CUSD:") > -1)// блок ответ баланса 
                    {        
                         
                   Serial.println ("full bal Sms  " + String(val));  
                   val = val.substring(val.indexOf("Na Vashomu"), val.indexOf("Taryf"));
                   Serial.println ("substring bal Sms     " + String(val)); 
                   smsOn =true;
                   statusText = "Yes, Capitan!    " +String (val);
                   sms(statusText, MASTER);
                   delay (1000);
                   Serial.println ("sms balanse sended     " + String(val)); 
                   statusChanged = false;
                  }  
  
   else  if (val.indexOf("BAL") > -1)// блок запрос баланса  
                     {
                     smsOn =false;
                     mySerial.println ("ATD*101#");
                     delay(500);
                     Serial.println("zapros balansa"); 
                     Serial.println ("val     " + String (val));
                     statusChanged = false; 
                     }        

else  if (val.indexOf("GDE") > -1){// блок запрос GPS 
  
                     Serial.println("GPS request"); 
                     Serial.println ("I am here     ");// + String (date)+ String (time) +String (lat)+String (lng));
                     statusText = ("I am here     ");// + String (date)+ String (time) +String (lat)+String (lng));
                     sms (statusText, MASTER);
                     statusChanged = false; 
                     }        
   
                     
	else if (val.indexOf("ROP") > -1)
	{																																																																																																										// если обнаружено кодовое слово ROP
		smsOn = true;
		Serial.println("ROP request"); // сообщаем об этом в терминал
	}
	else if (val.indexOf("COOL ON") > -1)
	{ // если обнаружено кодовое слово Cool On
		coolOn = true;
		Serial.println("Cool ON"); // сообщаем об этом в терминал
		digitalWrite(LED12Pin, HIGH); //включаем 12 пин плюс
	}
	else if (val.indexOf("COOL OFF") > -1)
	{ // если обнаружено кодовое слово Cool off
		coolOn = false;
		Serial.println("COOL OFF");
		digitalWrite(LED12Pin, LOW);
	}
	else if (val.indexOf("VENT ON") > -1)
	{ // если обнаружено кодовое слово Vent On
		ventOn = true;
		Serial.println("VENT ON");
		digitalWrite(LED11Pin, HIGH); //включаем 11 пин плюс
	}
	else if (val.indexOf("VENT OFF") > -1)
	{ // если обнаружено кодовое слово vent off
		ventOn = false;
		Serial.println("Vent OFF");
		digitalWrite(LED11Pin, LOW);
	}
	else if (val.indexOf("LIGHT ON") > -1)
	{ // если обнаружено кодовое слово Light On
		lightOn = true;
		Serial.println("Light ON");
		digitalWrite(LED10Pin, HIGH);
	}
	else if (val.indexOf("LIGHT OFF") > -1)
	{ // если обнаружено кодовое слово light off
		lightOn = false;
		Serial.println("Light OFF");
		digitalWrite(LED10Pin, LOW);
	}

	else
	{
		statusChanged = false;
	}
	

	if (statusChanged)
	{
		if (smsOn)
		{
			statusText = "Yes, Capitan!!! Humi: " + String(humi) + "  " + "Temp: " + "  " + String(temp) + " " + "Voltage: " + String(volt);
		
			if (coolOn)
			{
				statusText += " COOL ON";
			}
			else
			{
				statusText += " COOL OFF";
			}
			
			if (ventOn)
			{
				statusText += " VENT ON";
			}
			else
			{
				statusText += " VENT OFF";
			}
			
			if (lightOn)
			{
				statusText += " LIGHT ON";
			}
			else
			{
				statusText += " LIGHT OFF";
			}
     
		}
	
		
		sms(statusText, MASTER);
		Serial.println(statusText); // Dublicate to serial for debug purpose
	}


	val = "";

 
if(currentMillis - previousMillis > interval){

 previousMillis = currentMillis;  
                   
        
          
      Serial.print("voltage  ");
      Serial.print(volt); // выводим его в последовательный порт
      Serial.println(" V");
              Serial.print("temperature  ");
              Serial.println(temp);
              Serial.print("Humi   ");
              Serial.println(humi);

      
               groundcount = digitalRead(13);                           // считываем показания с вывода кнопки 13
               Serial.print("ground   ");
               Serial.println(groundcount);
               
    if (groundcount != groundcount_old){ // сравниваем состояние с предыдущим состоянием
       
    if (groundcount == LOW)             // если текущее состояние LOW, значит кнопка включена
      delay (1000);
      buttonPushCounter++;             // если состояние изменилось, увеличиваем счётчик
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
   if (groundcount == LOW && groundSms == false)
       {
      String groundStr = "Alarm! The door opens!";
      sms(groundStr, MASTER); 
      Serial.println(" Ground detected. Sms sended");
      groundSms=true;
         }  
      if (groundcount == HIGH) {      
      Serial.println("OFF");}
        }  
  groundcount_old = groundcount;  // сохраняем текущее состояние как последнее состояние для следующего раза
 
     if (buttonPushCounter % 7 == 0){         //при каждом седьмом нажатии
     groundSms = false;                       //включаем разрешение на отправку смс по событию массы
     buttonPushCounter = 0;                   // обнуляем счетчик срабатываний
                                       }    


                                         
              
              movecount = digitalRead(4);                           // считываем показания с вывода кнопки 4
              Serial.print("move   ");
              Serial.println(movecount);


                   if (movecount != movecount_old){ // сравниваем состояние с предыдущим состоянием
       
    if (movecount == HIGH)             // если текущее состояние HIGH, значит кнопка включена
      delay (1000);
      Serial.println("ON");
      movebuttonPushCounter++;             // если состояние изменилось, увеличиваем счётчик
      Serial.print("number of moving: ");
      Serial.println(movebuttonPushCounter);
   if (movecount == HIGH && moveSms == false)
       {
        String moveStr = "Capitan! Moving detected!!!";
        sms(moveStr, MASTER); 
        Serial.print(" Moving detected. Sms sended");
        moveSms=true;
         }
     
    if (movecount == LOW) {      
      Serial.println("OFF");
        }
     delay(1000);                 // небольшая задержка для устранения эффекта дребезга
     movecount_old = movecount;  // сохраняем текущее состояние как последнее состояние для следующего раза
                           
    //          }           
 
 if (movebuttonPushCounter % 7 == 0){       //при каждом седьмом нажатии
     moveSms = false;                        //включаем разрешение на отправку смс по событию движения
     movebuttonPushCounter = 0;              // обнуляем счетчик срабатываний
                                     }
         }
//if (volt <= 11.8)// граница разряда акб
//     {
 //      String   voltStr = "voltage LOW  V: "+String (volt);
 //         LowVolt = true; 
 //         Serial.println(" Low V: " +String (volt));
 //         delay (1000);
 //                         if (LowVolt == true && SmsVolt == true)
 //                              {
 //                              voltStr = "Voltage low!" + String (volt); 
  //                             sms(voltStr, MASTER); 
 //                              Serial.println(" Low V sms sended V:" +String (volt));
  //                             SmsVolt = false;
 //                              }


 //              }

}

}
 

 

Вот первая, отдельно работающая часть. 

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

ну я так и думал. Почитайте про оператор F() для константных строк - одно это, думаю, даст вам экономию оперативной памяти раза в три, не меньше

ссылка - https://www.arduino.cc/reference/en/language/variables/utilities/progmem/ - то, о чем я говорю - это самый последний абзац "The F() macro". Но вообще полезно прочитать все.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Спасибо. Прочитал.

Вот из этого:

The F() macroWhen an instruction like :

Serial.print("Write something on  the Serial Monitor");

is used, the string to be printed is normally saved in RAM. If your sketch prints a lot of stuff on the Serial Monitor, you can easily fill the RAM. If you have free FLASH memory space, you can easily indicate that the string must be saved in FLASH using the syntax:

Serial.print(F("Write something on the Serial Monitor that is stored in FLASH"));

 

Я понял, что:

1. Я могу из скетча удалить все ненужные мне (кроме как на этапе отладки) выводы в порт сообщений строками Serial.print. Во время работы устройства, они реально не нужны больше.

2. Дополнительно воспользовавшись Serial.print (F (...) ); и "запихнув" туда свои string с переменными - я еще более "разгружу" скетч.

Поправьте, плиз, если ошибся.

Спасибо!

 

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

по п 1 только вам решать. какие строки нужны. какие нет

по п 2 - похоже, вы поняли неправильно. Макрос F() работает с константами. поэтому "строки с переменными" в него запихнуть не выйдет

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

По пункту 1 - Serial.print  и mySerial.print - это разные функции. Первая выводит данные в монитор порта (и поэтому может быть полностью исключена из финальной версии скетча), вторая - выводит данные на модем. Так? 

 

По пункту 2 - я еще очень путаюсь в этих вещах. Насколько я себе представлял - мой скетч использует много памяти из-за наличия строк, которые в монитор и в модем выводят набор данных.  

Я сейчас глупость спрошу, но если у меня значения, из которых формируется смс ( val) это постоянно обновляемый набор данных (напряжение, температура, баланс и т.д) - то разве это константа?

Спасибо. Голова кругом уже, но я стараюсь понять и разобраться

 

UPD:

Please note that variables must be either globally defined, OR defined with the static keyword, in order to work with PROGMEM.

The following code will NOT work when inside a function:

const char long_str[] PROGMEM = "Hi, I would like to tell you a bit about myself.\n";

The following code WILL work, even if locally defined within a function:

const static char long_str[] PROGMEM = "Hi, I would like to tell you a bit about myself.\n"

Читаю дальше чуть внимательнее - получается, что я могу только фиксированные строки таким образом "перебросить" в флеш. Получается, чтобы отправить смс по-новому мне надо сформировать строку из "постоянной части", которая теперь будет "жить" во флеши, и переменных из скетча.

Правильно? Или опять мимо?

Спасибо!

 

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

SHA_MAN пишет:

Читаю дальше чуть внимательнее - получается, что я могу только фиксированные строки таким образом "перебросить" в флеш. Получается, чтобы отправить смс по-новому мне надо сформировать строку из "постоянной части", которая теперь будет "жить" во флеши, и переменных из скетча.

Правильно? Или опять мимо?

 

правильно.

Кроме того, у вас в программе масса просто фиксированных строк - например команды модема.

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

SHA_MAN пишет:
мне надо сформировать строку из "постоянной части", которая теперь будет "жить" во флеши, и переменных из скетча.

Правильно? Или опять мимо?

А по мне так опять мимо.

Если Вы собираетесь "формировать", то никакой экономии не получите. Вам надо формировать только переменную часть. Постоянную часть выводить прямо из прогмем, и туту же переменную часть ей в догонку.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

Снова здравствуйте

Начал пробовать "переселять" во флеш строки.

Сейчас, увы, проверить в работе нет возможности, пока на уровне компилятора.

#include <pgmspace.h>
#include <avr/pgmspace.h>

Добавил такие библиотеки (но есть подозрение, что это одно и то же, подскажите плиз).

Переделал запросы модему так:


	mySerial.begin(9600);		 //подключаем порт модема на скорости по умолчанию (можно менять AT-командой)
	mySerial.println(F("ATI")); //вывести в терминал иноформацию о модеме
	delay(100);
	mySerial.println(F("AT+CSQ")); //вывести в терминал уровень сигнала (если 99, то связи нет)
	delay(100);
	mySerial.println(F("AT+CLIP=1")); //включаем АОН
	delay(100);
	mySerial.println(F("AT+CMGF=1")); //режим кодировки СМС - обычный (для англ.)
	delay(100);
	mySerial.println(F("AT+CSCS=\"GSM\"")); //режим кодировки текста
	delay(100);
	mySerial.println(F("AT+CNMI=2,2")); //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память)
	delay(5000);

Компиляция прошла успешно. Вместо 73% показало 70%.  Должно работать? Я на верном пути?

Спасибо!

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

SHA_MAN пишет:

 Должно работать? Я на верном пути?

что касается строк - да :)

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

ЕвгенийП пишет:

Вам надо формировать только переменную часть. Постоянную часть выводить прямо из прогмем, и туту же переменную часть ей в догонку.

 

 if (val.indexOf("+CUSD:") > -1)// блок ответ баланса 
                    {        
                         
                   Serial.println (F("full bal Sms  ")) + String(val);  
                   val = val.substring(val.indexOf("Na Vashomu"), val.indexOf("Taryf"));
                   Serial.println (F("substring bal Sms     ")) + String(val); 
                   smsOn =true;
                   statusText = "Yes, Capitan!    " +String (val);
                   sms(statusText, MASTER);
                   delay (1000);
                   Serial.println (F("sms balanse sended     ")) + String(val); 
                   statusChanged = false;
                  }  

Вот так? Постоянная часть сообщения (строка) из флеши, переменная из скетча.

Компилятор "скушал" вроде, не ругнулся.

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

SHA_MAN пишет:

Вот так? Постоянная часть сообщения (строка) из флеши, переменная из скетча.

а в 8-й строке почему так же не сделали?

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

не так. что плюс забыл в строке 4. Какаа Вы вообще её понимаете?

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

b707 пишет:

SHA_MAN пишет:

Вот так? Постоянная часть сообщения (строка) из флеши, переменная из скетча.

а в 8-й строке почему так же не сделали?

Пропустил. Вот так? 

    statusText = "(F(Yes, Capitan!    ))" +String (val);

Вряд ли. В кавычках получится просто набор символов, а не вызов из памяти.

statusText = (F ("Yes, Capitan!    ")) +String (val);

А если так делаю - ругается компилятор. Не могу допереть как правильно синтаксис тут выполнить. Подскажете?

 
"ROP_sms_300519_del:141: error: conversion from 'const __FlashStringHelper*' to 'const StringSumHelper' is ambiguous
 
                    statusText = (F ("Yes, Capitan!    ")) +String (val);
 
                                                                       ^
 
 
SHA_MAN
Offline
Зарегистрирован: 10.05.2019

ЕвгенийП пишет:

не так. что плюс забыл в строке 4. Какаа Вы вообще её понимаете?

Ход мыслей был таков - вывести в монитор порта (serial.print)  сообщение из двух составляющих. Первая часть - из области флеши (для экономии памяти) набор букв "substring bal Sms " и из скетча значение переменной "val". По итогу ожидал увидеть в мониторе после строки "substring bal Sms" результат выполнения функции substring (обрезок из входящей смс) .

 

Serial.println (F("substring bal Sms     ")) + String(val);

 

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

SHA_MAN пишет:

Ход мыслей был таков - вывести в монитор порта (serial.print)  сообщение из двух составляющих. Первая часть - из области флеши (для экономии памяти) набор букв "substring bal Sms " и из скетча значение переменной "val". По итогу ожидал увидеть в мониторе после строки "substring bal Sms" результат выполнения функции substring (обрезок из входящей смс) .

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

Если хотите "вывести в монитор порта (serial.print)  сообщение из двух составляющих", то и выводите двумя вызовами Serial.print. Одним константу, вторым переменную. Чего Вы там с плюсами мудрите.

SHA_MAN
Offline
Зарегистрирован: 10.05.2019

ЕвгенийП пишет:

SHA_MAN пишет:

Ход мыслей был таков - вывести в монитор порта (serial.print)  сообщение из двух составляющих. Первая часть - из области флеши (для экономии памяти) набор букв "substring bal Sms " и из скетча значение переменной "val". По итогу ожидал увидеть в мониторе после строки "substring bal Sms" результат выполнения функции substring (обрезок из входящей смс) .

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

Если хотите "вывести в монитор порта (serial.print)  сообщение из двух составляющих", то и выводите двумя вызовами Serial.print. Одним константу, вторым переменную. Чего Вы там с плюсами мудрите.

Благодарю, попробую. 

Serial.println(F("zapros balansa")); 
                     Serial.println (F("val     "));
                     Serial.print  (String (val));

Не могу понять почему фокус с выносом во флеш не получается при формировании строки смс 

statusText = "F(I am here     )"; // + String (date)+ String (time) +String (lat)+String (lng));

Как правильно оформить синтаксис в таком случае, чтобы "подтягивались" значения из скетча к фразам из флеши? По аналогии с serial.Print не получается, компилятор ругаться начинает.

Спасибо!

sadman41
Offline
Зарегистрирован: 19.10.2016
const char text_elapsedTime[] PROGMEM = "Elapsed time (ms): ";

#define FSH_P(p) (reinterpret_cast<const __FlashStringHelper *>(p))

void setup() {
  Serial.begin(115200);
  Serial.println(String(FSH_P(text_elapsedTime)) + String(millis()));
}

Только всё равно это сравнимо с ударом сковородкой по голове. Гораздо "дешевле" по ресурсам сразу в Serial.print() передавать указатель на PGM-строку.