Непонятки на ровном месте

rapidshe
Offline
Зарегистрирован: 31.12.2015

Не знаю как описать проблему.

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

Два режима работы. Сигналка включена и сигналка выключена. Для обозначения состояния сначала использовал boolean, потом byte, потом int... почему то сначала смена типа помогала. или мне так казалось.

В общем сейчас "флаг" режима che. Если che=1, сигнализация активирована, если =0, система дективирована

сначала в самом начале ставил "int che;"  потом в сетапе задавал значение 0(потом будет из еепром писаться).

Далее введя в монитор команду на включение, в монитор начинали приходить сигналы с датчиков(по факту сейчас вместо них пульт433 с 4 кнопками. просто зажимаю любую кнопку надолго) и через мекунду-две переставали приходить. Стоило опять ввести команду на включения (при этом на выключение не отсылал), опять начинаю приходить сигналы секунду-две.

такое ощущение что ардуина забывает только что полученное значение флага.

 

"нормально всё работает только в версии скетча(представлена именно она), когда в самом начале  стоит int che =1;, потом в сетапе che=0; и далее уже режимы нормально меняются.

почему так? это магия или так и должно быть?

#include <SoftwareSerial.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <RCSwitch.h>
SoftwareSerial gsm(7, 8); 
OneWire  ds(10);
RCSwitch RC = RCSwitch();

int che = 1;
//Сигнализация

boolean smsflag[4]; //указать количество беспроводных датчиков сигнализации
unsigned long loopTime[7]; //указать количество беспроводных датчиков сигнализации
unsigned long currentTime;

//Беспроводные датчики
byte numRC = 4; //количество беспроводных датчиков сигнализации
int RCvalue[] = {12410657,12410658,12410660,12410664}; //добавить коды всех датчиков через запятую
String RCvalueName [] = {"Kuhn9","Dver' vhod","Dver' garaj","Luk"}; //названия должны соответствовать кодам датчиков из предыдущей строки


//датчики температуры DS18B20
//____НЕОБХОДИМО ПРОПИСАТЬ АДРЕСА СВОИХ ДАТЧИКОВ______
byte flagDallRead;
byte addr[1][8]={{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}; //в первых скобках [] скобках необхлодимо указать сколько у вас DS18B20 и в фигурных скобках прописать их адреса {{},{}.....{},{}} 
byte numDS = 1; // количество DS18B20.
float Temp[1]; //в скобках указать количество ваших DS18B20



//ДЛЯ GSM и около него
boolean isStringMessage = false;  // Переменная принимает значение True, если текущая строка является сообщением
int ch;
String sms = "";
String val = ""; 
String val1 = ""; //переменная для хранения технической информации сообщения/звонка (номер, время)
String val2 = ""; //переменная для хравнения содержания полученной СМСки
String master1 = "7916ххххххх";


//ДЛЯ РЕЛЕ
byte Pins[] = {4, 5, 6, 7}; // Массив задействованных номеров Pins Arduino, для управления реле. 
byte PinStatus[4]; // Массив для фиксации изменений
byte numPins = 4; // количество реле
byte ON = HIGH; //для проверки работоспособности на светодиодах ON=HIGH, для реле ON=LOW
byte OFF = LOW; //для проверки работоспособности на светодиодах OFF=LOW, для реле OFF=HIGH


void setup() {
che=0;
Serial.begin(9600);
delay(100);
    Serial.println("GOTOVIMS9");
{// GSM 
gsm.begin(19200);
    delay(100);
gsm.print("AT+CMGF=1\r");         //устанавливает текстовый режим смс-сообщения
    delay(100);
gsm.print("AT+IFC=1, 1\r");       //устанавливает программный контроль потоком передачи данных
    delay(100);
gsm.print("AT+CPBS=\"SM\"\r");    //открывает доступ к данным телефонной книги SIM-карты
    delay(100);
gsm.print("AT+GSMBUSY=1, 1\r");   //запрет всех входящих звонков
    delay(100);
gsm.print("AT+CMGDA=«DEL ALL»\r");  //Очищаем накопившиеся СМС
    delay(100);
gsm.print("AT+CNMI=1,2,2,1,0\r"); //включает оповещение о новых сообщениях
    delay(300);
    delay(5000);}
RC.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
for(int i = 0; i <= numPins -1; i++) { //восставновление состояния реле
   pinMode(Pins[i],OUTPUT);
   PinStatus[i]=EEPROM.read(i); //считываем состояние до перезагрузки ардуины
   digitalWrite(Pins[i],PinStatus[i]); //восстанавливаем состояние реле
   } 
for(int i = 0; i <= numRC -1; i++) { //для отправки смс
   loopTime[i] = 0;
   smsflag[i]=false;
   } 
Serial.println("GOTOVO");
}

void loop() {
      currentTime = millis();       // считываем время, прошедшее с момента запуска программы
      dallRead(flagDallRead * 1000);
if (Serial.available()) {  //обработка Serial данных
    while (Serial.available()) 
         {  //сохраняем строку в переменную val
         ch = Serial.read();
         val2 += char(ch);
         delay(10);
         }
         Serial.println(val2);
   //sms(val2, String("+79161112219")); 
   val1=master1; 
   razborkomand();
   val2="";
   val1="";  //очищаем
  }
if (gsm.available()) {//если модуль что то шлет
    while(gsm.available()) 
         {
          ch = gsm.read();
          if(ch == '\r') continue;
          if(ch == '\n') 
            {
            gsmRead(val); 
            val = ""; 
            }
          else val += char(ch);
         }
    }
if (RC.available()) {
  if (che == 1) {
   //обработа сигналов с беспроводных датчиков
     ch = RC.getReceivedValue(); 
     for(int i = 0; i <= numRC -1; i++) 
        {
        if (ch == RCvalue[i]) {  Alarm(RCvalueName[i]);}
        }
     
   }
   RC.resetAvailable();
   }
 // if (RC.available()) {  Serial.println("RC"); RC.resetAvailable();}
}






void AlarmSet(int vklvikl, String phone, String onoff) {
  che = vklvikl;
  sms=onoff;
  smssend(phone);
//  if (che == 1)  Serial.println("1");
//  if (che == 0)  Serial.println("0");
}

void Alarm(String zona) {
//Serial.print(che); 
Serial.println(zona); 
}
void razborkomand () {
if (val2.indexOf("Pozvoni") > -1) { if (val1.indexOf(master1) > -1){Proslushka(master1);} } //если в сообщении "позвони", ардуинка звонит нам на номер, с которого пришел запрос
if (val2.indexOf("Temp?") > -1) { if (val1.indexOf(master1) > -1){TempStatus(master1);} } //если в сообщении "температура?", ардуинка высылает температуры на номер, с которого пришел запрос
if (val2.indexOf("Vkl") > -1) { //если в сообщении "вкл1234", включить реле №1 и №2 и №3 и №4
   if (val2.indexOf("1")> -1) RelaySet(1, ON);
   if (val2.indexOf("2")> -1) RelaySet(2, ON);
   if (val2.indexOf("3")> -1) RelaySet(3, ON);
   if (val2.indexOf("4")> -1) RelaySet(4, ON);
   } 
if (val2.indexOf("Vikl") > -1) { //если в сообщении "выкл1234", выключить реле №1 и №2 и №3 и №4
   if (val2.indexOf("1")> -1) RelaySet(1, OFF);
   if (val2.indexOf("2")> -1) RelaySet(2, OFF);
   if (val2.indexOf("3")> -1) RelaySet(3, OFF);
   if (val2.indexOf("4")> -1) RelaySet(4, OFF);
   } 
if (val2.indexOf("On") > -1) { if (val1.indexOf(master1) > -1){AlarmSet(1, master1, String ("ON")); }} //если в сообщении "ON", ардуинка включает режим сигнализации и отправляет смс с оповещением о постановке на сигнализацию тому, кто прислал команду
if (val2.indexOf("Off") > -1) { if (val1.indexOf(master1) > -1){AlarmSet(0, master1, String ("OFF")); }} //если в сообщении "OFF", ардуинка выключает режим сигнализации и отправляет смс с оповещением о сняьтт с сигнализации тому, кто прислал команду

}
void gsmRead(const String val) { //разбираем данные от gsm
 if (!val.startsWith("+CMT") && isStringMessage == false ) {Serial.println(val);} //если НЕ смс и это не вторая строка(которая является непосредственно сообщением), значит это иная информация от модуля. выводим в сериал
 
 if (isStringMessage == true) // если флаг "ПРАВДА", значит дошли до строки с сообщением
    {
    isStringMessage = false;  // меняем флаг на "ЛОЖЬ", чтобы при обработке последующей информации, не относящейся к сообщению, в этот кусок не попасть снова
    if (val1.indexOf(master1) > -1) // Если в первой строке VAL1 есть мастер(или один из номеров) номер
       {
       Serial.println("master"); //в сериал шлется, что сообщение от мастера
       val2 = val; // сохраняем в переменную
       Serial.println("VAL2: " + val2); // выводим в сериал 
       razborkomand();  // разбираем что за команда пришла
       }
    else Serial.println("NE master");
    }
 else 
    { 
    if (val.startsWith("+CMT"))  // если текущая строка начинается с "+CMT", то следующая строка является сообщением;
       {
       val1=val; 
       isStringMessage = true; //флаг означающий, что следующая строка сообщение
       Serial.println("VAL1: " + val1); // выводим в сериал 
       } 
    }   
}  
void smssend(String phone) { //процедура отправки СМС
   Serial.print(sms);   Serial.println(phone); 
   /*Serial.println("SMS send started");
  gsm.print("AT+CMGF=1\r");
  delay(100);
  gsm.println("AT + CMGS = \"" + phone + "\"");
  delay(500);
  gsm.print(sms);
//  text = ""; 
  delay(500);
  gsm.print((char)26);
  delay(5000);
  Serial.println("SMS send complete");*/
  sms="";
}
void Proslushka(String phone){ //Цикл дозвона абоненту (для аудиоконтроля)___________________
  gsm.println("AT+CMIC=0,15");    // Команда для установки чувствительности микрофона Поэкспериментировать с цифрой.
// 0,- это канал микрофона (1,2,3),15 это уровень см.инструкцию к СИМ900
delay(2000);
  gsm.println("ATD+"+ phone + ";");  // Набираем номер
//Serial2.println("ATH"); // Вешаем трубку
}
void RelaySet(byte rnum, byte state) { //управление реле
  PinStatus[(rnum-1)] = state; 
  digitalWrite(Pins[(rnum-1)],PinStatus[(rnum-1)]); 
  EEPROM.write((rnum-1),PinStatus[(rnum-1)]); //запись в энергонезависимую память состояния реле для вооставноления этого состояния после потери питания
}
void TempStatus(String phone) {
  sms = "";
  for(byte n = 0; n <= numDS-1; n++) 
      {
      sms += "T";
      sms += (n+1);
      sms += " ";
      sms += Temp[n];
      sms += "C";
      sms += '\n';
      }
  smssend(phone);

  sms = "";
}

void dallRead(unsigned long interval){ //температура
  static unsigned long prevTime = 0;
  if (millis() - prevTime > interval) { //Проверка заданного интервала
  static boolean flagDall = 0; //Признак операции
  prevTime = millis();
  flagDall =! flagDall; //Инверсия признака
  if (flagDall) {
    ds.reset();
    ds.write(0xCC); //Обращение ко всем датчикам
    ds.write(0x44); //Команда на конвертацию
    flagDallRead = 1; //Время возврата в секундах
  }
  else {
    byte i;
     int temp;
    for (i = 0; i < 3; i++){ //Перебор количества датчиков
     ds.reset();
     ds.select(addr[i]);
     ds.write(0xBE); //Считывание значения с датчика
     temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры
     Temp[i] = (float)temp / 16.0; 
     flagDallRead = 2; //Время возврата в секундах
     }
   }
  }
}

уццукц

rapidshe
Offline
Зарегистрирован: 31.12.2015

забыл строки указать и подсветить

и еще. если убрать проверку режима работы (стр114,122), то данные принимаются нормльно

#include <SoftwareSerial.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <RCSwitch.h>
SoftwareSerial gsm(7, 8); 
OneWire  ds(10);
RCSwitch RC = RCSwitch();

int che = 1;
//Сигнализация

boolean smsflag[4]; //указать количество беспроводных датчиков сигнализации
unsigned long loopTime[7]; //указать количество беспроводных датчиков сигнализации
unsigned long currentTime;

//Беспроводные датчики
byte numRC = 4; //количество беспроводных датчиков сигнализации
int RCvalue[] = {12410657,12410658,12410660,12410664}; //добавить коды всех датчиков через запятую
String RCvalueName [] = {"Kuhn9","Dver' vhod","Dver' garaj","Luk"}; //названия должны соответствовать кодам датчиков из предыдущей строки


//датчики температуры DS18B20
//____НЕОБХОДИМО ПРОПИСАТЬ АДРЕСА СВОИХ ДАТЧИКОВ______
byte flagDallRead;
byte addr[1][8]={{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}; //в первых скобках [] скобках необхлодимо указать сколько у вас DS18B20 и в фигурных скобках прописать их адреса {{},{}.....{},{}} 
byte numDS = 1; // количество DS18B20.
float Temp[1]; //в скобках указать количество ваших DS18B20



//ДЛЯ GSM и около него
boolean isStringMessage = false;  // Переменная принимает значение True, если текущая строка является сообщением
int ch;
String sms = "";
String val = ""; 
String val1 = ""; //переменная для хранения технической информации сообщения/звонка (номер, время)
String val2 = ""; //переменная для хравнения содержания полученной СМСки
String master1 = "7916ххххххх";


//ДЛЯ РЕЛЕ
byte Pins[] = {4, 5, 6, 7}; // Массив задействованных номеров Pins Arduino, для управления реле. 
byte PinStatus[4]; // Массив для фиксации изменений
byte numPins = 4; // количество реле
byte ON = HIGH; //для проверки работоспособности на светодиодах ON=HIGH, для реле ON=LOW
byte OFF = LOW; //для проверки работоспособности на светодиодах OFF=LOW, для реле OFF=HIGH


void setup() {
che=0;
Serial.begin(9600);
delay(100);
    Serial.println("GOTOVIMS9");
{// GSM 
gsm.begin(19200);
    delay(100);
gsm.print("AT+CMGF=1\r");         //устанавливает текстовый режим смс-сообщения
    delay(100);
gsm.print("AT+IFC=1, 1\r");       //устанавливает программный контроль потоком передачи данных
    delay(100);
gsm.print("AT+CPBS=\"SM\"\r");    //открывает доступ к данным телефонной книги SIM-карты
    delay(100);
gsm.print("AT+GSMBUSY=1, 1\r");   //запрет всех входящих звонков
    delay(100);
gsm.print("AT+CMGDA=«DEL ALL»\r");  //Очищаем накопившиеся СМС
    delay(100);
gsm.print("AT+CNMI=1,2,2,1,0\r"); //включает оповещение о новых сообщениях
    delay(300);
    delay(5000);}
RC.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
for(int i = 0; i <= numPins -1; i++) { //восставновление состояния реле
   pinMode(Pins[i],OUTPUT);
   PinStatus[i]=EEPROM.read(i); //считываем состояние до перезагрузки ардуины
   digitalWrite(Pins[i],PinStatus[i]); //восстанавливаем состояние реле
   } 
for(int i = 0; i <= numRC -1; i++) { //для отправки смс
   loopTime[i] = 0;
   smsflag[i]=false;
   } 
Serial.println("GOTOVO");
}

void loop() {
      currentTime = millis();       // считываем время, прошедшее с момента запуска программы
      dallRead(flagDallRead * 1000);
if (Serial.available()) {  //обработка Serial данных
    while (Serial.available()) 
         {  //сохраняем строку в переменную val
         ch = Serial.read();
         val2 += char(ch);
         delay(10);
         }
         Serial.println(val2);
   //sms(val2, String("+79161112219")); 
   val1=master1; 
   razborkomand();
   val2="";
   val1="";  //очищаем
  }
if (gsm.available()) {//если модуль что то шлет
    while(gsm.available()) 
         {
          ch = gsm.read();
          if(ch == '\r') continue;
          if(ch == '\n') 
            {
            gsmRead(val); 
            val = ""; 
            }
          else val += char(ch);
         }
    }
if (RC.available()) {
  if (che == 1) {
   //обработа сигналов с беспроводных датчиков
     ch = RC.getReceivedValue(); 
     for(int i = 0; i <= numRC -1; i++) 
        {
        if (ch == RCvalue[i]) {  Alarm(RCvalueName[i]);}
        }
     
   }
   RC.resetAvailable();
   }
 // if (RC.available()) {  Serial.println("RC"); RC.resetAvailable();}
}






void AlarmSet(int vklvikl, String phone, String onoff) {
  che = vklvikl;
  sms=onoff;
  smssend(phone);
//  if (che == 1)  Serial.println("1");
//  if (che == 0)  Serial.println("0");
}

void Alarm(String zona) {
//Serial.print(che); 
Serial.println(zona); 
}
void razborkomand () {
if (val2.indexOf("Pozvoni") > -1) { if (val1.indexOf(master1) > -1){Proslushka(master1);} } //если в сообщении "позвони", ардуинка звонит нам на номер, с которого пришел запрос
if (val2.indexOf("Temp?") > -1) { if (val1.indexOf(master1) > -1){TempStatus(master1);} } //если в сообщении "температура?", ардуинка высылает температуры на номер, с которого пришел запрос
if (val2.indexOf("Vkl") > -1) { //если в сообщении "вкл1234", включить реле №1 и №2 и №3 и №4
   if (val2.indexOf("1")> -1) RelaySet(1, ON);
   if (val2.indexOf("2")> -1) RelaySet(2, ON);
   if (val2.indexOf("3")> -1) RelaySet(3, ON);
   if (val2.indexOf("4")> -1) RelaySet(4, ON);
   } 
if (val2.indexOf("Vikl") > -1) { //если в сообщении "выкл1234", выключить реле №1 и №2 и №3 и №4
   if (val2.indexOf("1")> -1) RelaySet(1, OFF);
   if (val2.indexOf("2")> -1) RelaySet(2, OFF);
   if (val2.indexOf("3")> -1) RelaySet(3, OFF);
   if (val2.indexOf("4")> -1) RelaySet(4, OFF);
   } 
if (val2.indexOf("On") > -1) { if (val1.indexOf(master1) > -1){AlarmSet(1, master1, String ("ON")); }} //если в сообщении "ON", ардуинка включает режим сигнализации и отправляет смс с оповещением о постановке на сигнализацию тому, кто прислал команду
if (val2.indexOf("Off") > -1) { if (val1.indexOf(master1) > -1){AlarmSet(0, master1, String ("OFF")); }} //если в сообщении "OFF", ардуинка выключает режим сигнализации и отправляет смс с оповещением о сняьтт с сигнализации тому, кто прислал команду

}
void gsmRead(const String val) { //разбираем данные от gsm
 if (!val.startsWith("+CMT") && isStringMessage == false ) {Serial.println(val);} //если НЕ смс и это не вторая строка(которая является непосредственно сообщением), значит это иная информация от модуля. выводим в сериал
 
 if (isStringMessage == true) // если флаг "ПРАВДА", значит дошли до строки с сообщением
    {
    isStringMessage = false;  // меняем флаг на "ЛОЖЬ", чтобы при обработке последующей информации, не относящейся к сообщению, в этот кусок не попасть снова
    if (val1.indexOf(master1) > -1) // Если в первой строке VAL1 есть мастер(или один из номеров) номер
       {
       Serial.println("master"); //в сериал шлется, что сообщение от мастера
       val2 = val; // сохраняем в переменную
       Serial.println("VAL2: " + val2); // выводим в сериал 
       razborkomand();  // разбираем что за команда пришла
       }
    else Serial.println("NE master");
    }
 else 
    { 
    if (val.startsWith("+CMT"))  // если текущая строка начинается с "+CMT", то следующая строка является сообщением;
       {
       val1=val; 
       isStringMessage = true; //флаг означающий, что следующая строка сообщение
       Serial.println("VAL1: " + val1); // выводим в сериал 
       } 
    }   
}  
void smssend(String phone) { //процедура отправки СМС
   Serial.print(sms);   Serial.println(phone); 
   /*Serial.println("SMS send started");
  gsm.print("AT+CMGF=1\r");
  delay(100);
  gsm.println("AT + CMGS = \"" + phone + "\"");
  delay(500);
  gsm.print(sms);
//  text = ""; 
  delay(500);
  gsm.print((char)26);
  delay(5000);
  Serial.println("SMS send complete");*/
  sms="";
}
void Proslushka(String phone){ //Цикл дозвона абоненту (для аудиоконтроля)___________________
  gsm.println("AT+CMIC=0,15");    // Команда для установки чувствительности микрофона Поэкспериментировать с цифрой.
// 0,- это канал микрофона (1,2,3),15 это уровень см.инструкцию к СИМ900
delay(2000);
  gsm.println("ATD+"+ phone + ";");  // Набираем номер
//Serial2.println("ATH"); // Вешаем трубку
}
void RelaySet(byte rnum, byte state) { //управление реле
  PinStatus[(rnum-1)] = state; 
  digitalWrite(Pins[(rnum-1)],PinStatus[(rnum-1)]); 
  EEPROM.write((rnum-1),PinStatus[(rnum-1)]); //запись в энергонезависимую память состояния реле для вооставноления этого состояния после потери питания
}
void TempStatus(String phone) {
  sms = "";
  for(byte n = 0; n <= numDS-1; n++) 
      {
      sms += "T";
      sms += (n+1);
      sms += " ";
      sms += Temp[n];
      sms += "C";
      sms += '\n';
      }
  smssend(phone);

  sms = "";
}

void dallRead(unsigned long interval){ //температура
  static unsigned long prevTime = 0;
  if (millis() - prevTime > interval) { //Проверка заданного интервала
  static boolean flagDall = 0; //Признак операции
  prevTime = millis();
  flagDall =! flagDall; //Инверсия признака
  if (flagDall) {
    ds.reset();
    ds.write(0xCC); //Обращение ко всем датчикам
    ds.write(0x44); //Команда на конвертацию
    flagDallRead = 1; //Время возврата в секундах
  }
  else {
    byte i;
     int temp;
    for (i = 0; i < 3; i++){ //Перебор количества датчиков
     ds.reset();
     ds.select(addr[i]);
     ds.write(0xBE); //Считывание значения с датчика
     temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры
     Temp[i] = (float)temp / 16.0; 
     flagDallRead = 2; //Время возврата в секундах
     }
   }
  }
}

 

rapidshe
Offline
Зарегистрирован: 31.12.2015

длину массива в 017 исправил на 4, 

пересечение пинов в 042 и 005 исправил.

непонятнка осталась(