Парсинг XML. Прогноз погоды

vitalikost
Offline
Зарегистрирован: 28.11.2014

Добрый день! Решил сделать метеостанцию с прогнозом погоды. 

Для получения данных был выбран сайт http://www.eurometeo.ru/. На данном сайте есть мой город, а также самое главное бесплатный экспорт в XML.

Для реализации у меня есть Arduino Mega и enc28j60.

 

Для реализации была выбрана библиотека: https://github.com/ntruchsess/arduino_uip

Данный пример отлично работает с штатной библиотекой и модулем W5100, для использования заменить строку в коде: #include <UIPEthernet.h> на #include <Ethernet.h>.

Данные кроме ком порта решил визуализировать на LCD1602(что было по рукой).

Результат творчества. 

#include <SPI.h>
#include <UIPEthernet.h>
//#include <string.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.eurometeo.ru";   
//IPAddress ip(192, 168, 0, 2);
EthernetClient client;
String HTTP_req;
long previousMillis_1,previousMillis;//переменная для хранения значений таймера
boolean stopclient=true;
#include <LiquidCrystal.h>  // Лобавляем необходимую библиотеку
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7)
int str=0;//

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);
  // Дадим время шилду на инициализацию
  delay(1000);
  Serial.print("Free Ram - ");
  Serial.println( freeRam ());
  Serial.println("connecting...");
  
  for(byte a=1;a<10;a++ ){
        if (client.connect(server, 80)) {
          Serial.println("---------------");
          // Создаем HTTP-запрос
          client.println("GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1");
          client.println("Host: www.eurometeo.ru");
          client.println("User-Agent: arduino-ethernet");
          client.println("Connection: close");
          client.println();
          break;
        } 
        else {
          // if you didn't get a connection to the server:
          Serial.println("connection failed");
          delay(5000);
        }
  }

  pinMode(13,OUTPUT);//инициализация портов  
 
  lcd.begin(16, 2);                  // Задаем размерность экрана
  lcd.clear();    
  previousMillis_1=0;  previousMillis=0;
}
void loop() {
  // Если есть доступные биты, читаем их и выводим на экран
    if (client.available()) {
        Serial.println("Loading....."); 
        lcd.setCursor(0, 0);
        lcd.print("Loading.....");       // Выводим текст
        while (client.available()) {
           char c = client.read(); // read 1 byte (character) from client
          HTTP_req += c;  // save the HTTP request 1 char at a time              
        //  Serial.print(c); 
         delay(1);   
        }
       lcd.setCursor(0, 1); 
       Serial.println("End Loading....."); 
       lcd.print("End Loading.....");       // Выводим текст
    }  

    if (HTTP_req.indexOf("</weather>") > 0){//Точно получили все данные
        if(stopclient){  //остановливаем клиент  
            if (!client.connected()) {
              Serial.println();
              Serial.println("---------------");
              Serial.println("disconnecting");
              client.stop();
             }
        Serial.println("=============================="); 
        Serial.print("Free Ram - ");
        Serial.println( freeRam ());
        Serial.println("=============================="); 
        //delay(5000);
        stopclient=false;//
        
      }            

          if (millis() - previousMillis_1 >2000) //меняем по кругу
         {  
           previousMillis_1 = millis();  //запучкаем таймер
 
          if(HTTP_req.indexOf("<datetime>",str) > 0)
          {
             lcd.clear();                  // 
             int a,new_str;
             a =HTTP_req.indexOf("<datetime>",str);
             Serial.print(HTTP_req.substring(a+10, a+29)+", t = ");  
             lcd.setCursor(0, 0);              // Устанавливаем курсор в начало 1 строки
             lcd.print(HTTP_req.substring(a+10, a+29));       // Выводим текст
             new_str=a+29;
             a = HTTP_req.indexOf("<temperature>",a+29);
             Serial.print(HTTP_req.substring(a+13, a+18));  
             lcd.setCursor(0, 1);              // Устанавливаем курсор в начало 2 строки
             lcd.print("T ="+HTTP_req.substring(a+13, a+18));    
             Serial.print(", h = ");  
             a = HTTP_req.indexOf("<humidity>",a+18);
             Serial.println(HTTP_req.substring(a+10, a+12));  
             lcd.print(" H ="+HTTP_req.substring(a+10, a+12));    
             str =new_str;
          }else{str=0;}//if
     }//if
    }//if
//Проверка, не зависла ли ардуино?


  if (millis() - previousMillis >500) 
 {  
   previousMillis = millis();  //запучкаем таймер
   digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
 }
  
}


int freeRam () {
 extern int __heap_start, *__brkval;  int v;  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

 

Araris
Offline
Зарегистрирован: 09.11.2012

vitalikost пишет:

Для получения данных был выбран сайт http://www.eurometeo.ru/. На данном сайте есть мой город, а также самое главное бесплатный экспорт в XML.

Ай спасибо !

vitalikost
Offline
Зарегистрирован: 28.11.2014

Вот резултат роботы, жрет дофига озу. Может как-то оптимизировать? 

Araris
Offline
Зарегистрирован: 09.11.2012

 Сейчас скетч построен так, что сначала весь ответ сайта полностью принимается в String HTTP_req;, а потом парсится и выводится на экран.

 Оптимизировать можно, если парсить прямо в процессе приёма, тогда размеры HTTP_req (и объём памяти, ей занимаемый) можно будет значительно сократить.

 В идеале стоило бы отказаться от использования String в пользу char-массивов.

vitalikost
Offline
Зарегистрирован: 28.11.2014

Что финня, постоянно в ребут уходит: упростил код:

#include <SPI.h>
#include <UIPEthernet.h>
#include <string.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.eurometeo.ru";   
//IPAddress ip(192, 168, 0, 2);
EthernetClient client;

char HTTP_req[]= "";
int req_index = 0; // index into HTTP_req buffer

long previousMillis_1,previousMillis;//переменная для хранения значений таймера
boolean stopclient=true;
int str=0;//

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);
  // Дадим время шилду на инициализацию
  delay(1000);
  Serial.print("Free Ram - ");
  Serial.println( freeRam ());
  Serial.println("connecting...");

  for(byte a=1;a<10;a++ ){
    if (client.connect(server, 80)) {
      Serial.println("---------------");
      // Создаем HTTP-запрос
      client.println("GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1");
      client.println("Host: www.eurometeo.ru");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println();
      break;
    } 
    else {
      // if you didn't get a connection to the server:
      Serial.println("connection failed");
      delay(5000);
    }
  }

}
void loop() {
  // Если есть доступные биты, читаем их и выводим на экран
  if (client.available()) {
    char c = client.read(); // read 1 byte (character) from client
    HTTP_req[req_index] = c; // save HTTP request character
    req_index++;
    Serial.print(c); 
    delay(1);   
  }  


  if (millis() - previousMillis >500) 
  {  
    previousMillis = millis();  //запучкаем таймер
    digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
  }

}


int freeRam () {
  extern int __heap_start, *__brkval;  
  int v;  
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Результат роботы:

Free Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
connection failed
---------------
HTTP/1.1 200 OK
ServerFree Ram - 6207
connecting...
---------------
HTTP/1.1 200 OK
Server

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Разобрался, надо размер буфера указать char HTTP_req[4230]= "";

Это размер пакета данных, буду дробить на 500, и анализировать, посмотрим что с этого получится. 

vitalikost
Offline
Зарегистрирован: 28.11.2014

char-массивов пока еще не разобрался, точнее, блоками выводить получилось, а вот с поиском в массиве не очень. Решил оптимизировать тока роботу со строками.  Убрав все лишнее, вывод только в консоль:

#include <SD.h>
#include <SPI.h>
#include <UIPEthernet.h>
//#include <string.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.eurometeo.ru";   
//IPAddress ip(192, 168, 0, 2);
EthernetClient client;
String HTTP_req;
long previousMillis;//переменная для хранения значений таймера
boolean stopclient=true;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);
  // Дадим время шилду на инициализацию
  delay(1000);
  Serial.print("Free Ram - ");
  Serial.println( freeRam ());
  Serial.println("connecting...");

  for(byte a=1;a<10;a++ ){
    if (client.connect(server, 80)) {
      Serial.println("---------------");
      // Создаем HTTP-запрос
      client.println("GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1");
      client.println("Host: www.eurometeo.ru");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println();
      break;
    } 
    else {
      // if you didn't get a connection to the server:
      Serial.println("connection failed");
      delay(5000);
    }
  }

  pinMode(13,OUTPUT);//инициализация портов  

  previousMillis=0;
}

void loop() {
  // Если есть доступные биты, читаем их и выводим на экран
  if (client.available()) {
    Serial.println("Loading....."); 
    while (client.available()) {
      char c = client.read(); // read 1 byte (character) from client
      HTTP_req += c;  // save the HTTP request 1 char at a time              
      //     Serial.print(c); 
      

      
     if (HTTP_req.indexOf("</step>") > 0){
             int a;
             a =HTTP_req.indexOf("<datetime>");
             Serial.print(HTTP_req.substring(a+10, a+29)+", t = ");  
             a = HTTP_req.indexOf("<temperature>",a+29);
             Serial.print(HTTP_req.substring(a+13, a+18));  
             Serial.print(", h = ");  
             a = HTTP_req.indexOf("<humidity>",a+18);
             Serial.println(HTTP_req.substring(a+10, a+12));  
     
       HTTP_req=""; 
      }
      
      delay(1);   
    }
  

  if (HTTP_req.indexOf("</weather>") > 0){//Точно получили все данные
  
    Serial.println("End Loading....."); 

    if(stopclient){  //остановливаем клиент  
      if (!client.connected()) {
        Serial.println();
        Serial.println("---------------");
        Serial.println("disconnecting");
        client.stop();
      }
      Serial.println("=============================="); 
      Serial.print("Free Ram - ");
      Serial.println( freeRam ());
      Serial.println("=============================="); 
      //delay(5000);
      stopclient=false;//
    }//if
  }//if



}  
  

  //Проверка, не зависла ли ардуино?

  if (millis() - previousMillis >500) 
  {  
    previousMillis = millis();  //запучкаем таймер
    digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
  }


}


int freeRam () {
  extern int __heap_start, *__brkval;  
  int v;  
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}



Резултат роботы:

Free Ram - 5429
connecting...
---------------
Loading.....
2016-08-25 05:00:00, t = 17.40, h = 47
2016-08-25 11:00:00, t = 22.55, h = 36
2016-08-25 17:00:00, t = 23.17, h = 29
2016-08-25 23:00:00, t = 18.96, h = 26
2016-08-26 05:00:00, t = 16.55, h = 24
2016-08-26 11:00:00, t = 23.04, h = 18
2016-08-26 17:00:00, t = 24.15, h = 20
2016-08-26 23:00:00, t = 18.67, h = 23
2016-08-27 05:00:00, t = 16.34, h = 32
2016-08-27 11:00:00, t = 24.60, h = 34
2016-08-27 17:00:00, t = 26.56, h = 32
2016-08-27 23:00:00, t = 20.84, h = 33
End Loading.....

---------------
disconnecting
==============================
Free Ram - 4097
==============================

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Следал хранение данных в структуре:

struct meteo 
{
  String Date_time;
  float t;
  int h;
} 
add_meteo[12];

Также подробно описана структура файла для парсинга:

Пока проект заканчиваю, возможно попозже добавлю визуализацию данных(1602 маловат для этого):

#include <SD.h>
#include <SPI.h>
#include <UIPEthernet.h>
//#include <string.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.eurometeo.ru";   
//IPAddress ip(192, 168, 0, 2);
EthernetClient client;
String HTTP_req;
long previousMillis;//переменная для хранения значений таймера
boolean stopclient=true;
//Структура, где будем хранитиь данные о погоде
//Параметром можно и по больше, незабываем память не резиновая.
struct meteo 
{
  String Date_time;
  float t;
  int h;
} 
add_meteo[12];

byte index=0;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);
  // Дадим время шилду на инициализацию
  delay(1000);
  Serial.print("Free Ram - ");
  Serial.println( freeRam ());
  Serial.println("connecting...");

  for(byte a=1;a<10;a++ ){
    if (client.connect(server, 80)) {
      Serial.println("---------------");
      // Создаем HTTP-запрос
      //Сдесь данные свого города:
      client.println("GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1");
      client.println("Host: www.eurometeo.ru");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println();
      break;
    } 
    else {
      // if you didn't get a connection to the server:
      Serial.println("connection failed");
      delay(5000);
    }
  }

  pinMode(13,OUTPUT);//инициализация портов  
  previousMillis=0;
}

void loop() {
  // Если есть доступные биты, читаем их и выводим на экран
  if (client.available()) {
    Serial.println("Loading....."); 
   
    while (client.available()) {
      char c = client.read(); // read 1 byte (character) from client
      HTTP_req += c;  // save the HTTP request 1 char at a time              
  //         Serial.print(c); 

      if (HTTP_req.indexOf("</step>") > 0){//12 блоков начало <step> конец </step>
      
/*
		<step>
			<datetime>2016-08-08 05:00:00</datetime>
			<pressure>754.24</pressure> 
			<temperature>17.43</temperature>
			<humidity>28</humidity>
			<cloudcover>0</cloudcover> 
			<windspeed>5.30</windspeed>
			<windgust>9.78</windgust>
			<winddir>258</winddir>
			<precipitation>0.00</precipitation>
		</step>

<step>	Шаг прогноза, содержит в себе данные на определенное время
<datetime>	Время прогноза погоды
<pressure>	Атмосферное давление в мм рт.столба
<temperature>	Температура воздуха в °C
<humidity>	Относительная влажность
<cloudcover>	Облачность в % (100% облака без просветов, 0% - чистое небо)
<windspeed>	Скорость ветра в м/с
<windgust>	Скорость порывов ветра в м/с
<winddir>	Направление ветра в градусах от 0 до 359. 0 - южный ветер, ветер дует по направлению с юга, 90 - ветер с запада, 180 - ветер с севера, 270 - ветер с востока
<precipitation>	Осадки в мм за 3 часов



*/

        //Беру только 2 параметра: темепературу и влажность. 
        int a;
        a =HTTP_req.indexOf("<datetime>");
        Serial.print(HTTP_req.substring(a+10, a+29)+", temperature = ");  
        add_meteo[index].Date_time = HTTP_req.substring(a+10, a+29);

        a = HTTP_req.indexOf("<temperature>",a+29);
        Serial.print(HTTP_req.substring(a+13, a+18)); 
        char floatbufVar[32];
        String stringVar = HTTP_req.substring(a+13, a+18);
        stringVar.toCharArray(floatbufVar,sizeof(floatbufVar));
        add_meteo[index].t=atof(floatbufVar);


        Serial.print(", humidity = ");  
        a = HTTP_req.indexOf("<humidity>",a+18);
        Serial.println(HTTP_req.substring(a+10, a+12));  
        add_meteo[index].h=HTTP_req.substring(a+10, a+12).toInt();

        //Ощищаем для экономии озу.
        HTTP_req=""; 
        index++;
      }

      delay(1);   
    }


    if (HTTP_req.indexOf("</weather>") > 0){//Точно получили все данные

      Serial.println("End Loading....."); 

      if(stopclient){  //остановливаем клиент  
        if (!client.connected()) {
          Serial.println();
          Serial.println("---------------");
          Serial.println("disconnecting");
          client.stop();
        }
        Serial.println("=============================="); 
        Serial.print("Free Ram - ");
        Serial.println( freeRam ());
        Serial.println("=============================="); 
        //delay(5000);
        stopclient=false;//
        HTTP_req="";
        //проверка Массива, потом можно будет убрать
        for(index=0;index<12;index++)
        {
          Serial.print(add_meteo[index].Date_time +", t = " );  
          Serial.print(add_meteo[index].t);  
          Serial.print(", h = ");  
          Serial.println(add_meteo[index].h);  
        }
      Serial.println("=============================="); 
      index=0;
      }//if
    }//if



  }  


  //Проверка, не зависла ли ардуино?
  //Крутю по кругу массив
  if (millis() - previousMillis >500) 
  {  
    previousMillis = millis();  //запучкаем таймер
    digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
    
   if(stopclient==false){  //Крутим если скачали полный файл, иногда качает частями
    
    Serial.print(add_meteo[index].Date_time+", t = " );  
    Serial.print(add_meteo[index].t);  
    Serial.print(", h = ");  
    Serial.println(add_meteo[index].h);  
 
    
    index++;
    //Обнуляем счетчик
    if(index==12){ index=0;}
   }
    
  }//if


}//loop


int freeRam () {
  extern int __heap_start, *__brkval;  
  int v;  
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}




Результат:

 

Free Ram - 5178
connecting...
---------------
Loading.....
2016-08-25 05:00:00, temperature = 17.40, humidity = 47
2016-08-25 11:00:00, temperature = 22.55, humidity = 36
2016-08-25 17:00:00, temperature = 23.17, humidity = 29
2016-08-25 23:00:00, temperature = 18.96, humidity = 26
2016-08-26 05:00:00, temperature = 16.55, humidity = 24
2016-08-26 11:00:00, temperature = 23.12, humidity = 16
2016-08-26 17:00:00, temperature = 24.25, humidity = 19
2016-08-26 23:00:00, temperature = 18.74, humidity = 23
2016-08-27 05:00:00, temperature = 16.34, humidity = 32
2016-08-27 11:00:00, temperature = 24.60, humidity = 34
2016-08-27 17:00:00, temperature = 26.56, humidity = 32
2016-08-27 23:00:00, temperature = 20.84, humidity = 33
End Loading.....

---------------
disconnecting
==============================
Free Ram - 3533
==============================
2016-08-25 05:00:00, t = 17.40, h = 47
2016-08-25 11:00:00, t = 22.55, h = 36
2016-08-25 17:00:00, t = 23.17, h = 29
2016-08-25 23:00:00, t = 18.96, h = 26
2016-08-26 05:00:00, t = 16.55, h = 24
2016-08-26 11:00:00, t = 23.12, h = 16
2016-08-26 17:00:00, t = 24.25, h = 19
2016-08-26 23:00:00, t = 18.74, h = 23
2016-08-27 05:00:00, t = 16.34, h = 32
2016-08-27 11:00:00, t = 24.60, h = 34
2016-08-27 17:00:00, t = 26.56, h = 32
2016-08-27 23:00:00, t = 20.84, h = 33
==============================
2016-08-25 05:00:00, t = 17.40, h = 47
2016-08-25 11:00:00, t = 22.55, h = 36
2016-08-25 17:00:00, t = 23.17, h = 29
2016-08-25 23:00:00, t = 18.96, h = 26
2016-08-26 05:00:00, t = 16.55, h = 24
2016-08-26 11:00:00, t = 23.12, h = 16
2016-08-26 17:00:00, t = 24.25, h = 19
2016-08-26 23:00:00, t = 18.74, h = 23
2016-08-27 05:00:00, t = 16.34, h = 32
2016-08-27 11:00:00, t = 24.60, h = 34
2016-08-27 17:00:00, t = 26.56, h = 32
2016-08-27 23:00:00, t = 20.84, h = 33
2016-08-25 05:00:00, t = 17.40, h = 47
2016-08-25 11:00:00, t = 22.55, h = 36
2016-08-25 17:00:00, t = 23.17, h = 29
2016-08-25 23:00:00, t = 18.96, h = 26
2016-08-26 05:00:00, t = 16.55, h = 24
2016-08-26 11:00:00, t = 23.12, h = 16
2016-08-26 17:00:00, t = 24.25, h = 19
2016-08-26 23:00:00, t = 18.74, h = 23
2016-08-27 05:00:00, t = 16.34, h = 32
2016-08-27 11:00:00, t = 24.60, h = 34
2016-08-27 17:00:00, t = 26.56, h = 32
2016-08-27 23:00:00, t = 20.84, h = 33

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Итак идем дальше, есть 2.4 tft lcd shield 0x9325, и библиотека MCUFRIEND_kbv. Проверил данный shield на Меге и Уно. Работает без проблем, и без правки библиотек. СД карта на Меге не завелась, так как не соответствуют пины, ну мне пока и не нужно. Пока только визуализировано температуру, в дальнейшем задействую тач, и возможность строить гистограмму не только по температуре, а также и по другим параметрам (влажность, давление, осадки, скорость ветра, облачность). 

Видео : https://yadi.sk/i/HZXLU4QCurniS

#include <SD.h>
#include <SPI.h>
#include <UIPEthernet.h>
//#include <string.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.eurometeo.ru";   
//IPAddress ip(192, 168, 0, 2);
EthernetClient client;
String HTTP_req;
long previousMillis;//переменная для хранения значений таймера
boolean stopclient=true;
//Структура, где будем хранитиь данные о погоде
//Параметром можно и по больше, незабываем память не резиновая.
struct meteo 
{
  String Date_time;
  float t;
  int h;
} 
add_meteo[12];
//Блок роботы с TFT
#include <Adafruit_GFX.h> // Hardware-specific library
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


byte index=0;

void setup() {
 // Serial.begin(9600);
  Ethernet.begin(mac);
  // Дадим время шилду на инициализацию
  delay(1000);
  
    tft.reset();
    uint16_t id = tft.readID();
    tft.begin(id);
    tft.setRotation(1);     
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE, BLACK);
    tft.setTextSize(2);     // System font is 8 pixels.  ht = 8*2=16
  
  
  tft.print("Free Ram - ");
  tft.println( freeRam ());
  tft.println("connecting...");

  for(byte a=1;a<10;a++ ){
    if (client.connect(server, 80)) {
 //     Serial.println("---------------");
      // Создаем HTTP-запрос
      //Сдесь данные свого города:
      client.println("GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1");
      client.println("Host: www.eurometeo.ru");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println();
      break;
    } 
    else {
      // if you didn't get a connection to the server:
      tft.println("connection failed");
      delay(5000);
    }
  }

  pinMode(13,OUTPUT);//инициализация портов  
  previousMillis=0;
}

void loop() {
  // Если есть доступные биты, читаем их и выводим на экран
  if (client.available()) {
    tft.println("Loading....."); 
   
    while (client.available()) {
      char c = client.read(); // read 1 byte (character) from client
      HTTP_req += c;  // save the HTTP request 1 char at a time              
  //         Serial.print(c); 

      if (HTTP_req.indexOf("</step>") > 0){//12 блоков начало <step> конец </step>
      
/*
		<step>
			<datetime>2016-08-08 05:00:00</datetime>
			<pressure>754.24</pressure> 
			<temperature>17.43</temperature>
			<humidity>28</humidity>
			<cloudcover>0</cloudcover> 
			<windspeed>5.30</windspeed>
			<windgust>9.78</windgust>
			<winddir>258</winddir>
			<precipitation>0.00</precipitation>
		</step>

<step>	Шаг прогноза, содержит в себе данные на определенное время
<datetime>	Время прогноза погоды
<pressure>	Атмосферное давление в мм рт.столба
<temperature>	Температура воздуха в °C
<humidity>	Относительная влажность
<cloudcover>	Облачность в % (100% облака без просветов, 0% - чистое небо)
<windspeed>	Скорость ветра в м/с
<windgust>	Скорость порывов ветра в м/с
<winddir>	Направление ветра в градусах от 0 до 359. 0 - южный ветер, ветер дует по направлению с юга, 90 - ветер с запада, 180 - ветер с севера, 270 - ветер с востока
<precipitation>	Осадки в мм за 3 часов



*/

        //Беру только 2 параметра: темепературу и влажность. 
        int a;
        a =HTTP_req.indexOf("<datetime>");
     //   Serial.print(HTTP_req.substring(a+10, a+29)+", temperature = ");  
        add_meteo[index].Date_time = HTTP_req.substring(a+10, a+29);

        a = HTTP_req.indexOf("<temperature>",a+29);
   //     Serial.print(HTTP_req.substring(a+13, a+18)); 
        char floatbufVar[32];
        String stringVar = HTTP_req.substring(a+13, a+18);
        stringVar.toCharArray(floatbufVar,sizeof(floatbufVar));
        add_meteo[index].t=atof(floatbufVar);


  //      Serial.print(", humidity = ");  
        a = HTTP_req.indexOf("<humidity>",a+18);
  //      Serial.println(HTTP_req.substring(a+10, a+12));  
        add_meteo[index].h=HTTP_req.substring(a+10, a+12).toInt();

        //Ощищаем для экономии озу.
        HTTP_req=""; 
        index++;
      }

      delay(1);   
    }


    if (HTTP_req.indexOf("</weather>") > 0){//Точно получили все данные

      tft.println("End Loading....."); 

      if(stopclient){  //остановливаем клиент  
        if (!client.connected()) {
     //     Serial.println();
    //      Serial.println("---------------");
          tft.println("disconnecting");
          client.stop();
        }
      //  Serial.println("=============================="); 
        tft.print("Free Ram - ");
        tft.println( freeRam ());
      //  Serial.println("=============================="); 
        //delay(5000);
        stopclient=false;//
        HTTP_req="";
        delay(2000); 
        //проверка Массива, потом можно будет убрать
        tft.fillScreen(BLACK);
        tft.setCursor(0, 0);
        tft.setTextSize(2);
        for(index=0;index<12;index++)
        {
          tft.print(add_meteo[index].Date_time.substring(2,16) +"t=" );  
          tft.print(add_meteo[index].t);  
          tft.print(",h=");  
          tft.print(add_meteo[index].h);  
        }
        
        delay(2000); 
        
        //Grid
        tft.fillScreen(BLACK);
        int line;
        tft.drawFastVLine(0, 0, 100, GREEN);
        for (line = 0; line < 13; line++) tft.drawFastVLine(25*line, 0, 100, GREEN);
        ;
        tft.drawFastVLine(319, 0, 100, GREEN);
      
        tft.drawFastHLine(0, 100, 320, GREEN);
        for (line = 0; line < 11; line++) tft.drawFastHLine(0, 10*line, 320, GREEN);
        ;
        //end Grid
        //min,max
        float min_t,max_t;

        min_t=100; max_t=-100;
        for (line = 0; line < 12; line++)
        {
          if(min_t>add_meteo[line].t) min_t=add_meteo[line].t;
          if(max_t<add_meteo[line].t) max_t=add_meteo[line].t;
        }
        //end min,max
        
        
        tft.setTextSize(1); 
        tft.setTextColor(WHITE,BLACK);
        //tft.setCursor(0, 120);
        //tft.println(min_t);
        //tft.println(max_t);
        //Добавим 10% для красивой сетки
        min_t=min_t-min_t*0.2;
        max_t=max_t+max_t*0.1;
        
        for (line = 0; line < 12; line++)
        {
        //  tft.drawLine(13+25*line, 100,13+25*line,100-map(add_meteo[line].t,min_t,max_t,0,100), RED);
          tft.fillRect(13+25*line, 100,5,-map(add_meteo[line].t,min_t,max_t,0,100), RED);
          tft.setCursor(13+25*line, 100-map(add_meteo[line].t,min_t,max_t,0,100));
          tft.print(add_meteo[line].t);
        }  
        
        tft.setCursor(0, 120);
        tft.setTextSize(1);
        for(index=0;index<12;index++)
        {
          tft.print(add_meteo[index].Date_time +", t = " );  
          tft.print(add_meteo[index].t);  
          tft.print(" , h = ");  
          tft.println(add_meteo[index].h);  
        }
        
    //  Serial.println("=============================="); 
      index=0;
      }//if
    }//if



  }  


  //Проверка, не зависла ли ардуино?
  if (millis() - previousMillis >500) 
  {  
    previousMillis = millis();  //запучкаем таймер
    digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
  }//if


}//loop


int freeRam () {
  extern int __heap_start, *__brkval;  
  int v;  
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}




 

misha_1006
Offline
Зарегистрирован: 27.06.2020

почему у меня ошибка в    client.println("Host: <a href="http://www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>)

 

unable to find string literal operator 'operator""http' with 'const char [15]', 'unsigned int' arguments

помогите если можете

 

misha_1006
Offline
Зарегистрирован: 27.06.2020

почему у меня ошибка в    client.println("Host: <a href="http://www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>)

 

unable to find string literal operator 'operator""http' with 'const char [15]', 'unsigned int' arguments

помогите если можете

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

Кавычки внутри кавычек необходимо экранировать символом \

vitalikost
Offline
Зарегистрирован: 28.11.2014
 client.println("Host: <a href="http://www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>);

заменить "client.println("Host: www.eurometeo.ru");"

vitalikost
Offline
Зарегистрирован: 28.11.2014

тут можно найти свой город. 

https://eurometeo.ru/ukraina/cherkaska-oblast/cherkasi/export/

Мой город уже в статистику не попадает, а свой проверяйте.

добавлено: По ходу сайт уже давно статистику не обновляет по всем городам