Sending your data through the air

The Software

I wrote all the software using the Arduino IDE. You can download the software for the transmitter, SDL_Arudino_WeatherLink_Tx and receiver, SDL_Arduino_WeatherLink_Rx, from my GitHub site [8]. I won't go through most of the software because it is pretty straightforward, and you can look at the source code for the details. The most complicated part of the transmitter software is the sleep code, and specifically the code designed to minimize current consumption. I will go through the two methods I use to put the Pro Mini to sleep.

Overall, the transmitter gathers the data from the connected weather instrument (and an optional SunAirPlus solar controller [9] if you are building a solar-powered unit), formats it into a 62-byte string, adds a checksum, and then transmits it to the receiver. The serial debugging output of a transmission cycle is shown in Listing 1.

Listing 1

Transmitter Debug Output

Using DS3231 to Wake Up
ALARM_1 Found
16:01:36 4/1/2000
wakeState=5
MessageCount=27
Outside Temperature (C): 25.00
Outside Humidity (%RH): 34.40
Wind Vane Voltage =5.00
Wind Vane Degrees =0
TotalRainClicks=1
windClicks=0
Average Wind Speed=0.00 KPH
shortestWindTime (usec)10000000
LIPO_Battery Load Voltage:  3.91 V
LIPO_Battery Current:       46.40 mA
Solar Panel Voltage:   1.02 V
Solar Panel Current:   0.00 mA
Load Voltage:   4.98 V
Load Current:   27.60 mA
crc = 0xFEB0
----------Sending packet-----

Notice the current measurement from SunAirPlus in line 22 (27.60 mA). That's a lot higher than 5mA. Why? Because the radio is on when transmitting a packet and reading the solar data. Then the software turns it off and goes back to sleep, and the current returns to 5mA.

On the receiver end, I read the data from the receiver based on the Pro Mini LP by using an I2C interface at 0x08. Listing 2 is an example of a packet of data coming from the transmitter.

Listing 2

Transmitter Packet

block 1
0xab 0x66 0x1 0x4d 0xa0 0xe 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
block 2
0x0 0x80 0x6a 0x7c 0x40 0xcc 0xcc 0xbc 0x41 0x32 0x33 0x53 0x41 0x29 0x5c 0x8f 0x3f 0x0 0x0 0x0 0x80 0x0 0x0 0x0 0x0 0x3e 0x7 0x0 0x0 0xdb 0x7f 0x0

In the receiver, the data is buffered and then supplied to the host computer when requested on the I2C bus. The receiver emulates an I2C device, which makes the receiver compatible with many different types of development computers.

Sleep Code – Sleepy

The most complex part of the transmitter code is the sleep code, in which I use two different methods. The first is a software sleep mechanism based on the internal hardware watchdog timer. I use a class called Sleepy from JeeLib [10], which is a great wrapper for all the myriad bits that need to be set and reset for the Arduino ATMega328P to reduce power dramatically by sleeping. When the ATMega328P is in the sleep state (low-power mode), only the watchdog, the two hardware interrupts, or a pin change can wake up the processor. In this design, I use the two hardware interrupts (INT0/INT1 connected to pins D2 and D3) to count the tips of the rain bucket and the number of times the anemometer is turning to calculate wind speed.

The function loseSomeTime is called for 16msec at a time so as not to overflow the watchdog timer and, more importantly, to allow the processor to go back to sleep immediately after processing an interrupt. The processor immediately wakes up on an anemometer interrupt, counts the interrupt, and goes right back to sleep because of this loop:

for (long i = 0; i < nextSleepLength / 16; ++i)
  Sleepy::loseSomeTime(16);

After the loop has been exhausted, the program transmits a packet to the receiver. Although the timing is not perfect, it does work and dramatically reduces power consumption (to <5mA).

Why a loop? You need to put the processor back to sleep after an interrupt, but you want to send a packet when the full sleep cycle is done at the termination of the loop. Note that the index variable i is defined long, because I want to count beyond 65,000. Using this Sleepy class and the loop scheme, you can send packets anywhere from two or three times a second to intervals of hours.

Buy this article as PDF

Express-Checkout as PDF

Pages: 6

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content