Чтение и эмуляция датчиков Oregon Scientific (433Mhz)

Porosenok
Offline
Зарегистрирован: 06.11.2016

Кстати, на днях собирал в едином корпусе транслятор данных с датчиков на narodmon. Заметил ещё такую особенность - приёмник надо относить от контроллера подальше, контроллер очень сильно фонит. Поэтому в одном корпусе не вышло...

snickser
Offline
Зарегистрирован: 02.07.2016

Сейчас будет вопрос, как две DATA в один PWM2 вставить )))

 

RogerRU
RogerRU аватар
Offline
Зарегистрирован: 08.11.2016

snickser пишет:

Сейчас будет вопрос, как две DATA в один PWM2 вставить )))

 

))) вопрос на 5 баллов )) Имелось в виду, что пофиг какой DATA соединять с D2 т.к. по сути это один вывод, просто выведен на 2 контакта. 

Зачем так сделано? - не знаю.

Sprite
Offline
Зарегистрирован: 30.10.2016

Porosenok пишет:

Sprite пишет:

На приемнике       На Ардуино

 1)   VCC         -           +5

2)                   -         GND

3)                   -         PWM 2

4)  GND          -         GND

Может надо так:

 1)   VCC         -           +5

2)    DATA        -         PWM 2

3)    DATA        -         PWM 2

4)  GND          -         GND

Спасибо за ответ.

Убрал один провод DATA от GND и всё заработало.

Sprite
Offline
Зарегистрирован: 30.10.2016

Sprite пишет:
Убрал один провод DATA от GND и всё заработало.


У меня есть в наличии 4 разных модели датчика Oregon. Сигнал ринимается только от двух. Есть ли возможность добавить другие модели датчика?

RogerRU
RogerRU аватар
Offline
Зарегистрирован: 08.11.2016

Sprite пишет:
У меня есть в наличии 4 разных модели датчика Oregon. Сигнал ринимается только от двух. Есть ли возможность добавить другие модели датчика?

Смотря какие датчики. Разные датчики используют разные версии протоколов. Всего их 3 - v1.0 , v2.1 и v3.0

Обсуждаемый в данной ветке код работает с версией протокола 2.1 Вбейте в google модель ваших датчиков и выясните версию протокола RF

Если протокол 2.1, то видимо что то с датчиком

 

gulin176
Offline
Зарегистрирован: 03.09.2016

thgn800 датчик не видит. Была у меня классная станция, ребёнок разбил, датчик остался

Sprite
Offline
Зарегистрирован: 30.10.2016

RogerRU пишет:

Sprite пишет:
У меня есть в наличии 4 разных модели датчика Oregon. Сигнал ринимается только от двух. Есть ли возможность добавить другие модели датчика?

Смотря какие датчики. Разные датчики используют разные версии протоколов. Всего их 3 - v1.0 , v2.1 и v3.0

Обсуждаемый в данной ветке код работает с версией протокола 2.1 Вбейте в google модель ваших датчиков и выясните версию протокола RF

Если протокол 2.1, то видимо что то с датчиком

 


Датчик такой Oregon RTGN318.
Рабочий на 100%. Метеостанция с ним работает отлично.
Не смог найти версию RF.

Porosenok
Offline
Зарегистрирован: 06.11.2016

RTGN318 - пятиканальный с дальностью в 70м. Оба видовых признака версии 3.0

Sprite
Offline
Зарегистрирован: 30.10.2016

Porosenok пишет:

RTGN318 - пятиканальный с дальностью в 70м. Оба видовых признака версии 3.0


Спасибо за разъяснение. Просто на предыдущей страницы высказывалось мнение, что это 2.1.

А есть подобные скетчи или темы работающие с 3.0?

Porosenok
Offline
Зарегистрирован: 06.11.2016

На первой странице векти форума вроде бы был скетч, поддерживающий все версии.

Sprite
Offline
Зарегистрирован: 30.10.2016

Porosenok пишет:

На первой странице векти форума вроде бы был скетч, поддерживающий все версии.


Судя по описанию похоже на то.
Спасибо, попробую.

Sprite
Offline
Зарегистрирован: 30.10.2016

Sprite пишет:
Porosenok пишет:

На первой странице векти форума вроде бы был скетч, поддерживающий все версии.

Судя по описанию похоже на то. Спасибо, попробую.

Скетч из первого поста темы у меня не заработал. Пишет только DecoderOK и всё.

На обновлённый скетч из 14 поста темы ругается компилятор, не могу понять в чём проблема.

RogerRU
RogerRU аватар
Offline
Зарегистрирован: 08.11.2016

Sprite пишет:

На обновлённый скетч из 14 поста темы ругается компилятор, не могу понять в чём проблема.

Что пишет то?

Sprite
Offline
Зарегистрирован: 30.10.2016

RogerRU пишет:

Sprite пишет:

На обновлённый скетч из 14 поста темы ругается компилятор, не могу понять в чём проблема.

Что пишет то?

Ругается на библиотеку "#include "decoders.h" которой нет по ссылке https://github.com/jcw/jeelib

Sprite
Offline
Зарегистрирован: 30.10.2016

Подскажите, кто нибудь смог скомпилировать и загрузить скетч из этого поста?

http://arduino.ru/forum/proekty/chtenie-i-emulyatsiya-datchikov-oregon-s...

Sprite
Offline
Зарегистрирован: 30.10.2016

kaluganin пишет:

Продолжая тему, если кому интересно сделал веб серверок с отображением датчиков орегоновских. отличие - основной код вынесен в библиотеки.


Не могли бы вы поделиться библиотеками?

snickser
Offline
Зарегистрирован: 02.07.2016

Sprite пишет:

Скетч из первого поста темы у меня не заработал. Пишет только DecoderOK и всё.

На обновлённый скетч из 14 поста темы ругается компилятор, не могу понять в чём проблема.

Используйте код из поста №113. Тот что на первой странице - глуховат.

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Sprite пишет:

Скетч из первого поста темы у меня не заработал. Пишет только DecoderOK и всё.

На обновлённый скетч из 14 поста темы ругается компилятор, не могу понять в чём проблема.

Используйте код из поста №113. Тот что на первой странице - глуховат.


Он не поддерживает v.3

snickser
Offline
Зарегистрирован: 02.07.2016
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;
    }
};

http://jeelabs.net/projects/cafe/wiki/Decoding_the_Oregon_Scientific_V2_...

Sprite
Offline
Зарегистрирован: 30.10.2016

Этого кода нет в посте #113. В какое место его добавить?

snickser
Offline
Зарегистрирован: 02.07.2016

Ну, там по аналогии легко догадаться... с первого раза ))

Вставляете рядом с кодом V2...

OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;
        if (orscV2.nextPulse(p))
            reportSerial("OSV2", orscV2);  
        if (orscV3.nextPulse(p))
            reportSerial("OSV3", orscV3);       

Только меня терзают смутные сомнения, что он так же "глуховат" как и оригинальный, так как взять оттуда же...
А Вы уверены, что у вас там именно v3 протокол в эфире?

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Ну, там по аналогии легко догадаться... с первого раза ))

Вставляете рядом с кодом V2...

OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;
        if (orscV2.nextPulse(p))
            reportSerial("OSV2", orscV2);  
        if (orscV3.nextPulse(p))
            reportSerial("OSV3", orscV3);       

Только меня терзают смутные сомнения, что он так же "глуховат" как и оригинальный, так как взять оттуда же...

Догадаться то можно легко, но не всегда это работает.

Я вот уже второй день пытаюсь переделать скетч от Ув. Porosenok, чтобы он выодил на экран 1602, вместо 2004 и всё безрезультатно(((

snickser пишет:

А Вы уверены, что у вас там именно v3 протокол в эфире?

Porosenok пишет:

RTGN318 - пятиканальный с дальностью в 70м. Оба видовых признака версии 3.0

snickser
Offline
Зарегистрирован: 02.07.2016

Ну, вы попробуйте для начала... Как уже и говорил код V2 декодера в посте #113 лучше "слышит" датчики.

Вот полный код, попробуйте его

// RF Receiver

#define PORT 2


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 (w == 0 && 24 <= 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 if (width >= 2500  && pos >= 8) 
         {
            return 1;
         } 
         else 
         {
            return -1;
         }
         return 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="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" href="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" rel="nofollow"><a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a></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="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" href="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" rel="nofollow"><a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a></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="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a></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="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" href="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" rel="nofollow"><a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a></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="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a></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;


volatile word pulse;

void ext_int_1(void) {
    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(String(millis()/1000.,3) + " ");
    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.println();
    decoder.resetDecoder();
}


void setup () {
    Serial.begin(9600);
    Serial.println("\n[ookDecoder]");
    
    pinMode(PORT, INPUT);  // use the AIO pin

   attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);



}

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);       
      }
}


 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Ну, вы попробуйте для начала... Как уже и говорил код V2 декодера в посте #113 лучше "слышит" датчики.

Вот полный код, попробуйте его

Спасибо за полный код. Попробовал.

В Serial что то идёт. 

[ookDecoder]
16.260 OSV2 1A2D10B14023508235F0
16.648 OSV2 1A2D10B14023508235F0
18.329 HEZ 7DF7DD75775D03
26.703 OSV2 EA4C404480237073
26.704 HEZ 
26.931 OSV2 EA4C404480237073
26.933 HEZ 
54.733 OSV2 CACC338E0823108359A5
55.601 OSV2 1A2D10B14023508235F0
69.703 HEZ F6FF9FDFFFE703
69.962 OSV2 EA4C404490238003
69.963 HEZ F2FF9FDFFFE703
71.372 OSV2 BACC1391000330C84BBA
94.260 OSV2 1A2D10B14023508235F0
94.613 OSV2 1A2D10B14023508235F0
112.703 HEZ FFFF399F243901
112.948 OSV2 EA4C4044002400A3
112.950 HEZ 
115.649 OSV2 BACC338E282310835A9A
124.304 HEZ 7DDD5DD7FD7D01
133.260 OSV2 1A2D10B15023508236E6
133.615 OSV2 1A2D10B15023508236E6
155.704 HEZ FF679F77F6FF01
155.974 OSV2 EA4C404401241013
155.975 HEZ 
172.260 OSV2 1A2D10B15023508236E6
172.666 OSV2 1A2D10B15023508236E6
176.404 OSV2 AACC338E482300835A24
176.733 OSV2 AACC338E482300835A24
177.145 HEZ FFFFFFFFEBFA02
198.703 OSV2 EA4C404411242063
199.016 OSV2 EA4C404411242063
211.260 OSV2 1A2D10B16023508237DC
211.614 OSV2 1A2D10B16023508237DC
 

Что нужно добавить в код, чтобы это расшифровать?

И судя по всему v.3 не видит.

Рядом с приёмником лежат три датчика:

Канал 1 - THGN122N

Канал 2 - THN132N

Канал 3 - RTGN318

 

snickser
Offline
Зарегистрирован: 02.07.2016

Ну, OSV2 1A2D10B14023508235F0 - это точно Орегон, на первом канале.

Про остальные надо думать.

Формат строки очень прост

1A:2D:10:B1:40:23:50:82:35:F0

Byte Code Sample Example Description
0..1 bytes[0], bytes[1] 1A2D Device Model ID
2 (upper 4 bits) bytes[2]>>4 1 Channel (1)
note: channels were 1,2,4- 4 is channel 3.
2 (lower) bytes[2]&0x0F 0 Unknown
3 bytes[3] B1 Rolling Code
Reported to change on battery replacement.
4 (upper) bytes[4]>>4 4 Tenths place of temp in degrees celsius
BCD format
4 (lower) bytes[4]&0x0F 0 Battary status
5 (upper) bytes[5]>>4 2 Tens place of temp in degrees celsius
BCD format
5 (lower) bytes[5]&0x0F 3 Ones place of temp in degrees celsius
BCD format
6 (upper) bytes[6]>>4 5 Humidity ones place
BCD format
6 (lower) bytes[6]&0x0F 0 Sign of degrees
Non zero indicates negative
7 (upper) bytes[7]>>4 8 Unknown
7 (lower) bytes[7]&0x0F 2 Humidity tems place
BCD format
8 bytes[8] 35 Checksum
9 bytes[9] F0 CRC

Получаем 23.4 градуса и 25% влажность. Надо только проверку Checksum делать, потому как CRC не всегда приезжает из того кода.

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Ну, OSV2 1A2D10B14023508235F0 - это точно Орегон, на первом канале.

Про остальные надо думать.

Формат строки очень прост

1A:2D:10:B1:40:23:50:82:35:F0

Получаем 23.4 градуса и 25% влажность. Надо только проверку Checksum делать, потому как CRC не всегда приезжает из того кода.

Есть другие рабочие коды, которые сразу выдают параметры температуры и влажности, но они v.3 так же не видят, вот в чём проблема.

snickser
Offline
Зарегистрирован: 02.07.2016

Ну смотрите, у вас ещё приезжает

OSV2 AACC338E482300835A24

и

OSV2 EA4C404411242063

Это два других датчика. Тот что код короче скорее всего THN132N , потому как он без влажности. Но он говорит что на 4 канале (третий, а не второй как вы написали). А тот что длинее скорее всего RTGN318. Или это вы соседские датчики видите ))

EA4C:40:44:11:24:20:63

24.1 градуса... третий канал. Вроде подходит.

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Ну смотрите, у вас ещё приезжает

OSV2 AACC338E482300835A24

и

OSV2 EA4C404411242063

Это два других датчика. Тот что код короче скорее всего THN132N , потому как он без влажности. Но он говорит что на 4 канале (третий, а не второй как вы написали). А тот что длинее скорее всего RTGN318. Или это вы соседские датчики видите ))

EA4C:40:44:11:24:20:63

24.1 градуса... третий канал. Вроде подходит.

 

Вы можете помочь и дописать скетч, чтобы он сразу переводил в понятные цифры?

Я не думаю, что это соседские датчики.

snickser
Offline
Зарегистрирован: 02.07.2016

ну держите... ;)

// RF Receiver

#define PORT 2


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 (w == 0 && 24 <= 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 if (width >= 2500  && pos >= 8) 
         {
            return 1;
         } 
         else 
         {
            return -1;
         }
         return 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;
    }
};


OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;

volatile word pulse;

void ext_int_1(void) {
    static word last;
    // determine the pulse length in microseconds, for either polarity
    pulse = micros() - last;
    last += pulse;
}

//
// Oregon packet decoder
//

float temperature(const byte* data)
{
   int sign = (data[6]&0x8) ? -1 : 1;
   float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0);
   return sign * temp;
}

byte humidity(const byte* data)
{
   return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4) ;
}

float humi_ext(const byte* data)
{
   return  humidity(data) + ((data[7]&0xF0)>>4)/10.0 ;
}

byte battery(const byte* data)
{
   return (data[4] & 0xF) ;
}

byte serial(const byte* data)
{
   return (data[3]);
}

byte channel(const byte* data)
{
   byte channel;
   switch (data[2]>>4)
   {
      case 0x1:
         channel = 1;
         break;
      case 0x2:
         channel = 2;
         break;
      case 0x4:
         channel = 3;
         break;
   }
 return channel;
} 

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;
}


void reportSerial (const char* s, class DecodeOOK& decoder) {
    byte pos;
    const byte* data = decoder.getData(pos);
    Serial.print(String(millis()/1000.,3) + " ");
    Serial.print(s);
    Serial.print(' ');
    for (byte i = 0; i < pos; ++i) {
        Serial.print(data[i] >> 4, HEX);
        Serial.print(data[i] & 0x0F, HEX);
    }

    if( data[8] == (Sum(8,data)-0xa)&0xFF ){
      Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
      Serial.print(" "+String(temperature(data),1)+" "+String(humidity(data))+"%");
      Serial.print(" "+String(battery(data)));
    } else if( data[6] == (Sum(6,data)-0xa)&0xFF ){
      Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
      Serial.print(" "+String(temperature(data),1));
      Serial.print(" "+String(battery(data)));
    } else {
      Serial.print(" Checksumm error");
    }
   
    Serial.println();

    decoder.resetDecoder();
}




void setup () {
    Serial.begin(9600);
    Serial.println("\n[ookDecoder]");
    
    pinMode(PORT, INPUT);  // use the AIO pin

   attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);



}

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);        
      }
}


 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

ну держите... ;)

Спасибо вам ОГРОМНОЕ!

Датчик за окном RTGN318 - канал 1:

36.486 OSV2 BACC1391200300C84AA9 1 91 3.2 80% 0

 
Датчик на столе RTGN318 - канал 2:
 
236.027 OSV2 CACC23AE082500835B17 2 ae 25.0 30% 8
 
Датчик на столе THN132N - канал 3:
 
758.457 OSV2 EA4C40651825D093 Checksumm error
При нажати на датчике Reset снова
844.545 OSV2 EA4C406558251024 Checksumm error
При нажати на датчике Reset снова
886.723 OSV2 EA4C409E88250085 Checksumm error
 
 

 

snickser
Offline
Зарегистрирован: 02.07.2016

Sprite пишет:

886.723 OSV2 EA4C409E88250085 Checksumm error

Честно говоря я поставил наугад, у меня таких нет чтоб проверить... докрутите код сами )

Вот оригинальный код подсчёта контрольных сум, первая часть для датчиков без влажности.

/**
 * \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
}

 

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Sprite пишет:

886.723 OSV2 EA4C409E88250085 Checksumm error

Честно говоря я поставил наугад, у меня таких нет чтоб проверить... докрутите код сами )

Знал бы что крутить, покрутил бы.

Спасибо за помощь.

Самое главное, что V.3 работает.

snickser
Offline
Зарегистрирован: 02.07.2016

Нет у вас там никакого V3... ;) все ваши датчики используют протокол v2

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Нет у вас там никакого V3... ;) все ваши датчики используют протокол v2

 


Если так, то почему же не работают датчики RTGN318 с кодом, с которым прекрасно работают датчики THGN122N и THN132N?

snickser
Offline
Зарегистрирован: 02.07.2016

В смысле? Вы же сами писали только что...

Датчик на столе RTGN318 - канал 2:
 
236.027 OSV2 CACC23AE082500835B17 2 ae 25.0 30% 8
 
Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

В смысле? Вы же сами писали только что...

Датчик на столе RTGN318 - канал 2:
 
236.027 OSV2 CACC23AE082500835B17 2 ae 25.0 30% 8
 


Так этот датчик только и работает с кодом который вы подправили, добавили v.3 в код из поста#113.
С другими кодами RTGN318 не работает, т.к. там только v.2 прописана.

snickser
Offline
Зарегистрирован: 02.07.2016

Да, но он не используется :) иначе бы вместо OSV2 там писалось бы OSV3 =)

Я лишь использовал код декодера V2 тот что работает лучше по моему мнению, и именно он то у вас и заработал!... )

 

 

 

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Да, но он не используется :) иначе бы вместо OSV2 там писалось бы OSV3 =)

Я лишь использовал код декодера V2 тот что работает лучше по моему мнению, и именно он то у вас и заработал!... )

 

 

 

 


Тогда странно.

Я попробую код из #113 и проверю, какие датчики работают, а какие нет. Ведь в нём нет поддержки v.3?

Вы ведь в код из #113 добавили только v.3?

snickser
Offline
Зарегистрирован: 02.07.2016

Вот, держите, возможно сработает... ;)

// RF Receiver


#define PORT 2


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 (w == 0 && 24 <= 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 if (width >= 2500  && pos >= 8) 
         {
            return 1;
         } 
         else 
         {
            return -1;
         }
         return 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;
    }
};


OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;

volatile word pulse;

void ext_int_1(void) {
    static word last;
    // determine the pulse length in microseconds, for either polarity
    pulse = micros() - last;
    last += pulse;
}

//
// Oregon packet decoder
//

float temperature(const byte* data)
{
   int sign = (data[6]&0x8) ? -1 : 1;
   float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0);
   return sign * temp;
}

byte humidity(const byte* data)
{
   return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4) ;
}

float humi_ext(const byte* data)
{
   return  humidity(data) + ((data[7]&0xF0)>>4)/10.0 ;
}

byte battery(const byte* data)
{
   return (data[4] & 0xF) ;
}

byte serial(const byte* data)
{
   return (data[3]);
}

byte channel(const byte* data)
{
   byte channel;
   switch (data[2]>>4)
   {
      case 0x1:
         channel = 1;
         break;
      case 0x2:
         channel = 2;
         break;
      case 0x4:
         channel = 3;
         break;
   }
 return channel;
} 

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;
}


void reportSerial (const char* s, class DecodeOOK& decoder) {
    byte pos;
    const byte* data = decoder.getData(pos);
    Serial.print(millis()/1000.,3);
    Serial.print(" ");
    Serial.print(s);
    Serial.print(' ');
    for (byte i = 0; i < pos; ++i) {
        Serial.print(data[i] >> 4, HEX);
        Serial.print(data[i] & 0x0F, HEX);
    }

    if( data[8] == (Sum(8,data)-0xa)&0xFF ){
      Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
      Serial.print(" "+String(temperature(data),1)+" "+String(humidity(data))+"%");
      Serial.print(" "+String(battery(data)));
    } else {
      int sum = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
      if( (sum&0xF) == (data[6]>>4) && (sum>>4) == (data[7]&0xF) ){
        Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
        Serial.print(" "+String(temperature(data),1));
        Serial.print(" "+String(battery(data)));
      } else {
        Serial.print(" Checksum error");
      }
    }
    Serial.println();

    decoder.resetDecoder();
}




void setup () {
    Serial.begin(9600);
    Serial.println("\n[ookDecoder]");
    
    pinMode(PORT, INPUT);  // use the AIO pin

   attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);



}

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);        
      }
}


 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:
Вот, держите, возможно сработает... ;)

Спасибо!

Для RTGN318 результат выводит по 2 одинаковые строки:

295.576 OSV2 DACC132E08251083547B 1 2e 25.0 31% 8
295.905 OSV2 DACC132E08251083547B 1 2e 25.0 31% 8
348.557 OSV2 CACC132E1825108354B2 1 2e 25.1 31% 8
348.897 OSV2 CACC132E1825108354B2 1 2e 25.1 31% 8
401.556 OSV2 BACC132E1825008352B4 1 2e 25.1 30% 8
401.905 OSV2 BACC132E1825008352B4 1 2e 25.1 30% 8
 
Для THN132N результат по одной строке:
445.208 OSV2 EA4C2099482660F4 2 99 26.4 8
485.897 OSV2 EA4C209958267084 2 99 26.5 8
649.896 OSV2 EA4C209968268014 2 99 26.6 8
 
Для THGN122N результат по одной строке:
1025.863 OSV2 1A2D10FB182670824D81 1 fb 26.1 27% 8
1064.863 OSV2 1A2D10FB582650824FF3 1 fb 26.5 25% 8
1104.116 OSV2 1A2D10FB6826508250C9 1 fb 26.6 25% 8
 
Буду проверять совместную работу нескольких датчиков, т.к. до этого проверял каждый в отдельности.
 
Sprite
Offline
Зарегистрирован: 30.10.2016

Для RTGN318 при выборе разных каналов выдаёт такое:

1 - 1 a8

2 - 2 28

3 - 103 a7

4 - 3 ab

5 - 103 2d

snickser
Offline
Зарегистрирован: 02.07.2016

Я не знаю как программируются каналы в этом датчике, дело в том что в документации на этот счёт пусто. Кроме стандартных значений 1,2,4 тот код ничего не умеет понимать.

Покажите полные пакеты от датчика на 3 и 5 канале, можно будет придумать как их показывать.

 

 

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Я не знаю как программируются каналы в этом датчике, дело в том что в документации на этот счёт пусто. Кроме стандартных значений 1,2,4 тот код ничего не умеет понимать.

Покажите полные пакеты от датчика на 3 и 5 канале, можно будет придумать как их показывать.

3 канал на RTGN318:

2287.793 OSV2 DACC3326282600835067 103 26 26.2 30% 8

2348.788 OSV2 CACC3326282600834FB8 103 26 26.2 30% 8
 
2409.788 OSV2 BACC3326282600834EAB 103 26 26.2 30% 8
 
5 канал на RTGN318:
 
2444.322 OSV2 DACC5397382600835B3A 103 97 26.3 30% 8
 
2515.318 OSV2 CACC539728269082613E 103 97 26.2 29% 8
 
2586.318 OSV2 BACC53970826008356CC 103 97 26.0 30% 8
 
Почему то в serial для него идут по две посылки.
 

 

snickser
Offline
Зарегистрирован: 02.07.2016

А вот интересно, у вас есть пятиканальная базовая станция которая умеет этот датчик показывать?... Что будет, точнее как по порядку они выстроятся на базе, если сделать два датчика один на 3-ем канале, а другой на 4-ом... )

Дело в том, что номера каналов могут быть числом 1,2,4 (старший разряд третьего бита), но у ваших датчиков там может быть 1,2,3,4,5. Вот и интересно, что случится если смешать 3 и 4. Как их база расставить. Дело в том что старые базы число 4 воспринимают как третий канал.

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

А вот интересно, у вас есть пятиканальная базовая станция которая умеет этот датчик показывать?... Что будет, точнее как по порядку они выстроятся на базе, если сделать два датчика один на 3-ем канале, а другой на 4-ом... )

Дело в том, что номера каналов могут быть числом 1,2,4 (старший разряд третьего бита), но у ваших датчиков там может быть 1,2,3,4,5. Вот и интересно, что случится если смешать 3 и 4. Как их база расставить. Дело в том что старые базы число 4 воспринимают как третий канал.

Дело в том, что у меня станция Oregon BAR 800, с ней в комплекте датчик RTGN318. В инструкции к станции написано, что канал установить на "1". Станция может отображать только один канал, нет переключения по каналам. Даже на экране нет отображения номера канала. Мало того, если установить канал отличный от "1", то сигнал с него станция примет только один раз и больше не примет, поэтому со станцией работают датчики только с первым каналом. 

snickser
Offline
Зарегистрирован: 02.07.2016

Тогда найдите и поменяйте вот эту функцию на эту

byte channel(const byte* data)
{
   byte channel;
   switch (data[2])
   {
      case 0x10:
         channel = 1;
         break;
      case 0x20:
         channel = 2;
         break;
      case 0x40:
         channel = 3;
         break;
      case 0x13:
         channel = 1;
         break;
      case 0x23:
         channel = 2;
         break;
      case 0x33:
         channel = 3;
         break;
      case 0x43:
         channel = 4;
         break;
      case 0x53:
         channel = 5;
         break;
   }
 return channel;
} 

Думается число 3 в младшем разряде у вас будет постоянно.

Или вот более изящно )))

byte channel(const byte* data)
{
   byte channel;
   switch (data[2]>>4)
   {
      case 0x1:
         channel = 1;
         break;
      case 0x2:
         channel = 2;
         break;
      case 0x3:
         channel = 3;
         break;
      case 0x4:
         if(data[2]==0x43){
          channel = 4;
         } else {
          channel = 3;
         } 
         break;
      case 0x5:
         channel = 5;
         break;
   }
 return channel;
} 

 

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

Тогда найдите и поменяйте вот эту функцию на эту

Поменял.

Для RTGN318.

Устанавливаю канал - 1.

Нажимаю Reset на датчике.

6.074 OSV2 DACC131F6825908362A7 1 1f 25.6 39% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
170.604 OSV2 DACC138D9825208363E2 1 8d 25.9 32% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
252.697 OSV2 DACC132A08261083519A 1 2a 26.0 31% 8
 

Устанавливаю канал - 2.

Нажимаю Reset на датчике.

307.760 OSV2 DACC232908261083513C 2 29 26.0 31% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
331.787 OSV2 DACC23AA182610835B2A 2 aa 26.1 31% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
360.492 OSV2 DACC23A918260083593F 2 a9 26.1 30% 8
 

Устанавливаю канал - 3.

Нажимаю Reset на датчике.

402.447 OSV2 DACC33AA182600835B5D 3 aa 26.1 30% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
416.822 OSV2 DACC33A9182600835A5D 3 a9 26.1 30% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
433.499 OSV2 DACC332908260083514B 3 29 26.0 30% 8
 

Устанавливаю канал - 4.

Нажимаю Reset на датчике.

452.415 OSV2 DACC43A8182600835A74 4 a8 26.1 30% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
468.444 OSV2 DACC4328082600835162 4 28 26.0 30% 8
 
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
490.780 OSV2 DACC4319082600835162 4 19 26.0 30% 8
 

Устанавливаю канал - 5.

Нажимаю Reset на датчике.

513.392 OSV2 DACC531B082600835400 5 1b 26.0 30% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
528.997 OSV2 DACC531A082600835300 5 1a 26.0 30% 8
 
Нажимаю ещё раз Reset на датчике (канал не меняю).
553.587 OSV2 DACC5329082600835300 5 29 26.0 30% 8
 
snickser
Offline
Зарегистрирован: 02.07.2016

ну, норм. =)

Sprite
Offline
Зарегистрирован: 30.10.2016

snickser пишет:

ну, норм. =)


Да, спасибо за помощь!
Буду с этим дальше возиться.
Выводить на экран 1602 и отправка на narodmon.