
//Тестовый код сборки GSM-M590 от Neru5.RU
  #include <SoftwareSerial.h>
  #include <EEPROM.h>
  #include <OneWire.h>
OneWire ds(10);
SoftwareSerial GsmSerial(2, 3);      // RX-2 pin, TX-3 pin
//#define S 7 //ЗАПУСК МОДУЛЯ 300мс
String AdminPhone="79247694477";    // Телефон админа в формате 7xxxxxxxxxx
int pinLed=13;                    // Номер порта светодиода, который будем включать/выключать
int ch1=5;                        //канал 1
int ch2=4;                       //канал2
//int S=7;
float U=0;  //переменная напряжения питания
//float tim=0;
int Temp=0;                        // переменная температуры
String D="";
String T="";
float t=0;
void setup()
//pinMode(S, OUTPUT);
//digitalWrite(S, HIGH);            //даем запуск модема
 // delay(300);                       //держим оптрон 300мс
 // digitalWrite(S, LOW);           //отключаем оптрон
{ delay(3000);                      // задержка 3 сек для прогрузки модуля GSM
                     
  pinMode(pinLed, OUTPUT);                       // Режим порта на вывод
   pinMode(ch1, OUTPUT);
    pinMode(ch2, OUTPUT);
  //----подбор скорости
   Serial.begin(115200);
  GsmSerial.begin(115200);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(57600);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(38400);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(19200);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(4800);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(2400);
  GsmSerial.println("AT+IPR=9600");
  delay(200);
  GsmSerial.begin(9600);
  Serial.begin(9600); 
  //---конец блока подбора скорости
  //Serial.begin(9600);
 // GsmSerial.begin(9600);                        // Устанавливаем скорость связи Ардуино и модема
 //GsmSerial.println("AT+IPR=9600<CR>");   //смена скорости модема
  
  GsmSerial.println("ATE0");                // выключаем эхо
  delay(100);
  GsmSerial.println("AT+CLIP=1");                // Включаем АОН
  delay(100);
  GsmSerial.println("AT+CMGF=1");                // Формат СМС = ASCII текст
  delay(100);
  GsmSerial.println("AT+CSCS=\"GSM\"");          // Режим кодировки текста = GSM (только англ.)
  delay(100);
  GsmSerial.println("AT+CNMI=2,2");              // Текст смс выводится в com-порт
  delay(100);
  
 String str="";
  while(str.indexOf("+COPS: 0") == -1) {        // Ждем пока модем будет готов
    GsmSerial.println("AT+COPS?");
    str=ReadCom();
    delay(200);
  }
  SendSms("Sustem ON", AdminPhone);       // отправить смс о готовности устройства
}



void loop()
{ 
    
  String strSms = ReadCom();                  // Читаем смс, если есть
  while (strSms.length()==0)      {        
    delay(500);
     strSms = ReadCom();
  } 
  
  // Если телефон админа, то читаем дальше
  if (strSms.indexOf(AdminPhone) > -1)   {
    if (strSms.indexOf("+CMT") > -1)     {    // Если смс
      // Кодовое слово "on"
      if (strSms.indexOf("on") > -1) {    // Если обнаружено ключевое слово на включение
        digitalWrite(pinLed,HIGH);             // Включаем светодиод
        digitalWrite(ch1,HIGH);
        SendSms("podogrev vkluchen", AdminPhone);       // отправить смс, что включили
        Serial.println("termo=on");           //отправляем состояние в порт
      }
            //if (ch1==) {tim++;}
     // Кодовое слово "2on"
      if (strSms.indexOf("2on") > -1) {    // Если обнаружено ключевое слово на включение
         digitalWrite(ch2,HIGH);
        SendSms("ch2=on", AdminPhone);       // отправить смс, что включили
        Serial.println("ch2=on");           //отправляем состояние в порт
    }
      // Кодовое слово "off"
      if (strSms.indexOf("off") > -1){    // Если обнаружено ключевое слово на выключение
        digitalWrite(pinLed,LOW);             // Выключаем светодиод
        digitalWrite(ch1,LOW);
        SendSms("otkluchen podogrev", AdminPhone);     // отправить смс, что выключили
        Serial.println("ch1=off");
      }
      // Кодовое слово "2off"
      if (strSms.indexOf("2off") > -1){    // Если обнаружено ключевое слово на выключение
         digitalWrite(ch2,LOW);
        SendSms("ch2=off", AdminPhone);     // отправить смс, что выключили
        Serial.println("ch2=off");
      }
       // Кодовое слово "power"
      if (strSms.indexOf("power") > -1){    // Если обнаружено ключевое слово запроса напряжения питания
         U=analogRead(0);                  //Считываем напряжение питания с порта А0
        U=U*146/10000;                      // преобразовали значение переменной в привычное напряжение (U*0,0146)
        String D=String(U,1);            //преобразуем данные в символы для отправки по смс
        SendSms(D, AdminPhone);     // отправить смс c напряжением питания
      }
      
      //--------------------------<блок обработки датчика DS18b20 (стандартный код) >------------------------ 
       byte i;                       
   byte present = 0;
   byte type_s;
   byte data[12];
   byte addr[8];
   float celsius;
   if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
  ds.reset_search();
  delay(250);
   return;
  }
Serial.print("ROM =");
   for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
   }
 if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
  return;
  }
Serial.println();
// первый байт определяет чип
   switch (addr[0]) {
   case 0x10:
Serial.println(" Chip = DS18S20"); // или более старый DS1820
   type_s = 1;
   break;
   case 0x28:
Serial.println(" Chip = DS18B20");
   type_s = 0;
   break;
   case 0x22:
Serial.println(" Chip = DS1822");
    type_s = 0;
    break;
   default:
Serial.println("Device is not a DS18x20 family device.");
   return;
    }
    ds.reset();
    ds.select(addr);
    ds.write(0x44); // начинаем преобразование, используя ds.write(0x44,1) с "паразитным" питанием
    delay(1000); // 750 может быть достаточно, а может быть и не хватит
    present = ds.reset();
    ds.select(addr);
    ds.write(0xBE);
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
    for ( i = 0; i < 9; i++) { // нам необходимо 9 байт
    data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
    }
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
   // конвертируем данный в фактическую температуру
   // так как результат является 16 битным целым, его надо хранить в
   // переменной с типом данных "int16_t", которая всегда равна 16 битам,
   // даже если мы проводим компиляцию на 32-х битном процессоре
   int16_t raw = (data[1] << 8) | data[0];
   if (type_s) {
   raw = raw << 3; // разрешение 9 бит по умолчанию
   if (data[7] == 0x10) {
   raw = (raw & 0xFFF0) + 12 - data[6];
    }
    } else {
    byte cfg = (data[4] & 0x60);
    // при маленьких значениях, малые биты не определены, давайте их обнулим
    if (cfg == 0x00) raw = raw & ~7; // разрешение 9 бит, 93.75 мс
    else if (cfg == 0x20) raw = raw & ~3; // разрешение 10 бит, 187.5 мс
    else if (cfg == 0x40) raw = raw & ~1; // разрешение 11 бит, 375 мс
    //// разрешение по умолчанию равно 12 бит, время преобразования - 750 мс
    }
    celsius = (float)raw / 16.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
//----------------------------<конец блока обработки датчика 18В20 (передали значение температуры переменной celsius >--------------------------------

      //Кодовое слово "temp"
     if (strSms.indexOf("temp") > -1){    // Если обнаружено ключевое слово запроса температуры (опция, для использования смотри инструкцию на Neru5.RU)
       String T=String(celsius,1);            //преобразуем данные в символы для отправки по смс
     SendSms(T, AdminPhone);     // отправить смс c температурой
     }
       // Кодовое слово "clear"
      if (strSms.indexOf("clear") > -1){    // Если обнаружено ключевое слово удаления сообщений (если нужно очистить сим карту)
         GsmSerial.println("AT+CMGD=1,4");  // удаляем все сообщения
         SendSms("clear OK", AdminPhone);     // отправить смс о выполнении очистки
      }
      
    
     //-----------------------------------------------------------------------------------
    }
    if (strSms.indexOf("RING") > -1)     {    // Если звонят (выполняется на каждый гудок)
      // Можем, что нибудь выполнить
      Serial.println("start call");
    }
  }
  if (strSms.indexOf("NO CARRIER") > -1){   // Если звонок окончен
    //SendSms("called", AdminPhone);     // Можем отправить смс, что нам звонили
    Serial.println("end call");
  }
    }
    

// Читает смс
String ReadCom()
{
  int chCode = 0;                              // Код символа
  String strSms = "";                          // Текст
  if (GsmSerial.available()) {                 // Есть данные от модема
    delay(300);
    // Считываем смс с com-порта модема
    while (GsmSerial.available()) {            // Если есть еще символы, то читаем
      chCode = GsmSerial.read();               // Считываем очередной символ
      strSms += char(chCode);                  // Добавляем к строке
      delay(10);
    }
  }
  if (strSms.length()>0) {
    Serial.println("++++++++++");
    //Serial.println();
    Serial.println(strSms.length());
    Serial.println(strSms);
  }
  return strSms;
}

// Отправляет текст смс на определенный номер
void SendSms(String text, String phone)
{
  phone="+"+phone;
  GsmSerial.println("AT+CMGS=\"" + phone + "\""); // Заголовок АТ команды и номер телефона
  delay(500);
  GsmSerial.print(text);                          // Текст смс
  delay(500);
  GsmSerial.print((char)26);                      // Конец сообщения и отправляем смс
  delay(500);
}

