Oregon_NR_AIR.h
19.6 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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#include <Arduino.h>
#ifndef Oregon_NR_h
#define Oregon_NR_h
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// !!!!!!!!!!! Release by R3PB AIR-TRANSPONDER SYSTEM !!!!!!!!!!!!!
// This Arduino code is for receive and transmit data using Oregon Scientific RF protocol version 2.1 and 3.0.
//
// Last updated: 14 October 2019
//
// The folowed sensors data format are supported.
//
// Receive and transmit:
// THGN132N (THGR122N, THGN123N),
// RTGN318,
// THGR810.
// Receive only:
// THN132N,
// WGR800,
// UVN800.
//
// Aslo supported self-developed sensors. Please contact author for additional infromation.
//
// This file is part of the Arduino OREGON_NR library.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// The MIT License (MIT)
//
// Copyright (c) 2019 Sergey Zawislak
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Данная библиотека Ардуино предназначена для приема и передачи данных в формате беспроводного протокола Oregon Scientific v2.1 и v3.0
//
// Последнее обновление 14 Октября 2019
//
// Поддерживается формат следующих датчиков
//
// Приём и передача:
// THGN132N (THGR122N, THGN123N),
// RTGN318,
// THGR810.
// Тольок приём:
// THN132N,
// WGR800,
// UVN800.
//
// Также поддерживаются датчики собственной разработки (за дополнительной документацей обращаться к автору)
//
// Этот файл - часть библиотеки OREGON_NR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2019 Сергей Зависляк
//
// Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации
// (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений,
// включая неограниченное право на использование, копирование, изменение, слияние, публикацию, распространение, сублицензирование
// и/или продажу копий Программного Обеспечения, а также лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
//
// Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.
//
// ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ
// ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ
// НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, В ТОМ ЧИСЛЕ, ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ,
// ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Распознавание пакетов от следующих датчиков Oregon Scientific:
//
#define THGN132 0x1D20 // Температура, влажность, 3 канала,
#define THN132 0xEC40 // Температура, 3 канала,
#define RTGN318 0xCC3 // Температура, влажность, 5 каналов,
#define THGR810 0xF824 // Температура, влажность, 10 каналов,
#define WGR800 0x1984 // Направление и скорость ветра
#define PCR800 0x2914 // Уровень осадков 2D10
//#define PCR800 0x2D10 // Уровень осадков 2D10
#define UVN800 0xD874 // УФ-индекс, освещённость (спасибо XOR за предоставленные данные)
// Датчик mr.Tech
// #define AIR1 0xAAA1 // AIR transponder борт 1
// #define AIR2 0xAAA2 // AIR transponder борт 2
// #define AIR3 0xAAA3 // AIR transponder борт 3
#define AIR 0xAAA // префикс транспондера
// Датчики собственной разработки:
#define THP 0x5500 // Температура, влажность, атм давление, 8 каналов, работа от 3-ех батарей АА,
#define GAS 0xAA00 // Температура, влажность, концентрация СО и CH4, 8 каналов,
#define FIRE 0xBB00 // Контроль сигналов пожарных линий датчиков ИП22 и ИП72
#define CURRENT 0xEE00 // Ток, напряжение, 8 каналов,
#define CAPRAIN 0x8800 // Емкостной всепогодный датчик осадков
//
//Этими параметрами можно поиграть для экономии ресурсов
#define ADD_SENS_SUPPORT 1 // ПОддежка дополнительных типов датчиков собственной разработки - отключение незначительно экономит ОЗУ
#define IS_ASSEMBLE 1 // Пытаться ли собрать из двух повреждённых пакетов один целый (для v2) - отключение сильно экономит ОЗУ!
//
// Этими параметрами можно поиграть для настройки наилучшего приёма
#define MAX_LENGTH2 976 // Максимальная длина импульса преамбулы v2 - не меньше периода, чтобы ловился сигнал от разных эмуляторов
#define MIN_LENGTH2 883 // Минимальная длина импульса при захвате (для v2 импульсы укорочены на 93мкс), т.е. должна быть не больше 883мкс,
#define MAX_LENGTH3 488 // Максимальная длина импульса преамбулы v3 - не меньше полупериода, чтобы ловился сигнал от разных эмуляторов
#define MIN_LENGTH3 330 // Минимальная длина импульса при захвате (для v2 импульсы укорочены на 138мкс), т.е. должна быть не больше 350мкс,
#define LENGTH_TOLERANCE 64 // Допустимое отклонение для длины импульса. Зависит от приёмника
// В зависимости от уровня сигнала может "плавать длина импульсов"
#define CATCH_PULSES 3 // Сколько искать правильных импульсов для начала захвата. Рекомендовано 2 - 4.
// Больше - можно не поймать пакет в условиях сильных шумов
// Меньше - можно пропустить пакет, сильно отвлекаясь на анализ шумов
//Эти параметры трогать не надо!
#define FIND_PACKET 1
#define ANALIZE_PACKETS 2
#define PER_LENGTH2 976 // Период передачи данных. Для v2 и v3 976,56мкс (1024Гц)
#define PER_LENGTH3 488
#define READ_BITS 105 // Максимальная длина пакета в тактах (105)
#define READ_BITS2 210 // Максимальная длина пакета в тактах * 2 (210)
#define PACKET_LENGTH 20 // Длина пакета в ниблах без учёта преамбулы (с синхрониблом) (20)
static int RECEIVER_PIN;
class Oregon_NR
{
public:
//Данные датчика
word sens_type; //Sensor type
word transponder; // Префикс пранспондера
// byte tr_number; // Номер транспондера
float sens_tmp, //Temperature
sens_hmdty; //Humidity
byte sens_chnl, //Channel number
sens_id, //ID
sens_battery; //Battery status
byte ver = 0; //Protocol version
bool crc_c = 0; //CRC check result. Сбрасывается при захвате. Выставляется при приёме корректного пакета.
bool captured = 0; //Capture data flag. Выставляется, если были считаны данные в память.
unsigned long work_time; //Capture time
byte packet[PACKET_LENGTH]; //Result packet
byte valid_p[PACKET_LENGTH]; //Validity mask - маска уверенного распознавания битов
byte packets_received = 0; //Number of received packets in block (0...2)
byte received_CRC; //Calculated СRC
Oregon_NR(byte, byte); //Конструктор. Параметры:
Oregon_NR(byte, byte, byte, bool); //(вывод приёмника, номер прерывания, вывод светодиода, pull up)
void start(); //Star listening receiver
void stop(); //Stop listening receiver. Чтобы не занимал процессор, когда не нужен
void capture(bool); //Capture packet. if parameter is true function dumps capture data to Serial.
bool consist_synchro = false; //При поиске синхронибла опираться подтверждённые или сомнительные данные?
byte empty_space = 3; //Какое количество "пустых" тактов нужно для определения конца посылки?
//Параметр определяется уровнем сигнала и скоростью АРУ приёмника.
//Чем они лучше, тем меньше число. НО меньше двух не рекомендуется
//В сатрой версии было 5
bool catch2 = 1, catch3 = 1; //какие версии протокола принимать
int timing_correction = 0; //Коррекция частоты приёма (от -10 до +10)
byte decode_method = 3; // Метод декодирования тактов
//1 - традиционный
//3 - при девиации частоты
//Ветрометр
float sens_avg_ws, sens_max_ws;
byte sens_wdir;
float get_avg_windspeed(byte*);
float get_max_windspeed(byte*);
byte get_winddirection(byte*);
//UV
byte UV_index, lightness;
byte get_UV(byte*);
byte get_light(byte*);
//RAIN METER
float rain_rate, total_rain;
float get_rain_rate(byte*);
float get_total_rain(byte*);
//AIR TRANSPONEDER
long lat_, lon_; // широта, долгота
word alt_; // высота
word get_longitude(byte* oregon_data); // get longitude
word get_latitude(byte* oregon_data); // get latitude
word get_altitude(byte* oregon_data); // get altitude
byte restore_sign; //Битовое поле, инормирующее об успешных способах реставрации пакета
//0 - восстановлены одиночные такты
//1 - восстановлены двойные такты
//2 - исправление версии протокола при разборке пакета
//3 - восстановлено методом сращивания (v2) - отключено для экономии ресурсов
bool receiver_dump = 0; //Сбрасывать ли дамп канала в Serial. работает тольок если capture(true)
// фактически это осциллограмма огибающей сигнала с приёмника
// Также выводятся тактовые последовательности до и после восстановления
#if ADD_SENS_SUPPORT == 1
float sens_pressure, //Pressure
sens_voltage, // напряжение в В (for CURRENT и THP sensors)
sens_tmp2; //Temperature2 (for GASv2 sensor)
byte sens_CO, //CO (ppm*10) (for GASv2 sensor)
sens_CH; //CH4 (ppm*100)(ppm)
byte sens_ip22, //IP22 channel data (for FIRE sensor)
sens_ip72, //IP72 channel data (for FIRE sensor)
sens_lockalarm; //LOCK_ALARM channel data (for FIRE sensor)
float sens_current; // ток в А (for CURRENT sensor)
word sens_pump_count; // счётчик насоса
unsigned long sens_drop_counter;// счётчик капель (for CAPRAIN sensor)
int sens_capacitance; //Емкость сенсора (for CAPRAIN sensor)
#endif
private:
byte read_tacts, read_tacts2, result_size;
byte LED = 0xFF; //вывод светодиода, который мигает при приёме
bool PULL_UP; //куда подключён светодиод
byte packet_number = 0; //Количесвто принятых пакетов в посылке
int INT_NO; //Номер прерывания приёмника
//bool reciever_ctrl = true; //Флаг контроля ресивера (выставляется при приходе импулься, сбрасывается в таймере)
//Массивы данных для записи данных с канала и полученных битов
byte decode_tacts[READ_BITS2]; //Массив тактов. значения
// 0=ноль
// 1=единица
// 2=неизвестен
// 3=переход+
// 4=переход-
byte collect_data[READ_BITS2], //Память для сбора данных с приёмника
#if IS_ASSEMBLE
collect_data2[READ_BITS2];
#else
collect_data2[1];
#endif
//А когда становится массивом полученных битов, то значения такие:
// 128 - неизвестен
// >128 - единица
// <128 - ноль
byte receive_status = FIND_PACKET;
byte start_pulse_cnt = 0;
unsigned long pulse_length, timer_marklong;
unsigned long pulse_marker, right_pulse_marker;
unsigned long pre_marker; // Для хранения временных меток преамбулы при захвате пакета
unsigned long first_packet_end;
byte data_val, data_val2; // Качество пакетов
byte synchro_pos, synchro_pos2; // Позиции синхрониблов в записи
byte get_gas_CH(byte* gas_data);
byte get_gas_CO(byte* gas_data);
byte get_gas_hmdty(byte* gas_data);
float get_gas_temperature_in(byte* gas_data);
float get_gas_temperature_out(byte* gas_data);
byte get_gas_channel(byte* gas_data);
void restore_data(byte* oregon_data, word sensor_type);
bool check_CRC(byte* oregon_data, word sensor_type);
byte get_id(byte* oregon_data);
float get_humidity(byte* oregon_data);
byte get_battery(byte* oregon_data);
byte get_channel(byte* oregon_data);
word get_sensor(byte* oregon_data);
word get_transponder(byte* oregon_data);
// byte get_tr_number(byte* oregon_data);
float get_temperature(byte* oregon_data);
int get_info_data(byte* code, byte* result, byte* valid);
void assemble_data(byte* s1, byte* s2, int shift);
int correlate_data(byte* ser1, byte* ser2);
int collect(byte* cdptr);
int get_data(int btt, byte p_ver, byte* cdptr);
void get_tacts(byte*, byte);
int get_synchro_pos(byte* code);
void led_light(bool);
// word get_longitude(byte* oregon_data); // get longitude
// word get_latitude(byte* oregon_data); // get latitude
#if ADD_SENS_SUPPORT == 1
byte get_fire_ip22(byte* fire_data);
byte get_fire_ip72(byte* fire_data);
byte get_fire_lockalarm(byte* fire_data);
float get_current(byte* curent_data);
float get_voltage(byte* voltage_data);
word get_pump_count(byte* voltage_data);
unsigned long get_dropcounter(byte* packetdata);
int get_capacitance(byte* packetdata);
float get_thp_humidity(byte* oregon_data);
float get_thp_temperature(byte* oregon_data);
float get_thp_pressure(byte* oregon_data);
float get_thp_voltage(byte* oregon_data);
#endif
};
#endif