Arduino Uno based Oregon Scientific v 2.1 sensor emulator transmission

Well, it’s been a good while since our last post but there is a good excuse for it, there is a new product coming soon in the shop, a new temperature and humidity sensor so keep visiting us..

Now, for today I am going to make public a piece of code that was worked on by Olivier Lebrun of http://connectingstuff.net. He managed to put the code together to send in an Oregon Scientific v 2.1 format information that can be received and decoded by an Arduino RF shield. As we know up to know if you searched the Internet you will find loads and loads of examples of code that will receive RF signals from Oregon sensors but no code to transmit, well he did it so fair play to him.
What we did we just added an Sension SHT temperature/Humidity Sensor and some lines of code and now we had a fully working Arduino Based Oregon like sensor.

Here is the code produced by adding to Olivier’s code:

/*
 * connectingStuff, Oregon Scientific v2.1 Emitter
 * http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/
 *
 * Copyright (C) 2013 olivier.lebrun@gmail.com
 * Sensirion data added 03/2013
 * 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.
*/
int SHT_clockPin = 2;  // pin used for clock
int SHT_dataPin  = 3;  // pin used for data
#undef THN132N

const byte TX_PIN = 11;
 
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(0×00);
#else
  byte POSTAMBLE[]={0×00};
  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 (0×10, 0×20, 0×30)
 */
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] = 0×00;
}
 
/**
 * \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] = 0×08;
    temp *= -1;
  }
  else
  {
    data[6] = 0×00;
  }
 
  // 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);
  pinMode(13, 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, 0×20);
  setId(OregonMessageBuffer, 0xBB);
}
 
void loop()

 

 
{
  float temperature = getTemperature();
  float humidity = getHumidity();
  Serial.print(” | “);
  Serial.print(temperature);
  Serial.print(” | “);
  Serial.println(humidity);

  // Get Temperature, humidity and battery level from sensors
  // (ie: 1wire DS18B20 for température, …)
  setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
  setTemperature(OregonMessageBuffer, temperature);
 
#ifndef THN132N
  // Set Humidity
  setHumidity(OregonMessageBuffer, humidity);
#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 copy 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();
 
  digitalWrite(13, LOW);
  delay(30000);
  digitalWrite(13, HIGH);
}
float getTemperature(){
  //Return Temperature in Celsius
  SHT_sendCommand(B00000011, SHT_dataPin, SHT_clockPin);
  SHT_waitForResult(SHT_dataPin);

  int val = SHT_getData(SHT_dataPin, SHT_clockPin);
  SHT_skipCrc(SHT_dataPin, SHT_clockPin);
  return (float)val * 0.01 – 40; //convert to celsius
}

float getHumidity(){
  //Return  Relative Humidity
  SHT_sendCommand(B00000101, SHT_dataPin, SHT_clockPin);
  SHT_waitForResult(SHT_dataPin);
  int val = SHT_getData(SHT_dataPin, SHT_clockPin);
  SHT_skipCrc(SHT_dataPin, SHT_clockPin);
  return -4.0 + 0.0405 * val + -0.0000028 * val * val;
}

void SHT_sendCommand(int command, int dataPin, int clockPin){
  // send a command to the SHTx sensor
  // transmission start
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, LOW);

  // shift out the command (the 3 MSB are address and must be 000, the last 5 bits are the command)
  shiftOut(dataPin, clockPin, MSBFIRST, command);

  // verify we get the right ACK
  digitalWrite(clockPin, HIGH);
  pinMode(dataPin, INPUT);

  if (digitalRead(dataPin)) Serial.println(“ACK error 0″);
  digitalWrite(clockPin, LOW);
  if (!digitalRead(dataPin)) Serial.println(“ACK error 1″);
}

void SHT_waitForResult(int dataPin){
  // wait for the SHTx answer
  pinMode(dataPin, INPUT);

  int ack; //acknowledgement

  //need to wait up to 2 seconds for the value
  for (int i = 0; i < 1000; ++i){
    delay(2);
    ack = digitalRead(dataPin);
    if (ack == LOW) break;
  }

  if (ack == HIGH) Serial.println(“ACK error 2″);
}

int SHT_getData(int dataPin, int clockPin){
  // get data from the SHTx sensor

  // get the MSB (most significant bits)
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  byte MSB = shiftIn(dataPin, clockPin, MSBFIRST);

  // send the required ACK
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);

  // get the LSB (less significant bits)
  pinMode(dataPin, INPUT);
  byte LSB = shiftIn(dataPin, clockPin, MSBFIRST);
  return ((MSB << 8) | LSB); //combine bits
}

void SHT_skipCrc(int dataPin, int clockPin){
  // skip CRC data from the SHTx sensor
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
}

Now, there are a few small things to be done, one is to change the code and add the posibility to change the channel easily with a switch?
But who wants to use an Arduino Uno just to have a sensor working?
Let’s make it work on batteries as well. Curious to know how ? Visit us again soon.

The sensor was tested and is being received with and RFXCOM receiver.

Get in touch if you have discovered something more related to this sensor protocol.

 

 

Posted in 433.92 MHz, Arduino, oregon scientific rf protocols, RF | Comments Off

Happy Christmas!

Happy Christmas everyone!

Posted in Technology | Comments Off

Dublin Mini Maker Faire

We made it to the Dublin Mini Maker Faire this year, we want it to register and have a boot but we missed the deadline so we decided to go anyway and meet “the makers”.

Dublin Mini Maker Faire

It was good to see so may people passionate about technology and electronics, we had a few chats with as many as we could and exchanged ideeas, answered a few questions and asked a few questions ourselves.

It is amazing to see children interested in learning how to solder showing that is never too early or never too late to learn how to do it.

never too late to learn

Thank you for the chat: TOG, Science Ireland, Robots.ie and all the others :) get in touch for new projects.

Looking  forward to the next Maker Faire, next time we will register in time to have a better presence..

Posted in Technology | Comments Off

Oregon Scientific version 2.1 & 3.0 RF protocol

The RF transmissions use on-off-keying (OOK) with Manchester coding on a
carrier frequency of 433.92MHz. See the Wikipedia entry on Manchester coding
for more information or consult a basic text on digital RF communications.
All OS protocol versions use the “normal” polarity definition of Manchester
coding. This convention requires that a zero bit be represented by an off-to-on
transition of the RF signal at the middle of a clock period. Another way to
describe this is that the bit value is equal to the RF signal state before the
transition.
By definition, RF transitions must occur in the middle of each clock period. In
this document, that point will be designated by an integer number. The
boundary between two clock periods will therefore be equal to an integer plus
one half.
OS version 1.0 sensors transmit bits with a clock rate of approximately 342Hz,
while version 2.1 and 3.0 sensors use a bit rate of 1024Hz. In all version 2.1 and
3.0 sensors measured to date, this rate does not vary by more than a few
tenths of a Hertz.

Version 2.1 Message Formatting
For version 2.1 sensors only, each data bit is actually sent four times. This is accomplished by first sending each data bit twice (inverted the first time), doubling the size of the original message. A one bit is sent as a “01” sequence and a zero bit is sent as “10”. Secondly, the entire message is repeated once.

Some sensors will insert a gap (about 10.9 msec for the THGR122NX) between the two repetitions, while others (e.g. UVR128) have no gap at all.
For an example of this, consider the message “111101010111” as it would be sent by a version 2.1 sensor. First an inverted copy of the message is created, and then interleaved with the original message, taking the inverted bit first.
Original Message: 1 1 1 1 0 1 0 1 0 1 1 1
Inverted Message: 0 0 0 0 1 0 1 0 1 0 0 0
Transmitted Bits: 01 01 01 01 10 01 10 01 10 01 01 01
When decoding a version 2.1 message, only every other bit need be used (and possibly inverted, depending on whether the first or second bit is kept). If the second bit in each bit pair is kept, no inversion is required.
It should be apparent for version 2.1 messages now, that one can assume the opposite polarity for Manchester coding (e.g. a zero bit is represented by an on-to-off transition in the RF signal) – this only changes which of the two interleaved bit streams is considered to be inverted.

RF Pulse Widths
The duration of Manchester-coded RF pulses is exactly either ½ or 1 data clock period. OS version 2.1 and 3.0 protocols shorten the RF pulse width by truncating the end of the pulse (not the start of the pulse). As a result, RF transitions do not occur on exactly regular time boundaries and may be displaced in time from data clock edges. Pulses are shortened by about 138us for v3.0 sensors and 93us in v2.1.

Message Layout
All message data is “nibble-oriented” (a nibble is 4-bits). The next depicts the message structure of version 2.1 and 3.0 messages. The size of each block (in nibbles) is given in parentheses.

Oregon Scientific v 2.1 RF Protocol Message Data Layout

Oregon Scientific v 2.1 RF Protocol Message Data Layout

Both 2.1 and 3.0 protocols have a similar message structure containing four parts.
1. The preamble consists of “1” bits, 24 bits (6 nibbles) for v3.0 sensors and 16 bits (4 nibbles) for v2.1 sensors (since a v2.1 sensor bit stream contains an inverted and interleaved copy of the data bits, there is in fact a 32 bit sequence of alternating “0” and “1” bits in the preamble).
2. A sync nibble (4-bits) which is “0101” in the order of transmission. With v2.1 sensors this actually appears as “10011001”. Since nibbles are sent LSB first, the preamble nibble is actually “1010” or a hexadecimal “A”.
3. The sensor data payload, which is described in the “Message Formats” section below.
4. A post-amble (usually) containing two nibbles, the purpose or format of which is not understood at this time. At least one sensor (THR238NF) sends a 5-nibble post-amble where the last four nibbles are all zero. The number of bits in each message is sensor-dependent. The duration of most v3.0 messages is about 100msec. Since each bit is doubled in v2.1 messages, and each v2.1 message is repeated once in its entirety, these messages last about four times as long, or 400msec.

Decoding Hardware
Reception and decoding is possible using an Arduino board combined with one of the inexpensive 434MHz receiver modules which are readily available.
Hardware available for decoding on the Atmel processor includes a hardware timer with an edge-triggered sampling input. Edges on the trigger input will cause the timer value to be latched and a processor interrupt is then generated. One easy way to handle decoding then is not to attempt clock recovery, but to examine the time difference between transitions on the OOK RF signal.

Classifying Time Intervals

The decoding algorithm works by classifying time intervals between RF transitions (on-to-off and off-to-on) as either short or long.
Because the RF pulses are shortened, separate time thresholds are used for classifying the time period (short or long) depending on the RF state (on or off). Based on the data rate (1024Hz) and the two amounts by which pulses are shortened (96us and 138us), the table below shows the expected values of time intervals (in microseconds) based on the protocol version and RF state.

Oregon Scientific RF Time Intervals v.2.1 and v 3.0

Oregon Scientific RF Time Intervals v.2.1 and v 3.0

Averaged thresholds for classifying time intervals as short or long have been determined. Times given in the table below are in microseconds. Time intervals which fall outside the “Short Min” or “Long Max” values are considered invalid. These are for version 2.1 and 3.0 sensors.

RF State

RF State

These averaged thresholds only vary by about 20usec from the ideal threshold that would be chosen for either version of sensor (2.1 versus 3.0).
A small improvement in performance might be possible by using different threshold values for each protocol version – which would be possible after the preamble is identified and the protocol version is known.

Decoding Using Time Intervals

The decoding algorithm works by capturing a timer value when RF transitions (on-to-off or off-to-on) occur, and calculating the time interval between successive transitions. These intervals are classified as either short (one-half clock period) or long (one full clock period).
An integer counter keeps track of time in units of one-half clock tick; this counter’s value will be called “half-time”. After being properly initialized, half-time is incremented by one when a short interval occurs and by two for long intervals. Half time is a very useful quantity for decoding RF messages:
• When half-time is even, we are at the middle of a clock period. The transition occurring at this point determines the bit being transmitted.
• When half-time is odd we are at the boundary between two clock periods.
Transitions occurring here are of no interest in determining transmitted bits.
• When half time is even, dividing it by two yields the current message bit
number.
Using half-time, some very simple logic can be used to decode the RF signal.
Decoding Messages
When a transition falls on a boundary between two clock periods (i.e. half-time is odd), there is no message bit to be decoded. There may still be some useful information here however; if the current time period is long it means that the last transition also occurred at a clock period boundary. This means that there was no transition in the middle of the currently ending clock period, and signifies a violation of Manchester-coding format. This should be detected as an error condition.

When a transition falls in the middle of a clock period (half-time is even), a
message bit can be detected and its value is simply equal to the RF state
(on=”1” and off=”0”) just prior to the transition.
The decoding algorithm described above is simple and correctly determines the
polarity of each bit based on the current RF signal state (on/off). Another
algorithm has been developed by others which also works but does not consider
the RF state when detecting bits (except for the first bit). This algorithm is
described later.
The half-time value is also useful for verifying that bit-doubling is correct in version 2.1 messages. Since a long transition period is required to change from a 1 to a 0 bit (or vice-versa), every bit pair in these messages is required to end with a long transition period. Furthermore, when time is aligned with the end of a double-bit period, half-time taken modulo-4 will be zero.
When decoding a message from a version 2.1 sensor, and half-time modulo-4 is non-zero, no bit is detected. When half-time modulo-4 is zero, a bit is detected and a check is made that the current transition period is a long one (otherwise an error exists).

Alternate Algorithms
These algorithms have been published on the internet previously by various people.
As will be shown below, if the value of the first message bit is known then the message can be decoded by considering only the time intervals between RF state transitions, and ignoring the actual RF state value at each transition.
In a Manchester coded signal, each source data bit generates either a pair of short transition intervals or a single long transition interval. A source bit will generate a pair of short transition intervals when it is the same value as the preceding source bit. When a source bit has the opposite value as the preceding source bit, a single long transition interval is generated.
This description of Manchester coding lends itself to decoding based solely on transition timing. A pair of short transitions represents a bit identical to the previous bit. A long transition means the current bit is the opposite of the previous bit. This works as long as the value of the first bit can be correctly determined – otherwise the resulting decoded bit stream will be inverted.
Here is another algorithm that will properly decode version 2.1 messages:
every long period represents no change in bit state while every pair of short periods represents the bit state changing. Under this interpretation, the preamble decodes as 32 “1” bits instead of a repeating “1010…” pattern.
Furthermore, each bit in the message appears doubled without inversion – the sync nibble would be “00110011” for example. Answering the question of why this works is an exercise left for the reader.

Message Formats
All messages decoded so far (versions 2.1 and 3.0) appear to have an identical format for the sensor data payload, as shown in the table below. Figure 1 (earlier in this document) depicts the payload format. The message is assumed to contain “n” nibbles, numbered from zero to n-1. For convenience, this table also shows the checksum and post-amble portions of the message.

Checksum and post-amble

Checksum and post-amble

The coding of sensor-specific data varies according to the type of measurements being reported by the sensor. Some sensors use the same coding as others which report the similar data – but this is not always the case. For example, the THGR810 and THGR122NX temperature/humidity sensors use the same data coding, but the RGR968 and PCR800 rain gauges do not.
Most (but not all) sensor data is in BCD format, least significant digit (LSD) first. For example the value of 27.5 degrees Celsius would be coded as the hex nibbles “572”. The decimal point is assumed to be in a fixed location and is not actually transmitted.

 

Posted in 433.92 MHz, Arduino, oregon scientific rf protocols, Projects | Tagged , | Comments Off

RF Oregon Scientific version 1.0 Protocol Samples

A number of samples are available to help describe the protocol and structure of messages.

The version 1.0 preamble is shown below. The clock rate used to generate the x-axis was 342Hz. The integer values on the horizontal axis are aligned with the middle of each clock period.

Oregon Scientific RF Version 1.0 Preamble

Oregon Scientific RF Version 1.0 Preamble

Since the transmitted bit is equal to the RF state just before the middle of the clock period, this preamble consists of 12 “1” bits. These occur starting at zero on the labeled plot, and the transition defining the last preamble bit is at eleven.
The next graphic shows the sync portion of the RF message. The middle of the first clock period after the preamble is numbered “12” in this graphic. The sync interval runs from clock periods 12 through 15 in this case.

Sync Interval RF Oregon Scientific v 1.0

Sync Interval RF Oregon Scientific v 1.0

By the standards used in the rest of the RF message, this sync period is illegal because it has no RF transitions in the middle of each clock period. However, if we continue to sample the RF state just before the middle of each clock period, the sync portion of the message contains five bits – 0,1,1,0,0.
Clock alignment jumps slightly between the end of the sync period and the first data bit. Above, the transition which occurs just prior to the middle of clock period 17 is actually the middle of the first data clock period. It is not known why this apparent time shift exists.

The next figure shows the data portion of the message after the clock has been re-synchronized after the sync period. The middle of the clock period containing the first data bit is numbered zero.

Oregon Scientific RF Version 1.0 Data Payload (starting with "0")

Oregon Scientific RF Version 1.0 Data Payload (starting with "0")

It is clear that the length of the off period after the long sync pulse can have two different values. The shorter value occurs when the first data bit is a “1” and the longer value corresponds to a first data bit of “0”.

Recall that the RF pulse is off at the end of the sync period. There are two ways the data portion of the message can begin depending on the value of the first data bit.

If that bit is a zero, then the RF will remain off until the middle of the first clock period. Since there must be a transition in the middle of the clock period, the RF will need to go on at that point. This is the situation seen in figure 14. Obviously, that first pulse can either be long or short depending on the value of the second bit. In this case, the second bit is also zero so the pulse is a short one.

The next graphic shows the case where the first data bit is a “1”. In this case there is a transition prior to the middle of the first clock period. Since a transition is required at the middle of the clock period, this pulse must be a short one.

RF Oregon Scientific V1.0 Data Payload (starting with "1")

RF Oregon Scientific V1.0 Data Payload (starting with "1")

As mentioned above, and for unknown reasons, a clock synchronized with the preamble is slightly out of sync with the data portion of the message. The measured time from the end of the long sync pulse to the middle of the first data clock period is 6.68 milliseconds.

AGC Problems
In some receivers, the long RF-off time periods that occur during the sync interval of version 1.0 RF messages may cause problems with automatic gain control. If the receiver is designed to receive data at kilo-hertz rates, the AGC may start ramping up receiver gains during these long RF-off intervals. When the RF finally comes back on, the receiver may be over-loaded and the first few data bits will be corrupted until the AGC can recover.
This problem can be solved if the AGC circuits are locked down (frozen) at some point during the preamble of a version 1.0 RF message and unlocked after the message ends. This is the technique used with the WSDL WxShield to receive version 1.0 messages.

Posted in 433.92 MHz, Arduino, oregon scientific rf protocols, Projects, RF | Tagged , , , | Comments Off

Oregon Scientific v 1.0 RF Protocol Description

While scouring the internet for information on the Oresgon Scientific RF protocols I came accross some information gathered by others so I woul like to share it here. Much of the information here has been gathered from various postings on the internet. Several people have successfully decoded OS protocols. This document summarizes what has been already made public and adds a little more to the pile of knowledge.

Description
The RF transmissions use on-off-keying (OOK) with Manchester coding on a
carrier frequency of 433.92MHz. See the Wikipedia entry on Manchester coding
for more information or consult a basic text on digital RF communications.
All OS protocol versions use the “normal” polarity definition of Manchester coding. This convention requires that a zero bit be represented by an off-to-on transition of the RF signal at the middle of a clock period. Another way to describe this is that the bit value is equal to the RF signal state before the transition.
By definition, RF transitions must occur in the middle of each clock period. In this document, that point will be designated by an integer number. The boundary between two clock periods will therefore be equal to an integer plus one half.
OS version 1.0 sensors transmit bits with a clock rate of approximately 342Hz, while version 2.1 and 3.0 sensors use a bit rate of 1024Hz. In all version 2.1 and 3.0 sensors measured to date, this rate does not vary by more than a few tenths of a Hertz.

Lets start with Version 1.0 message formatting, These sensors also repeat each message once, but do not repeat each bit.

RF Pulse Widths
The duration of Manchester-coded RF pulses is exactly either ½ or 1 data clock
period. As a result, RF transitions do not occur on exactly regular time boundaries and may be displaced in time from data clock edges.
Version 1.0 sensors have the RF pulses lengthened instead of shortened.

Version 1.0 sensors have a simpler format as shown in  the figure below.

  1. The preamble contains twelve “1” bits.
  2. The sync section consists of a long off period (4.2msec), a long RF pulse(5.7msec) and another long off period (around 5msec).
  3. The first data sample point (clock edge) is not always marked by an RF transition and must be measured from the end of the long sync pulse.
  4. The data payload is fixed length since all version 1.0 sensors can only measure temperature.
  5. These sensors do not transmit a post-amble.

 

rf-Oregon-Scientific-v1

Layout of version 1.0 messages

The table below summarizes the information
versions.
Protocol Version 1.0
Bit Rate (Hz) 342
Manchester Polarity Reverse
Preamble Bit Count 12
Bits Doubled No
Message Repeated Yes
RF Pulse LengthOffset +255 usec
Decoding Hardware
Reception and decoding is possible using an Arduino board combined with one of the inexpensive 434MHz receiver modules which are readily available.
Hardware available for decoding on the Atmel processor includes a hardware timer with an edge-triggered sampling input. Edges on the trigger input will cause the timer value to be latched and a processor interrupt is then generated. One easy way to handle decoding then is not to attempt clock recovery, but to examine the time difference between transitions on the OOK RF signal.

Classifying Time Intervals

The decoding algorithm works by classifying time intervals between RF transitions (on-to-off and off-to-on) as either short or long.

Because the RF pulses are shortened, separate time thresholds are used for classifying the time period (short or long) depending on the RF state (on or off). Based on the data rate (1024Hz) and the two amounts by which pulses are shortened (96us and 138us), the table below shows the expected values of time intervals (in microseconds) based on the protocol version and RF state.

Protocol Version       RF On     RF off Short

 

Protocol Version RF On RF Off
Short Long Short Long
1.0 (preamble/data)Version 1.0 leading sync offVersion 1.0 sync pulseVersion 1.0 trailing sync off 1720 31805700 1219 268042005200 

A small improvement in performance might be possible by using different threshold values for each protocol version – which would be possible after the preamble is identified and the protocol version is known.

A reasonable set of thresholds for version 1.0 sensors (in micro-seconds) is shown in the table below:

RF State                 Short Min        Short Max              Long Min           Long Max
Off                                 970                 1950                          1950                  2900
On                                 1500                2400                        3400                 1100
Sync Begin (Off)                                                                   4000                 4400
Sync (On)                                                                                5585                 5985
Sync End (Off)                                                                       5000                5400
Sync End (Off)                                                                       6480                6880

Note: The two “Sync End” intervals correspond to the two cases where the first data bit is a “1” or “0” respectively.

Decoding Using Time Intervals
The decoding algorithm works by capturing a timer value when RF transitions (on-to-off or off-to-on) occur, and calculating the time interval between successive transitions. These intervals are classified as either short (one-half clock period) or long (one full clock period).
An integer counter keeps track of time in units of one-half clock tick; this counter’s value will be called “half-time”. After being properly initialized, half-time is incremented by one when a short interval occurs and by two for long intervals. Half time is a very useful quantity for decoding RF messages:
• When half-time is even, we are at the middle of a clock period. The transition occurring at this point determines the bit being transmitted.
• When half-time is odd we are at the boundary between two clock periods.
Transitions occurring here are of no interest in determining transmitted
bits.
• When half time is even, dividing it by two yields the current message bit
number.
Using half-time, some very simple logic can be used to decode the RF signal.

Decoding Messages

When a transition falls on a boundary between two clock periods (i.e. half-time is odd), there is no message bit to be decoded. There may still be some useful information here however; if the current time period is long it means that the last transition also occurred at a clock period boundary. This means that there was no transition in the middle of the currently ending clock period, and signifies a violation of Manchester-coding format. This should be detected as an error condition.

When a transition falls in the middle of a clock period (half-time is even), a message bit can be detected and its value is simply equal to the RF state (on=”1” and off=”0”) just prior to the transition.
The decoding algorithm described above is simple and correctly determines the polarity of each bit based on the current RF signal state (on/off). Another algorithm has been developed by others which also works but does not consider the RF state when detecting bits (except for the first bit). This algorithm is described later.
The half-time value is also useful for verifying that bit-doubling is correct in version 2.1 messages. Since a long transition period is required to change from a 1 to a 0 bit (or vice-versa), every bit pair in these messages is required to end with a long transition period. Furthermore, when time is aligned with the end of a double-bit period, half-time taken modulo-4 will be zero.
When decoding a message from a version 2.1 sensor, and half-time modulo-4 is non-zero, no bit is detected. When half-time modulo-4 is zero, a bit is detected and a check is made that the current transition period is a long one (otherwise an error exists).

Alternate Algorithms

These algorithms have been published on the internet previously by various
people.
As will be shown below, if the value of the first message bit is known then the
message can be decoded by considering only the time intervals between RF
state transitions, and ignoring the actual RF state value at each transition.
In a Manchester coded signal, each source data bit generates either a pair of
short transition intervals or a single long transition interval. A source bit will
generate a pair of short transition intervals when it is the same value as the
preceding source bit. When a source bit has the opposite value as the
preceding source bit, a single long transition interval is generated.
This description of Manchester coding lends itself to decoding based solely on
transition timing. A pair of short transitions represents a bit identical to the
previous bit. A long transition means the current bit is the opposite of the
previous bit. This works as long as the value of the first bit can be correctly
determined – otherwise the resulting decoded bit stream will be inverted.

Version 1.0 Message Format
At this point, there is only a single known format for version 1.0 messages. All version 1.0 sensors are temperature-only units.

Nibble(s)  Contents            Details
0                 Rolling Code     This 8-bit value changes randomly when the sensor is reset or batteries changed.
1                 Channel              Channels 1,2,3 are coded as 0,4,8
5..2            Temperature     BCD temperature in degrees Centigrade

7..6            Cheksum           Byte-oriented checksum

Version 1.0 messages are 8 nibbles in length. The channel setting occupies only
two bits in nibble 1 and it is possible that the other two bits may be part of the
rolling code. They have occasionally been seen to be non-zero.
The rolling code does not change every time the reset button is pressed.
Several reset operations are usually required to get this code to change.
According to internet sources, the first temperature nibble (nibble 5) is
actually a bit status field containing the following bits:
• 0 – Not used
• 1 – A “1” value indicates negative temperature
• 2 – Unknown (may be a malfunction flag)
• 3 – Battery low when “1”
The checksum is computed by organizing the 8 nibbles into four bytes in little endian order. Any overflow is summed back into the total sum.
For example, a message received as (in the order of transmission) “8487101C” would contain the following bytes: 0×48, 0×78, 0×01, 0xC1. The first three bytes are summed and compared to the checksum (0xC1 in this example). This message contains a rolling code of “8” and the sensor is set to channel 2, reading 17.8 ºC.
For another example take the message “88190AAB”. The bytes 0×88, 0×91 and
0xA0 sum to a value of 0x1B9. The overflow (0×1) is summed back in giving a
final checksum of 0xBA. This sensor has a rolling code of “8”, is set to channel
3, reads -9.1 ºC and has a low battery.

Posted in 433.92 MHz, Arduino, DIY, oregon scientific rf protocols, RF | Tagged , , , | Comments Off

Current Cost RF protocol

Well, I am bit stuck because I can not find any information related to the RF protocol used in the Current Cost products so I will have to do some hard work trying to intercept the packets and decode them using the USB RF 433.92 MHz Transceiver module.
It looks like a long process but I will give it a go. If anyone has any info on the protocol I am interested to find more about it.
More to follow soon!

Posted in Uncategorized | Tagged | Comments Off

Arduino and Oregon Scientific Sensors Projects

Back to my newly discovered passion, Arduino.

I see that there is a lot of interest in these sensors and there isn’t much info about the protocol used by them. I have realised that is not really worth making your own sensors if your really want to make quality sensors, you can’t beat the price of mass produced ones no matter what. It is only interesting to build your own when they are find to find or they are not produced any more. I have stumbled across  more information related to the protocol so I want it to share it here Oregon Scientific RF Protocols

I believe they can be replicated and they can be used easily, just try and have plenty of free time, there are many ways to read the data, my favourite remains Arduino.

I have found a Dutch project called Nodo Due which is based on Arduino and allows you used it for home automation and to receive raw information from some 433.92 Mhz sources. A very good project but is all in Dutch :(

Available http://members.chello.nl/p.tonkes8/index.html quite an active forum and for me it seems like a good idea. I have offered to help but I don’t speak Dutch.

Here is the schematic:

A very good project based on Arduino and with a very few extra components, all of them easy to find. Tested by me and running fine on Arduino Uno, it does not compile in Arduino Mega 2560 and I haven’t much time trying to find out why.

Enjoy and play ..

Comments Off

New developments USB – RS485

 

Well, it’s been a while since the last update so here it goes: we are preparing a few products which will be available in the shop, and as always the people that built them know them better. We’ll have a bit of a description of the manufacturing process going through all the required stages.

What will the products be?

Here it is : USB to RS485 adapter..

And the revised schematics:

SCHEMATIC USB-RS485

USB - RS485 adapter

And the test results are in..

Signal integrity test:

Test conditions:

Cable: 30 meters of twisted pair subsea grade cable 120 ohm terminated

Driver: USB-RS485 Adapter with the 120 ohm terminator jumper ON.

The character ‘U’ (ASCII 0×55) sent via a terminal (PUTTY) with 8 bits data, 1 start bit, 1 stop no parity

The baud rate was set for 115200 bps, 50000bps, and 1Mbps, the waveforms were captured with a 1Gs/s digital storage scope triggered on the start bit.

 

Character ‘U’ was captured on the scope at the far end of the cable (30m)

The speed is 115200 bps

 

A detailed view of a bit at 115200 bps

 

 

 

 

The bit rate was increased to 500.000 bps and the charaRS485_1Mbits_char_signalcter was sampled again.

 

 

 

 

This detailed bit view shows no sign of reflections on the falling and/or rising edges of the signal.

 

 

 

 

Finally the  view of  a 1Mbit/s signal over 30m of terminated cable.

 

 

 

Conclusion:
The signal integrity is maintained over 30m of twisted pair cable, terminated at both ends, driver and receiver. Signals are sampled on the far end (receiver side) with a digital storage oscilloscope at 1 Gs/s.
Posted in Projects, RS485, Technology, USB | Tagged , , | Comments Off

Tinkering with Arduino

Well, about time for me to try and understand what is going on inside all these things making use of the 433 MHz, kind of hard not knowing a lot about programming and stuff :) Thanks God for the multitude of books about Arduino and the projects available everywhere, still a pain in the neck trying to find the correct IDE version that will compile a SKETCH, one lesson learned: don’t expect everyone to include the libraries they’ve used or even mention them.. Why do people just put buckets of code that will not compile and will only cause frustration trying to find some crazy libraries that might work or not.. I believe Arduino got out of hand, is this what is happening when you grow too big and you can’t control your environment? I am not a big fun of controlling, unless is done with a remote :) Anyway, progress report here, as usual trying to find new and easier way to automate devices around the house, the first BIG project coming soon here, the Home Automation transceiver, no more need for two separate bulky devices to do it, no need for two USB ports, no need for two pieces of software.. Will it ever happen? Not to soon by the way things move now, not after spending 3 1/2 hours trying to find out why Arduino 022 will not compile a sketch, and trying version 018, 019, 020 only to finally find out that 021 does the job. Of course using Windows 7 x64 doesn’t help either. So the plan is to put together a device that will receive OS (Oregon Scientific) sensors data, KAKU (Klick On Klick Off) devices status and send commands to these devices using only one piece of hardware, will it work? Will Ireland manage to produce such a thing? Or should Ireland stick to what it best at : Guinness, Chedar Cheese, Beef, Potatoes, Art …

I was going to say that at the end of the day Italy makes Arduino but they are better known for Pizza and Pasta, but i had to stop in my tracks when I remembered Ferrari, Lamborghini, Masserati..

Now, what is Arduino? From their web page:

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It’s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.

Arduino can sense the environment by receiving input from a variety of sensors and can affect its surroundings by controlling lights, motors, and other actuators. The microcontroller on the board is programmed using the Arduino programming language (based on Wiring) and the Arduino development environment (based on Processing). Arduino projects can be stand-alone or they can communicate with software on running on a computer (e.g. Flash, Processing,MaxMSP).

The boards can be built by hand or purchased preassembled; the software can be downloaded for free. The hardware reference designs (CAD files) are available under an open-source license, you are free to adapt them to your needs.

Arduino received an Honorary Mention in the Digital Communities section of the 2006 Ars Electronica Prix. The Arduino team is: Massimo BanziDavid CuartiellesTom Igoe,Gianluca Martino, and David MellisCredits.

Enough ranting, will keep posting updates here..

Techie Info: I am using Arduino UNO and one Linx RXM-433-LR-S RF module

433 Mhz RF Module

Posted in Arduino, DIY, Learning, Projects, Technology, Uncategorized | Tagged | Comments Off