What to do when your 20+ year old Radio Shack outdoor weather sensor dies? Build your own! Along the way, learn about power consumption, LoRa, and defending against the elements (and bugs--the insect kind.)

Low Power remote weather station

When our aged Radio Shack remote temperature and humidity station finally failed, I decided to replace it with a system of my own design. The system below has several features that might interest other makers and hobbyists.

The original Radio Shack product consisted of a single outside sensor measuring temperature and humidity (T/H) and an inside receiving station that displayed outdoor readings and could display indoor T/H with the press of a button. Both of these stations were battery-operated. I wanted, at minimum, to monitor the outdoor and indoor environment and to retain the indoor display at its current location. The latter design specification required that the display continue to be battery-powered. As the project developed, I added a home-brew data collection node that permits more sophisticated tracking and plotting of weather data and presentation of the data on a web page.

There were several “out of the gate” constraints. I am an intermediate programmer in the Arduino environment and tried to avoid using another language or IDE. I wanted to avoid writing my own libraries if at all possible. I planned to use hobbyist-grade,  off-the-shelf components that could be hand-soldered. Minimizing power consumption, both the outdoor sensor and the indoor display, was a priority. Although not an initial concern (a reflection of my naivete), effective weatherization and prompt response to environmental change were surprisingly challenging issues.

Power consumption drove almost all component selections. This calculation involved three variables. First, the current draw of the device when on and processing instructions or data. Second, the duty cycle—if a T/H reading were performed every 5 minutes, how long did the device need to remain on to collect and send (or display) data? Minimizing the Ton/Ttotal fraction could significantly affect overall power consumption. Third, current draw between sampling and transmission cycles. Ideally, there would be no power draw between sampling events, but that was not a realistic expectation.

The Artemis boards from Sparkfun were a logical choice for MCU. These devices draw only a couple of milliamps powered up. Power consumption could be reduced even further with a lot of fancy programming (shutting off peripherals, slowing the clock, etc.). Display power consumption can be significant, and display choice was easy—ePaper. This technology has the advantage of drawing current only upon display refresh; otherwise, there is no power used (that’s why your ePaper Kindle can display a graphic when not in use.) Waveshare has a nice 4.2-inch ePaper unit. Instructions were hard to follow, and I needed to generate some fonts, but ultimately, the device worked well. For data transmission, I chose HopeRF LoRa boards (915 MHz, I’m U.S.-based). I’ll get back to LoRa shortly. I decided to use Bosch BME280 sensors for measurements. While a little expensive compared to other sensors, these units provide temperature, humidity, and barometric pressure (T/H/P) and have robust I2C libraries. The current draw was so low as to not figure into my calculations.

I did not arrive at a suitable timer solution immediately. To minimize component count, I planned to use the 3.3V regulator on the Artemis board to power the sensor, the display, and the radio. This meant that I could not simply put the MCU to sleep; I needed to turn off the power to the MCU and peripherals. I played around with a low-power 555 circuit and MOSFET switch, but the term “low-power” was only when compared to conventional 555 chips. The best solution was a purpose-built ultra-low power timer chip. These devices have an internal timing circuit, with the interval set by a single external resistor, and are typically used with an MCU. When the timer turns ON, current flow is enabled. When the MCU has completed its task, it sends a DONE message to the timer, and current flow is disabled. I worked with the TPL5110 chip (both homemade and the Adafruit breakout board) extensively, again using a MOSFET switch. There were numerous difficulties in using this form of ultra-low power timer. My adventures with this little guy are documented here: https://forums.adafruit.com/viewtopic.php?p=927526. The ultimate solution was to use a TPL5111 connected to the enable pin of the 3.3V regulator on the Artemis board. This implementation required the removal of a surface mount pull-up resistor (R1 on the Nano, R3 on the Thing Plus) but allowed me to have control over all power on the board. These resistors set the voltage regulator enable pin at HIGH unless the enable pin is grounded. Since Artemis is touted as a low-power solution for IoT, a trace that could be cut would be a welcome circuit alteration; ditto for LEDs on the board. In the end, the modified board was a nifty solution, with the entire circuit drawing only 20 microamps while waiting to make the subsequent measurement. Both the TPL5110 and TPL5111 are very interesting chips and are worthy of study. The Adafruit breakout boards are terrific implementations and provide design flexibility, with the ability to suppress the ON LED and to use either a supplied miniature potentiometer on the board or a discrete resistor to set the interval timer.

LoRa appealed as a good radio option for several reasons. The sub-gigahertz carrier frequency permits better penetration of walls and buildings and longer transmission distances. Transmission protocols are optimized for small data packets. The protocols do not require time-consuming handshakes and security overhead. Finally, several libraries are available for the Arduino environment that simplify implementation. However, the absence of handshakes and transmission/receive synchronization puts the burden of assuring data delivery on the programmer rather than on built-in transmission protocols.

At this point, the astute reader will be asking how stations communicate. After all, Ton/Ttotal is only a small fraction of the duty cycle (by design). If one station powers up and transmits data, the likelihood is that the receiving station will be off and unpowered. There’s no means by which a receiving station can be awakened. The solution is a third, always-on  station containing no sensors but functioning as a data concentrator and forwarder. I will refer to this as the home station. I chose to attach the home station to a computer. The MCU is a Pi Pico (I hadn’t ever used one and wanted to try it. It’s OK, but I’ll stick with Teensys for complex tasks.) The Pico’s only “peripheral” is the radio. The Pico is powered by the computer’s USB port and communicates over serial with a Processing program running on the computer. With only a couple hundred (if that) lines of code, I can plot barometric pressure and serve up a table of readings on a web page. The data flow is as follows:

1)     The outside sensor wakes up every five minutes and sends T/H/P readings to the home station. There is no communication from the home station back to the outdoor sensor. The outside sensor shuts down after transmission. No effort is made to confirm receipt by the home station
.2)     The home station stores the most recent reading from the outside sensor in RAM. The outside readings are also sent to the computer for further processing.
3)     The inside sensor and display unit wakes up every 5 minutes. It measures indoor T/H/P, sends that information to the home station, and retains a copy of the measurements in RAM. 
4)     Upon receiving an update from the indoor sensor and display, the home station posts this information to the computer. It then sends the most recent outside observations to the indoor station. After receiving the most recent outdoor observations, the indoor station updates the display and then shuts down.
5)     Lather, rinse, repeat.


How is this setup different from a store-bought LoRa gateway? Simple: it’s not a LoRa gateway. No one outside my family cares what the temperature is outside my house. Or in my house, for that matter. I can set up a simple, cheap server on my internal wireless network. If I don’t want to record and plot data, I don’t even need a computer, just an old USB charger and the home station setup. 

The hardware build is hand-wired. The sensors communicate via I2C. I used the Sparkfun Qwiic system, which is very convenient. It is easy to procure and wire a Qwiic-compatible connector to the small BME280 boards available on Amazon and eBay. Be careful to purchase a BME rather than BMP 280 if you want humidity information. There are numerous LoRa radios. The HopeRF line has a 2mm, rather than 2.54mm pitch, requiring a breakout board or careful soldering. In addition to SPI connections, a minimum of two additional pins are needed on the Artemis. I am using a simple ¼ wave wire antenna. Power is supplied by the Artemis board regulator. This minimizes components and turns off power to the radio when the Artemis’ regulator is disabled. 

I used FontEdit to create a 36-point font for the ePaper display. The program is free and relatively easy to use. WaveShare’s instructions are hard to understand, but I was able to develop solid working code. If you use an MCU other than the Artemis, be mindful that the font tables and bitmap buffer consume a lot of RAM.

Another point worth considering is weatherization. My outside sensor worked intermittently when there were rapid temperature and humidity changes. I strongly suspected condensation was the culprit. After examining all my solder joints and wiring and finding no faults, I decided to pot my outside board. I 3D printed a container slightly larger than my circuit board and a small dam to place around the sensor board so that it would not be submerged in epoxy. I also purchased a 90-degree USB-C dongle, which allowed me to retain access to the Artemis board’s USB-C connector. This would be needed to recharge the battery (the Artemis board also has a built-in LiPo charger) and update software if needed.

I used (relatively) inexpensive clear craft epoxy, readily available on Amazon. Craft epoxy is formulated to cure very slowly. This allows all bubbles to escape and gives the user an extended window in which to work with the material. Since I was not seeking a perfect aesthetic outcome and didn’t want my idiot cats investigating this project, I put the container on an electric food warmer at about 150 degrees F. The epoxy was hard within an hour. I then allowed curing to finish overnight at room temperature. The circuit board is housed within a plastic jar that I ventilated and painted white. The ventilation holes are covered with window screen material; I live in a rural area, and we have lots of bugs. Before I potted the circuit, I tested the epoxy by making a small plastic pan. I put two wires into the pan that were separate, two wires that I had twisted to make electrical contact, and then poured in epoxy. I used the heat acceleration technique described previously. After the epoxy set, the two separate wires remained isolated electrically, and the two twisted wires still had zero ohms resistance. I also tested the dam idea and confirmed I could exclude epoxy from protected areas. Since I potted the circuit, there have been no further intermittent failures.

Software for this project uses LoRa libraries, BME280 libraries, and WaveShare code. I traded code simplicity and shortened on-time in exchange for guaranteed data delivery. Because the home station receives data unrequested, data collisions are inevitable. If a few data points per day are lost, this is acceptable for a non-critical application. The data string is sent twice with a short delay between transmissions to reduce the risk of undelivered data. My current configuration monitors outdoor conditions, the conditions in my kitchen (location of the display), and a third sensor in our mudroom, which gets cold with a freezing risk in winter. The mudroom sensor is not presented on the display but is available on the web page. I am certain there are theoretical and practical upper limits to the number of sensors and displays that can be supported with this arrangement. Calculating the theoretical limit is left as an exercise for the reader. Practically, as network traffic increases, there will be a point at which data loss due to collisions will become unacceptable for your specific application. Many factors will affect this, including component matching and precision (particularly for timing resistors), environmental factors, and software tweaks or additions. There is no upper limit on the number of displays if the displays are continuously powered and not sending back sensor information, but battery-operated units contribute to radio traffic and should be added to the sensor count, even if no environmental data is returned to the home base. It is the total radio traffic, rather than sensor measurement transmissions, that limits the network. 

The code itself may appear incomplete. However, recall that code execution halts when the voltage regulator is turned off (MCU sends a “done” signal to the timer), and this closes any perceived gaps in the software. I apologize for the quality of the code. It contains many extraneous variables, debugging statements, and dead end experiments that I commented out. If Elektor decides this is an utterly brilliant piece of work and wants to turn it into a full-fledged article, I’ll clean up the code. For now, you are on your own. With the exception of the WaveShare code, I have not included libraries. These are easily added to your environment using tools supplied by the Arduino IDE.

The Processing language is a Java derivative with an extended user base and lots of good libraries. It is sufficiently similar to Arduino C++ that I don’t feel like tearing my remaining hair out when I code. Eventually, I plan to write JavaScript code for browser-based trend plotting, and will develop a MongoDB database for data storage. The Processing code is provided, as well as the Arduino sketches.

I used a rechargeable Lithium 18560 battery for power. I recharge the units every 4 to 6 weeks, using the recharging circuit supplied on the MCU board. Be careful when purchasing these batteries. There are many poorly made or refurbished units available on Amazon and eBay, boasting of impossible energy densities at ridiculously low prices. These units often do not hold a charge well and do not begin to approach the advertised storage capacity.  A genuinely new battery with a built-in protective PCB from a responsible manufacturer should cost $7-10 USD and be rated between 2600 and 3000 mAH. Certainly, other power configurations are possible and are limited only by your creativity and application requirements.

I have not provided detailed schematics; connections are straightforward and which pins to use on the MCU will depend on your board layout. I have included an overall data flow diagram as well as power and data flow diagrams for the display and sensor units, as well as pictures of the various units. I hope that this information is of use to someone other than me, and I welcome suggestions and tweaks. Enjoy!

5 May 2023 Update: this project is now an article in preparation for the July-August issue of Elektor Magazine. Detailed schematics and a BOM will be available there.

 In sustained use, I noticed that the system would occasionally lock up. Troubleshooting identified the offending component as the home station. After reading through various forums, it looked as though the SX1276 radio, when left on for sustained periods of time, could freeze. I do not have the programming skills to determine if this was intrinsic to radio firmware, the Arduino library used, or some combination of the two. Because the sensors and the display station had repeated power on/power off cycles, the behavior was not seen in these modules. My solution was to turn the home station off for 500 msec every hour. I used an Arduino Mini as a “smart timer.” The mini communicated with the Pico, bringing the Pico’s enable pin LOW for 500 msec when at least an hour had passed. The Pico would bring a pin HIGH when power cycling the board  posed the least (but non-zero) risk of interrupting data collection or flow. The power reset would occur only when Mini had read that the “safe” pin was high. While some might consider the use of a Mini as pretty extravagant to be used as a timing device, a genuine pro Mini on Sparkfun is $11, and a HiLetGo knockoff on Amazon sells 3 for ~$16, resulting in the unit price equaling the price of a single TPL5111. Frequency of lockup has markedly decreased. I encourage input from the Elektor community on a better solution; this feels like a real kludge although it works. I’ve uploaded new software for the home station and Mini.