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

4ishops
Offline
Зарегистрирован: 06.10.2012

Информация по датчикам 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);
}

 

dimka
dimka аватар
Offline
Зарегистрирован: 21.09.2012
/* урок от Дмитрия Осипова - узнаём коды кнопок пульта от радиопультов, для (радио розеток)
http://www.youtube.com/user/d36073?feature=watch*/
#include <RemoteReceiver.h>
// Connect the receiver to digital pin 2.-пин 2.это вход для Радиоприёмника
void setup() {
  Serial.begin(9600);  
  RemoteReceiver::init(0, 3, showCode);
}
void loop() {
}
void showCode(unsigned long receivedCode, unsigned int period) {  
  Serial.print("Code: ");
  Serial.print(receivedCode);
  Serial.print(", period duration: ");
  Serial.print(period);
  Serial.println("us.");
}
/*жмем на иконку с лупой, в верхнем правом углу (монитор порта)
записываем полученные коды (можно на бумаге) шутка!*/
// урок от Дмитрия Осипова. http://www.youtube.com/user/d36073?feature=watch
//отсылаем коды кнопок (радиопультов - от радио розеток)с ПК - через (монитор порта)-(COM порт)
#include <RemoteSwitch.h> // это скачанная библиотека
//коды кнопок от радиопультов, для радио розеток
// как? узнать коды кнопок пульта от радиопультов, для (радио розеток). (видеоурок я выложил на YouTube)
#define RF1ON 18062   //(18062) код кнопки от радиопульта с (8 кнопками) для радио розеток, из леруа мерлен.
#define RF1OFF 18060
#define RF2ON 19034
#define RF2OFF 19032
#define RF3ON 15146
#define RF3OFF 15144

#define RFF1 359349 //(359349)код кнопки от другого радиопульта с (3 кнопками) для радио розеток, №2.
#define RFF2 359331
#define RFF3 359323


#define PERIOD 294;  //(294) period duration: - полученные из (монитор порта)
#define PERIOD 342;
#define PERIOD 343;

void setup()
{
  Serial.begin(9600);   //установка порта на скорость 9600 бит/сек
}
void loop()
{
  while (Serial.available() == 0); //функция  Serial.аvailable() проверяет, есть ли в COM порте доступные для чтения данные, мы будем «топтаться» на месте и ожидать данные.
  int val = Serial.read() - '0'; 
  if (val == 1) transmit(RF1ON);   //если с COM порта поступил символ (1), начинаем отправлять через пин №11 (там радио передатчик),- код кнопки №1 радио пульта  
  if (val == 2) transmit(RF1OFF);
  if (val == 3) transmit(RF2ON); 
  if (val == 4) transmit(RF2OFF);
  if (val == 5) transmit(RF3ON);
  if (val == 6) transmit(RF3OFF);
  if (val == 7) {transmit(RF1ON);transmit(RF2ON);transmit(RF3ON);}  //если с (COM порта) поступил символ (7),- (включаем сразу 3 розетки)
  if (val == 8) {transmit(RF1OFF);transmit(RF2OFF);transmit(RF3OFF);}
  
  if (val == 9) transmit(RFF1);
  if (val == 0) transmit(RFF3);

  
  } 
  
  void transmit(unsigned long rcode){

unsigned long code = rcode;

unsigned long period = PERIOD;

code |= (unsigned long)period << 23;

code |= 4L << 20; //(|= 4L) цифра перед (L), это (условное число), количества повторов посылаемого сигнала. (соответственно и паузы)

RemoteSwitch::sendTelegram(code, 11); // RF transmitter pin - пин радио передатчика
    
 }  

 

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Жалуется компилятор на эту строчку 

RemoteSwitch::sendTelegram(code, 11); // RF transmitter pin - пин радио передатчика

вот что пишет 

sketch_sep02a.ino: In function 'void transmit(long unsigned int)':

sketch_sep02a:53: error: 'sendTelegram' was not declared in this scope
 
fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

В сетапе не было строчки по настройке пина передатчика на выход

Transformer
Offline
Зарегистрирован: 20.09.2013

нашел инфу, спасибо.

pdmitry2
Offline
Зарегистрирован: 03.07.2013

Transformer пишет:

нашел инфу, спасибо.

Не поделитесь?)

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Библиотека virtual vire поможет Вам в этом вопросе

Transformer
Offline
Зарегистрирован: 20.09.2013
fly245
-

Жалуется компилятор на эту строчку 

1 RemoteSwitch::sendTelegram(code, 11); // RF transmitter pin - пин радио передатчика

вот что пишет 

sketch_sep02a.ino: In function 'void transmit(long unsigned int)':

sketch_sep02a:53: error: 'sendTelegram' was not declared in this scope
 
Оказалось что библиотеки RemoteSwitch разные по своему "содержанию" на одной библиотеке у меня всё работало. а на другой такаяже проблема появилась))) Удалил все обновлённые библиотеки, вернул старые и снова стало все хорошо.
 
Кстати, fly245 если проблема у тебя не решилась, библиотеку RemoteSwitch для работы Димкиного кода могу подкинуть или сам скачай унего должно быть подходящая.
fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Спасибо Transformer -понял,что библиотеки разные.С вопросом разобрался.баловался с люстрой ду дома.

tammat
Offline
Зарегистрирован: 07.10.2011

Добрый день, всем!

Как сделать чтобы в первом скетче на странице функция ReportSerial возвращала данные s и data как глобальные?

 

Извините за ламерский вопрос.

Спасибо.

PAV
Offline
Зарегистрирован: 29.10.2012

Я тоже прошу прощения за ламерский вопрос, но на КАКОЙ ПИН Arduino UNO подключать приемник? На А0?

Ничего не получается, никаких данных не видно в мониторе. Датчик THGN122N.

Что может быть не так?

C передатчика на приемник получается передавать данные, а орегоновский не ситает ;(

vladiv
Offline
Зарегистрирован: 18.03.2014

Доброго времени суток!

У меня проблема с эмулятором датчика. Вышеприведенный скетч не воспринимается приемником, в то же время данные с датчика Oregon THGN132N читаются без труда. Почему??? Осцилла нет, мануал по протоколу 2.1 прочитал. Но все равно не вижу, что не так отправляется. Что может быть не так?

4ishops
Offline
Зарегистрирован: 06.10.2012

vladiv пишет:

У меня проблема с эмулятором датчика. Вышеприведенный скетч не воспринимается приемником, в то же время данные с датчика Oregon THGN132N читаются без труда. Почему??? Осцилла нет, мануал по протоколу 2.1 прочитал. Но все равно не вижу, что не так отправляется. Что может быть не так?

 

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

 

zarro
Offline
Зарегистрирован: 26.04.2014

Приобрёл два датчика THGN132N.  даже в непосредственной близости ни один скетч корректно не читает. Оригинальный скетч с хабра читает примерно раз в 2 часа с одного из датчиков. скетч эмулятора работает и корректно 100% пакетов читает с тем-же оборудованием. Пробовал Arduino UNO и  NANO несколько плат. Приёмники пробовал XY-MK-5V и  супергетординный RR3.  Осчцилографом контролирую сигнал есть. Собрал схему сброса датчика OREGON для точной настройки приёмника на частоту, но настройка и так оказалась точной. Похоже, проблема в каких-то таймингах кода при его дешифрации. где это в программе влияет, пока не разобрался. буду подключать анализатор и сравнивать код со статьёй.

 

4ishops
Offline
Зарегистрирован: 06.10.2012

Автор оригинального скетча добавил поддержку дополнительных датчиков, скетч ниже, исходники - 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

 

/// @dir ookRelay2
/// Generalized decoder and relay for 868 MHz and 433 MHz OOK signals.
// 2010-04-11 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <JeeLib.h>
#include "decoders.h"

#define DEBUG 1     // set to 1 to also report results on the serial port
//#define DEBUG_LED // define as pin 1..19 to blink LED on each pin change
#define NODO 0      // use the Nodo shield hardware (only 433 MHz receiver)

// RF12 communication settings
#define NODEID 19
#define NETGRP 5

// I/O pin allocations, leave any of these undefined to omit the code for it
#if NODO
//#define PIN_433 2     // D.2 = 433 MHz receiver
#define POWER_433 12  // must be 1 to supply power to the receiver
#define DEBUG_LED 13  // std Arduino led is also red status led
#else
//#define USE_RF12 1    // only set if the RFM12B hardware is present
//#define PIN_868 14    // AIO1 = 868 MHz receiver
#define PIN_433 14    // AIO4 = 433 MHz receiver
//#define PIN_DCF 15    // AIO2 = DCF77 receiver
#endif

#if PIN_868
VisonicDecoder viso;
EMxDecoder emx;
KSxDecoder ksx;
FSxDecoder fsx;

DecoderInfo di_868[] = {
    { 1, "VISO", &viso },
    { 2, "EMX", &emx },
    { 3, "KSX", &ksx },
    { 4, "FSX", &fsx },
    { -1, 0, 0 }
};

// State to track pulse durations measured in the interrupt code
volatile word pulse_868;
word last_868; // never accessed outside ISR's

ISR(ANALOG_COMP_vect) {
    word now = micros();
    pulse_868 = now - last_868;
    last_868 = now;
}
#endif

#if PIN_433
OregonDecoder orsc;
CrestaDecoder cres;
KakuDecoder kaku;
KakuADecoder kakuA; //WvD
XrfDecoder xrf;
HezDecoder hez;
FlamingoDecoder fmgo;
SmokeDecoder smk;
ByronbellDecoder byr;
ElroDecoder elro;

DecoderInfo di_433[] = {
    { 5, "ORSC", &orsc },
    { 6, "CRES", &cres },
    { 7, "KAKU", &kaku },
    { 8, "XRF", &xrf },
    { 9, "HEZ", &hez },
    { 10, "ELRO", &elro },
    { 11, "FMGO", &fmgo },
    { 12, "SMK", &smk },
    { 13, "BYR", &byr },
    { 14, "KAKUA", &kakuA },
    { -1, 0, 0 }
};

// State to track pulse durations measured in the interrupt code
volatile word pulse_433;
word last_433; // never accessed outside ISR's

#if PIN_433 >= 14
#define VECT PCINT1_vect
#elif PIN_433 >= 8
#define VECT PCINT0_vect
#else
#define VECT PCINT2_vect
#endif

ISR(VECT) {
    word now = micros();
    pulse_433 = now - last_433;
    last_433 = now;
}
#endif

// Outgoing data buffer for RF12
byte packetBuffer [RF12_MAXDATA], packetFill;

// Timer to only relay packets up to 10x per second, even if more come in.
MilliTimer sendTimer;

static void setupPinChangeInterrupt () {
#if PIN_868
    pinMode(PIN_868, INPUT);
    digitalWrite(PIN_868, 1);   // pull-up
    
    // enable analog comparator with fixed voltage reference
    ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE);
    ADCSRA &= ~ _BV(ADEN);
    ADCSRB |= _BV(ACME);
    ADMUX = PIN_868 - 14;
#endif

#if PIN_433
    pinMode(PIN_433, INPUT);
    digitalWrite(PIN_433, 1);   // pull-up

    // interrupt on pin change
#if PIN_433 >= 14
    bitSet(PCMSK1, PIN_433 - 14);
    bitSet(PCICR, PCIE1);
#elif PIN_433 >= 8
    bitSet(PCMSK0, PIN_433 - 8);
    bitSet(PCICR, PCIE0);
#else
    bitSet(PCMSK2, PIN_433);
    bitSet(PCICR, PCIE2);
#endif
#endif
}

// Append a new data item to the outgoing packet buffer (if there is room
static void addToBuffer (byte code, const char* name, const byte* buf, byte len) {
#if DEBUG
    Serial.print(name);
    for (byte i = 0; i < len; ++i) {
        Serial.print(' ');
        Serial.print((int) buf[i]);
    }
    // Serial.print(' ');
    // Serial.print(millis() / 1000);
    Serial.println();
#endif

    if (packetFill + len < sizeof packetBuffer) {
        packetBuffer[packetFill++] = code + (len << 4);
        memcpy(packetBuffer + packetFill, buf, len);
        packetFill += len;
    } else {
#if DEBUG
        Serial.print(" dropped: ");
        Serial.print(name);
        Serial.print(", ");
        Serial.print((int) len);
        Serial.println(" bytes");
#endif        
    }
}

static void addDecodedData (DecoderInfo& di) {
    byte size;
    const byte* data = di.decoder->getData(size);
    addToBuffer(di.typecode, di.name, data, size);
    di.decoder->resetDecoder();
}

// Check for a new pulse and run the corresponding decoders for it
static void runPulseDecoders (DecoderInfo* pdi, volatile word& pulse) {
    // get next pulse with and reset it - need to protect against interrupts
    cli();
    word p = pulse;
    pulse = 0;
    sei();

    // if we had a pulse, go through each of the decoders
    if (p != 0) { 
#if DEBUG_LED
        digitalWrite(DEBUG_LED, 1);
#endif
        while (pdi->typecode >= 0) {
            if (pdi->decoder->nextPulse(p))
                addDecodedData(*pdi);
            ++pdi;
        }
#if DEBUG_LED
        digitalWrite(DEBUG_LED, 0);
#endif
    }
}

// see http://jeelabs.org/2011/01/27/ook-reception-with-rfm12b-2/
static void rf12_init_OOK () {
    rf12_initialize(0, RF12_868MHZ);

    rf12_control(0x8027); // 8027    868 Mhz;disabel tx register; disable RX
                          //         fifo buffer; xtal cap 12pf, same as xmitter
    rf12_control(0x82c0); // 82C0    enable receiver; enable basebandblock 
    rf12_control(0xA68a); // A68A    868.2500 MHz
    rf12_control(0xc691); // C691    c691 datarate 2395 kbps 0xc647 = 4.8kbps 
    rf12_control(0x9489); // 9489    VDI; FAST;200khz;GAIn -6db; DRSSI 97dbm 
    rf12_control(0xC220); // C220    datafiltercommand; ** not documented cmd 
    rf12_control(0xCA00); // CA00    FiFo and resetmode cmd; FIFO fill disabeld
    rf12_control(0xC473); // C473    AFC run only once; enable AFC; enable
                          //         frequency offset register; +3 -4
    rf12_control(0xCC67); // CC67    pll settings command
    rf12_control(0xB800); // TX register write command not used
    rf12_control(0xC800); // disable low dutycycle 
    rf12_control(0xC040); // 1.66MHz,2.2V not used see 82c0  
}

// DCF77 radio clock signal decoder
#if PIN_DCF

static word dcfWidth;
static byte dcfLevels, dcfBits, dcfParity, dcfValue[8], dcfBuf[6];

static byte dcfExtract (byte pos, byte len) {
    word *p = (word*) (dcfValue + (pos >> 3));
    byte val = (*p >> (pos & 7)) & ((1 << len) - 1);
    return val - (val / 16) * 6; // bcd -> dec
}

static byte dcfMinute () {
    dcfBuf[0] = dcfExtract(50, 8);
    dcfBuf[1] = dcfExtract(45, 5);
    dcfBuf[2] = dcfExtract(36, 6);
    dcfBuf[3] = dcfExtract(29, 6);
    dcfBuf[4] = dcfExtract(21, 7);
    dcfBuf[5] = dcfExtract(17, 1);
    return 1 <= dcfBuf[0] && dcfBuf[0] <= 99 &&
            1 <= dcfBuf[1] && dcfBuf[1] <= 12 &&
             1 <= dcfBuf[2] && dcfBuf[2] <= 31 &&
              dcfBuf[3] <= 23 && dcfBuf[4] <= 59;
}

static void dcf77setup () {
    pinMode(PIN_DCF, INPUT);
    digitalWrite(PIN_DCF, 1); // pull-up
}

static byte dcf77poll () {
    byte ok = 0;
    static word last;
    word now = millis();
    if (now != last) {
        // track signal levels using an 8-bit shift register
        dcfLevels = (dcfLevels << 1) | digitalRead(PIN_DCF);
#if DEBUG_LED
        digitalWrite(DEBUG_LED, dcfLevels & 1);
#endif
        if (dcfLevels == 0x07F) {
            // found one 0 followed by seven 1's
            if (dcfWidth > 1000) {
                if (dcfBits == 59)
                    ok = dcfMinute();
                memset(dcfValue, 0, sizeof dcfValue);
                dcfBits = 0;
            }
            dcfWidth = 0;
        } else if (dcfLevels == 0xFE) {
            // found seven 1's followed by one 0
// Serial.print(" >");
// Serial.println((int) dcfWidth);
            if (dcfWidth >= 144) {
                dcfValue[dcfBits>>3] |= _BV(dcfBits & 7);
                dcfParity ^= 1;
            }
            switch (++dcfBits) {
                case 15: dcfParity = 0;
                case 29: case 36: case 59: if (dcfParity) dcfBits = 0;
            }
            dcfWidth = 0;
        }

        dcfWidth += now - last;
        last = now;
    }
    return ok;
}

#endif // PIN_DCF

void setup () {
#if DEBUG_LED   
    pinMode(DEBUG_LED, 1);
    // brief LED flash on startup to make sure it works
    digitalWrite(DEBUG_LED, 1);
    delay(100);
    digitalWrite(DEBUG_LED, 0);
#endif

#if DEBUG
    Serial.begin(57600);
    Serial.println("\n[ookRelay2]");
#endif

#if USE_RF12
#if PIN_868
    rf12_init_OOK();
#else
    rf12_initialize(NODEID, RF12_868MHZ, NETGRP);
#endif
#endif

#if PIN_433
    setupPinChangeInterrupt();
#endif

#if POWER_433
    pinMode(POWER_433, 1);
    digitalWrite(POWER_433, 1);
#endif

#if PIN_DCF
    dcf77setup();
#endif
}

void loop () {
#if PIN_868
    runPulseDecoders(di_868, pulse_868);    
#endif

#if PIN_433
    runPulseDecoders(di_433, pulse_433);   
#endif

#if PIN_DCF
    if (dcf77poll())
        addToBuffer(0, "DCF", dcfBuf, sizeof dcfBuf);
#endif 

    if (sendTimer.poll(100) && packetFill > 0) {
#if USE_RF12
#if PIN_868
        rf12_initialize(NODEID, RF12_868MHZ, NETGRP);
#endif
        rf12_sendNow(0, packetBuffer, packetFill);
        rf12_sendWait(1);
#if PIN_868
        rf12_init_OOK();
#endif
#endif
        packetFill = 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
 

freem
Offline
Зарегистрирован: 21.03.2014

zarro пишет:

Приобрёл два датчика THGN132N.  даже в непосредственной близости ни один скетч корректно не читает.

Попробуйте именить декодер как тут http://connectingstuff.net/blog/decodage-protocole-oregon-arduino-1/
Мне помогло.

zarro
Offline
Зарегистрирован: 26.04.2014

Спасибо, новый скетч работает. разбираюсь пока с HEZ  и  CRES....

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

http://connectingstuff.net/blog/decodage-protocole-oregon-arduino-1/ это и в правду помогло!

XOR
Offline
Зарегистрирован: 25.04.2015

вычисление контрольной суммы и 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;
}

XOR
Offline
Зарегистрирован: 25.04.2015

теперь попробуем разобраться с содежимым посылки

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 влажность ниже
С влажность выше

XOR
Offline
Зарегистрирован: 25.04.2015

UVN800
48DA78146500F00641B5 темный
48DA7814651050083AF2 солнце

65 адрес
1 UV индекс
5 мл нибл
8 ст нибл зависит от уровня освещенности, начальное значение 6F.
кллка с 4 сатиметров 70, 1UV 80, 2UV 8B

re3lex
Offline
Зарегистрирован: 02.06.2015

Привет.

Имею дома погодную станцию OregonSciencific с 3-мя датчиками THGR122N.

Собрал ардуинку и приемник на 433Mhz. Но приемник принимает сигналы от датчика только на расстоянии около 10 см.

Если дальше, то не видит ничего.

Пробовал такой приемник

И вот такой

 

Сейчас заказал приемник на супергетеродине (433Mhz Superheterodyne 3400RF), но уже жду подвоха.

 

Поделитесь опытом: кто какой приемник использует для приема орегоновских датчиков и как далеко они работают.

Мне бы добиться уверено приема на расстоянии 10 метров через пару гипсовых стен.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а антенну получше не пробовал подцепить, но сначала частоту подстроить. крутилка в центре платы. но только пластиковой отверткой

re3lex
Offline
Зарегистрирован: 02.06.2015

jeka_tm пишет:

а антенну получше не пробовал подцепить

Пробовал: вместо проволки намотаной на приемнике с первой картинк припаял 17см кусок 1,5мм^2 медного провода. Результат не сильно поменялся. Конечно нельзя исключать мои кривые руки, но я все ж склонен думать, что приемник фиговый.

re3lex
Offline
Зарегистрирован: 02.06.2015

jeka_tm пишет:

крутилка в центре платы. но только пластиковой отверткой

 

Ох ты, не знал про крутилку.

А не подскажешь какой порядок подстройки?

Просто отодвинуть подальше датчик, покрутить крутилку и ждать с него посылки?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

отодвинул когда пропал прием и подкручиваешь, появился сигнал отнеси еще дальше и так пока не настроишь на максимум . а потом еще антенну можно добавить. но с антенной есть вероятноть что потребуется допольнительная подстройка

re3lex
Offline
Зарегистрирован: 02.06.2015

Спасибо! Пробую!

Ну а про приемник что посоветовать можешь?

Те что я выше привел могут работать с датчиками на на расстоянии 10 метров через стены?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

zarro
Offline
Зарегистрирован: 26.04.2014

Чтобы НОРМАЛЬНО работало в городских условиях где куча автосигнализаций и прочего хлама на канале 433 Мгц, нужно ставить супергетеродин. я использую вот такие модели приёмников:

RX-AM4SF  стоимость ~400p

RX-4MM5++    стоимость ~200p в последнее время только их и использую!

У меня несколько объектов функционируют прекрасно! Даже соседские датчики ловит. Антенна - 17см кусок 1,5мм медной проволоки. 

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

re3lex
Offline
Зарегистрирован: 02.06.2015

zarro пишет:

Чтобы НОРМАЛЬНО работало в городских условиях где куча автосигнализаций и прочего хлама на канале 433 Мгц, нужно ставить супергетеродин. я использую вот такие модели приёмников:

RX-AM4SF  стоимость ~400p

RX-4MM5++    стоимость ~200p в последнее время только их и использую!

У меня несколько объектов функционируют прекрасно! Даже соседские датчики ловит. Антенна - 17см кусок 1,5мм медной проволоки. 

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

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

А скажите, а как вот эти два приемника, что вы упомянули, настраиваются? Там вроде нет крутилки в катушке, как на тех, что я выше картинки приводил?

zarro
Offline
Зарегистрирован: 26.04.2014

Там ПАВ фильтр! Приёмник настроен лазером на заводе! В настройке не нуждается! Чуствительность и избирательность таких приёмников существенно выше!

re3lex
Offline
Зарегистрирован: 02.06.2015

zarro пишет:

Там ПАВ фильтр! Приёмник настроен лазером на заводе! В настройке не нуждается! Чуствительность и избирательность таких приёмников существенно выше!

Понял, спасибо!

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

но тут и проблема может быть. приемник настроен на определенную частоту, а метеостанция работает на другой

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

re3lex
Offline
Зарегистрирован: 02.06.2015

jeka_tm пишет:

но тут и проблема может быть. приемник настроен на определенную частоту, а метеостанция работает на другой

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

ну вот с теми приемниками, что приводил выше картинки, именно эта проблема: после того как подкрутил стержень в катушке, расстояние уверенного распознования увеличилось, но, к сожалению, не сильно.

С другой стороны вроде советуют (тут и не только)нормальный гетеродиновый приемник применить.

Может с ним получится

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

и сколько стало? с какой антенной?

re3lex
Offline
Зарегистрирован: 02.06.2015

jeka_tm пишет:

и сколько стало? с какой антенной?

да, по-существу, прибавка ерунда: было 1-2 см, стало около 50 см.

Антенна 17 см тонкой медной проволки.

Дело было ночью, потому не было сил продолжать настройку.

Сейчас заказал супергетеродинный приемник RRQ3-433 и антенну к нему с SMA разъемом.

Как приедет буду его мучить. Надеюсь взлетит.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

супергетеродинный конечно лучше, но вот покупать нужно на частоту твоей метеостанции. и плясать от этого. узнаешь частоту и покупаешь. на 433 мгц много частот вообще то на которые делают передатчики и приемника. например 432.7 и 433.92. и врядли они будут хорошо друг с другом хорошо работать

re3lex
Offline
Зарегистрирован: 02.06.2015

безусловно.

Мой датчик thgr122N, если верить информации в интернете, передает на частоте 433.92.

Приемник, который я заказал, судя по документации, тоже работает на 433.92.

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну тогда должно получится

PAV
Offline
Зарегистрирован: 29.10.2012

А посоветуйте с ebay какой-нибудь супергетеродинный приемник, пожалуйста.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

PAV пишет:

А посоветуйте с ebay какой-нибудь супергетеродинный приемник, пожалуйста.

Если есть брелок(можно убитый) с экраном от сигнализации старлайн или томогавк-там модуль приемопередатчика на 433,92 мгц.Приемниктам супергетеродинный.ЕДИНСТВЕННОЕ  цоколевка  этого модуля-ее можно найти на фрикерклубе.Модуль питается напряжением  3,3-5,0 вольт ,управляется работа приемника  подачей  низкого уровня на вывод свитч.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

в радиобрелке приемопередатчик скорее окажется с частотной модуляцией(или фазовой, как кому больше нрав), а на фото вверху девайсы с амплитудной модуляцией, это нужно учитывать.

 

частоту видно по количеству витков на катушке - 2 витка 433, 3 витка 315

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Кстати в тему -я б не советовал у сверхрегенеративных приёмников (на фото Т.С) трогать катушки, у них и так диапазон захвата немерянный. Если ловит только на расстояние 10см -то скорее всего китайские товарищи прислали приёмник на другую частоту. Типа ну нет у нас 433Мгц сейчас, положим на 315. :) Тут даже нечего экперементировать, нельзя так сдвинуть катушку, что-б частота на 100мГц выросла. Всё это пустатая трата времени. Нужно заказывать снова.

re3lex
Offline
Зарегистрирован: 02.06.2015

dimax пишет:

Кстати в тему -я б не советовал у сверхрегенеративных приёмников (на фото Т.С) трогать катушки, у них и так диапазон захвата немерянный. Если ловит только на расстояние 10см -то скорее всего китайские товарищи прислали приёмник на другую частоту. Типа ну нет у нас 433Мгц сейчас, положим на 315. :) Тут даже нечего экперементировать, нельзя так сдвинуть катушку, что-б частота на 100мГц выросла. Всё это пустатая трата времени. Нужно заказывать снова.

Похоже на то.

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

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

на фото в певом после гавенный приемник.. передатчик еще боле-менее но.

второе - такой приемник как на фото нужно питать стабильными 5в!!! это важно. вы питаете от ардуина а там не 5в а меньше если с юсб.

далее - все соединения на приемник - паять!  тогда будет работать.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Short Circuit пишет:

в радиобрелке приемопередатчик скорее окажется с частотной модуляцией(или фазовой, как кому больше нрав), а на фото вверху девайсы с амплитудной модуляцией, это нужно учитывать.

 

частоту видно по количеству витков на катушке - 2 витка 433, 3 витка 315

Частотная модуляция у сигналки шерхан,старлайны и томогавки работают в ам модуляции

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

все в ам или только старые?  помоему не все..

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Шерханы старые вроде и на АМ были.Старлайна  А6,А9 -АМ сто процентов.Диалоговые стары вроде тоже ам,но там частота скачет у трансиверов

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

ам и скачет?? то не АМ.. я понял, вы просто строите догадки и не знаете что к чему на самом деле.

re3lex
Offline
Зарегистрирован: 02.06.2015

В итоге проблема решилась заменой приемника на RRQ3-433.

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

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

и сколько отдали денег?

re3lex
Offline
Зарегистрирован: 02.06.2015

565 р .