reciver_AIR_TCP.ino
17.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#include <Oregon_NR_AIR.h>
//#include <Oregon_TR.h>
//#include <ESP8266WiFi.h>
//#include <WiFiClient.h>
//#include <ESP8266HTTPClient.h>
//#include <Ethernet.h>
//#include <Bridge.h>
//#include <HttpClient.h>
//#include <Dns.h>
// ВАЖНО! Скетч использует прожорливую библиотеку Ethernet.h. В итоге скетч исползует почти максимальный объём памяти,
// из за чего, любые дополнения в скетч(новые переменные, функции..) могут привести к неработоспособности !!!
// Характерный признак этого - пустая строка в БД. Тоесть в базу будут уходить пустые значения, т.к. памяти для них уже не будет хватать..
// Как это проверить?! В void send_post() добавить Serial.print(postData.length()) - в мониторе порта, при приёме пакета,
// будет отображён размер длины post запроса. Если размер будет равен 0 то всё пропало:) нужно укорачивать размер кода программы.
// ============ ОПРЕДЕЛИМ ПЛАТУ ДЛЯ РАБОТЫ =====================
#define UNO
#ifdef UNO
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x3E, 0xAD };
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0); // маска подсети
IPAddress ip(192,168,1,101);
//IPAddress dns1(192,168,1,1);
IPAddress dns1(8, 8, 8, 8);
EthernetClient client; // Клиент hitech
//Oregon_NR oregon(2, 0, 13); // Для Arduino UNO/Nano - приёмник на выводе D2, Прерывание 0, Светодиод приёма на вывод 13
Oregon_NR oregon(2, 0); // Если светодиод не нужен
#endif
//#define WEMOS_D1
#ifdef WEMOS_D1
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
WiFiClient client; // Клиент hitech
Oregon_NR oregon(13, 13, 2, true); // для Wemos D1 - датчик на выводе D7 (GPIO13), Светодиод на D2 подтянут к +пит.
#endif
//===========================================================
// Индикация ---------------------------- //
#define BLUE_LED 2 // Индикация подключения к WiFi
//#define GREEN_LED 14 // Индикатор успешной доставки пакета
//#define RED_LED 255 // Индикатор ошибки доставки пакета
// -------------------------------------- //
// Интервалы соединения с сервером ------ //
#define SEND_INTERVAL 120000 // 350000 - 5 min //Как часто отсылать данные на сервер
#define CONNECT_TIMEOUT 10000 // Время ожидания соединения
#define DISCONNECT_TIMEOUT 10000 // Время ожидания отсоединения
// -------------------------------------- //
//Параметры входа в WiFi ---------------- //
const char* ssid = "ASUS";
const char* password = "123456789";
//--------------------------------------- //
//Параметоы соединения с сервером (hitech)
char server[] = "192.168.1.239"; // Локальный сервер
int port = 3000; // Локальный порт
//char server[] = "zaoki.ru"; // Внешний сервер. Использую для отладки системы.
//int port = 80; // Испльзую порт 80. До этого был SSL 443 порт - не работало. На стороне сервера NGINX необходимо настроить профиль так,
//--------------------------------------- // чтобы NGINX принимал все входящие соединения по 443 порту. А пока пришлось 433 порт отключить!
// инициализация переменных для хранения данных с транспондеров
// Транспондер ID ----------------------- //
char* transponder_id = AIR1;
//const char* transponder_name = transponder_id;
// -------------------------------------- //
float latitude_, longitude_;
byte altitude_, curs_, vario_;
word speed_;
// ------------------------------------------------ //
void setup() {
Serial.begin(115200);
// Запуск eth --------------------------------------
#ifdef UNO
Ethernet.begin(mac, ip, dns1, gateway, subnet); // Тут, похоже, важен порядок передаваемых в библиотеку значений. В другой последовательности почему то не работает!!?
// if (client.connect(server, 80)) {
// Serial.println("connected");
// client.println("GET /map HTTP/1.0");
// client.println();
// } else {
// Serial.println("connection failed");
// }
#endif
// Запуск Wifi --------------------------------------
#ifdef WEMOS_D1
//wifi_connect();
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA); //Отключаем hotspot и переводим ESP в режим wifi клиент. В хотспот работает как каждый с каждым - иногда выручает :)
WiFi.begin(ssid, password); //Соединяемся с роутером
Serial.println("");
Serial.print("Connecting");
// ждём соединения
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
#endif
// --------------------------------------------------------
//--------вкючение прослушивания радиоканала -----------------------------------------------------------------------
oregon.start();
oregon.receiver_dump = true; // true - Включает "осциллограф" - отображение данных, полученных с приёмника
// Если не распознаются последние байты принятого пакета можно попробовать подстроить частоту захвата данных
oregon.timing_correction = 0; // Коррекция частоты завхвата данных. Обычно достаоточно подобрать значение от -5 до 5 (было 0)
oregon.decode_method = 3; // или использовать метод 3 для декодирования
//-------------------------------------------------------------------------------------------------------------------
}
void loop() {
//Захват пакета,/////////////////////////////////////////////////////
oregon.capture(0); // 1 - выводить в Serial сервисную информацию
//Захваченные данные годны до следующего вызова capture
//ОБработка полученного пакета//////////////////////////////////////////////
if (oregon.captured) {
//Вывод информации в Serial
Serial.print ((float) millis() / 1000, 1); //Время
Serial.print ("s\t\t");
//Версия протокола
if (oregon.ver == 2) Serial.print(" ");
if (oregon.ver == 3) Serial.print("3 ");
//Информация о восстановлени пакета
if (oregon.restore_sign & 0x01) Serial.print("s"); //восстановлены одиночные такты
else Serial.print(" ");
if (oregon.restore_sign & 0x02) Serial.print("d"); //восстановлены двойные такты
else Serial.print(" ");
if (oregon.restore_sign & 0x04) Serial.print("p "); //исправленна ошибка при распознавании версии пакета
else Serial.print(" ");
//Вывод полученного пакета. Точки - это ниблы, содержащие сомнительные биты
for (int q = 0;q < PACKET_LENGTH - 1; q++)
if (oregon.valid_p[q] == 0x0F) Serial.print(oregon.packet[q], HEX);
else Serial.print(".");
//Время обработки пакета
Serial.print(" ");
Serial.print(oregon.work_time);
Serial.print("ms ");
// if ((oregon.sens_type == THGN132 || (oregon.sens_type & 0x0FFF) == RTGN318 || oregon.sens_type == THGR810 || oregon.sens_type == THN132) && oregon.crc_c){
// Serial.print("\t");
// Serial.print(" TYPE: ");
// if (oregon.sens_type == THGN132) Serial.print("THGN132N");
// if (oregon.sens_type == THGR810) Serial.print("THGR810 ");
// if ((oregon.sens_type & 0x0FFF) == RTGN318) Serial.print("RTGN318");
// if (oregon.sens_type == THN132) Serial.print("THN132N ");
// Serial.print(" CHNL: ");
// Serial.print(oregon.sens_chnl);
// if (oregon.sens_tmp >= 0 && oregon.sens_tmp < 10) Serial.print(" TMP: ");
// if (oregon.sens_tmp < 0 && oregon.sens_tmp >-10) Serial.print(" TMP: ");
// if (oregon.sens_tmp <= -10) Serial.print(" TMP:");
// if (oregon.sens_tmp >= 10) Serial.print(" TMP: ");
// Serial.print(oregon.sens_tmp, 1);
// Serial.print("C ");
// if (oregon.sens_type == THGN132 || oregon.sens_type == THGR810 || (oregon.sens_type & 0x0FFF) == RTGN318) {
// Serial.print("HUM: ");
// Serial.print(oregon.sens_hmdty, 0);
// Serial.print("%");
// }
// else Serial.print(" ");
// Serial.print(" BAT: ");
// if (oregon.sens_battery) Serial.print("F "); else Serial.print("e ");
// Serial.print("ID: ");
// Serial.print(oregon.sens_id, HEX);
// }
// if (oregon.sens_type == WGR800 && oregon.crc_c){
// Serial.print("\t");
// Serial.print(" TYPE: ");
// Serial.print("WGR800");
// Serial.print(" AVG WS: ");
// Serial.print(oregon.sens_avg_ws, 1);
// Serial.print("m/s MAX WS: ");
// Serial.print(oregon.sens_max_ws, 1);
// Serial.print("m/s WDIR: "); //N = 0, E = 4, S = 8, W = 12
// Serial.print(oregon.sens_wdir);
// Serial.print(" BAT: ");
// if (oregon.sens_battery) Serial.print("F "); else Serial.print("e ");
// Serial.print("ID: ");
// Serial.print(oregon.sens_id, HEX);
// }
// if (oregon.sens_type == UVN800 && oregon.crc_c){
// Serial.print("\t");
// Serial.print(" TYPE: ");
// Serial.print("UVN800");
// Serial.print(" UV IDX: ");
// Serial.print(oregon.UV_index);
// Serial.print(" BAT: ");
// if (oregon.sens_battery) Serial.print("F "); else Serial.print("e ");
// Serial.print("ID: ");
// Serial.print(oregon.sens_id, HEX);
// }
// if (oregon.sens_type == PCR800 && oregon.crc_c){
// Serial.print("\t");
// float wnddata;
// Serial.print(" TYPE: ");
// Serial.print("PCR800,");
// Serial.print(" RAIN RATE: ");
// Serial.print(oregon.rain_rate, 3);
// Serial.print(" mm/h, ");
// Serial.print(" TOTAL RAIN: ");
// Serial.print(oregon.total_rain, 5);
// Serial.print(" mm, ");
// Serial.print(" BAT: ");
// if (oregon.sens_battery) Serial.print("F "); else Serial.print("e ");
// Serial.print("ID: ");
// Serial.print(oregon.sens_id, HEX);
// }
if (oregon.sens_type == transponder_id && oregon.crc_c){
latitude_ = ((float(oregon.lat_)/1000)); // устанавливаем запятую после третьего знака с конца - деление на 1000
longitude_ = ((float(oregon.lon_)/1000));
altitude_ = (oregon.alt_);
// на перспективу + три параметра
//curs_ = (oregon.cur_); // курс
//vario_ = (oregon.var_); // вариометр
//speed_ = (oregon.speed_); // скорость
Serial.print("\t");
Serial.print(" TYPE: ");
Serial.print("AIR1; ");
Serial.print("Latitude: ");
Serial.print((latitude_), 3); // Отображаю с точностью 3 знака после запятой
Serial.print("; Longitude: ");
Serial.print((longitude_),3); // Отображаю с точностью 3 знака после запятой
Serial.print(" Altitude: ");
Serial.println(oregon.alt_); // Serial.print(" метров над уровнем моря");
send_post(); // Отправляем данные методом POST на сервер в БД
}
Serial.println();
}
}
////////////////////////////////////////////////////////////////////////////////////////
//== КОД ДЛЯ ESP (WEMOS) =====================================================================
#ifdef WEMOS_D1
void send_post() {
HTTPClient http; //Declare object of class HTTPClient
//WiFiClient client
String postData;
//String s_latitude_ = String(latitude_); // преобразование полученных данных в String необходимо для того, что бы можно было передать POST запрос
//String s_longitude_ = String(longitude_); // если не преобразовать, то сервер примет этот параметр пустым
//String s_altitude_ = String(altitude_);
//String s_speed_ = String(speed_); // speed_ - параметр пока не определён. Это на перспективу.
String s_latitude_ = String(latitude_, 3);
String s_longitude_ = String(longitude_, 3);
postData = "transponder=AIR1&latitude=" + s_latitude_ + "&longitude=" + s_longitude_ + "&altitude=" + String(altitude_);
http.begin("http://hitech:3000/post_to_db"); //Specify request destination
http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header
int httpCode = http.POST(postData); //Send the request
String payload = http.getString(); //Get the response payload
Serial.print("Request respons: ");
Serial.print(httpCode); //Print HTTP return code
Serial.println(payload); //Print request response payload
http.end(); //Close connection
}
#endif
//== КОД ДЛЯ UNO ===========================================================
#ifdef UNO
void send_post() {
String postData;
postData = "transponder=AIR1&latitude=" + String((latitude_),3) + "&longitude=" + String((longitude_),3) + "&altitude=" + String(altitude_);
client.connect(server, port);
client.println( "POST /post_to_db HTTP/1.1");
client.println("Host: "+String(server));
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: "); // Необходимо указать правильную длинну content-length, что бы все данные попали в БД
client.println(postData.length()); // Для этого определяем кол-во символов (в заранее сформированном запросе в фомате POST) с помощью length()
client.println("Connection: close"); // Connection close - В ЭТОМ МЕСТЕ УСТАНОВЛЕ ВЕРНО! Иначе сервер будет откликаться на запрос по типу GET
client.println(); // Не удалять! Переводы строки нужны в заголовке согласно требованиям!
client.println(postData); // Теперь отправляем строку с данными в формате POST
client.println(); // Опять перевод строки!!
client.stop(); // Закрываем соединение
client.flush(); // Flush :)
}
#endif
//=======================================================================
void wait_timer(int del){
unsigned long tm_marker = millis();
while (millis() - tm_marker < del) yield();
return;
}