Ардуино сервер

gmv_tft
Offline
Зарегистрирован: 23.02.2013

Это мой первый проект. Цель данного проекта - изучение основ конструирования и программирования контроллеров, а также знакомство с php и mysql.

Что может данная железка:

  1. Часы с датой
  2. Чтение сообщений отосланных пользователями с сайта.
  3. Чтение напоминаний в зависимости от даты.
  4. Погода, а также прогноз погоды на следующий день (с яндекса).
  5. Температура и влажность в помещении (передача  показаний на сервер).
  6. Радио  с ПДУ.

Используемые комплектующие

  1. MEGA 2560
  2. LCD20x4 (без поддержки кириллицы )
  3. Интернет плата ENC28J60
  4. DHT11
  5. TEA5767, TDA7056A, REM , динамик и т.п. с разборки

Данный проект имеет центральную консоль, к которой планируется подключать  дополнительные датчики и устройства управления.

Работает все просто. Каждую минуту контроллер запрашивает  “свою страничку” GET запросом, в который входит его индекс для авторизации и передается текущая температура и влажность, которые записываются в БД. На сервере проверяется, есть ли текущие  напоминания или непрочитанные сообщения. Парсится погода с яндекса. Все полученные данные формируются в удобный формат для контроллера (с разделителями)  и отправляются клиенту обратно. Контроллер  принимает сообщение и по разделителям формирует вывод на lcd, если нет сообщений  или напоминаний, то подмешивается текущая температура.

Если смс написана на русском, то она автоматически переводится  транслитом и  записывается в БД.

Каждый пользователь может создать напоминание (повторяющееся каждый год или однократное).

 Если пришла смс или напоминание, то выводится информация об этом (количество смс, логин юзера  первой в очереди на чтение) и  загорается светодиод.

Если нажать на кнопку чтения смс, формируется внеочередной специальный  GET запрос с чтением первой в очереди смс. В ответ сервер отсылает подготовленный текст и  помечает смс (или напоминание) прочитанной .

Пользователь может посмотреть во вкладке home текущую температуру и влажность. В этой вкладке планируется продолжение проекта управления домом.

Также в устройстве  есть радио с аналоговым усилителем. Управляется радио с ПДУ (регулировка громкости, переключение каналов, power, mute).  Частота текущей станции подмешивается и выводится на lcd.

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

Основная нагрузка на обработку строк ложится на php, что уменьшает код  программы МК.

#include "LiquidCrystal.h"
#include "EtherCard.h"
#include "DHT.h"
#include "IRremote.h"
#include "Wire.h"

double fm_radio[]={99.6,100.0,100.4,100.9,101.4,101.8,103.0,104.3,105.5,107.4};//радио нашего региона
String fm_radio_str[]={"99.60","100.0","100.4","100.9","101.4","101.8","103.0","104.3","105.5","107.4"};//масcив для вывода на lcd текущей радиостанции
int fm_radio_n=0,fm_radio_max=9;
byte vol=20;//громкость усилителя
unsigned char frequencyH=0;
unsigned char frequencyL=0;
unsigned int frequencyB;
double frequency=0;
int h_dht11, t_dht11;//влажность, температура
int dht_11=7;// пин подключения датчика температуры и влажности
int vol_pin=8;//пин подключения регулировки громкости
int RECV_PIN = 4;//пин подключения фотоприемника
int ledpin=5,swpin=6;//пины подключения светодиода и кнопки
int flag=0;//флаг определения режимов работы
boolean radio_flag=0;//флаг определения работы радио
boolean mute=0;//mute усилителя
IRrecv irrecv(RECV_PIN);
decode_results results;
DHT dht(dht_11, DHT11);
LiquidCrystal lcd(31, 30, 28, 26, 24, 22);
static byte mymac[] = {0x70,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[700];
static uint32_t timer;
char website[] PROGMEM = "www.*****";

//функция приема текстовой строки сетевой карты
static void my_callback (byte status, word off, word len) {
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  lcd_print((const char*) Ethernet::buffer + off);
}
//функция записи в TEA5767 (радио)
void fm_write(double frequency){
   frequencyB=4*(frequency*1000000+225000)/32768;
   frequencyH=frequencyB>>8;
   frequencyL=frequencyB&0XFF;
   delay(100);
   Wire.beginTransmission(0x60);
   Wire.write(frequencyH);
   Wire.write(frequencyL);
   Wire.write(0xBC);//включить режим моно
   Wire.write(0x10);
   Wire.write(0x00);
   Wire.endTransmission();
   delay(100);
   lcd.setCursor(0,3);
   String str_lcd=String(t_dht11)+"C "+String(h_dht11)+"% ";
   str_lcd=str_lcd+"Radio "+fm_radio_str[fm_radio_n];
   lcd.print(str_lcd);
   }
//Функция вывода на lcd
void lcd_print(String str){
  lcd.clear();
  String str_lcd;
  int a,b;
//Вывод времени, погоды и температуры
  if (flag==0){
    a=str.indexOf("|");
    a++;
    b=str.indexOf("Orel");
    str_lcd=str.substring(a,b);
    lcd.setCursor(0,0);
    lcd.print(str_lcd);
    a=str.indexOf("Tomorrow");
    lcd.setCursor(0,1);
    str_lcd=str.substring(b,a);
    lcd.print(str_lcd);
    lcd.setCursor(0,2);
    b=str.indexOf("|",a);
    if (b<0){
      str_lcd=str.substring(a);
      lcd.print(str_lcd);
      lcd.setCursor(0,3);
      str_lcd=String(t_dht11)+"C "+String(h_dht11)+"% ";
      if (radio_flag==1) str_lcd=str_lcd+"Radio "+fm_radio_str[fm_radio_n];
      lcd.print(str_lcd);
      digitalWrite(ledpin,LOW);
      return;
    }
    str_lcd=str.substring(a,b);
    lcd.print(str_lcd);
    b++;
    lcd.setCursor(0,3);
    str_lcd=str.substring(b);
    lcd.print(str_lcd);
    digitalWrite(ledpin,HIGH);//светодиодная индикация - пришла смс
    return;
  }
 //Вывод принятой смс
  if (flag==1){
    digitalWrite(ledpin,LOW);
    //проверка пустого перезапроса, если нет смс, вывести время, погоду и температуру
    if (str.indexOf("Orel")>0){
      flag=0;
      lcd_print(str);
      return;
    }
    a=str.indexOf("|");
    a++;
    b=a+20;
    lcd.setCursor(0,0);
    str_lcd=str.substring(a,b);
    lcd.print(str_lcd);
    a=b+20;
    lcd.setCursor(0,1);
    str_lcd=str.substring(b,a);
    lcd.print(str_lcd);
    b=a+20;
    lcd.setCursor(0,2);
    str_lcd=str.substring(a,b);
    lcd.print(str_lcd);
    a=b+20;
    lcd.setCursor(0,3);
    str_lcd=str.substring(b,a);
    lcd.print(str_lcd);
    timer = millis() + 20000;//время для прочтения смс
  }
}

void setup () {
  pinMode(vol_pin, OUTPUT);
  Wire.begin();
  irrecv.enableIRIn();
  pinMode(ledpin, OUTPUT);
  pinMode(swpin, INPUT);
  dht.begin();
  Serial.begin(9600);
  lcd.begin(20,4);
  if (ether.begin(sizeof Ethernet::buffer, mymac,53) == 0) 
  Serial.println( "Failed to access Ethernet controller");
  if (!ether.dhcpSetup())
  Serial.println("DHCP failed");
  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  
  if (!ether.dnsLookup(website))
  Serial.println("DNS failed");
  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
//Обработка команд ПДУ
  if (irrecv.decode(&results)){
    irrecv.resume();
  }
//power
  if (results.value==284111055){
    if (radio_flag==0){
      frequency=fm_radio[fm_radio_n];
      fm_write(frequency);
      analogWrite(vol_pin,vol); 
      radio_flag=1;
    }
    else {
      analogWrite(vol_pin,0);// mute усилителя
      Wire.beginTransmission(0x60);   
      Wire.write(frequencyH);
      Wire.write(frequencyL);
      Wire.write(0xBC);
      Wire.write(0x50);//power off
      Wire.write(0x00);
      Wire.endTransmission();
      delay(100);
      lcd.setCursor(0,3);
      String str_lcd=String(t_dht11)+"C "+String(h_dht11)+"% Radio off   ";
      lcd.print(str_lcd);
      radio_flag=0;
    }
    results.value=0;
  }
//ch+
    if (results.value==284117175 && radio_flag==1){
      fm_radio_n++;
      if (fm_radio_n>fm_radio_max) fm_radio_n=0;
      frequency=fm_radio[fm_radio_n];
      fm_write(frequency);
      results.value=0;
  }
//ch-
   if (results.value==284149815 && radio_flag==1){
     fm_radio_n--;
     if (fm_radio_n<0) fm_radio_n=fm_radio_max;
     frequency=fm_radio[fm_radio_n];
     fm_write(frequency);
     results.value=0;
  }
//vol+
  if (results.value==284100855 && radio_flag==1){
     if (vol<70) vol=vol+5;//проверка max громкости
     else vol=70;
     analogWrite(vol_pin,vol);
     results.value=0;
  }
//vol-
   if (results.value==284133495 && radio_flag==1){ 
     if (vol>0) vol=vol-5; 
     else vol=0;
     analogWrite(vol_pin,vol);
     results.value=0;
  }
//mute
   if (results.value==284127375 && radio_flag==1){ 
     if (mute==0){
       analogWrite(vol_pin,0); 
       mute=1;
    }
     else{  
       analogWrite(vol_pin,vol); 
       mute=0;
    }
     results.value=0;
   }
   ether.packetLoop(ether.packetReceive());
//обработка нажатия кнопки чтения смс
  if (!digitalRead(swpin)){
     delay (50);
     while (!digitalRead(swpin)) flag=1;
     ether.browseUrl(PSTR("/"), "*****?*****", website, my_callback);
  }
//перезапрос страницы, и запись на сервер 
  if (millis() > timer){
      h_dht11 = dht.readHumidity();//влажност
      t_dht11 = dht.readTemperature();//температура
      timer = millis() + 60000;
      flag=0;
      String ard_get="*****?*****&t_home=";
      ard_get=ard_get+t_dht11+"&rh_home="+h_dht11;   
      char buf[100];
      ard_get.toCharArray(buf, 100);
      ether.browseUrl(PSTR("/"),buf , website, my_callback);
  }
}

 

paf
Offline
Зарегистрирован: 25.01.2013

Ну вот! Ну кто так делает? Взял и .... 

.....всё сделал! Всё! И что теперь с этим делать? Я так долго, так мучительно думал, ну как мне это все делать?! Это же надо столько узнать, изучить... а через год забыть... О-оо! 

А он взял, прискакал на белом...эээ.... голубом вертолете. Все желания выполнил...  

Но вот этот DHCP... Не могу взять в толк почему не статичный IP?  

И ардуино больше ничем кроме этого не занимается? Или все еще впереди? 

:) Спасибо. Искал пример для ИК управления. 

gmv_tft
Offline
Зарегистрирован: 23.02.2013

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

paf
Offline
Зарегистрирован: 25.01.2013

128х64
 

У меня Ардуино UNO стоит контроллером отопления.  Имеется граф. дисплей 128х64. Пара DS18b20 наружняя и домашняя температура воздуха, часы DS1307. Контроллер работает автономно.  Хочу заставить его писать на старую ММСку лог по температуре, пока безуспешно. Комплектная либа не понимает FAT, а ММСку невозможно отформатировать иначе.  

Nikolai54
Offline
Зарегистрирован: 23.06.2013

gmv_tft, Вы когда будите на связи?

gmv_tft
Offline
Зарегистрирован: 23.02.2013

Проект получил небольшое продолжение.

К старым функциям добавилось:

  1. Меню для навигации.
  2. Сигнализация (датчик объема) + GSM телефон .
  3. Возможность заказа через устройство (заказ отсылается на почту).
  4. Прогноз погоды на 8 дней.

Снял ролик работы устройства http://www.youtube.com/watch?v=BIcRCZdWJk4&feature=youtu.be

#include "LiquidCrystal.h"
#include "IRremote.h"
#include "Wire.h"
#include "EtherCard.h"
#include "DHT.h"

LiquidCrystal lcd(31, 30, 28, 26, 24, 22);
byte snow[8] = {//снег
  B00000,
  B10101,
  B01110,
  B11011,
  B01110,
  B10101,
  B00000,
  B00000
};
byte rain[8] = {//дождь
  B00100,
  B01110,
  B11111,
  B11111,
  B01110,
  B00000,
  B00000,
  B00000
};
byte storm[8] = {//гроза
  B00010,
  B00100,
  B01110,
  B00100,
  B01000,
  B00000,
  B00000,
  B00000
};
byte cloudy[8] = {//облачно
  B01010,
  B10101,
  B01010,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};
byte sky[8] = {//ясно
  B00100,
  B10001,
  B00100,
  B01010,
  B00100,
  B10001,
  B00100,
  B00000
};

int RECV_PIN=4;//Пин подключения фотоприемника
int vol_pin=8;//Пин регулировки громкости
int led_pin=5;//пин подключения светодиода
int dht_11=7;// пин подключения датчика температуры и влажности
int alarm_pin=6;//пин подключения датчика объема
int h_dht11, t_dht11;//влажность, температура
boolean alarm=false;
DHT dht(dht_11, DHT11);
IRrecv irrecv(RECV_PIN);
decode_results results;
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[700];
static uint32_t timer; //таймер get запросов
static uint32_t timer1; //таймер обновления
static uint32_t pause=500;//установка паузы
static uint32_t pause1=60000;//пауза таймера
char website[] PROGMEM = "www.*******";
static String line_str="";//переменная контента
static byte  line_flag=0;//флаг режима работы сетевой карты 0 - ожидание запроса 1 - ожидание ответа 2 - ответ получен
char flag_lcd='t';//флаг режима работы lcd ('m'-вывод/работа с меню 't'- вывод времени и погоды 'a' - включена сигнализация)
char line_cmd='n';//команды запросов ('n' - без запроса;...)
String m_n[9]={"Radio","Weather","SMS","Memo","Buy","Signal system","Settings"};//основное меню
String r_n[4]={"Power","Programm","Volume"};//радио меню
String r_v[4]={"off",">>>>","10"};//изначальные значение радио меню
String r_p[11]={"Dorojnoe","100.0","100.4","100.9","101.4","Radio 7","Retro FM","Avto","105.5","107.4"};//радио программы (названия)
String b_n[3]={"Products","Send order"};// меню покупок
String a_m[3]={"Start alarm","Sounder"};//меню сигнализации
String a_n[3]={"Start","on"};//изначальные значения сигнализации
String s_m[4]={"Phone number","Pause updates","Pause"};
String s_n[4]={">>>>","1","500"};
double fm_r[11]={99.6,100.0,100.4,100.9,101.4,101.8,103.0,104.3,105.5,107.4};//радио программы (частоты)
int r_p_i=0;//текущее значение программы (последнее)
String p_cmd="";//обновление продуктов на сервер
String e_now="";//уведомления
String sms="";//текущая смс
String memo="";//текущая напоминание
String history_m_s[10];//история меню
int history_m_i=0;//позиция в истории меню
String st_read_gsm="";//ответ телефона
String tel_gsm="+7*******";//номер хозяина

//функция поступления данных из телефона, запускается каждый цикл loop()
void serialEvent1() 
{
  st_read_gsm="";
  while (Serial1.available() > 0)
  {
    char c=char(Serial1.read());
    st_read_gsm+=c;
  }
}
//функция запуска команды для телефона
void at_cmd_gsm(String cmd_gsm) 
{
   Serial1.println(cmd_gsm); 
   delay (100);
}
//перевод string в int
int stoi(String str){
  int a=0,b=0;
  a=str.length();
  for (int i=0;i<a;i++){
    int c=int(str.charAt(i))-'0';
    b=b+c*(pow(10,(a-1-i)));
  }
  return b;
}
//Вывод на экран значков погодных явлений
static void events(String str, int a){
  if (str.charAt(a)=='1') lcd.write (1);
  else if (str.charAt(a)=='2') lcd.write (2);
  else if (str.charAt(a)=='3') lcd.write (3);
  else if (str.charAt(a)=='4') lcd.write (4);
  else if (str.charAt(a)=='5') lcd.write (5);  
}
//чтение интернет буфера
static void my_callback (byte status, word off, word len) {
  Ethernet::buffer[off+300] = 0;
  line_str=String((const char*) Ethernet::buffer + off);
  Serial.println(line_str);
  int a=0,b=0;
  a=line_str.indexOf('|');
  b=line_str.lastIndexOf('|');
  if (a>0 && b>a){
    a++;
    line_str=line_str.substring(a,b);
    line_flag=2;
  }
}
//Вывод текущей информации на дисплей
void lcd_print(String str="", char cmd='t'){
    lcd.clear();
  if (cmd=='t'){
    int x=0,y=0,a,b;
    y=line_str.indexOf("|",x);
    lcd.setCursor(0,0);
    lcd.print(line_str.substring(x,y));
    y++;
    x=line_str.indexOf("|",y);
    String w=line_str.substring(y,x);
    lcd.setCursor(0,1);
    lcd.print("Orel ");
    a=w.indexOf('*');
    lcd.print(w.substring(0, a));
    a++;
    events(w,a);
    lcd.print(" ");
    w=String(t_dht11)+"C "+String(h_dht11)+"h";
    lcd.print(w);
    lcd.setCursor(0,2);
    x++;
    y=line_str.indexOf("|",x);
    w=line_str.substring(x,y);
    a=w.indexOf('*');
    lcd.print(w.substring(0, a));
    a++;
    events(w,a);
    a+=2;
    b=w.indexOf('*',a);
    lcd.print(w.substring(a, b));
    b++;
    events(w,b);
    lcd.setCursor(0,3);
    y++;
    x=line_str.indexOf("|",y);
    sms=line_str.substring(y,x);
    x++;
    y=line_str.indexOf("|",x);
    memo=line_str.substring(x,y);
    if (flag_lcd=='a' || flag_lcd=='A'){
      lcd.print("Signal system");
    }
    else if (e_now!=""){
      lcd.print(e_now);
      e_now="";
    }
    else if (sms!=""){
      lcd.print("Sms: ");
      lcd.print(sms);
    }
    else if (memo!=""){
      lcd.print("Memo: ");
      lcd.print(memo);
    }
  }
  else if (cmd=='s' || cmd=='m'){
    if (str=="") lcd.print("No messages!");
    else {
      lcd.setCursor(0,0);
      lcd.print(str.substring(0, 20));
      lcd.setCursor(0,1);
      lcd.print(str.substring(20, 40));
      lcd.setCursor(0,2);
      lcd.print(str.substring(40, 60));
      lcd.setCursor(0,3);
      lcd.print(str.substring(60, 80));
      if (cmd=='s') sms="";
      if (cmd=='m') memo="";
    }
  }
}
/*Класс радио*/
class fm_radio{
  public:
    void fm_write(double frequency);
    void fm_off();
    int fm_value(char cmd);
    fm_radio();
    boolean radio_on;//флаг проверки радио
    boolean mute;//mute
  private:
    int vol;//громкость усилителя
    unsigned char frequencyH;
    unsigned char frequencyL;
    unsigned int frequencyB;
    double frequency;
};
fm_radio::fm_radio(){
  analogWrite(vol_pin,0);
  mute=false;
  vol=10;
  radio_on=false;
}
//включение (переключение станций)
void fm_radio::fm_write(double frequency){
     frequencyB=4*(frequency*1000000+225000)/32768;
     frequencyH=frequencyB>>8;
     frequencyL=frequencyB&0XFF;
     delay(100);
     Wire.beginTransmission(0x60);
     Wire.write(frequencyH);
     Wire.write(frequencyL);
     Wire.write(0xBC);
     Wire.write(0x10);
     Wire.write(0x00);
     Wire.endTransmission();
     analogWrite(vol_pin,vol);
     mute=false;
     radio_on=true;
   }
//отключение радио
void fm_radio::fm_off(){
      delay(100);
      Wire.beginTransmission(0x60);   
      Wire.write(frequencyH);
      Wire.write(frequencyL);
      Wire.write(0xBC);
      Wire.write(0x50);
      Wire.write(0x00);
      Wire.endTransmission();
      analogWrite(vol_pin,0);
      radio_on=false;
}
//гроомкость радио '+' '-' регулировка громкости, 'r' чтение значения громкости, 'm' mute
int fm_radio::fm_value(char cmd='r'){
  if (!radio_on || cmd=='r') return vol;
  if (cmd=='+' && vol<70) vol=vol+5;
  if (cmd=='-' && vol>5) vol=vol-5;
  if (cmd=='m') mute=!mute;
  if (!mute) analogWrite(vol_pin,vol);
  else analogWrite(vol_pin,0);
  return vol;
}
/***************************************************/

/*Класс обработки и вывода меню*/
class menu{
  public:
    void print_menu();
    int update_menu(char);
    boolean product(String str);
    boolean weather(String str);
    void set_menu(String m_n[50], String m_v[50],int p=0);
    void set_menu(String m_n[50], char m,int p=0);
    String menu_name[50];// перечень меню
    String menu_value[50];//текстовое значение
    int value[50];//числовые значения
    int value_old[50];//старое числовое значение
    int id[50];//id элемента продукта
    int pos;// позиция в меню
   private:
    char type_menu;//тип меню 'i' -числовой 't' - текстовый 'w' - погода парсинг погодных явлений 
    int pos_max;// максимальная позиция
};
//Обновление меню
int menu::update_menu(char cmd){
if (cmd=='u'&& pos>0) pos--;
if (cmd=='d'&& pos<pos_max) pos++;
if (cmd=='+' && type_menu=='i') value[pos]++;
if (cmd=='-' && value[pos]>0 && type_menu=='i') value[pos]--;
print_menu();
return pos;
}
//вывод на экран
void menu::print_menu(){
lcd.clear();
int k=0;//начальная строка масива при выводе
int str_pos=0;//позиция строки для печати (0...3)
k=(pos/4)*4;
for (int i=k;i<(k+4);i++){
  if (i>pos_max) break;
  if(i==pos){
    lcd.setCursor(0,str_pos);
    lcd.write(126);
  }
  lcd.setCursor(1,str_pos);
  if (type_menu!='w') lcd.print(menu_name[i]);
  else {
    int a,b;
    a=menu_name[i].indexOf('*');
    lcd.print(menu_name[i].substring(0, a));
    a++;
    events(menu_name[i],a);
    a+=2;
    b=menu_name[i].indexOf('*',a);
    lcd.print(menu_name[i].substring(a, b));
    b++;
    events(menu_name[i],b);
  }
  lcd.setCursor(15,str_pos);
  if (type_menu=='t') lcd.print(menu_value[i]); 
  else if (type_menu=='i') lcd.print(value[i]);
  else if (type_menu=='m') lcd.print(">>>>");
  str_pos++;
  }
}
//запись продуктов
boolean menu::product(String str){
  type_menu='i';
  int a=0, b=0;
  String s="";
 while(str.indexOf("*",b)>-1){
    a=str.indexOf("*",b);
    a++;
    b=str.indexOf("~",a);
    s=str.substring(a,b);
    id[pos]=stoi(s);
    b++;
    a=str.indexOf("~",b);
    s=str.substring(b,a);
    menu_name[pos]=s;
    a++;
    b=str.indexOf("*",a);
    if (b<0){
      if (str.indexOf("^")>0){
        b=(str.length())-1;
      } 
      else b=(str.length());
    }
    s=str.substring(a,b);
    value[pos]=stoi(s);
    value_old[pos]=value[pos];
    pos_max=pos;
    pos++;
 }
 if (str.indexOf("^")>0) return false;
 else {
   pos=0;
   return true;
 }
}
//запись погоды в меню
boolean menu::weather(String str){
  type_menu='w';
  int a=0, b=0;
  String s="";
 while(str.indexOf("|",a)>-1){
    b=str.indexOf("|",a);
    s=str.substring(a,b);
    b++;
    a=b;
    pos--;
    menu_name[pos]=s;
    pos++;
    pos_max=pos;
    pos++;
 }
 if (str.indexOf("^")>0) return false;
 else {
   pos=0;
   pos_max--;
   return true;
 }
}
//загрузка меню
void menu::set_menu(String m_n[50], String m_v[50], int p){
  type_menu='t';
  for (int i=0;i<50;i++){//очистка масива
    menu_name[i]="";
    menu_value[i]="";
  }
  pos_max=0;
  for (int i=0;i<50;i++){
    if (m_n[i]==""){
      pos_max=i-1;
      break;
    }
    menu_name[i]=m_n[i];
    menu_value[i]=m_v[i];
 }
 pos=p;
 if (pos>pos_max) pos=0;
 print_menu();
}
//перегрузка метода меню
void menu::set_menu(String m_n[50], char m='m',int p){
  type_menu=m;
  for (int i=0;i<50;i++){//очистка масива
    menu_name[i]="";
  }
  pos_max=0;
  for (int i=0;i<50;i++){
    if (m_n[i]==""){
      pos_max=i-1;
      break;
    }
    menu_name[i]=m_n[i];
 }
 pos=p;
 if (pos>pos_max) pos=0;
 print_menu();
}
/***************************************************/
void setup()
{
  Serial1.begin(9600);
  pinMode(alarm_pin, INPUT); 
  dht.begin();
  pinMode(led_pin, OUTPUT);
  irrecv.enableIRIn();
  Serial.begin(9600);
  lcd.createChar(1, snow);
  lcd.createChar(2, rain);
  lcd.createChar(3, storm);
  lcd.createChar(4, cloudy);
  lcd.createChar(5, sky);
  lcd.begin(20,4);
  Wire.begin();
  if (ether.begin(sizeof Ethernet::buffer, mymac,53) == 0) 
  Serial.println( "Failed to access Ethernet controller");
  if (!ether.dhcpSetup()) Serial.println("DHCP failed");
  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  
  if (!ether.dnsLookup(website)) Serial.println("DNS failed");
  ether.printIp("SRV: ", ether.hisip);
}

menu m;
fm_radio r;

void loop()
{
  if (flag_lcd=='A' && millis() > timer1) flag_lcd='a';//задержка после установки сигнализации с пульта
  if (st_read_gsm!=""){//обработка команд телефона 
     if (st_read_gsm.indexOf("RING")>=0) at_cmd_gsm("AT+CLCC");
     if (flag_lcd=='n') tel_gsm="+7";
     if (st_read_gsm.indexOf(tel_gsm)>=0){
        at_cmd_gsm("AT+CHUP");
        if (flag_lcd=='n') {//Определение номера
         int i=st_read_gsm.indexOf(tel_gsm);
         int k=i+12;
         tel_gsm=st_read_gsm.substring(i,k);
         flag_lcd='t';
         history_m_i=0;
         lcd_print(tel_gsm,'s');
         timer1 = millis() + 30000;               
        }        
        else if (flag_lcd!='a') {//установка сигнализации с телефона
          flag_lcd='a';
          history_m_i=0;
          lcd.clear();
          r.fm_off();
          r_v[0]="off";    
          timer1=0;
        }
        else if (flag_lcd=='a') {//Снятие
          flag_lcd='t';
          history_m_i=0;
          lcd.clear();
          timer1=0;      
        }
     }
     st_read_gsm="";
     delay(300);
   }
  if (digitalRead(alarm_pin) && !alarm) alarm=true;//опрос датчика объема
  if (flag_lcd=='a' && digitalRead(alarm_pin)){//сигнализация сработала
    String at="ATD "+tel_gsm+";";
    at_cmd_gsm(at);
    if (a_n[1]=="on"){
      double a=fm_r[r_p_i];
      r.fm_write(a);
      r_v[0]="on";
    }
      flag_lcd='t';
      history_m_i=0;
      lcd.clear();
      timer1=0;
  }
  if (line_cmd!='n' && line_flag==1 && millis() > (timer+3*pause)){//отслеживание ошибки потери пакетов
    line_cmd='n';
    line_flag=0;
    m.pos=0;
    flag_lcd='t';
    if (e_now=="") e_now="No Internet!";
    lcd_print();
  }
  if (r.radio_on) e_now="Radio. "+ String(r_p[r_p_i]);
  else e_now="";
  if (sms!="" || memo!="" || flag_lcd=='a') digitalWrite(led_pin,HIGH);// индикация уведомления
  else digitalWrite(led_pin,LOW);
  ether.packetLoop(ether.packetReceive());
  if (irrecv.decode(&results)) irrecv.resume();
//обработка обновления из запросов датчиков
  if (millis() > timer1 && line_cmd=='n' && ((flag_lcd=='t')||(flag_lcd=='a'))){
    h_dht11 = dht.readHumidity();//влажност
    t_dht11 = dht.readTemperature();//температура
    line_cmd='d';
    timer1 = millis() + pause1;
  }
//Обработка ответов
  if (line_cmd!='n' && line_flag==2){
    if (line_cmd=='w' || line_cmd=='W'){//запись погоды на 8 дней
     if (m.weather(line_str)){
       m.pos=0;
       history_m_i++;
       history_m_s[history_m_i]="w_v";
       m.print_menu();
       line_cmd='n';
     }
     else line_cmd='W';
    }
    if (line_cmd=='b' || line_cmd=='B'){
     if (m.product(line_str)){
       m.pos=0;
       history_m_i++;
       history_m_s[history_m_i]="m_p";
       m.print_menu();
       line_cmd='n';
     }
     else line_cmd='B';
    }
    if (line_cmd=='d'){
      lcd_print(line_str);
      line_cmd='n';
    }  
    if (line_cmd=='s'){
      lcd_print(line_str,'s');
      line_cmd='n';
    }   
    if (line_cmd=='@'){
      lcd_print(line_str,'s');
      line_cmd='n';
    }         
    if (line_cmd=='m'){
      lcd_print(line_str,'m');
      line_cmd='n';
    }  
    if (line_cmd=='c'){
      line_cmd='n';
    }           
    line_flag=0;
  }
//GET запросы  
  if (line_cmd!='n' && line_flag==0 && millis() > timer){
    timer = millis() + pause;
    String ard_get="?name=arduino&cmd="; 
    char buf[100];
    if (line_cmd=='w'){//запрос прогноза погоды на 8 дней
      for (int i=0;i<50;i++){
        m.menu_name[i]="";
        m.value[i]=0;
        m.value_old[i]=0;
        m.id[i]=0;
      }
        m.pos=1;
        ard_get=ard_get+"weather&weather="+String(m.pos);
    } 
    if (line_cmd=='W'){//запрос прогноза погоды на 8 дней далее
        ard_get=ard_get+"weather&weather="+String(m.pos);
    }   
    if (line_cmd=='d'){//запрос погоды и уведомлений 
      ard_get=ard_get+"smw_get&alarm="+String(alarm)+"&t_dht="+String(t_dht11)+"&h_dht="+String(h_dht11);
      alarm=false;
    }   
     if (line_cmd=='s'){//запрос sms
      ard_get=ard_get+"sms";
    }   
     if (line_cmd=='m'){//запрос memo
      ard_get=ard_get+"memo";
    }   
     if (line_cmd=='b'){//запрос продуктов
      ard_get=ard_get+"p_get";
      for (int i=0;i<50;i++){
        m.menu_name[i]="";
        m.value[i]=0;
        m.value_old[i]=0;
        m.id[i]=0;
      }
      m.pos=0;
    }  
     if (line_cmd=='B'){//запрос продуктов далее
      ard_get=ard_get+"p_get&p_id="+String(m.id[(m.pos-1)]);
    }  
    if (line_cmd=='@'){//запрос email заказа
      ard_get=ard_get+"p_email";
    }   
    if (line_cmd=='c'){//сохроняем корзину
      ard_get=ard_get+"p_set&p_cmd="+p_cmd;
    }      
      Serial.println(ard_get); 
      ard_get.toCharArray(buf, 100);
      line_flag=1;
      ether.browseUrl(PSTR("/"),buf , website, my_callback);
  }
/*ПДУ Power*/
  if (results.value==284111055){
    if (flag_lcd=='m'){
      flag_lcd='t';
      history_m_i=0;
      lcd.clear();
      timer1=0;
    }
    else if (flag_lcd=='a' || flag_lcd=='A' || flag_lcd=='n') {
      flag_lcd='t';
      history_m_i=0;
      lcd.clear();
      timer1=0;      
    }
    else if (flag_lcd=='t'){
      if (!r.radio_on){
        double a=fm_r[r_p_i];
        r.fm_write(a);
        r_v[0]="on";
        e_now="Radio. "+ String(r_p[r_p_i]);
        lcd.setCursor(0,3);
        lcd.print("                   ");
        lcd.setCursor(0,3);
        lcd.print(e_now);
      }
      else if (r.radio_on) {
        r.fm_off();
        r_v[0]="off";    
        e_now="";
        lcd.setCursor(0,3);
        lcd.print("                   ");
        lcd.setCursor(0,3);
        lcd.print(e_now);
        timer1=0;
      }
    }
    results.value=0;
  }
/*ПДУ mute*/
  if (results.value==284127375){
     if (flag_lcd!='m'){
      flag_lcd='m';
      history_m_s[history_m_i]="m_n";
      m.set_menu(m_n);
    }
    else if (flag_lcd=='m'){
     if (history_m_i>0) history_m_i--;
      if (history_m_s[history_m_i]=="m_n") m.set_menu(m_n);
      if (history_m_s[history_m_i]=="r_n") m.set_menu(r_n,r_v);
      if (history_m_s[history_m_i]=="r_p") m.set_menu(r_p);
      if (history_m_s[history_m_i]=="b_n"){
        p_cmd="";
        for (int i=0;i<50;i++){
          if (m.value[i]!=m.value_old[i]){
            if (p_cmd!="") p_cmd=p_cmd+"|";
            p_cmd=p_cmd+String(m.id[i])+"|"+String(m.value[i]);
            if (line_cmd=='n') line_cmd='c';
          }
        }
        m.set_menu(b_n);
      }
     if (history_m_s[history_m_i]=="a_m") m.set_menu(a_m,a_n);       
     if (history_m_s[history_m_i]=="s_m") m.set_menu(s_m,s_n); 
    }
    results.value=0;
  }
/*ПДУ up*/  
   if (results.value==284117175){
     if (flag_lcd=='m') m.update_menu('u');
     else if (flag_lcd=='t' && r.radio_on){
       if (r_p_i<9) r_p_i++;
       double a=fm_r[r_p_i];
       r.fm_write(a);
       e_now="Radio. "+ String(r_p[r_p_i]);
       lcd.setCursor(0,3);
       lcd.print("                   ");
       lcd.setCursor(0,3);
       lcd.print(e_now);
      }
     results.value=0;
  }
/*ПДУ down*/
   if (results.value==284149815){
     if (flag_lcd=='m') m.update_menu('d');
     else if (flag_lcd=='t' && r.radio_on){
       if (r_p_i>0) r_p_i--;
       double a=fm_r[r_p_i];
       r.fm_write(a);
       e_now="Radio. "+ String(r_p[r_p_i]);
       lcd.setCursor(0,3);
       lcd.print("                   ");
       lcd.setCursor(0,3);
       lcd.print(e_now);
      }
     results.value=0;
  }
/*ПДУ +*/
   if (results.value==284100855){
     if (flag_lcd=='m'){
       int pos=m.update_menu('+');
       if (history_m_s[history_m_i]=="m_n"){//подменю основного меню
         if (m_n[pos]=="Radio"){
           history_m_i++;
           history_m_s[history_m_i]="r_n";
           m.set_menu(r_n,r_v);
         }
         else if (m_n[pos]=="Weather"){
           if (line_cmd=='n') line_cmd='w';
         } 
         else if (m_n[pos]=="SMS"){
           if (line_cmd=='n') line_cmd='s';
         }         
         else if (m_n[pos]=="Memo"){
           if (line_cmd=='n') line_cmd='m';
         }
         else if (m_n[pos]=="Buy"){
           history_m_i++;
           history_m_s[history_m_i]="b_n";
           m.set_menu(b_n);
         }  
         else if (m_n[pos]=="Signal system"){
           history_m_i++;
           history_m_s[history_m_i]="a_m";
           m.set_menu(a_m,a_n);
         }
         else if (m_n[pos]=="Settings"){
           history_m_i++;
           history_m_s[history_m_i]="s_m";
           m.set_menu(s_m,s_n);
         }
       }
       else if (history_m_s[history_m_i]=="r_n"){//подменю радио
         if (r_n[pos]=="Programm" && r.radio_on){
           history_m_i++;
           history_m_s[history_m_i]="r_p";
           m.set_menu(r_p);
         }
         if (r_n[pos]=="Power"){
           double a=fm_r[r_p_i];
           r.fm_write(a);
           r_v[pos]="on";
           m.set_menu(r_n,r_v,pos);
         }
         if (r_n[pos]=="Volume" && r.radio_on){
           int volume=r.fm_value('+');
           r_v[pos]=String(volume);
           m.set_menu(r_n,r_v,pos);
         }
       }
       else if (history_m_s[history_m_i]=="r_p"){//подменю программ
          r_p_i=pos;
          double a=fm_r[r_p_i];
          r.fm_write(a);
       }
       else if (history_m_s[history_m_i]=="b_n"){//подменю покупок
         if (b_n[pos]=="Products"){
           if (line_cmd=='n') line_cmd='b';
         }
         if (b_n[pos]=="Send order"){
           if (line_cmd=='n') line_cmd='@'; //отсылаем запрос на отправку email
         }
       }    
       else if (history_m_s[history_m_i]=="a_m"){//подменю сигнализации
         if (a_m[pos]=="Start alarm"){
           flag_lcd='A';
           history_m_i=0;
           lcd_print();
           timer1 = millis() + 30000;  
         }
         if (a_m[pos]=="Sounder"){
           if (a_n[pos]=="off") a_n[pos]="on";
           m.set_menu(a_m,a_n,pos);
         }
       }
       else if (history_m_s[history_m_i]=="s_m"){//подменю настроик
         if (s_m[pos]=="Phone number"){
           flag_lcd='n';
           lcd_print("Call to set the phone number or press the POWER button.",'s');
         }
         if (s_m[pos]=="Pause updates"){
           if (pause1<600000)  pause1=pause1+60000;
           s_n[pos]=String(pause1/60000);
           m.set_menu(s_m,s_n,pos);
         }
         if (s_m[pos]=="Pause"){
           if (pause<3000)  pause=pause+500;
           s_n[pos]=String(pause);
           m.set_menu(s_m,s_n,pos); 
         }
       }
     }
     if (flag_lcd=='t' && r.radio_on){
        int volume=r.fm_value('+');
        r_v[2]=String(volume);
      }
     results.value=0;
  }
/*ПДУ -*/
   if (results.value==284133495){ 
     if (flag_lcd=='m'){
       int pos=m.update_menu('-');
       if (history_m_s[history_m_i]=="r_n"){//подменю радио
         if (r_n[pos]=="Power" && r.radio_on){
           r.fm_off();
           r_v[pos]="off";
           m.set_menu(r_n,r_v,pos);
         }
         if (r_n[pos]=="Volume" && r.radio_on){
           int volume=r.fm_value('-');
           r_v[pos]=String(volume);
           m.set_menu(r_n,r_v,pos);
         }
       }
       else if (history_m_s[history_m_i]=="a_m"){//подменю сигнализации
         if (a_m[pos]=="Sounder"){
           if (a_n[pos]=="on") a_n[pos]="off";
           m.set_menu(a_m,a_n,pos);
         }
       }
       else if (history_m_s[history_m_i]=="s_m"){//подменю настроик
         if (s_m[pos]=="Pause updates"){
           if (pause1>60000)  pause1=pause1-60000;
           s_n[pos]=String(pause1/60000);
           m.set_menu(s_m,s_n,pos);
         }
         if (s_m[pos]=="Pause"){
           if (pause>500)  pause=pause-500;
           s_n[pos]=String(pause);
           m.set_menu(s_m,s_n,pos); 
         }
       }
     }
     if (flag_lcd=='t' && r.radio_on){
        int volume=r.fm_value('-');
        r_v[2]=String(volume);
      }
     results.value=0;
  }
}

 

xpokc
Offline
Зарегистрирован: 16.12.2012

Здравствуйте! не могли бы вы мне помочь, у меня проблема, с часами ds1307 и экраном  st 7920  я ни как не могу понять ка написать код часов чтобы они отображались корректно  на данном экране и как сделать меню настройки для этих часов заранее спасибо!