A simple RF sensor network using AVR microcontrollers
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
db
include
rpi-receiver
rpi-tools
sensor-t
.gitignore
README.asc
UNLICENSE

README.asc

proj-rf-sensor-network

This is a simple RF sensor network with small sensors sending measurements to a radio receiver board on top of a Raspberry Pi.

Hardware

I’m using some cheap 433.92MHz sensors from Jaycar:

They have digital I/O, low power and reasonable range. Toggling the data line on the transmitter should see a corresponding change in the output line of the receiver. Of course, there’s no provision for collisions etc.

The transmitters need to be battery powered and use low current so that they can be compact and last at least a year before the battery runs out.

Protocol

The data rate I chose is 4800 baud, but we need to work out some way to synchronise the clocks between the transmitter and the receiver, otherwise we’ll never be able to work out where the data boundaries are. I chose to use Manchester coding, which used two bits for every data bit (i.e. halves the data rate), but this ensures a clock transition for every bit. This makes it much easier to synchronise the receiver’s clock with the data clock.

The protocol for sending a message comprises the following:

  1. a preamble, comprising 32 x 0-bits, followed by 2 x 1-bits

  2. a sync byte, marking the start of the message

  3. a message length byte

  4. one or more bytes of the message

  5. a CRC calculated from the message length and content

The RF receiver has an AGC circuit which means that in the absence of any real signal, it will decode random noise. The purpose of the preamble to send a strong signal to the receiver, force the AGC to a reasonable level and allow the decoder to sync up with the 0→1 transitions that make a Manchester-encoded 0-bit.

Message format

The message format is designed to be compact, self-describing and to allow for future data to be added.

Item Type Meaning Count

id

uint8_t

Unique station ID

1

nvalues

uint8_t

Number of sensor values

1

type

uint8_t

Sensor type

nvalues

value

uint16_t

Sensor value

The following sensor types are currently supported:

  • 1 - Temperature in C (x10)

  • 2 - Pressure

  • 3 - Message sequence number

  • 4 - Light level

  • 5 - Humidity

  • 6 - Battery voltage in V (x10)

The sequence number is always included in a message.

Receiver

The receiver has a sampling clock that samples the Data Out from the receiver at 16 times the expected baud rate. Incoming bits are rotated through a 16-bit window. When the window value looks like this:

x x x 0 0 0 0 0 1 1 1 1 1 x x x x

then a 0-bit is accepted. Similarly, which the window looks like this:

x x x 1 1 1 1 1 0 0 0 0 0 x x x x

then a 1-bit is accepted.

Once a bit transition has been matched, the receiver will initially look for the next bit after another 16 samples have been received. To cater for clock skew between the transmitter and the receiver, subsequent bits can be matched at small negative or positive offsets from this pattern.

Once a reliable self-clocked data stream is being received, the receiver FSM starts matching the various parts the make up the message protocol, until a validate message has been received. The receiver maintains a buffer of received message for a fixed number of stations.

Separately to this, the receiver acts as an I2C client for the Raspberry Pi. The Raspberry Pi uses the I2C bus to clock out the latest received messages in the buffer. It can then process the information as it chooses, for example making it available via its web server.

13-Mar-2016:

A new daemon, sensord, is provided, to run on the Raspberry Pi and monitor messages from the receiver. Updates are written by sensord direct to a MySQL database. Important sensor events (loss of reception, low battery voltage) are logged to a separate host via syslog.

More information

I wrote up a bit more about how this works here: