Чтение и эмуляция датчиков Oregon Scientific (433Mhz)
- Войдите на сайт для отправки комментариев
Вс, 21/04/2013 - 18:08
Информация по датчикам Oregon Scientific уже была на форуме, здесь лишь все собрано в одно место.
С помощью счетча ниже можно ловить показания датчиков из эфира (частота 433MHz).
Помимо Oregon, реализован разбор показаний еще нескольких других производителей датчиков.
Железо необходимое для проекта, фото -
// Oregon V2 decoder added - Dominique Pierre // Oregon V3 decoder revisited - Dominique Pierre // New code to decode OOK signals from weather sensors, etc. // 2010-04-11 <jcw@equi4.com> <a data-cke-saved-href="http://opensource.org/licenses/mit-license.php" href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a> // $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $ class DecodeOOK { protected: byte total_bits, bits, flip, state, pos, data[25]; virtual char decode (word width) =0; public: enum { UNKNOWN, T0, T1, T2, T3, OK, DONE }; DecodeOOK () { resetDecoder(); } bool nextPulse (word width) { if (state != DONE) switch (decode(width)) { case -1: resetDecoder(); break; case 1: done(); break; } return isDone(); } bool isDone () const { return state == DONE; } const byte* getData (byte& count) const { count = pos; return data; } void resetDecoder () { total_bits = bits = pos = flip = 0; state = UNKNOWN; } // add one bit to the packet data buffer virtual void gotBit (char value) { total_bits++; byte *ptr = data + pos; *ptr = (*ptr >> 1) | (value << 7); if (++bits >= 8) { bits = 0; if (++pos >= sizeof data) { resetDecoder(); return; } } state = OK; } // store a bit using Manchester encoding void manchester (char value) { flip ^= value; // manchester code, long pulse flips the bit gotBit(flip); } // move bits to the front so that all the bits are aligned to the end void alignTail (byte max =0) { // align bits if (bits != 0) { data[pos] >>= 8 - bits; for (byte i = 0; i < pos; ++i) data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits)); bits = 0; } // optionally shift bytes down if there are too many of 'em if (max > 0 && pos > max) { byte n = pos - max; pos = max; for (byte i = 0; i < pos; ++i) data[i] = data[i+n]; } } void reverseBits () { for (byte i = 0; i < pos; ++i) { byte b = data[i]; for (byte j = 0; j < 8; ++j) { data[i] = (data[i] << 1) | (b & 1); b >>= 1; } } } void reverseNibbles () { for (byte i = 0; i < pos; ++i) data[i] = (data[i] << 4) | (data[i] >> 4); } void done () { while (bits) gotBit(0); // padding state = DONE; } }; // 433 MHz decoders class OregonDecoderV2 : public DecodeOOK { public: OregonDecoderV2() {} // add one bit to the packet data buffer virtual void gotBit (char value) { if(!(total_bits & 0x01)) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); } total_bits++; pos = total_bits >> 4; if (pos >= sizeof data) { resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { byte w = width >= 700; switch (state) { case UNKNOWN: if (w != 0) { // Long pulse ++flip; } else if (32 <= flip) { // Short pulse, start bit flip = 0; state = T0; } else { // Reset decoder return -1; } break; case OK: if (w == 0) { // Short pulse state = T0; } else { // Long pulse manchester(1); } break; case T0: if (w == 0) { // Second short pulse manchester(0); } else { // Reset decoder return -1; } break; } } else { return -1; } return total_bits == 160 ? 1: 0; } }; class OregonDecoderV3 : public DecodeOOK { public: OregonDecoderV3() {} // add one bit to the packet data buffer virtual void gotBit (char value) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); total_bits++; pos = total_bits >> 3; if (pos >= sizeof data) { resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { byte w = width >= 700; switch (state) { case UNKNOWN: if (w == 0) ++flip; else if (32 <= flip) { flip = 1; manchester(1); } else return -1; break; case OK: if (w == 0) state = T0; else manchester(1); break; case T0: if (w == 0) manchester(0); else return -1; break; } } else { return -1; } return total_bits == 80 ? 1: 0; } }; class CrestaDecoder : public DecodeOOK { public: CrestaDecoder () {} virtual char decode (word width) { if (200 <= width && width < 1300) { byte w = width >= 750; switch (state) { case UNKNOWN: if (w == 1) ++flip; else if (2 <= flip && flip <= 10) state = T0; else return -1; break; case OK: if (w == 0) state = T0; else gotBit(1); break; case T0: if (w == 0) gotBit(0); else return -1; break; } } else if (width >= 2500 && pos >= 7) return 1; else return -1; return 0; } }; class KakuDecoder : public DecodeOOK { public: KakuDecoder () {} virtual char decode (word width) { if (180 <= width && width < 450 || 950 <= width && width < 1250) { byte w = width >= 700; switch (state) { case UNKNOWN: case OK: if (w == 0) state = T0; else return -1; break; case T0: if (w) state = T1; else return -1; break; case T1: state += w + 1; break; case T2: if (w) gotBit(0); else return -1; break; case T3: if (w == 0) gotBit(1); else return -1; break; } } else if (width >= 2500 && 8 * pos + bits == 12) { for (byte i = 0; i < 4; ++i) gotBit(0); alignTail(2); return 1; } else return -1; return 0; } }; class XrfDecoder : public DecodeOOK { public: XrfDecoder () {} // see also <a data-cke-saved-href="http://davehouston.net/rf.htm" href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a> virtual char decode (word width) { if (width > 2000 && pos >= 4) return 1; if (width > 5000) return -1; if (width > 4000 && state == UNKNOWN) state = OK; else if (350 <= width && width < 1800) { byte w = width >= 720; switch (state) { case OK: if (w == 0) state = T0; else return -1; break; case T0: gotBit(w); break; } } else return -1; return 0; } }; class HezDecoder : public DecodeOOK { public: HezDecoder () {} // see also <a data-cke-saved-href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a> virtual char decode (word width) { if (200 <= width && width < 1200) { byte w = width >= 600; gotBit(w); } else if (width >= 5000 && pos >= 5 /*&& 8 * pos + bits == 50*/) { for (byte i = 0; i < 6; ++i) gotBit(0); alignTail(7); // keep last 56 bits return 1; } else return -1; return 0; } }; // 868 MHz decoders class VisonicDecoder : public DecodeOOK { public: VisonicDecoder () {} virtual char decode (word width) { if (200 <= width && width < 1000) { byte w = width >= 600; switch (state) { case UNKNOWN: case OK: state = w == 0 ? T0 : T1; break; case T0: gotBit(!w); if (w) return 0; break; case T1: gotBit(!w); if (!w) return 0; break; } // sync error, flip all the preceding bits to resync for (byte i = 0; i <= pos; ++i) data[i] ^= 0xFF; } else if (width >= 2500 && 8 * pos + bits >= 36 && state == OK) { for (byte i = 0; i < 4; ++i) gotBit(0); alignTail(5); // keep last 40 bits // only report valid packets byte b = data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4]; if ((b & 0xF) == (b >> 4)) return 1; } else return -1; return 0; } }; class EMxDecoder : public DecodeOOK { public: EMxDecoder () {} // see also <a data-cke-saved-href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a> virtual char decode (word width) { if (200 <= width && width < 1000) { byte w = width >= 600; switch (state) { case UNKNOWN: if (w == 0) ++flip; else if (flip > 20) state = OK; else return -1; break; case OK: if (w == 0) state = T0; else return -1; break; case T0: gotBit(w); break; } } else if (width >= 1500 && pos >= 9) return 1; else return -1; return 0; } }; class KSxDecoder : public DecodeOOK { public: KSxDecoder () {} // see also <a data-cke-saved-href="http://www.dc3yc.homepage.t-online.de/protocol.htm" href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a> virtual char decode (word width) { if (200 <= width && width < 1000) { byte w = width >= 600; switch (state) { case UNKNOWN: gotBit(w); bits = pos = 0; if (data[0] != 0x95) state = UNKNOWN; break; case OK: state = w == 0 ? T0 : T1; break; case T0: gotBit(1); if (!w) return -1; break; case T1: gotBit(0); if (w) return -1; break; } } else if (width >= 1500 && pos >= 6) return 1; else return -1; return 0; } }; class FSxDecoder : public DecodeOOK { public: FSxDecoder () {} // see also <a data-cke-saved-href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a> virtual char decode (word width) { if (300 <= width && width < 775) { byte w = width >= 500; switch (state) { case UNKNOWN: if (w == 0) ++flip; else if (flip > 20) state = T1; else return -1; break; case OK: state = w == 0 ? T0 : T1; break; case T0: gotBit(0); if (w) return -1; break; case T1: gotBit(1); if (!w) return -1; break; } } else if (width >= 1500 && pos >= 5) return 1; else return -1; return 0; } }; OregonDecoderV2 orscV2; OregonDecoderV3 orscV3; CrestaDecoder cres; KakuDecoder kaku; XrfDecoder xrf; HezDecoder hez; VisonicDecoder viso; EMxDecoder emx; KSxDecoder ksx; FSxDecoder fsx; #define PORT 2 volatile word pulse; #if defined(__AVR_ATmega1280__) void ext_int_1(void) { #else ISR(ANALOG_COMP_vect) { #endif static word last; // determine the pulse length in microseconds, for either polarity pulse = micros() - last; last += pulse; } void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); Serial.print(s); Serial.print(' '); for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } // Serial.print(' '); // Serial.print(millis() / 1000); Serial.println(); decoder.resetDecoder(); } void setup () { Serial.begin(115200); Serial.println("\n[ookDecoder]"); #if !defined(__AVR_ATmega1280__) pinMode(13 + PORT, INPUT); // use the AIO pin digitalWrite(13 + PORT, 1); // enable pull-up // use analog comparator to switch at 1.1V bandgap transition ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE); // set ADC mux to the proper port ADCSRA &= ~ bit(ADEN); ADCSRB |= bit(ACME); ADMUX = PORT - 1; #else attachInterrupt(1, ext_int_1, CHANGE); DDRE &= ~_BV(PE5); PORTE &= ~_BV(PE5); #endif } void loop () { static int i = 0; cli(); word p = pulse; pulse = 0; sei(); //if (p != 0){ Serial.print(++i); Serial.print('\n');} if (p != 0) { if (orscV2.nextPulse(p)) reportSerial("OSV2", orscV2); if (orscV3.nextPulse(p)) reportSerial("OSV3", orscV3); if (cres.nextPulse(p)) reportSerial("CRES", cres); if (kaku.nextPulse(p)) reportSerial("KAKU", kaku); if (xrf.nextPulse(p)) reportSerial("XRF", xrf); if (hez.nextPulse(p)) reportSerial("HEZ", hez); } if (p != 0) { if (viso.nextPulse(p)) reportSerial("VISO", viso); if (emx.nextPulse(p)) reportSerial("EMX", emx); if (ksx.nextPulse(p)) reportSerial("KSX", ksx); if (fsx.nextPulse(p)) reportSerial("FSX", fsx); } }
Можно соорудить свой датчик например на DHT22 и слать с него данные на погодную станцию в формате Oregon. Подробнее по ссылке в скетче ниже.
/* * connectingStuff, Oregon Scientific v2.1 Emitter * <a data-cke-saved-href="http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/" href="http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/" rel="nofollow">http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/</a> * * Copyright (C) 2013 olivier.lebrun@gmail.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define THN132N const byte TX_PIN = 4; const unsigned long TIME = 512; const unsigned long TWOTIME = TIME*2; #define SEND_HIGH() digitalWrite(TX_PIN, HIGH) #define SEND_LOW() digitalWrite(TX_PIN, LOW) // Buffer for Oregon message #ifdef THN132N byte OregonMessageBuffer[8]; #else byte OregonMessageBuffer[9]; #endif /** * \brief Send logical "0" over RF * \details azero bit be represented by an off-to-on transition * \ of the RF signal at the middle of a clock period. * \ Remenber, the Oregon v2.1 protocol add an inverted bit first */ inline void sendZero(void) { SEND_HIGH(); delayMicroseconds(TIME); SEND_LOW(); delayMicroseconds(TWOTIME); SEND_HIGH(); delayMicroseconds(TIME); } /** * \brief Send logical "1" over RF * \details a one bit be represented by an on-to-off transition * \ of the RF signal at the middle of a clock period. * \ Remenber, the Oregon v2.1 protocol add an inverted bit first */ inline void sendOne(void) { SEND_LOW(); delayMicroseconds(TIME); SEND_HIGH(); delayMicroseconds(TWOTIME); SEND_LOW(); delayMicroseconds(TIME); } /** * Send a bits quarter (4 bits = MSB from 8 bits value) over RF * * @param data Source data to process and sent */ /** * \brief Send a bits quarter (4 bits = MSB from 8 bits value) over RF * \param data Data to send */ inline void sendQuarterMSB(const byte data) { (bitRead(data, 4)) ? sendOne() : sendZero(); (bitRead(data, 5)) ? sendOne() : sendZero(); (bitRead(data, 6)) ? sendOne() : sendZero(); (bitRead(data, 7)) ? sendOne() : sendZero(); } /** * \brief Send a bits quarter (4 bits = LSB from 8 bits value) over RF * \param data Data to send */ inline void sendQuarterLSB(const byte data) { (bitRead(data, 0)) ? sendOne() : sendZero(); (bitRead(data, 1)) ? sendOne() : sendZero(); (bitRead(data, 2)) ? sendOne() : sendZero(); (bitRead(data, 3)) ? sendOne() : sendZero(); } /******************************************************************/ /******************************************************************/ /******************************************************************/ /** * \brief Send a buffer over RF * \param data Data to send * \param size size of data to send */ void sendData(byte *data, byte size) { for(byte i = 0; i < size; ++i) { sendQuarterLSB(data[i]); sendQuarterMSB(data[i]); } } /** * \brief Send an Oregon message * \param data The Oregon message */ void sendOregon(byte *data, byte size) { sendPreamble(); //sendSync(); sendData(data, size); sendPostamble(); } /** * \brief Send preamble * \details The preamble consists of 16 "1" bits */ inline void sendPreamble(void) { byte PREAMBLE[]={0xFF,0xFF}; sendData(PREAMBLE, 2); } /** * \brief Send postamble * \details The postamble consists of 8 "0" bits */ inline void sendPostamble(void) { #ifdef THN132N sendQuarterLSB(0x00); #else byte POSTAMBLE[]={0x00}; sendData(POSTAMBLE, 1); #endif } /** * \brief Send sync nibble * \details The sync is 0xA. It is not use in this version since the sync nibble * \ is include in the Oregon message to send. */ inline void sendSync(void) { sendQuarterLSB(0xA); } /******************************************************************/ /******************************************************************/ /******************************************************************/ /** * \brief Set the sensor type * \param data Oregon message * \param type Sensor type */ inline void setType(byte *data, byte* type) { data[0] = type[0]; data[1] = type[1]; } /** * \brief Set the sensor channel * \param data Oregon message * \param channel Sensor channel (0x10, 0x20, 0x30) */ inline void setChannel(byte *data, byte channel) { data[2] = channel; } /** * \brief Set the sensor ID * \param data Oregon message * \param ID Sensor unique ID */ inline void setId(byte *data, byte ID) { data[3] = ID; } /** * \brief Set the sensor battery level * \param data Oregon message * \param level Battery level (0 = low, 1 = high) */ void setBatteryLevel(byte *data, byte level) { if(!level) data[4] = 0x0C; else data[4] = 0x00; } /** * \brief Set the sensor temperature * \param data Oregon message * \param temp the temperature */ void setTemperature(byte *data, float temp) { // Set temperature sign if(temp < 0) { data[6] = 0x08; temp *= -1; } else { data[6] = 0x00; } // Determine decimal and float part int tempInt = (int)temp; int td = (int)(tempInt / 10); int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10); int tempFloat = (int)round((float)(temp - (float)tempInt) * 10); // Set temperature decimal part data[5] = (td << 4); data[5] |= tf; // Set temperature float part data[4] |= (tempFloat << 4); } /** * \brief Set the sensor humidity * \param data Oregon message * \param hum the humidity */ void setHumidity(byte* data, byte hum) { data[7] = (hum/10); data[6] |= (hum - data[7]*10) << 4; } /** * \brief Sum data for checksum * \param count number of bit to sum * \param data Oregon message */ int Sum(byte count, const byte* data) { int s = 0; for(byte i = 0; i<count;i++) { s += (data[i]&0xF0) >> 4; s += (data[i]&0xF); } if(int(count) != count) s += (data[count]&0xF0) >> 4; return s; } /** * \brief Calculate checksum * \param data Oregon message */ void calculateAndSetChecksum(byte* data) { #ifdef THN132N int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff); data[6] |= (s&0x0F) << 4; data[7] = (s&0xF0) >> 4; #else data[8] = ((Sum(8, data) - 0xa) & 0xFF); #endif } /******************************************************************/ /******************************************************************/ /******************************************************************/ void setup() { pinMode(TX_PIN, OUTPUT); Serial.begin(9600); Serial.println("\n[Oregon V2.1 encoder]"); SEND_LOW(); #ifdef THN132N // Create the Oregon message for a temperature only sensor (TNHN132N) byte ID[] = {0xEA,0x4C}; #else // Create the Oregon message for a temperature/humidity sensor (THGR2228N) byte ID[] = {0x1A,0x2D}; #endif setType(OregonMessageBuffer, ID); setChannel(OregonMessageBuffer, 0x20); setId(OregonMessageBuffer, 0xBB); } void loop() { // Get Temperature, humidity and battery level from sensors // (ie: 1wire DS18B20 for température, ...) setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high setTemperature(OregonMessageBuffer, 11.2); #ifndef THN132N // Set Humidity setHumidity(OregonMessageBuffer, 52); #endif // Calculate the checksum calculateAndSetChecksum(OregonMessageBuffer); // Show the Oregon Message for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i) { Serial.print(OregonMessageBuffer[i] >> 4, HEX); Serial.print(OregonMessageBuffer[i] & 0x0F, HEX); } // Send the Message over RF sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer)); // Send a "pause" SEND_LOW(); delayMicroseconds(TWOTIME*8); // Send a copie of the first message. The v2.1 protocol send the // message two time sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer)); // Wait for 30 seconds before send a new message SEND_LOW(); delay(30000); }
Жалуется компилятор на эту строчку
вот что пишет
sketch_sep02a.ino: In function 'void transmit(long unsigned int)':
В сетапе не было строчки по настройке пина передатчика на выход
нашел инфу, спасибо.
нашел инфу, спасибо.
Не поделитесь?)
Библиотека virtual vire поможет Вам в этом вопросе
Жалуется компилятор на эту строчку
1
RemoteSwitch::sendTelegram(code, 11);
// RF transmitter pin - пин радио передатчика
вот что пишет
sketch_sep02a.ino: In function 'void transmit(long unsigned int)':
Спасибо Transformer -понял,что библиотеки разные.С вопросом разобрался.баловался с люстрой ду дома.
Добрый день, всем!
Как сделать чтобы в первом скетче на странице функция ReportSerial возвращала данные s и data как глобальные?
Извините за ламерский вопрос.
Спасибо.
Я тоже прошу прощения за ламерский вопрос, но на КАКОЙ ПИН Arduino UNO подключать приемник? На А0?
Ничего не получается, никаких данных не видно в мониторе. Датчик THGN122N.
Что может быть не так?
C передатчика на приемник получается передавать данные, а орегоновский не ситает ;(
Доброго времени суток!
У меня проблема с эмулятором датчика. Вышеприведенный скетч не воспринимается приемником, в то же время данные с датчика Oregon THGN132N читаются без труда. Почему??? Осцилла нет, мануал по протоколу 2.1 прочитал. Но все равно не вижу, что не так отправляется. Что может быть не так?
У меня проблема с эмулятором датчика. Вышеприведенный скетч не воспринимается приемником, в то же время данные с датчика Oregon THGN132N читаются без труда. Почему??? Осцилла нет, мануал по протоколу 2.1 прочитал. Но все равно не вижу, что не так отправляется. Что может быть не так?
Как я понял там есть некая бага с расчетом контрольной суммы, подробнее посмотрите на сайте который указан в скетче. Если разберетесь в итоге будет здорово.
Приобрёл два датчика THGN132N. даже в непосредственной близости ни один скетч корректно не читает. Оригинальный скетч с хабра читает примерно раз в 2 часа с одного из датчиков. скетч эмулятора работает и корректно 100% пакетов читает с тем-же оборудованием. Пробовал Arduino UNO и NANO несколько плат. Приёмники пробовал XY-MK-5V и супергетординный RR3. Осчцилографом контролирую сигнал есть. Собрал схему сброса датчика OREGON для точной настройки приёмника на частоту, но настройка и так оказалась точной. Похоже, проблема в каких-то таймингах кода при его дешифрации. где это в программе влияет, пока не разобрался. буду подключать анализатор и сравнивать код со статьёй.
Автор оригинального скетча добавил поддержку дополнительных датчиков, скетч ниже, исходники - https://github.com/jcw/jeelib
Датчики:
VisonicDecoder viso;
EMxDecoder emx;
KSxDecoder ksx;
FSxDecoder fsx;
OregonDecoder orsc;
CrestaDecoder cres;
KakuDecoder kaku;
KakuADecoder kakuA; //WvD
XrfDecoder xrf;
HezDecoder hez;
FlamingoDecoder fmgo;
SmokeDecoder smk;
ByronbellDecoder byr;
ElroDecoder elro;
Приемник 433Mhz висит на А0
На выходе теперь так:
HEZ 255 249 255 124 146 211 0
CRES 190 186 250 255 235 190 175 235 255 255 250 255 171 251 239 255 251 234 10
FMGO 85 85 85 85
Приобрёл два датчика THGN132N. даже в непосредственной близости ни один скетч корректно не читает.
Попробуйте именить декодер как тут http://connectingstuff.net/blog/decodage-protocole-oregon-arduino-1/
Мне помогло.
Спасибо, новый скетч работает. разбираюсь пока с HEZ и CRES....
и, похоже, действительно, первый бит преамбулы приёмник проглатывает.
http://connectingstuff.net/blog/decodage-protocole-oregon-arduino-1/ это и в правду помогло!
вычисление контрольной суммы и crc в датчиках Oregon Scientific V 3.0
для примера будут послки с RFXCOM
THGR810
50FA282496101640043E0A
50 приемник сообщает что за протокол и тип датчика
3E и 0A контрольная сумма и crc
поменяем ниблы местами и отбросим A тк это синра
количество ниблов нечетное дополним слева нулем
0F82426901610440
сумма ниблов даст контрольную сумму 3E
а crc вычисляется с начальным значением 0 и полиномом 0x07
unsigned char Crc8(char *pcBlock, unsigned char len){
unsigned char crc = 0x00;
unsigned char i, data;
while (len--){
data = *pcBlock++;
crc ^= data;
for (i = 0; i < 8; i++) crc = crc & 0x80 ? (crc <<1) ^ 0x07 : crc << 1;
}
return crc;
}
теперь попробуем разобраться с содежимым посылки
THGR810
50FA282496101640043E0A
первый значащий нибл 2, в мануале называетя выбор канала, это таймслот в котором работает датчик.
все датчики должны пердавать данные через строго определеные промежутки времени.
если по какой то причини датчик выпадает из своего таймслота амс его теряет.
для THGR810 существует 10 таймслотов 53 59 61 67 71 79 83 87 91 93 секунд.
сл пара ниблов 96, это ид сеанса или адрес датчика, меняется каждый раз при сбросе датчика.
назначается рандомно но должен удовлетворять условию 7 бит = 2 xor 0
1 = десяты градуса
0 стрший бит b3 этого нибла будет в единице сразу после сброса,
скорее всего сообщает амс не архировать данные. падает в 0 черз 32посылки.
b2 сообщает о разряде батареи.
b1? b0 ?
1 единицы градусов
6 десятки градусов
4 единицы влажности
0 b3 =1 отрицательная температура
b2 = температура вне диапазона
b1 ?
b0 ?
0 индекс комфорта, см ниже
4 десятки влажности
0 индекс комфорта
0 -> 8 41% -> 40% 25
8 -> 0 40% -> 41% 25
0 -> C 70% -> 71% 25
C -> 0 71% -> 70% 25
4 -> 8 41% -> 40% 24
8 -> 4 40% -> 41% 24
4 -> C 70% -> 71% 24
C -> 4 71% -> 70% 24
0 -> 4 19.9 -> 20.0 55%
4 -> 0 20.0 -> 19.9 55%
0 -> 4 24.9 -> 25.0 55%
4 -> 0 25.0 -> 24.9 55%
0 температура вне диапазона влажность в диапазоне
4 температура и влажность в диапазоне
8 влажность ниже
С влажность выше
UVN800
48DA78146500F00641B5 темный
48DA7814651050083AF2 солнце
65 адрес
1 UV индекс
5 мл нибл
8 ст нибл зависит от уровня освещенности, начальное значение 6F.
кллка с 4 сатиметров 70, 1UV 80, 2UV 8B
Привет.
Имею дома погодную станцию OregonSciencific с 3-мя датчиками THGR122N.
Собрал ардуинку и приемник на 433Mhz. Но приемник принимает сигналы от датчика только на расстоянии около 10 см.
Если дальше, то не видит ничего.
Пробовал такой приемник
И вот такой
Сейчас заказал приемник на супергетеродине (433Mhz Superheterodyne 3400RF), но уже жду подвоха.
Поделитесь опытом: кто какой приемник использует для приема орегоновских датчиков и как далеко они работают.
Мне бы добиться уверено приема на расстоянии 10 метров через пару гипсовых стен.
а антенну получше не пробовал подцепить, но сначала частоту подстроить. крутилка в центре платы. но только пластиковой отверткой
а антенну получше не пробовал подцепить
Пробовал: вместо проволки намотаной на приемнике с первой картинк припаял 17см кусок 1,5мм^2 медного провода. Результат не сильно поменялся. Конечно нельзя исключать мои кривые руки, но я все ж склонен думать, что приемник фиговый.
крутилка в центре платы. но только пластиковой отверткой
Ох ты, не знал про крутилку.
А не подскажешь какой порядок подстройки?
Просто отодвинуть подальше датчик, покрутить крутилку и ждать с него посылки?
отодвинул когда пропал прием и подкручиваешь, появился сигнал отнеси еще дальше и так пока не настроишь на максимум . а потом еще антенну можно добавить. но с антенной есть вероятноть что потребуется допольнительная подстройка
Спасибо! Пробую!
Ну а про приемник что посоветовать можешь?
Те что я выше привел могут работать с датчиками на на расстоянии 10 метров через стены?
да хз какая у него чувствительность. пробуй. норм антенна плюс подстройка должно легко, зависит какая мощность у передатчика, чувствительность приемника, уровень шума и т.д.
Чтобы НОРМАЛЬНО работало в городских условиях где куча автосигнализаций и прочего хлама на канале 433 Мгц, нужно ставить супергетеродин. я использую вот такие модели приёмников:
RX-AM4SF стоимость ~400p
RX-4MM5++ стоимость ~200p в последнее время только их и использую!
У меня несколько объектов функционируют прекрасно! Даже соседские датчики ловит. Антенна - 17см кусок 1,5мм медной проволоки.
Для настройки аппаратуры на начальном этапе использовал эмулятор дачика, который практически непрерывно слал сигналл и ждать не приходилос.
Чтобы НОРМАЛЬНО работало в городских условиях где куча автосигнализаций и прочего хлама на канале 433 Мгц, нужно ставить супергетеродин. я использую вот такие модели приёмников:
RX-AM4SF стоимость ~400p
RX-4MM5++ стоимость ~200p в последнее время только их и использую!
У меня несколько объектов функционируют прекрасно! Даже соседские датчики ловит. Антенна - 17см кусок 1,5мм медной проволоки.
Для настройки аппаратуры на начальном этапе использовал эмулятор дачика, который практически непрерывно слал сигналл и ждать не приходилос.
Спасибо за совет!
А скажите, а как вот эти два приемника, что вы упомянули, настраиваются? Там вроде нет крутилки в катушке, как на тех, что я выше картинки приводил?
Там ПАВ фильтр! Приёмник настроен лазером на заводе! В настройке не нуждается! Чуствительность и избирательность таких приёмников существенно выше!
Там ПАВ фильтр! Приёмник настроен лазером на заводе! В настройке не нуждается! Чуствительность и избирательность таких приёмников существенно выше!
Понял, спасибо!
но тут и проблема может быть. приемник настроен на определенную частоту, а метеостанция работает на другой
если для связи между собой конечно хорошо подходит, но не для устройства с другой частотой
но тут и проблема может быть. приемник настроен на определенную частоту, а метеостанция работает на другой
если для связи между собой конечно хорошо подходит, но не для устройства с другой частотой
ну вот с теми приемниками, что приводил выше картинки, именно эта проблема: после того как подкрутил стержень в катушке, расстояние уверенного распознования увеличилось, но, к сожалению, не сильно.
С другой стороны вроде советуют (тут и не только)нормальный гетеродиновый приемник применить.
Может с ним получится
и сколько стало? с какой антенной?
и сколько стало? с какой антенной?
да, по-существу, прибавка ерунда: было 1-2 см, стало около 50 см.
Антенна 17 см тонкой медной проволки.
Дело было ночью, потому не было сил продолжать настройку.
Сейчас заказал супергетеродинный приемник RRQ3-433 и антенну к нему с SMA разъемом.
Как приедет буду его мучить. Надеюсь взлетит.
супергетеродинный конечно лучше, но вот покупать нужно на частоту твоей метеостанции. и плясать от этого. узнаешь частоту и покупаешь. на 433 мгц много частот вообще то на которые делают передатчики и приемника. например 432.7 и 433.92. и врядли они будут хорошо друг с другом хорошо работать
безусловно.
Мой датчик thgr122N, если верить информации в интернете, передает на частоте 433.92.
Приемник, который я заказал, судя по документации, тоже работает на 433.92.
ну тогда должно получится
А посоветуйте с ebay какой-нибудь супергетеродинный приемник, пожалуйста.
А посоветуйте с ebay какой-нибудь супергетеродинный приемник, пожалуйста.
Если есть брелок(можно убитый) с экраном от сигнализации старлайн или томогавк-там модуль приемопередатчика на 433,92 мгц.Приемниктам супергетеродинный.ЕДИНСТВЕННОЕ цоколевка этого модуля-ее можно найти на фрикерклубе.Модуль питается напряжением 3,3-5,0 вольт ,управляется работа приемника подачей низкого уровня на вывод свитч.
в радиобрелке приемопередатчик скорее окажется с частотной модуляцией(или фазовой, как кому больше нрав), а на фото вверху девайсы с амплитудной модуляцией, это нужно учитывать.
частоту видно по количеству витков на катушке - 2 витка 433, 3 витка 315
Кстати в тему -я б не советовал у сверхрегенеративных приёмников (на фото Т.С) трогать катушки, у них и так диапазон захвата немерянный. Если ловит только на расстояние 10см -то скорее всего китайские товарищи прислали приёмник на другую частоту. Типа ну нет у нас 433Мгц сейчас, положим на 315. :) Тут даже нечего экперементировать, нельзя так сдвинуть катушку, что-б частота на 100мГц выросла. Всё это пустатая трата времени. Нужно заказывать снова.
Кстати в тему -я б не советовал у сверхрегенеративных приёмников (на фото Т.С) трогать катушки, у них и так диапазон захвата немерянный. Если ловит только на расстояние 10см -то скорее всего китайские товарищи прислали приёмник на другую частоту. Типа ну нет у нас 433Мгц сейчас, положим на 315. :) Тут даже нечего экперементировать, нельзя так сдвинуть катушку, что-б частота на 100мГц выросла. Всё это пустатая трата времени. Нужно заказывать снова.
Похоже на то.
Вообще, видимо такие приемники можно использовать только с передатчиками, которые идут в комплекте: только в этом случае есть большая вероятность что они протестированы на работу с друг другом, но частота их работы может сильно плавать.
на фото в певом после гавенный приемник.. передатчик еще боле-менее но.
второе - такой приемник как на фото нужно питать стабильными 5в!!! это важно. вы питаете от ардуина а там не 5в а меньше если с юсб.
далее - все соединения на приемник - паять! тогда будет работать.
в радиобрелке приемопередатчик скорее окажется с частотной модуляцией(или фазовой, как кому больше нрав), а на фото вверху девайсы с амплитудной модуляцией, это нужно учитывать.
частоту видно по количеству витков на катушке - 2 витка 433, 3 витка 315
Частотная модуляция у сигналки шерхан,старлайны и томогавки работают в ам модуляции
все в ам или только старые? помоему не все..
Шерханы старые вроде и на АМ были.Старлайна А6,А9 -АМ сто процентов.Диалоговые стары вроде тоже ам,но там частота скачет у трансиверов
ам и скачет?? то не АМ.. я понял, вы просто строите догадки и не знаете что к чему на самом деле.
В итоге проблема решилась заменой приемника на RRQ3-433.
Все заработало, только надо выключить подстроечный резистр на ноге, куда данные приходят
и сколько отдали денег?
565 р .