Software apps and online services
Why another DIY weather station? I wanted to make a durable, weatherproof, accurate, and reliable weather station. There didn't seem to be any existing projects that meet all these criteria so here's my version!
I'm sure my code and circuits can be improved for performance and power usage, feel free to suggest something! And comments are welcome for anything else.
To begin, we need to review basic weather monitoring principles. The data we collect can only be as accurate as the local conditions the station is in. So the most important factor is situating the station in the proper location. I'll quote from a government guideline document:
- Should be placed on a patch of level ground, over a surface representative of the area.
- Should be mounted in a ventilated radiation shield.
- Height between 4’ 1” and 6’ 7” above ground (1.25 – 2.0 m)
- Place sensors at a horizontal distance of 2 times the height of the nearest object (tree, structure, etc)
- Keep away from other sources of heat such as chimneys, air vents, air conditioners, etc.
For wind and rain sensor placement, the horizontal distance is 10 and 4 times the height of the nearest obstruction. Knowing that I will not have anything close to those conditions, I decided to measure only temperature, humidity, and pressure. However, I've designed this project to be able to accommodate additional sensors at a later time.
I knew I needed to design a robust enclosure for all the components, select the proper off the shelf components where applicable, design auxiliary circuits, and program the integration with Weather Underground. It was important that the finished product look and feel professional as well. I'll walk through the design decisions for each component. I had already decided on the Particle Photon due to its ease of use and built in cloud connectivity.
Keep in mind that although this was the rough order of design, most components had to be designed/selected simultaneously, considering the whole system and integration.
The largest component in the project is the radiation shield, because it houses everything inside except the solar panel. I quickly realized a 3D printed component of that size range would be prohibitively expensive, and of lower quality than an injection molded plastic. Therefore a commercial off the shelf component was selected, based on size (it has to be big enough to fit the particle photon at the very least), material (white molded plastic), and cost: the La Crosse Technology 925-1418 Sensor Protection Shield with Mount.
After receiving the radiation shield, I took measurements of relevant dimensions and those determined the size of the sensor and microcontroller enclosure.
I selected the BME280 as a robust, accurate, and reasonably priced sensor. Both Adafruit and Sparkfun make breakouts for this sensor; I went with Sparkfun.
The ventilation fan had to fit inside the cylindrical inner diameter of the radiation shield. The fan should run off the same voltage as the Particle Photon for efficiency. I also targeted something that drew less than 500mA as a starting point. Weatherproofing was also important so in the end I selected an IP57 brushless fan at 5V drawing 220mA: Mechatronics Fan Group G4020M05B-RSR-EM.
Outdoor circuits should be protected from moisture, sunlight, and temperature extremes. However, there obviously are components which need to be exposed to a certain degree: the solar panel, ventilation fan, and the environmental sensor. The particle photon, battery, secondary circuits (battery measurement, solar charger, etc.) need to be protected in a separate enclosure.
Initially several commercial weatherproof electrical junction boxes were considered, but none of them had the exact form factor required, and in addition, it would ultimately look "hacked" together. I decided to design a 3D printed part for the enclosure. Knowing that the part would need tight tolerances for a o-ring seal, I selected SLA (stereolithography) as the process due to its high resolution and small minimum feature size.
There are two main ways moisture can penetrate the enclosure: water vapor transmission (WVTR) through the walls, and leak paths through the seals.
There are many materials for SLA, but Nylon 6 or 12 is common and cheap. Acrylic also produces good prints but is over twice as expensive. The downside to Nylon is that it has a huge WVTR compared to acrylic, and I was skeptical that over the course of a year that even 2mm wall thickness would have slow enough water vapor diffusion. With the semi-granular nature of the STL printing process, there is even more risk. My solution was to coat all surfaces exposed to the outside with an acrylic spray.
For the o-ring seal, I selected one made from EPDM, a polymer commonly used in water based applications. It is highly resistant to water vapor transmission and does not swell through immersion in water. I used a silicone o-ring lubricant to help create a better seal by closing micro gaps. It's important to pay attention to the type of lubricant because some formulations may attack either the EPDM or the nylon of the enclosure.
To apply sealing pressure to the o-ring, I designed a four bolt pattern at the corners of the enclosure, which creates a highly uneven pressure distribution along the length of the o-ring, but still seems to do enough in this application. In a high performance sealing application I would definitely select a stiffer material for the enclosure to correct that problem.
How should wires pass through the enclosure? The components which are designed to be permanently attached (fan and sensor board) are passed through holes, and then sealed with epoxy.
For the solar panel wires, I used a 4 wire connector with an o-ring so that the inside enclosure can be separated from the radiation shield. This leaves two wires to make the station expandable in the future (extra sensor, etc).
To absorb the moisture that does leak into the enclosure, as well as the residual moisture trapped during assembly, I sourced a desiccant pack which has a capacity big enough the dehumidify the enclosed volume, which is about 6.7 cubic inches.
Once sealed, after 11 days outside there was no color change in a color-change desiccant. This indicates that there are no major leak paths.
I also sprayed the radiation shield with water, while a color changing powder (white to green) was applied to a paper towel roll placed inside. Surprisingly, no droplets made their way inside!
To utilize solar panels efficiently, we need to regulate the current draw to prevent voltage collapse. I chose to use an off the shelf component from Adafruit as it is reasonably priced and had the form factor needed: USB / DC / Solar Lithium Ion/Polymer charger - v2. I followed the excellent build instructions from Adafruit, making sure to solder in the thermresistor for over/under temperature protection. In addition, I desoldered the barrel jack which was too bulky to fit in the enclosure properly. This solar charger uses a voltage tracking circuit that targets 4.5V, so as long as the solar panel's maximum power point is reasonably close to that, it will be efficient enough.
Battery Management circuits
There's a great blog post about low power voltage measurements, which I used to create two measurement circuits on the high side which draw no current when "off" (using a ePMOS and a RC circuit). The transistors in these circuits were chosen One circuit measures the battery voltage, and the other measures the solar panel voltage. The high current draw devices (fan, etc.) are only allowed to turn on if the solar panel is charging the battery. This ensures that power is managed conservatively-- in addition, the fan is needed to ventilate the enclosure when it is heated by the sun, so if the sun is not shining, the solar panel is not charging the battery, and the fan is not needed anyways!
Fan Speed Circuit
The fan is controlled through a low side eNMOS circuit with flyback Schottky diode for inductive voltage spike protection (Schottky selected due to fast PWM switching). The brushless fan did not need extra capacitors to filter out high frequency noise, but needs the diode to prevent very high voltage spikes. Even with the diode in place, spikes reached 32V after the motor current was cut (MOSFET Vmax = 40V). I measured this with long wires connecting stuff together on a breadboard, and with a mechanical switch. With a MOSFET's slower transition time and less inductance on the PCB, I expect these spikes to decrease even further (todo!). For now, there seems to be no damage to the circuits.
The Adafruit solar charger outputs roughly 4V from the lithium ion battery when fully charged, and up to 7V from the solar panel via its passthrough feature. On the other end of the range, when the sun is not out and the battery is at low capacity, the voltage could be closer to 3.5V. This is outside the range of the onboard 5V -> 3.3V regulator on the Particle Photon, so an external power supply was needed, which would power both the Photon and the fan. I selected the Pololu 5V Step-Up/Step-Down Voltage Regulator S7V7F5, which operates in the range of 2.7V to 11.8V and is about 90% efficient with minimum 500mA output current capability.
See the linked Github project for my code. I use the Sparkfun BME280 library from Markus Haack (https://github.com/mhaack).
The Photon spends most of its time in sleep mode to save power. On each wakeup, the main loop() runs once.
- Checks the last time a reset occurred and if greater than 1 week, resets the Photon. I was running into a hanging issue after about 11 days of runtime so hopefully this clears whatever errors are accumulating.
- If the solar panel is providing enough power to charge the battery, the fan is run for 50 sec and then the sensor is queried. Why 50sec? See section below. If the solar panel is not providing enough power to charge, don't run the fan and just take a sensor reading.
- The battery voltage is checked with WiFi off. Note: voltage is checked while the battery is under lower load than if it is transmitting data over WiFi. So this method is only a rough estimate. If a reference current sink circuit was implemented, this could improve accuracy.
- Running the fan motor also checks the battery voltage during runtime as a rough check of remaining battery capacity-- if it's 3.3V or less, the Photon goes into sleep for a long time (hopefully this would be a red flag to whoever is looking at the Weather Underground data). Why 3.3V? See battery section.
- The fan PWM duty cycle was were chosen to keep current draw at a reasonable level. Of course the frequency needs to be high enough so that the motor effectively averages out the input square wave signal. Note also that the MOSFET controlling the motor power uses more current as the PWM frequency increases (due to charge/discharge of gate capacitance).
- The sensor measurement is compared to the previous one. To save power, WiFi and data upload is only activated if the measurement is different by a chosen threshold amount.
- If WiFi times out, the Photon goes back to sleep.
- Data is published to a Webhook in the Particle Cloud. See Webhook section.
- Photon waits for publish success or timeout before going to sleep.
Humidity and pressure don't change very much between fan on and off. However, temperature does. I took measurements every 5 seconds for 1 min while the station was in direct sunlight and partial shade with low wind (at least 10 minute wait time in between measurements):
Each line is a time series of measurements from 0 being fan off to 60 seconds on. There's four scenarios for temperature:  decreases quickly and then levels off,  continuously decreases,  minor change,  increase in temperature. I removed 3 and 4 to focus on the ones most likely caused by radiation shield overheating. Because in the above graph it is difficult to determine rate of change, I plotted the difference from one period to the next:
Bit of an eye chart but around the 10th period, or 50 seconds, most of the lines are leveling off.
The Webhooks make it very easy to publish to weather underground. Create a new webhook and fill out the fields as shown, using the station ID and password that is created on the weather underground website:
The battery needs to be rechargeable, produce between 3.3V and 5V at expected current draw (to keep the power supply operating in an efficient range), have a form factor that fits in the enclosure, and have capacity large enough to keep the station running for a week without solar charging.
Lithium Ion is rechargeable and has nominal 3.7V with high (>1A) current draws. The form factor of 18350 is a perfect size for the enclosure, and contains roughly 900mAh.
I chose a protected cell so that I don't have to worry about over-discharging the battery: Efest 18350 900mAh Battery - Protected Flat Top.
To determine true capacity, I measured the battery during a constant 400mA discharge. Because the expected max current draw is around 300mA, this is conservative.
Looks good up until about 3.3V, where the output voltage starts collapsing. That's why I set the low battery check at 3.3V. Again, this is a conservative value because this is at a current draw of 400mA, while the check occurs at probably less than 25% of that. The total battery capacity is at least 2.9Wh or 800mAh.
Is this good enough to power the station for 1 week without external power?
Using a ee-203 current monitor, which plots current as i=10^(-V), the following graphs were obtained (3.7V from bench supply):
The following table lists the energy usage for the various ways one measurement cycle can be completed.
Note the 3.2mA for the sleep current draw. This seems pretty high for a deep sleep mode! Further investigation is needed to find out what is causing this current drain (floating GIPO? leakage from caps? secondary circuit left powered on? something in the software? Leave ideas in the comments, please!).
With the fan on, we use 56mA (wifi off) to 524mA (fan PWM high), with 10 ms period, 50% duty cycle. The average is therefore 262mA over the 50s the fan is on. However, the fan only turns on when the solar panel is charging the battery, so I assume the energy flow into the system is overall positive, and this high current draw will not be an issue.
With a 2.9Wh battery, we have 10, 440J of energy. Using P=IV, the 3.2mA in sleep mode at nominal 3.7V is 0.01184W. I calculated the appropriate sleep time between measurements assuming we need 7 days (604, 800s) without charging, and that a cloud connection takes place every measurement. This is conservative because the code allows for the station to avoid connecting if the measured values are similar to the previous one.
(604800/x)*(0.01184*(x-7.64)+3.79) = 10440
x= 682s = 11 min 22s
I set the sleep time to 12 minutes.
We want to be able to charge the battery at a reasonable rate. The solar charger takes a maximum 6V nominal solar panel, with preset max charge rate of 500mA (although this is adjustable). This is 0.625C (500mAh/800mAh), within the guidelines for charging Li-Ion batteries (0.5C to 1C).
It's a bit of a challenge to source cheap solar cells that still output a decent amount of power. For example, the Sparkfun or Adafruit 6V panels are around $30. I found a 5 pack of panels on Amazon for $4/pc. However, it's a unknown brand, time for some solar cell characterization!
I took these measurements at 4PM shortly after the summer solstice in California (so pretty much the most solar radiation you can expect all year).
Angling the panel from horizontal and facing it South will help maximize solar irradiation on the panel. Following the guidelines, I set my panel to face true south at an angle of 30 deg from horizontal, which is a good average for northern and southern California, where I'll be using the stations. I also set it at 50 deg, which is the recommended angle for the winter, when cloudy weather is more likely.
The panel was facing directly true south for 2 trials labeled "-S" and towards wherever the sun was at "30deg at sun". The angles are all from horizontal.
At the maximum power point for "30deg-S", the voltage is about 5.9V and output current is 183mA for a total of about 1W. For a cheap solar cell, this is adequate. The Adafruit solar charger uses a MCP73871 chip with Voltage Proportional Charge Control (VPCC), set to 4.5V. The charger will adjust current draw to maintain 4.5V charging.
At 4.5V, about 0.88 W is available. A rough estimate of the lower bound is that a fully discharged battery (2.9Wh) can be charged in 3.3 hrs (2.9/0.88).
We can see that December in California has the lowest solar energy, approximately 51% of the peak in June (for Average Tilt at Latitude or ATaL). Extrapolating the measured data, I estimate 0.88W * 0.51 = 0.45W (although the curves for power vs voltage do change shape slightly with light intensity, I have assumed this is a small effect). This means the shortest charge time in December is 6.4 hrs. With only 9.5 hrs of daylight in December, this leaves little margin for bad weather.
What if the panel was set up for the best fixed angle in winter? Setting the panel to 50 degrees (recommended for 30 deg latitude), the MPP is at 5.9V and 0.68W. At 4.5V, we can extract 0.56W. According to the guidelines, the insolation in summer is 91% compared to winter.
For a latitude of 40 degrees, and horizontal tilt of 60 degrees, that becomes 109% of the winter value. As a rough estimate, I will assume that at the fixed winter angle the energy available is similar for both winter and summer. With this assumption, 0.56W in winter and in summer would charge in 5.2 hours. This is a better compromise than fast charging in summer and very slow charging in winter. I'll update this page when winter comes around to see if this is sufficient!
Taking into account the actual charge profile, I could be underestimating. However, this seems to be in the right ballpark to keep the station running indefinitely with normal direct sunlight in California. Winter conditions or extreme latitude conditions will require resizing the solar panel and or battery.
I did a rough estimate of the solar charging amount using a normal distribution for sun insolation (need to research the correct sun model):
One issue I found was that there seems to be corrosion starting on the white connectors within the solar panel. I'll keep an eye on this to see if it gets worse, but you get what you pay for with these cheap panels.
video of assembly: in progress
- sometimes photon hangs (after 11 days, 3 days, etc.) Looking into sleep mode operation to see if that's a problem.
- check fan voltage spikes during operation on actual PCB
- improve modeling of solar insolation vs. season and throughout the day. Using this can further refine sleep time between measurements
- Try to reduce sleep current below 3mA!!