Парсинг XML. Прогноз погоды
- Войдите на сайт для отправки комментариев
Пт, 19/08/2016 - 10:27
Добрый день! Решил сделать метеостанцию с прогнозом погоды.
Для получения данных был выбран сайт http://www.eurometeo.ru/. На данном сайте есть мой город, а также самое главное бесплатный экспорт в XML.
Для реализации у меня есть Arduino Mega и enc28j60.
Для реализации была выбрана библиотека: https://github.com/ntruchsess/arduino_uip
Данный пример отлично работает с штатной библиотекой и модулем W5100, для использования заменить строку в коде: #include <UIPEthernet.h> на #include <Ethernet.h>.
Данные кроме ком порта решил визуализировать на LCD1602(что было по рукой).
Результат творчества.
001 | #include <SPI.h> |
002 | #include <UIPEthernet.h> |
003 | //#include <string.h> |
004 | byte mac[] = { |
005 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; |
006 | char server[] = "www.eurometeo.ru" ; |
007 | //IPAddress ip(192, 168, 0, 2); |
008 | EthernetClient client; |
009 | String HTTP_req; |
010 | long previousMillis_1,previousMillis; //переменная для хранения значений таймера |
011 | boolean stopclient= true ; |
012 | #include <LiquidCrystal.h> // Лобавляем необходимую библиотеку |
013 | LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7) |
014 | int str=0; // |
015 |
016 | void setup () { |
017 | Serial .begin(9600); |
018 | Ethernet.begin(mac); |
019 | // Дадим время шилду на инициализацию |
020 | delay(1000); |
021 | Serial .print( "Free Ram - " ); |
022 | Serial .println( freeRam ()); |
023 | Serial .println( "connecting..." ); |
024 | |
025 | for ( byte a=1;a<10;a++ ){ |
026 | if (client.connect(server, 80)) { |
027 | Serial .println( "---------------" ); |
028 | // Создаем HTTP-запрос |
029 | client.println( "GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1" ); |
030 | client.println( "Host: <a href=" http: //www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>); |
031 | client.println( "User-Agent: arduino-ethernet" ); |
032 | client.println( "Connection: close" ); |
033 | client.println(); |
034 | break ; |
035 | } |
036 | else { |
037 | // if you didn't get a connection to the server: |
038 | Serial .println( "connection failed" ); |
039 | delay(5000); |
040 | } |
041 | } |
042 |
043 | pinMode(13,OUTPUT); //инициализация портов |
044 | |
045 | lcd.begin(16, 2); // Задаем размерность экрана |
046 | lcd.clear(); |
047 | previousMillis_1=0; previousMillis=0; |
048 | } |
049 | void loop () { |
050 | // Если есть доступные биты, читаем их и выводим на экран |
051 | if (client.available()) { |
052 | Serial .println( "Loading....." ); |
053 | lcd.setCursor(0, 0); |
054 | lcd.print( "Loading....." ); // Выводим текст |
055 | while (client.available()) { |
056 | char c = client.read(); // read 1 byte (character) from client |
057 | HTTP_req += c; // save the HTTP request 1 char at a time |
058 | // Serial.print(c); |
059 | delay(1); |
060 | } |
061 | lcd.setCursor(0, 1); |
062 | Serial .println( "End Loading....." ); |
063 | lcd.print( "End Loading....." ); // Выводим текст |
064 | } |
065 |
066 | if (HTTP_req.indexOf( "</weather>" ) > 0){ //Точно получили все данные |
067 | if (stopclient){ //остановливаем клиент |
068 | if (!client.connected()) { |
069 | Serial .println(); |
070 | Serial .println( "---------------" ); |
071 | Serial .println( "disconnecting" ); |
072 | client.stop(); |
073 | } |
074 | Serial .println( "==============================" ); |
075 | Serial .print( "Free Ram - " ); |
076 | Serial .println( freeRam ()); |
077 | Serial .println( "==============================" ); |
078 | //delay(5000); |
079 | stopclient= false ; // |
080 | |
081 | } |
082 |
083 | if (millis() - previousMillis_1 >2000) //меняем по кругу |
084 | { |
085 | previousMillis_1 = millis(); //запучкаем таймер |
086 | |
087 | if (HTTP_req.indexOf( "<datetime>" ,str) > 0) |
088 | { |
089 | lcd.clear(); // |
090 | int a,new_str; |
091 | a =HTTP_req.indexOf( "<datetime>" ,str); |
092 | Serial .print(HTTP_req.substring(a+10, a+29)+ ", t = " ); |
093 | lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки |
094 | lcd.print(HTTP_req.substring(a+10, a+29)); // Выводим текст |
095 | new_str=a+29; |
096 | a = HTTP_req.indexOf( "<temperature>" ,a+29); |
097 | Serial .print(HTTP_req.substring(a+13, a+18)); |
098 | lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки |
099 | lcd.print( "T =" +HTTP_req.substring(a+13, a+18)); |
100 | Serial .print( ", h = " ); |
101 | a = HTTP_req.indexOf( "<humidity>" ,a+18); |
102 | Serial .println(HTTP_req.substring(a+10, a+12)); |
103 | lcd.print( " H =" +HTTP_req.substring(a+10, a+12)); |
104 | str =new_str; |
105 | } else {str=0;} //if |
106 | } //if |
107 | } //if |
108 | //Проверка, не зависла ли ардуино? |
109 |
110 |
111 | if (millis() - previousMillis >500) |
112 | { |
113 | previousMillis = millis(); //запучкаем таймер |
114 | digitalWrite(13, !digitalRead(13)); //меняем значение порта каждые 0.5секунд |
115 | } |
116 | |
117 | } |
118 |
119 |
120 | int freeRam () { |
121 | extern int __heap_start, *__brkval; int v; return ( int ) &v - (__brkval == 0 ? ( int ) &__heap_start : ( int ) __brkval); } |
Для получения данных был выбран сайт http://www.eurometeo.ru/. На данном сайте есть мой город, а также самое главное бесплатный экспорт в XML.
Ай спасибо !
Вот резултат роботы, жрет дофига озу. Может как-то оптимизировать?
Сейчас скетч построен так, что сначала весь ответ сайта полностью принимается в String HTTP_req;, а потом парсится и выводится на экран.
Оптимизировать можно, если парсить прямо в процессе приёма, тогда размеры HTTP_req (и объём памяти, ей занимаемый) можно будет значительно сократить.
В идеале стоило бы отказаться от использования String в пользу char-массивов.
Что финня, постоянно в ребут уходит: упростил код:
01
#include <SPI.h>
02
#include <UIPEthernet.h>
03
#include <string.h>
04
byte
mac[] = {
05
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
06
char
server[] =
"www.eurometeo.ru"
;
07
//IPAddress ip(192, 168, 0, 2);
08
EthernetClient client;
09
10
char
HTTP_req[]=
""
;
11
int
req_index = 0;
// index into HTTP_req buffer
12
13
long
previousMillis_1,previousMillis;
//переменная для хранения значений таймера
14
boolean stopclient=
true
;
15
int
str=0;
//
16
17
void
setup
() {
18
Serial
.begin(9600);
19
Ethernet.begin(mac);
20
// Дадим время шилду на инициализацию
21
delay(1000);
22
Serial
.print(
"Free Ram - "
);
23
Serial
.println( freeRam ());
24
Serial
.println(
"connecting..."
);
25
26
for
(
byte
a=1;a<10;a++ ){
27
if
(client.connect(server, 80)) {
28
Serial
.println(
"---------------"
);
29
// Создаем HTTP-запрос
30
client.println(
"GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1"
);
31
client.println(
"Host: <a href="
http:
//www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>);
32
client.println(
"User-Agent: arduino-ethernet"
);
33
client.println(
"Connection: close"
);
34
client.println();
35
break
;
36
}
37
else
{
38
// if you didn't get a connection to the server:
39
Serial
.println(
"connection failed"
);
40
delay(5000);
41
}
42
}
43
44
}
45
void
loop
() {
46
// Если есть доступные биты, читаем их и выводим на экран
47
if
(client.available()) {
48
char
c = client.read();
// read 1 byte (character) from client
49
HTTP_req[req_index] = c;
// save HTTP request character
50
req_index++;
51
Serial
.print(c);
52
delay(1);
53
}
54
55
56
if
(millis() - previousMillis >500)
57
{
58
previousMillis = millis();
//запучкаем таймер
59
digitalWrite(13, !digitalRead(13));
//меняем значение порта каждые 0.5секунд
60
}
61
62
}
63
64
65
int
freeRam () {
66
extern
int
__heap_start, *__brkval;
67
int
v;
68
return
(
int
) &v - (__brkval == 0 ? (
int
) &__heap_start : (
int
) __brkval);
69
}
Результат роботы:
01
Free Ram - 6207
02
connecting...
03
connection failed
04
---------------
05
HTTP/1.1 200 OK
06
ServerFree Ram - 6207
07
connecting...
08
connection failed
09
---------------
10
HTTP/1.1 200 OK
11
ServerFree Ram - 6207
12
connecting...
13
connection failed
14
---------------
15
HTTP/1.1 200 OK
16
ServerFree Ram - 6207
17
connecting...
18
connection failed
19
---------------
20
HTTP/1.1 200 OK
21
ServerFree Ram - 6207
22
connecting...
23
connection failed
24
---------------
25
HTTP/1.1 200 OK
26
ServerFree Ram - 6207
27
connecting...
28
connection failed
29
connection failed
30
---------------
31
HTTP/1.1 200 OK
32
ServerFree Ram - 6207
33
connecting...
34
connection failed
35
---------------
36
HTTP/1.1 200 OK
37
ServerFree Ram - 6207
38
connecting...
39
---------------
40
HTTP/1.1 200 OK
41
ServerFree Ram - 6207
42
connecting...
43
connection failed
44
---------------
45
HTTP/1.1 200 OK
46
ServerFree Ram - 6207
47
connecting...
48
---------------
49
HTTP/1.1 200 OK
50
ServerFree Ram - 6207
51
connecting...
52
connection failed
53
---------------
54
HTTP/1.1 200 OK
55
ServerFree Ram - 6207
56
connecting...
57
---------------
58
HTTP/1.1 200 OK
59
Server
Разобрался, надо размер буфера указать
char
HTTP_req[4230]=
""
;
Это размер пакета данных, буду дробить на 500, и анализировать, посмотрим что с этого получится.
char-массивов пока еще не разобрался, точнее, блоками выводить получилось, а вот с поиском в массиве не очень. Решил оптимизировать тока роботу со строками. Убрав все лишнее, вывод только в консоль:
001
#include <SD.h>
002
#include <SPI.h>
003
#include <UIPEthernet.h>
004
//#include <string.h>
005
byte
mac[] = {
006
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
007
char
server[] =
"www.eurometeo.ru"
;
008
//IPAddress ip(192, 168, 0, 2);
009
EthernetClient client;
010
String HTTP_req;
011
long
previousMillis;
//переменная для хранения значений таймера
012
boolean stopclient=
true
;
013
014
void
setup
() {
015
Serial
.begin(9600);
016
Ethernet.begin(mac);
017
// Дадим время шилду на инициализацию
018
delay(1000);
019
Serial
.print(
"Free Ram - "
);
020
Serial
.println( freeRam ());
021
Serial
.println(
"connecting..."
);
022
023
for
(
byte
a=1;a<10;a++ ){
024
if
(client.connect(server, 80)) {
025
Serial
.println(
"---------------"
);
026
// Создаем HTTP-запрос
027
client.println(
"GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1"
);
028
client.println(
"Host: <a href="
http:
//www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>);
029
client.println(
"User-Agent: arduino-ethernet"
);
030
client.println(
"Connection: close"
);
031
client.println();
032
break
;
033
}
034
else
{
035
// if you didn't get a connection to the server:
036
Serial
.println(
"connection failed"
);
037
delay(5000);
038
}
039
}
040
041
pinMode(13,OUTPUT);
//инициализация портов
042
043
previousMillis=0;
044
}
045
046
void
loop
() {
047
// Если есть доступные биты, читаем их и выводим на экран
048
if
(client.available()) {
049
Serial
.println(
"Loading....."
);
050
while
(client.available()) {
051
char
c = client.read();
// read 1 byte (character) from client
052
HTTP_req += c;
// save the HTTP request 1 char at a time
053
// Serial.print(c);
054
055
056
057
if
(HTTP_req.indexOf(
"</step>"
) > 0){
058
int
a;
059
a =HTTP_req.indexOf(
"<datetime>"
);
060
Serial
.print(HTTP_req.substring(a+10, a+29)+
", t = "
);
061
a = HTTP_req.indexOf(
"<temperature>"
,a+29);
062
Serial
.print(HTTP_req.substring(a+13, a+18));
063
Serial
.print(
", h = "
);
064
a = HTTP_req.indexOf(
"<humidity>"
,a+18);
065
Serial
.println(HTTP_req.substring(a+10, a+12));
066
067
HTTP_req=
""
;
068
}
069
070
delay(1);
071
}
072
073
074
if
(HTTP_req.indexOf(
"</weather>"
) > 0){
//Точно получили все данные
075
076
Serial
.println(
"End Loading....."
);
077
078
if
(stopclient){
//остановливаем клиент
079
if
(!client.connected()) {
080
Serial
.println();
081
Serial
.println(
"---------------"
);
082
Serial
.println(
"disconnecting"
);
083
client.stop();
084
}
085
Serial
.println(
"=============================="
);
086
Serial
.print(
"Free Ram - "
);
087
Serial
.println( freeRam ());
088
Serial
.println(
"=============================="
);
089
//delay(5000);
090
stopclient=
false
;
//
091
}
//if
092
}
//if
093
094
095
096
}
097
098
099
//Проверка, не зависла ли ардуино?
100
101
if
(millis() - previousMillis >500)
102
{
103
previousMillis = millis();
//запучкаем таймер
104
digitalWrite(13, !digitalRead(13));
//меняем значение порта каждые 0.5секунд
105
}
106
107
108
}
109
110
111
int
freeRam () {
112
extern
int
__heap_start, *__brkval;
113
int
v;
114
return
(
int
) &v - (__brkval == 0 ? (
int
) &__heap_start : (
int
) __brkval);
115
}
Резултат роботы:
01
Free Ram - 5429
02
connecting...
03
---------------
04
Loading.....
05
2016-08-25 05:00:00, t = 17.40, h = 47
06
2016-08-25 11:00:00, t = 22.55, h = 36
07
2016-08-25 17:00:00, t = 23.17, h = 29
08
2016-08-25 23:00:00, t = 18.96, h = 26
09
2016-08-26 05:00:00, t = 16.55, h = 24
10
2016-08-26 11:00:00, t = 23.04, h = 18
11
2016-08-26 17:00:00, t = 24.15, h = 20
12
2016-08-26 23:00:00, t = 18.67, h = 23
13
2016-08-27 05:00:00, t = 16.34, h = 32
14
2016-08-27 11:00:00, t = 24.60, h = 34
15
2016-08-27 17:00:00, t = 26.56, h = 32
16
2016-08-27 23:00:00, t = 20.84, h = 33
17
End Loading.....
18
19
---------------
20
disconnecting
21
==============================
22
Free Ram - 4097
23
==============================
Следал хранение данных в структуре:
1
struct
meteo
2
{
3
String Date_time;
4
float
t;
5
int
h;
6
}
7
add_meteo[12];
Также подробно описана структура файла для парсинга:
Пока проект заканчиваю, возможно попозже добавлю визуализацию данных(1602 маловат для этого):
001
#include <SD.h>
002
#include <SPI.h>
003
#include <UIPEthernet.h>
004
//#include <string.h>
005
byte
mac[] = {
006
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
007
char
server[] =
"www.eurometeo.ru"
;
008
//IPAddress ip(192, 168, 0, 2);
009
EthernetClient client;
010
String HTTP_req;
011
long
previousMillis;
//переменная для хранения значений таймера
012
boolean stopclient=
true
;
013
//Структура, где будем хранитиь данные о погоде
014
//Параметром можно и по больше, незабываем память не резиновая.
015
struct
meteo
016
{
017
String Date_time;
018
float
t;
019
int
h;
020
}
021
add_meteo[12];
022
023
byte
index=0;
024
025
void
setup
() {
026
Serial
.begin(9600);
027
Ethernet.begin(mac);
028
// Дадим время шилду на инициализацию
029
delay(1000);
030
Serial
.print(
"Free Ram - "
);
031
Serial
.println( freeRam ());
032
Serial
.println(
"connecting..."
);
033
034
for
(
byte
a=1;a<10;a++ ){
035
if
(client.connect(server, 80)) {
036
Serial
.println(
"---------------"
);
037
// Создаем HTTP-запрос
038
//Сдесь данные свого города:
039
client.println(
"GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1"
);
040
client.println(
"Host: <a href="
http:
//www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>);
041
client.println(
"User-Agent: arduino-ethernet"
);
042
client.println(
"Connection: close"
);
043
client.println();
044
break
;
045
}
046
else
{
047
// if you didn't get a connection to the server:
048
Serial
.println(
"connection failed"
);
049
delay(5000);
050
}
051
}
052
053
pinMode(13,OUTPUT);
//инициализация портов
054
previousMillis=0;
055
}
056
057
void
loop
() {
058
// Если есть доступные биты, читаем их и выводим на экран
059
if
(client.available()) {
060
Serial
.println(
"Loading....."
);
061
062
while
(client.available()) {
063
char
c = client.read();
// read 1 byte (character) from client
064
HTTP_req += c;
// save the HTTP request 1 char at a time
065
// Serial.print(c);
066
067
if
(HTTP_req.indexOf(
"</step>"
) > 0){
//12 блоков начало <step> конец </step>
068
069
/*
070
<step>
071
<datetime>2016-08-08 05:00:00</datetime>
072
<pressure>754.24</pressure>
073
<temperature>17.43</temperature>
074
<humidity>28</humidity>
075
<cloudcover>0</cloudcover>
076
<windspeed>5.30</windspeed>
077
<windgust>9.78</windgust>
078
<winddir>258</winddir>
079
<precipitation>0.00</precipitation>
080
</step>
081
082
<step> Шаг прогноза, содержит в себе данные на определенное время
083
<datetime> Время прогноза погоды
084
<pressure> Атмосферное давление в мм рт.столба
085
<temperature> Температура воздуха в °C
086
<humidity> Относительная влажность
087
<cloudcover> Облачность в % (100% облака без просветов, 0% - чистое небо)
088
<windspeed> Скорость ветра в м/с
089
<windgust> Скорость порывов ветра в м/с
090
<winddir> Направление ветра в градусах от 0 до 359. 0 - южный ветер, ветер дует по направлению с юга, 90 - ветер с запада, 180 - ветер с севера, 270 - ветер с востока
091
<precipitation> Осадки в мм за 3 часов
092
093
094
095
*/
096
097
//Беру только 2 параметра: темепературу и влажность.
098
int
a;
099
a =HTTP_req.indexOf(
"<datetime>"
);
100
Serial
.print(HTTP_req.substring(a+10, a+29)+
", temperature = "
);
101
add_meteo[index].Date_time = HTTP_req.substring(a+10, a+29);
102
103
a = HTTP_req.indexOf(
"<temperature>"
,a+29);
104
Serial
.print(HTTP_req.substring(a+13, a+18));
105
char
floatbufVar[32];
106
String stringVar = HTTP_req.substring(a+13, a+18);
107
stringVar.toCharArray(floatbufVar,
sizeof
(floatbufVar));
108
add_meteo[index].t=atof(floatbufVar);
109
110
111
Serial
.print(
", humidity = "
);
112
a = HTTP_req.indexOf(
"<humidity>"
,a+18);
113
Serial
.println(HTTP_req.substring(a+10, a+12));
114
add_meteo[index].h=HTTP_req.substring(a+10, a+12).toInt();
115
116
//Ощищаем для экономии озу.
117
HTTP_req=
""
;
118
index++;
119
}
120
121
delay(1);
122
}
123
124
125
if
(HTTP_req.indexOf(
"</weather>"
) > 0){
//Точно получили все данные
126
127
Serial
.println(
"End Loading....."
);
128
129
if
(stopclient){
//остановливаем клиент
130
if
(!client.connected()) {
131
Serial
.println();
132
Serial
.println(
"---------------"
);
133
Serial
.println(
"disconnecting"
);
134
client.stop();
135
}
136
Serial
.println(
"=============================="
);
137
Serial
.print(
"Free Ram - "
);
138
Serial
.println( freeRam ());
139
Serial
.println(
"=============================="
);
140
//delay(5000);
141
stopclient=
false
;
//
142
HTTP_req=
""
;
143
//проверка Массива, потом можно будет убрать
144
for
(index=0;index<12;index++)
145
{
146
Serial
.print(add_meteo[index].Date_time +
", t = "
);
147
Serial
.print(add_meteo[index].t);
148
Serial
.print(
", h = "
);
149
Serial
.println(add_meteo[index].h);
150
}
151
Serial
.println(
"=============================="
);
152
index=0;
153
}
//if
154
}
//if
155
156
157
158
}
159
160
161
//Проверка, не зависла ли ардуино?
162
//Крутю по кругу массив
163
if
(millis() - previousMillis >500)
164
{
165
previousMillis = millis();
//запучкаем таймер
166
digitalWrite(13, !digitalRead(13));
//меняем значение порта каждые 0.5секунд
167
168
if
(stopclient==
false
){
//Крутим если скачали полный файл, иногда качает частями
169
170
Serial
.print(add_meteo[index].Date_time+
", t = "
);
171
Serial
.print(add_meteo[index].t);
172
Serial
.print(
", h = "
);
173
Serial
.println(add_meteo[index].h);
174
175
176
index++;
177
//Обнуляем счетчик
178
if
(index==12){ index=0;}
179
}
180
181
}
//if
182
183
184
}
//loop
185
186
187
int
freeRam () {
188
extern
int
__heap_start, *__brkval;
189
int
v;
190
return
(
int
) &v - (__brkval == 0 ? (
int
) &__heap_start : (
int
) __brkval);
191
}
Результат:
01
Free Ram - 5178
02
connecting...
03
---------------
04
Loading.....
05
2016-08-25 05:00:00, temperature = 17.40, humidity = 47
06
2016-08-25 11:00:00, temperature = 22.55, humidity = 36
07
2016-08-25 17:00:00, temperature = 23.17, humidity = 29
08
2016-08-25 23:00:00, temperature = 18.96, humidity = 26
09
2016-08-26 05:00:00, temperature = 16.55, humidity = 24
10
2016-08-26 11:00:00, temperature = 23.12, humidity = 16
11
2016-08-26 17:00:00, temperature = 24.25, humidity = 19
12
2016-08-26 23:00:00, temperature = 18.74, humidity = 23
13
2016-08-27 05:00:00, temperature = 16.34, humidity = 32
14
2016-08-27 11:00:00, temperature = 24.60, humidity = 34
15
2016-08-27 17:00:00, temperature = 26.56, humidity = 32
16
2016-08-27 23:00:00, temperature = 20.84, humidity = 33
17
End Loading.....
18
19
---------------
20
disconnecting
21
==============================
22
Free Ram - 3533
23
==============================
24
2016-08-25 05:00:00, t = 17.40, h = 47
25
2016-08-25 11:00:00, t = 22.55, h = 36
26
2016-08-25 17:00:00, t = 23.17, h = 29
27
2016-08-25 23:00:00, t = 18.96, h = 26
28
2016-08-26 05:00:00, t = 16.55, h = 24
29
2016-08-26 11:00:00, t = 23.12, h = 16
30
2016-08-26 17:00:00, t = 24.25, h = 19
31
2016-08-26 23:00:00, t = 18.74, h = 23
32
2016-08-27 05:00:00, t = 16.34, h = 32
33
2016-08-27 11:00:00, t = 24.60, h = 34
34
2016-08-27 17:00:00, t = 26.56, h = 32
35
2016-08-27 23:00:00, t = 20.84, h = 33
36
==============================
37
2016-08-25 05:00:00, t = 17.40, h = 47
38
2016-08-25 11:00:00, t = 22.55, h = 36
39
2016-08-25 17:00:00, t = 23.17, h = 29
40
2016-08-25 23:00:00, t = 18.96, h = 26
41
2016-08-26 05:00:00, t = 16.55, h = 24
42
2016-08-26 11:00:00, t = 23.12, h = 16
43
2016-08-26 17:00:00, t = 24.25, h = 19
44
2016-08-26 23:00:00, t = 18.74, h = 23
45
2016-08-27 05:00:00, t = 16.34, h = 32
46
2016-08-27 11:00:00, t = 24.60, h = 34
47
2016-08-27 17:00:00, t = 26.56, h = 32
48
2016-08-27 23:00:00, t = 20.84, h = 33
49
2016-08-25 05:00:00, t = 17.40, h = 47
50
2016-08-25 11:00:00, t = 22.55, h = 36
51
2016-08-25 17:00:00, t = 23.17, h = 29
52
2016-08-25 23:00:00, t = 18.96, h = 26
53
2016-08-26 05:00:00, t = 16.55, h = 24
54
2016-08-26 11:00:00, t = 23.12, h = 16
55
2016-08-26 17:00:00, t = 24.25, h = 19
56
2016-08-26 23:00:00, t = 18.74, h = 23
57
2016-08-27 05:00:00, t = 16.34, h = 32
58
2016-08-27 11:00:00, t = 24.60, h = 34
59
2016-08-27 17:00:00, t = 26.56, h = 32
60
2016-08-27 23:00:00, t = 20.84, h = 33
Итак идем дальше, есть 2.4 tft lcd shield 0x9325, и библиотека MCUFRIEND_kbv. Проверил данный shield на Меге и Уно. Работает без проблем, и без правки библиотек. СД карта на Меге не завелась, так как не соответствуют пины, ну мне пока и не нужно. Пока только визуализировано температуру, в дальнейшем задействую тач, и возможность строить гистограмму не только по температуре, а также и по другим параметрам (влажность, давление, осадки, скорость ветра, облачность).
Видео : https://yadi.sk/i/HZXLU4QCurniS
001
#include <SD.h>
002
#include <SPI.h>
003
#include <UIPEthernet.h>
004
//#include <string.h>
005
byte
mac[] = {
006
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
007
char
server[] =
"www.eurometeo.ru"
;
008
//IPAddress ip(192, 168, 0, 2);
009
EthernetClient client;
010
String HTTP_req;
011
long
previousMillis;
//переменная для хранения значений таймера
012
boolean stopclient=
true
;
013
//Структура, где будем хранитиь данные о погоде
014
//Параметром можно и по больше, незабываем память не резиновая.
015
struct
meteo
016
{
017
String Date_time;
018
float
t;
019
int
h;
020
}
021
add_meteo[12];
022
//Блок роботы с TFT
023
#include <Adafruit_GFX.h> // Hardware-specific library
024
#include <MCUFRIEND_kbv.h>
025
MCUFRIEND_kbv tft;
026
027
#define BLACK 0x0000
028
#define BLUE 0x001F
029
#define RED 0xF800
030
#define GREEN 0x07E0
031
#define CYAN 0x07FF
032
#define MAGENTA 0xF81F
033
#define YELLOW 0xFFE0
034
#define WHITE 0xFFFF
035
036
037
byte
index=0;
038
039
void
setup
() {
040
// Serial.begin(9600);
041
Ethernet.begin(mac);
042
// Дадим время шилду на инициализацию
043
delay(1000);
044
045
tft.reset();
046
uint16_t id = tft.readID();
047
tft.begin(id);
048
tft.setRotation(1);
049
tft.fillScreen(BLACK);
050
tft.setTextColor(WHITE, BLACK);
051
tft.setTextSize(2);
// System font is 8 pixels. ht = 8*2=16
052
053
054
tft.print(
"Free Ram - "
);
055
tft.println( freeRam ());
056
tft.println(
"connecting..."
);
057
058
for
(
byte
a=1;a<10;a++ ){
059
if
(client.connect(server, 80)) {
060
// Serial.println("---------------");
061
// Создаем HTTP-запрос
062
//Сдесь данные свого города:
063
client.println(
"GET /ukraina/cherkaska-oblast/cherkasi/export/xml/data/ HTTP/1.1"
);
064
client.println(
"Host: <a href="
http:
//www.eurometeo.ru" title="www.eurometeo.ru"" rel="nofollow">www.eurometeo.ru"</a>);
065
client.println(
"User-Agent: arduino-ethernet"
);
066
client.println(
"Connection: close"
);
067
client.println();
068
break
;
069
}
070
else
{
071
// if you didn't get a connection to the server:
072
tft.println(
"connection failed"
);
073
delay(5000);
074
}
075
}
076
077
pinMode(13,OUTPUT);
//инициализация портов
078
previousMillis=0;
079
}
080
081
void
loop
() {
082
// Если есть доступные биты, читаем их и выводим на экран
083
if
(client.available()) {
084
tft.println(
"Loading....."
);
085
086
while
(client.available()) {
087
char
c = client.read();
// read 1 byte (character) from client
088
HTTP_req += c;
// save the HTTP request 1 char at a time
089
// Serial.print(c);
090
091
if
(HTTP_req.indexOf(
"</step>"
) > 0){
//12 блоков начало <step> конец </step>
092
093
/*
094
<step>
095
<datetime>2016-08-08 05:00:00</datetime>
096
<pressure>754.24</pressure>
097
<temperature>17.43</temperature>
098
<humidity>28</humidity>
099
<cloudcover>0</cloudcover>
100
<windspeed>5.30</windspeed>
101
<windgust>9.78</windgust>
102
<winddir>258</winddir>
103
<precipitation>0.00</precipitation>
104
</step>
105
106
<step> Шаг прогноза, содержит в себе данные на определенное время
107
<datetime> Время прогноза погоды
108
<pressure> Атмосферное давление в мм рт.столба
109
<temperature> Температура воздуха в °C
110
<humidity> Относительная влажность
111
<cloudcover> Облачность в % (100% облака без просветов, 0% - чистое небо)
112
<windspeed> Скорость ветра в м/с
113
<windgust> Скорость порывов ветра в м/с
114
<winddir> Направление ветра в градусах от 0 до 359. 0 - южный ветер, ветер дует по направлению с юга, 90 - ветер с запада, 180 - ветер с севера, 270 - ветер с востока
115
<precipitation> Осадки в мм за 3 часов
116
117
118
119
*/
120
121
//Беру только 2 параметра: темепературу и влажность.
122
int
a;
123
a =HTTP_req.indexOf(
"<datetime>"
);
124
// Serial.print(HTTP_req.substring(a+10, a+29)+", temperature = ");
125
add_meteo[index].Date_time = HTTP_req.substring(a+10, a+29);
126
127
a = HTTP_req.indexOf(
"<temperature>"
,a+29);
128
// Serial.print(HTTP_req.substring(a+13, a+18));
129
char
floatbufVar[32];
130
String stringVar = HTTP_req.substring(a+13, a+18);
131
stringVar.toCharArray(floatbufVar,
sizeof
(floatbufVar));
132
add_meteo[index].t=atof(floatbufVar);
133
134
135
// Serial.print(", humidity = ");
136
a = HTTP_req.indexOf(
"<humidity>"
,a+18);
137
// Serial.println(HTTP_req.substring(a+10, a+12));
138
add_meteo[index].h=HTTP_req.substring(a+10, a+12).toInt();
139
140
//Ощищаем для экономии озу.
141
HTTP_req=
""
;
142
index++;
143
}
144
145
delay(1);
146
}
147
148
149
if
(HTTP_req.indexOf(
"</weather>"
) > 0){
//Точно получили все данные
150
151
tft.println(
"End Loading....."
);
152
153
if
(stopclient){
//остановливаем клиент
154
if
(!client.connected()) {
155
// Serial.println();
156
// Serial.println("---------------");
157
tft.println(
"disconnecting"
);
158
client.stop();
159
}
160
// Serial.println("==============================");
161
tft.print(
"Free Ram - "
);
162
tft.println( freeRam ());
163
// Serial.println("==============================");
164
//delay(5000);
165
stopclient=
false
;
//
166
HTTP_req=
""
;
167
delay(2000);
168
//проверка Массива, потом можно будет убрать
169
tft.fillScreen(BLACK);
170
tft.setCursor(0, 0);
171
tft.setTextSize(2);
172
for
(index=0;index<12;index++)
173
{
174
tft.print(add_meteo[index].Date_time.substring(2,16) +
"t="
);
175
tft.print(add_meteo[index].t);
176
tft.print(
",h="
);
177
tft.print(add_meteo[index].h);
178
}
179
180
delay(2000);
181
182
//Grid
183
tft.fillScreen(BLACK);
184
int
line;
185
tft.drawFastVLine(0, 0, 100, GREEN);
186
for
(line = 0; line < 13; line++) tft.drawFastVLine(25*line, 0, 100, GREEN);
187
;
188
tft.drawFastVLine(319, 0, 100, GREEN);
189
190
tft.drawFastHLine(0, 100, 320, GREEN);
191
for
(line = 0; line < 11; line++) tft.drawFastHLine(0, 10*line, 320, GREEN);
192
;
193
//end Grid
194
//min,max
195
float
min_t,max_t;
196
197
min_t=100; max_t=-100;
198
for
(line = 0; line < 12; line++)
199
{
200
if
(min_t>add_meteo[line].t) min_t=add_meteo[line].t;
201
if
(max_t<add_meteo[line].t) max_t=add_meteo[line].t;
202
}
203
//end min,max
204
205
206
tft.setTextSize(1);
207
tft.setTextColor(WHITE,BLACK);
208
//tft.setCursor(0, 120);
209
//tft.println(min_t);
210
//tft.println(max_t);
211
//Добавим 10% для красивой сетки
212
min_t=min_t-min_t*0.2;
213
max_t=max_t+max_t*0.1;
214
215
for
(line = 0; line < 12; line++)
216
{
217
// tft.drawLine(13+25*line, 100,13+25*line,100-map(add_meteo[line].t,min_t,max_t,0,100), RED);
218
tft.fillRect(13+25*line, 100,5,-map(add_meteo[line].t,min_t,max_t,0,100), RED);
219
tft.setCursor(13+25*line, 100-map(add_meteo[line].t,min_t,max_t,0,100));
220
tft.print(add_meteo[line].t);
221
}
222
223
tft.setCursor(0, 120);
224
tft.setTextSize(1);
225
for
(index=0;index<12;index++)
226
{
227
tft.print(add_meteo[index].Date_time +
", t = "
);
228
tft.print(add_meteo[index].t);
229
tft.print(
" , h = "
);
230
tft.println(add_meteo[index].h);
231
}
232
233
// Serial.println("==============================");
234
index=0;
235
}
//if
236
}
//if
237
238
239
240
}
241
242
243
//Проверка, не зависла ли ардуино?
244
if
(millis() - previousMillis >500)
245
{
246
previousMillis = millis();
//запучкаем таймер
247
digitalWrite(13, !digitalRead(13));
//меняем значение порта каждые 0.5секунд
248
}
//if
249
250
251
}
//loop
252
253
254
int
freeRam () {
255
extern
int
__heap_start, *__brkval;
256
int
v;
257
return
(
int
) &v - (__brkval == 0 ? (
int
) &__heap_start : (
int
) __brkval);
258
}
почему у меня ошибка в
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
помогите если можете
почему у меня ошибка в
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
помогите если можете
Кавычки внутри кавычек необходимо экранировать символом \
заменить "client.println("Host: www.eurometeo.ru");"
тут можно найти свой город.
https://eurometeo.ru/ukraina/cherkaska-oblast/cherkasi/export/
Мой город уже в статистику не попадает, а свой проверяйте.
добавлено: По ходу сайт уже давно статистику не обновляет по всем городам