914 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			914 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
 | 
						||
<head>
 | 
						||
  <meta charset="utf-8" />
 | 
						||
  <meta name="generator" content="pandoc" />
 | 
						||
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
 | 
						||
  <meta name="author" content="M.T. Konstapel" />
 | 
						||
  <meta name="dcterms.date" content="2024-01-22" />
 | 
						||
  <title>Weather station</title>
 | 
						||
  <link rel="stylesheet" href="./css/mvp.css" />
 | 
						||
<style type="text/css">
 | 
						||
  :root {
 | 
						||
  --width-content: 1080px;
 | 
						||
  }
 | 
						||
 | 
						||
  nav {
 | 
						||
    justify-content: space-around;
 | 
						||
  }
 | 
						||
 | 
						||
</style>
 | 
						||
</head>
 | 
						||
<body>
 | 
						||
<header id="title-block-header">
 | 
						||
  <nav id="TOC">
 | 
						||
      <ul>
 | 
						||
                    <li>
 | 
						||
            <a href="#">Index</a>
 | 
						||
            <ul>
 | 
						||
            <li><a href="#why-do-you-need-a-weather-station"
 | 
						||
            id="toc-why-do-you-need-a-weather-station">Why do you need a
 | 
						||
            weather station?</a></li>
 | 
						||
            <li><a href="#what-should-a-weather-station-measure"
 | 
						||
            id="toc-what-should-a-weather-station-measure">What should a
 | 
						||
            weather station measure?</a></li>
 | 
						||
            <li><a href="#what-sensors-do-we-need"
 | 
						||
            id="toc-what-sensors-do-we-need">What sensors do we
 | 
						||
            need?</a></li>
 | 
						||
            <li><a
 | 
						||
            href="#what-to-use-for-communication-with-the-outside-world"
 | 
						||
            id="toc-what-to-use-for-communication-with-the-outside-world">What
 | 
						||
            to use for communication with the outside world?</a></li>
 | 
						||
            <li><a href="#what-else" id="toc-what-else">What
 | 
						||
            else?</a></li>
 | 
						||
            <li><a href="#theory-of-operation---hardware"
 | 
						||
            id="toc-theory-of-operation---hardware">Theory of operation
 | 
						||
            - Hardware</a></li>
 | 
						||
            <li><a href="#theory-of-operation---software"
 | 
						||
            id="toc-theory-of-operation---software">Theory of operation
 | 
						||
            - Software</a></li>
 | 
						||
            <li><a href="#prototype"
 | 
						||
            id="toc-prototype">Prototype</a></li>
 | 
						||
            <li><a href="#specifications"
 | 
						||
            id="toc-specifications">Specifications</a></li>
 | 
						||
            <li><a href="#schematic"
 | 
						||
            id="toc-schematic">Schematic</a></li>
 | 
						||
            <li><a href="#software-dependencies"
 | 
						||
            id="toc-software-dependencies">Software
 | 
						||
            dependencies</a></li>
 | 
						||
            <li><a href="#license" id="toc-license">License</a></li>
 | 
						||
            </ul>
 | 
						||
          </li>
 | 
						||
                              <li>
 | 
						||
            <a href="./weather_station.pdf">PDF version</a>
 | 
						||
          </li>
 | 
						||
                              <li>
 | 
						||
            <a href="https://git.meezenest.nl/">Git repo</a>
 | 
						||
          </li>
 | 
						||
                              <li>
 | 
						||
            <a href="https://meezenest.nl/mees/">Back</a>
 | 
						||
          </li>
 | 
						||
                </ul>
 | 
						||
 | 
						||
      <a href="https://www.meezenest.nl/mees/"><img alt="Logo" src="./images/mees_logo.svg" height="70"></a>
 | 
						||
  </nav>
 | 
						||
<h1 class="title">Weather station</h1>
 | 
						||
<p class="subtitle">with ModBus RTU interface</p>
 | 
						||
<p class="author">M.T. Konstapel</p>
 | 
						||
<p class="date">2024-01-22</p>
 | 
						||
<p><a href="./weather_station.pdf"><i>PDF version</i></a></p>
 | 
						||
</header>
 | 
						||
<main>
 | 
						||
<article>
 | 
						||
<p><b>Abstract </b><p>A weather station build around a SparkFun Weather
 | 
						||
Meter Kit (SEN-15901). The temperature, humidity and pressure are
 | 
						||
measured with I2C sensors housed in an RS1 Passive Radiation Shield from
 | 
						||
Garni. The data can be read via an RS485 ModBus RTU interface. The main
 | 
						||
processor is an Arduino Pro Mini (ATmega328P 5V@16MHz)</p></p>
 | 
						||
<h1 id="why-do-you-need-a-weather-station">Why do you need a weather
 | 
						||
station?</h1>
 | 
						||
<p>Well, you don’t…because if you want to know the weather, you look on
 | 
						||
your phone. So why bother than? Because since the beginning of time,
 | 
						||
people are obsessed with the weather. When I was a child, my grandmother
 | 
						||
was measuring the temperature and rainfall on a daily basis. My
 | 
						||
grandfather had an allotment, so he also was very interested in the
 | 
						||
weather. The first thing my father read in the newspaper was the weather
 | 
						||
report and the last thing he watched on the television was… the weather
 | 
						||
report. And every hour he listed to the weather report on the radio. If
 | 
						||
he talked to someone he always started the conversation by talking about
 | 
						||
the weather. And when I open a new browser window, it automatically
 | 
						||
opens the weather page.</p>
 | 
						||
<p>So the weather is fascinating and taking your own measurements is a
 | 
						||
lot of fun.</p>
 | 
						||
<h1 id="what-should-a-weather-station-measure">What should a weather
 | 
						||
station measure?</h1>
 | 
						||
<p>As my grandmother already measured temperature and rainfall, these
 | 
						||
ones are mandatory. And for the rest I looked at the website of the
 | 
						||
Dutch meteorological institute. They measure wind direction, average
 | 
						||
wind speed of the last 10 minutes, maximum wind gust of the last 10
 | 
						||
minutes, rainfall of the last hour as well as the last 24 hours,
 | 
						||
temperature, humidity and atmospheric pressure.</p>
 | 
						||
<h3 id="measurements">Measurements</h3>
 | 
						||
<ul>
 | 
						||
<li>Wind direction</li>
 | 
						||
<li>Wind speed (average of last 10 minutes)</li>
 | 
						||
<li>Wind gust (last 10 minutes)</li>
 | 
						||
<li>Rain fall (last hour)</li>
 | 
						||
<li>Rain fall (last 24 hours)</li>
 | 
						||
<li>Temperature</li>
 | 
						||
<li>Humidity</li>
 | 
						||
<li>Atmospheric pressure</li>
 | 
						||
</ul>
 | 
						||
<h1 id="what-sensors-do-we-need">What sensors do we need?</h1>
 | 
						||
<h2 id="wind-and-rain">Wind and rain</h2>
 | 
						||
<p>Measuring wind and rain is difficult. Well, not if you want to do it
 | 
						||
by hand: place a beaker on the ground and wait a day. Than measure the
 | 
						||
amount of water in it. Empty the beaker and start again. And for the
 | 
						||
wind, you can stick a pole in the ground and attach a ribbon to it. The
 | 
						||
direction of the wind can than be made visible. And even the wind speed
 | 
						||
can be determent by measuring the angle between the ribbon and the
 | 
						||
ground.</p>
 | 
						||
<p>But how to do this automatically? Of course you can buy a fancy
 | 
						||
commercial weather station. These are surprisingly cheap these days. But
 | 
						||
that’s not a challenge. Besides, than you buy into a proprietary
 | 
						||
ecosystem. And it probably only works when connected to the cloud. No
 | 
						||
thanks!</p>
 | 
						||
<p>Building from scratch is an option, but I am an electronic engineer,
 | 
						||
not a mechanical one. I can imagine that won’t be a success. Besides
 | 
						||
going the professional route, which is ridiculously expensive, there is
 | 
						||
really only one option left: the SparkFun SEN-15901 Weather Meter.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/SparkFun-Weather_Meter.jpg"
 | 
						||
title="SparkFun Weather Meter" alt="SparkFun Weather Meter" />
 | 
						||
<figcaption aria-hidden="true">SparkFun Weather Meter</figcaption>
 | 
						||
</figure>
 | 
						||
<p>But this contraption does not come with any signal conditioning. We
 | 
						||
have to make some kind of interface. Luckily, Sparkfun provides an
 | 
						||
Arduino library, so we only have to connect the SEN-15901 to an Arduino
 | 
						||
and run the code.</p>
 | 
						||
<h2 id="temperature-humidity-and-air-pressure">Temperature, humidity and
 | 
						||
air pressure</h2>
 | 
						||
<p>These three are easy: there are a lot of I2C chips capable of
 | 
						||
measuring these parameters. I choose the Silicon Labs Si7021 for
 | 
						||
humidity and temperature and the Bosch BMP280 for pressure. Just hook
 | 
						||
them up to the Arduino’s I2C bus, load the available libraries and Bob’s
 | 
						||
your uncle.</p>
 | 
						||
<p>To mount these sensors on the same mast as the SparkFun weather meter
 | 
						||
I use the RS1 passive radiation shield from Garni.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/garni_rs1.jpg"
 | 
						||
title="Garni RS1 Passive Radiation Shield"
 | 
						||
alt="Garni RS1 Passive Radiation Shield" />
 | 
						||
<figcaption aria-hidden="true">Garni RS1 Passive Radiation
 | 
						||
Shield</figcaption>
 | 
						||
</figure>
 | 
						||
<h3 id="sensors">Sensors</h3>
 | 
						||
<ul>
 | 
						||
<li>SparkFun SEN-15901 Weather Station</li>
 | 
						||
<li>Silicon Labs Si7021</li>
 | 
						||
<li>Bosch BMP280</li>
 | 
						||
</ul>
 | 
						||
<h1 id="what-to-use-for-communication-with-the-outside-world">What to
 | 
						||
use for communication with the outside world?</h1>
 | 
						||
<p>Most consumer grade weather stations (and almost all other consumer
 | 
						||
grade goods for that matter) use proprietary interfaces and protocols.
 | 
						||
Probably to annoy the more technical skilled customer as you are not
 | 
						||
able to interface these devices with other brands or self build systems.
 | 
						||
I really hate that practice, so I won’t do that. Instead I will
 | 
						||
implement a ModBus RTU interface. Dating back to 1979, this is the
 | 
						||
industrial standard for communication between devices. And if the
 | 
						||
professionals all use it, why not use it for this weather station?</p>
 | 
						||
<h2 id="modbus">ModBus</h2>
 | 
						||
<p>ModBus is a client/server data communications protocol in the
 | 
						||
application layer of the OSI model. ModBus can work over several
 | 
						||
different physical interfaces. For this application I will use an RS-485
 | 
						||
interface. This interface is easy to implement and cables can be very
 | 
						||
long, making it easy to locate the weather station. ModBus is a
 | 
						||
lightweight protocol which can comfortably fit inside an under-powered
 | 
						||
micro-controller like an Atmel ATmega328P. A simple RS-485 to USB dongle
 | 
						||
connected to a PC is all you need to read the values from the weather
 | 
						||
station.</p>
 | 
						||
<h1 id="what-else">What else?</h1>
 | 
						||
<p>Not much to be honest. Almost everything can be done in software. Of
 | 
						||
course we need a power supply. And preferably a reverse polarity
 | 
						||
protection. An input voltage of 12 Volt is convenient. 12 Volt power
 | 
						||
bricks can be found in every charity shop and you can also use a 12 Volt
 | 
						||
lead acid or lithium battery to power the weather station.</p>
 | 
						||
<h1 id="theory-of-operation---hardware">Theory of operation -
 | 
						||
Hardware</h1>
 | 
						||
<figure>
 | 
						||
<img src="./images/block_diagram.svg"
 | 
						||
title="Block diagram of weather station"
 | 
						||
alt="Block diagram of weather station" />
 | 
						||
<figcaption aria-hidden="true">Block diagram of weather
 | 
						||
station</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="wind-speed">Wind speed</h2>
 | 
						||
<p>Measuring the wind speed is done by a cup anemometer. It consisted of
 | 
						||
three or four hemispherical cups on horizontal arms mounted on a
 | 
						||
vertical shaft. The air flow past the cups in any horizontal direction
 | 
						||
turned the shaft at a rate roughly proportional to the wind’s speed.
 | 
						||
Every rotation, a magnet passes alongside a reed switch. The rate at
 | 
						||
which the reed switch opens en closes is a measure of the wind
 | 
						||
speed.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/sparkfun_cup_anemometer.jpg" title="Cup anemometer"
 | 
						||
alt="Cup anemometer" />
 | 
						||
<figcaption aria-hidden="true">Cup anemometer</figcaption>
 | 
						||
</figure>
 | 
						||
<p>By connecting one side of the reed switch to ground and the other via
 | 
						||
a pull-up resistor to the supply voltage the mechanical switching action
 | 
						||
is translated to an electrical pulse signal. This pulse can be read by a
 | 
						||
micro-controller.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/diagram_cup_anemometer.svg"
 | 
						||
title="Cup anemometer: theory of operation"
 | 
						||
alt="Cup anemometer: theory of operation" />
 | 
						||
<figcaption aria-hidden="true">Cup anemometer: theory of
 | 
						||
operation</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="wind-direction">Wind direction</h2>
 | 
						||
<p>Measuring the wind direction is done by a wind vane. It consists of a
 | 
						||
vertical blade mounted on a vertical shaft. Because the blade can turn,
 | 
						||
it will always find the position of the least air resistance. The shape
 | 
						||
of the blade is chosen so that it will always points directly to the
 | 
						||
wind. A magnet mounted on the shaft rotates past several reed switches.
 | 
						||
The switch that is closest to the magnet will close. If the magnet is
 | 
						||
precisely between two reed switches both switches will close increasing
 | 
						||
the resolution of the wind vane.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/sparkfun_wind_vane.jpg" title="Wind vane"
 | 
						||
alt="Wind vane" />
 | 
						||
<figcaption aria-hidden="true">Wind vane</figcaption>
 | 
						||
</figure>
 | 
						||
<p>Each reed switch is connected to a resistor and every resister has a
 | 
						||
different value. The total resistance of the network will change
 | 
						||
according to the wind direction. By connecting one side of the network
 | 
						||
to ground and the other side via a resistor to VCC, a resisive divider
 | 
						||
in made. This resistive divider converts the variable resistance to an
 | 
						||
analog voltage which can be sampled by the A/D converter of a
 | 
						||
micro-controller.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/diagram_wind_vane.svg"
 | 
						||
title="Wind vane: theory of operation"
 | 
						||
alt="Wind vane: theory of operation" />
 | 
						||
<figcaption aria-hidden="true">Wind vane: theory of
 | 
						||
operation</figcaption>
 | 
						||
</figure>
 | 
						||
<table>
 | 
						||
<thead>
 | 
						||
<tr class="header">
 | 
						||
<th>Direction</th>
 | 
						||
<th>Resistance</th>
 | 
						||
</tr>
 | 
						||
</thead>
 | 
						||
<tbody>
 | 
						||
<tr class="odd">
 | 
						||
<td>0°</td>
 | 
						||
<td>33kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>22.5°</td>
 | 
						||
<td>6.57kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>45°</td>
 | 
						||
<td>8.2kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>67.5°</td>
 | 
						||
<td>891Ω</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>90°</td>
 | 
						||
<td>1kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>112.5°</td>
 | 
						||
<td>688Ω</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>135°</td>
 | 
						||
<td>2.2kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>157.5°</td>
 | 
						||
<td>1.41kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>180°</td>
 | 
						||
<td>3.9kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>202.5°</td>
 | 
						||
<td>3.14kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>225°</td>
 | 
						||
<td>16kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>247.5°</td>
 | 
						||
<td>14.12kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>270°</td>
 | 
						||
<td>120kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>292.5°</td>
 | 
						||
<td>42.12kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>315°</td>
 | 
						||
<td>64.9kΩ</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>337.5°</td>
 | 
						||
<td>21.88kΩ</td>
 | 
						||
</tr>
 | 
						||
</tbody>
 | 
						||
</table>
 | 
						||
<h2 id="rain-fall">Rain fall</h2>
 | 
						||
<p>Measuring the amount of rain fall is done by a self-emptying tipping
 | 
						||
bucket. Rainwater is collected and funneled to a tipping bucket. The
 | 
						||
bucket tips over when a certain amount of water is collected. The bucket
 | 
						||
drains and a second bucket is automatically placed under the funnel.
 | 
						||
When a certain amount of water is collected in this second bucket it
 | 
						||
will tip over and the first bucket is raised again.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/sparkfun_rain_meter_inside.jpg" title="Rain meter"
 | 
						||
alt="Rain meter" />
 | 
						||
<figcaption aria-hidden="true">Rain meter</figcaption>
 | 
						||
</figure>
 | 
						||
<p>Every time the bucket tips over a magnet passes by a reed switch,
 | 
						||
which closes and opens again. As with the cup anemometer this mechanical
 | 
						||
movement can be translated to an electrical pulse by connecting one side
 | 
						||
of the switch to ground and the other side via a pull-up resistor to
 | 
						||
VCC. This pulse can than be read by a micro-controller.</p>
 | 
						||
<p><sup>NOTE</sup> The rain meter is very sensitive: even a small amount
 | 
						||
of movement and the bucket tips over. Mounting the rain meter in the
 | 
						||
mast together with the wind meters can cause false triggers from the
 | 
						||
rocking motion of the mast.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/diagram_rain_meter.svg"
 | 
						||
title="Rain meter: theory of operation"
 | 
						||
alt="Rain meter: theory of operation" />
 | 
						||
<figcaption aria-hidden="true">Rain meter: theory of
 | 
						||
operation</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="humidity">Humidity</h2>
 | 
						||
<p>Measuring the relative humidity is done by an electronic sensor based
 | 
						||
on capacitive sensing using polymeric dielectrics. The humidity sensor
 | 
						||
is a small capacitor consisting of a hygroscopic dielectric material
 | 
						||
placed between a pair of electrodes. Absorption of moisture by the
 | 
						||
sensor results in an increase in sensor capacitance. The opposite is
 | 
						||
also true: when the moisture disappears, sensor capacitane decreases.
 | 
						||
There is a direct relationship between relative humidity, the amount of
 | 
						||
moisture present in the sensor, and the sensor capacitance. The relative
 | 
						||
humidity is defined as the ratio of the amount of water vapor in the air
 | 
						||
at a specific temperature to the maximum amount that the air could hold
 | 
						||
at that temperature, expressed as a percentage. As the humidity sensor
 | 
						||
has a build in temperature sensor, it can calculate the relative
 | 
						||
humidity.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/capacitive_humidity_sensor.png"
 | 
						||
title="Humidity sensor" alt="Humidity sensor" />
 | 
						||
<figcaption aria-hidden="true">Humidity sensor</figcaption>
 | 
						||
</figure>
 | 
						||
<p>The Si7021 humidity sensor has an I²C bus for communication with a
 | 
						||
micro-controller.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/Si7021_block_diagram.png"
 | 
						||
title="Humidity sensor: block diagram"
 | 
						||
alt="Humidity sensor: block diagram" />
 | 
						||
<figcaption aria-hidden="true">Humidity sensor: block
 | 
						||
diagram</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="temperature">Temperature</h2>
 | 
						||
<p>Measuring the temperature is done by the build in temperature sensor
 | 
						||
of the humidity sensor. This sensor is used by the humidity sensor to
 | 
						||
calculate the relative humidity. But as this sensor is very accurate it
 | 
						||
can be used for ambient temperature measurments.</p>
 | 
						||
<h2 id="atmospheric-pressure">Atmospheric pressure</h2>
 | 
						||
<p>Measuring the atmospheric pressure is done by an electronic sensor
 | 
						||
based on a piezo-resistive pressure sensing element. The piezo-resistive
 | 
						||
effect is a change in the electrical resistivity of a semiconductor or
 | 
						||
metal when mechanical strain is applied. In this case the strain comes
 | 
						||
from the atmospheric pressure. The sensor measures the resistance which
 | 
						||
is proportional to the atmospheric pressure.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/piezo_resistive_pressure_sensor.png"
 | 
						||
title="Piezo-resistive pressure sensor"
 | 
						||
alt="Piezo-resistive pressure sensor" />
 | 
						||
<figcaption aria-hidden="true">Piezo-resistive pressure
 | 
						||
sensor</figcaption>
 | 
						||
</figure>
 | 
						||
<p>The BMP280 pressure sensor has an on board temperature sensor which
 | 
						||
can also be used to measure the ambient temperature. As this sensor is
 | 
						||
less accurate compared to the sensor of the Si7021 humidity sensor, the
 | 
						||
sensor is only used as a backup sensor. The BMP280 has an I²C bus for
 | 
						||
communication with a micro-controller.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/BMP280_block_diagram.png"
 | 
						||
title="Pressure sensor: block diagram"
 | 
						||
alt="Pressure sensor: block diagram" />
 | 
						||
<figcaption aria-hidden="true">Pressure sensor: block
 | 
						||
diagram</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="illumination">Illumination</h2>
 | 
						||
<p>This sensor is still under development.</p>
 | 
						||
<h2 id="modbus-interface">ModBus interface</h2>
 | 
						||
<p>The RS-485 interface is build with a MAX485E driver chip from Maxim
 | 
						||
Integrated. Nothing much to say as the implementation is pretty much
 | 
						||
following the typical application from the datasheet.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/rs-485.svg" title="RS-485 interface"
 | 
						||
alt="RS-485 interface" />
 | 
						||
<figcaption aria-hidden="true">RS-485 interface</figcaption>
 | 
						||
</figure>
 | 
						||
<p>If the device is the first or last device on the RS-485 bus, a 120
 | 
						||
Ohm termination resistor can be enabled by placing a jumper on header
 | 
						||
J7.</p>
 | 
						||
<p>The Arduino micro-controller can be programmed via an in circuit
 | 
						||
programmer, which shares the serial port with the MAX485E. Resistor R5
 | 
						||
isolates the output of the MAX485 from the signal of the programmer.</p>
 | 
						||
<h2 id="i²c-bus">I²C bus</h2>
 | 
						||
<p>The I²C bus is integrated in the micro-controller. But because the
 | 
						||
micro-controller uses a power supply of 5 Volt and the I²C sensors use
 | 
						||
3.3 Volt a bidirectional level shifter is needed. This way the sensors
 | 
						||
can be used on the 5V I²C bus without the risk of damaging the
 | 
						||
sensors.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/i2c_bus.svg" title="I²C bus level shifter"
 | 
						||
alt="I²C bus level shifter" />
 | 
						||
<figcaption aria-hidden="true">I²C bus level shifter</figcaption>
 | 
						||
</figure>
 | 
						||
<p>Let’s assume the I²C signal lines on either end of the MOSFETs are
 | 
						||
either outputting a logic high or is configured as an input. Effectively
 | 
						||
this means there is nothing pulling the signal levels down.</p>
 | 
						||
<p>The voltage between the gate and source of both MOSFETs is at 0V
 | 
						||
(both are at 3.3V) so the MOSFET is switched off. Therefore both sides
 | 
						||
of the MOSFETs are logic high.</p>
 | 
						||
<p>When either of the 3.3 Volt signal lines outputs a logic low the
 | 
						||
corresponding drain is pulled to ground. Now the voltage between the
 | 
						||
gate and the source is 3.3V and the MOSFET turns on causing the 5 Volt
 | 
						||
side to go low as well.</p>
 | 
						||
<p>When either of the 5 Volt signal lines outputs a logic low the body
 | 
						||
diode of the corresponding MOSFET start conducting, causing the source
 | 
						||
voltage to drop below the gate voltage. The MOSFET switches on and the
 | 
						||
3.3 volt side goes low.</p>
 | 
						||
<h2 id="power-supply">Power supply</h2>
 | 
						||
<p>Typical, a 12 Volt power supply is used to power the device, but it
 | 
						||
can be powered from a wide range of voltages, from 6.5 to 36 Volt. A
 | 
						||
switching regulator (U3) supplies the 5 Volt power rail and a linear low
 | 
						||
drop regulator (U4) supplies the 3.3 volt power rail.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/power_supply.svg" title="Power supply"
 | 
						||
alt="Power supply" />
 | 
						||
<figcaption aria-hidden="true">Power supply</figcaption>
 | 
						||
</figure>
 | 
						||
<h3 id="input-protection">Input protection</h3>
 | 
						||
<p>C1 and C5 short out high frequency signals, protecting the input from
 | 
						||
ESD. Bidirectional transient-voltage-suppression diodes D1 end D2 clamp
 | 
						||
transient voltages, again protecting the input from ESD.</p>
 | 
						||
<p>And than Q3 and its surrounding components: this is the reverse
 | 
						||
polarity protection. Usually, a series diode is used, but due to the
 | 
						||
voltage drop across such a diode it dissipates energy which is wasteful.
 | 
						||
The circuit with Q3 on the other hand has a very low voltage drop
 | 
						||
resulting in an almost zero loss solution.</p>
 | 
						||
<p>If VCC is applied in the correct polarity, the source will
 | 
						||
immediately rise to the about VCC because of the body diode
 | 
						||
conducting.</p>
 | 
						||
<p>The gate will charge towards -VCC with respect to the source through
 | 
						||
R1. When the gate reaches the threshold voltage the MOSFET channel will
 | 
						||
begin to conduct, and by the time the gate-source voltage reaches a few
 | 
						||
volts the MOSFET channel will be conducting almost all the current, the
 | 
						||
output voltage will be close to VCC. It continues to charge until it
 | 
						||
reaches about -10V at which point the zener diode begins to shunt
 | 
						||
significant current away from the gate.</p>
 | 
						||
<p>In steady state with VCC on the drain the gate sits at -10V with
 | 
						||
respect to the source, and the MOSFET happily conducts in the reverse
 | 
						||
direction.</p>
 | 
						||
<p>When VCC is applied in the reverse polarity, the body diode of the
 | 
						||
MOSFET cannot conduct. Only a small leakage current can flow from the
 | 
						||
source to the drain via resistor R1 and zener diode D3, which now acts
 | 
						||
as a normal diode. The gate and the source are now at almost the same
 | 
						||
potential and the MOSFET cannot conduct, protecting the device from
 | 
						||
reverse polarity.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/reverse_polarity_protection.svg"
 | 
						||
title="Reverse polarity protection" alt="Reverse polarity protection" />
 | 
						||
<figcaption aria-hidden="true">Reverse polarity protection</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="microcontroller">Microcontroller</h2>
 | 
						||
<p>The heart of the circuit is an Arduino Pro Mini, which is basically
 | 
						||
an Atmel ATmega328P with a special Arduino bootloader, making it an easy
 | 
						||
platform for developing software.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/micro-controller.svg" title="Microcontroller"
 | 
						||
alt="Microcontroller" />
 | 
						||
<figcaption aria-hidden="true">Microcontroller</figcaption>
 | 
						||
</figure>
 | 
						||
<p>Both the signals from the rain meter and the cup anemometer are
 | 
						||
connected to interrupt pins of the micro-controller. The signal from the
 | 
						||
rain meter is lightly filtered by C8.</p>
 | 
						||
<p>The ModBus address can be set by DIP switch J9.</p>
 | 
						||
<h1 id="theory-of-operation---software">Theory of operation -
 | 
						||
Software</h1>
 | 
						||
<h2 id="wind-speed-1">Wind speed</h2>
 | 
						||
<p>The pulse from the cup anemometer is connected to an interrupt input
 | 
						||
of the micro-controller. Every time its logic level changes an interrupt
 | 
						||
routine is called. This routine increments a counter and checks how many
 | 
						||
time has passed since the previous interrupt call. If the previous call
 | 
						||
was more than 6 seconds ago, the wind speed is (almost) zero. If the
 | 
						||
previous call was just over 3 second ago the interrupt counter now holds
 | 
						||
the amount of pulses in three seconds. This value is stored and from
 | 
						||
that value the wind speed can be calculated. If the previous call was
 | 
						||
less than 3 seconds ago the measurement is still in progress and no
 | 
						||
further action is taken. A measurment period of three seconds is choosen
 | 
						||
because it is the standard as used by the Dutch meteorological institute
 | 
						||
(KNMI).</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/wind_speed_diagram.svg" title="Wind speed interrupt"
 | 
						||
alt="Wind speed interrupt" />
 | 
						||
<figcaption aria-hidden="true">Wind speed interrupt</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="wind-direction-1">Wind direction</h2>
 | 
						||
<p>The analog signal from the wind vane is fed into the analog to
 | 
						||
digital converter of the micro-controller. The software samples this
 | 
						||
signal and determines which value from a lookup table is closest to the
 | 
						||
value from the ADC. The lookup table now gives the wind direction in
 | 
						||
degrees.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/wind_direction_diagram.svg"
 | 
						||
title="Getting the wind direction" alt="Getting the wind direction" />
 | 
						||
<figcaption aria-hidden="true">Getting the wind direction</figcaption>
 | 
						||
</figure>
 | 
						||
<p>As the tolerances between micro-controllers can be high, the wind
 | 
						||
vane has to be calibrated in order to get a correct lookup table.</p>
 | 
						||
<h2 id="rain-fall-1">Rain fall</h2>
 | 
						||
<p>The pulse from the rain meter is connected to an interrupt input of
 | 
						||
the micro-controller. Every time a rising edge is detected an interrupt
 | 
						||
routine is called. This routine debounces the signal and increments the
 | 
						||
rain counter. This counter can be used to calculate the rain fall.</p>
 | 
						||
<h2 id="humidity-1">Humidity</h2>
 | 
						||
<p>Via the I²C bus, the humidity value of the sensor is read. As the
 | 
						||
sensor can become saturated with moisture it can get stuck at 100%. This
 | 
						||
happens in particular with fog or other high humidity and condensing
 | 
						||
weather types. The sensor has a build in heater to drive of moisture and
 | 
						||
thus preventing this problem. Because the temperature of the sensor
 | 
						||
rises when the heater is turned on, accurate ambient temperature and
 | 
						||
humidity readings are no longer possible. But with a smart algorithm it
 | 
						||
is possible to get the benefits of the build in heater while still being
 | 
						||
able to use the sensor as an ambient thermometer.</p>
 | 
						||
<p>When the humidity rises above 95% for more than an hour the current
 | 
						||
temperature and humidity are stored and the heater is switched on for 5
 | 
						||
minutes. Than the heater is switched off again. If after 15 minutes the
 | 
						||
humidity is still above 95% the heater is turned on again for another 5
 | 
						||
minutes. But not before the temperature and humidity are measured and
 | 
						||
stored, as the sensor is now cooled off to ambient temperature. If the
 | 
						||
humidity is below 95% the sensor is free from moisture and the process
 | 
						||
is not repeated for another hour.</p>
 | 
						||
<p>When the heater algorithm is active, the temperature and humidity
 | 
						||
values are updated every 20 minutes instead of every 2 seconds. Statis
 | 
						||
bit 0 (ModBus register 30014) indicated if the heater is on or off and
 | 
						||
status bit 1 gives the update rate of the temperature and humidity
 | 
						||
values.</p>
 | 
						||
<p>This algorithm can be enabled by setting the HeaterCoil (see ModBus
 | 
						||
secion).</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/smart_heater.svg" title="Heater algorithm"
 | 
						||
alt="Heater algorithm" />
 | 
						||
<figcaption aria-hidden="true">Heater algorithm</figcaption>
 | 
						||
</figure>
 | 
						||
<h2 id="temperature-1">Temperature</h2>
 | 
						||
<p>The temperature is read from the humidity sensor as this sensor gives
 | 
						||
the most accurate temperature readings. When the heater is on (see
 | 
						||
section humidity above) the temperature readings are temporary stopped
 | 
						||
and only updated every 20 minutes. As a backup, the slightly less
 | 
						||
accurate temperature readings from the pressure sensor can be used.</p>
 | 
						||
<h2 id="atmospheric-pressure-1">Atmospheric pressure</h2>
 | 
						||
<p>Via the I²C bus, the atmospheric pressure value of the sensor is
 | 
						||
read. There is nothing further to say about this sensor: it is rather
 | 
						||
boring.</p>
 | 
						||
<h2 id="illumination-1">Illumination</h2>
 | 
						||
<p>This sensor is still under development.</p>
 | 
						||
<h2 id="modbus-interface-1">ModBus interface</h2>
 | 
						||
<p>The weather station uses ModBus RTU over a simplex RS-485 line. For
 | 
						||
now, the ModBus address is hard coded as 14 in the software. The values
 | 
						||
are available in the input registers and can be read via function code
 | 
						||
04.</p>
 | 
						||
<p>Below an example of how to read the wind direction and enable the
 | 
						||
heater algorithm in Python using the minimalmodbus library.</p>
 | 
						||
<pre><code>#!/usr/bin/env python3
 | 
						||
import minimalmodbus
 | 
						||
 | 
						||
# port name, slave address (in decimal)
 | 
						||
instrument = minimalmodbus.Instrument('/dev/ttyUSB1', 14)
 | 
						||
 | 
						||
# register number, number of decimals, function code
 | 
						||
wind_direction = instrument.read_register(1, 0, 4)
 | 
						||
print(wind_direction)
 | 
						||
 | 
						||
# register address, value, function code
 | 
						||
instrument.write_bit(0, 1, 5)</code></pre>
 | 
						||
<h3 id="input-registers-read-only">Input registers (read only)</h3>
 | 
						||
<p>Input registers are numbered 30001 to 39999 but have data addresses
 | 
						||
0x000 to 0x270E. The measurements and order of the measurements are the
 | 
						||
same as for APRS weather reports. But of course we use SI units.</p>
 | 
						||
<table>
 | 
						||
<colgroup>
 | 
						||
<col style="width: 13%" />
 | 
						||
<col style="width: 53%" />
 | 
						||
<col style="width: 33%" />
 | 
						||
</colgroup>
 | 
						||
<thead>
 | 
						||
<tr class="header">
 | 
						||
<th>Address</th>
 | 
						||
<th>Description</th>
 | 
						||
<th>Units</th>
 | 
						||
</tr>
 | 
						||
</thead>
 | 
						||
<tbody>
 | 
						||
<tr class="odd">
 | 
						||
<td>00</td>
 | 
						||
<td>Device ID (0x5758)</td>
 | 
						||
<td>NO UNIT</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>01</td>
 | 
						||
<td>Wind direction</td>
 | 
						||
<td>degrees * 10</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>02</td>
 | 
						||
<td>Wind speed (average of 10 minutes)</td>
 | 
						||
<td>m/s * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>03</td>
 | 
						||
<td>Wind gust (peak of last 10 minutes)</td>
 | 
						||
<td>m/s * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>04</td>
 | 
						||
<td>Temperature (two’s complement)</td>
 | 
						||
<td>degrees Celcius * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>05</td>
 | 
						||
<td>Rain last hour</td>
 | 
						||
<td>l/m2 * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>06</td>
 | 
						||
<td>Rain last 24 hours</td>
 | 
						||
<td>l/m2 * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>07</td>
 | 
						||
<td>Rain since midnight</td>
 | 
						||
<td>NOT IMPLEMENTED</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>08</td>
 | 
						||
<td>Humidity</td>
 | 
						||
<td>percent * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>09</td>
 | 
						||
<td>Barometric pressure</td>
 | 
						||
<td>hPa * 10</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>10</td>
 | 
						||
<td>Luminosity</td>
 | 
						||
<td>W/m2</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>11</td>
 | 
						||
<td>Snow fall</td>
 | 
						||
<td>NOT IMPLEMENTED</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>12</td>
 | 
						||
<td>Raw rain counter</td>
 | 
						||
<td>l/m2 * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>13</td>
 | 
						||
<td>Temperature (two’s complement)</td>
 | 
						||
<td>degrees Celcius * 100</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>14</td>
 | 
						||
<td>Status bits</td>
 | 
						||
<td>see table below</td>
 | 
						||
</tr>
 | 
						||
</tbody>
 | 
						||
</table>
 | 
						||
<p><sup>NOTE</sup> Register 13 holds the backup temperature reading from
 | 
						||
the pressure sensor.</p>
 | 
						||
<table>
 | 
						||
<colgroup>
 | 
						||
<col style="width: 18%" />
 | 
						||
<col style="width: 31%" />
 | 
						||
<col style="width: 25%" />
 | 
						||
<col style="width: 24%" />
 | 
						||
</colgroup>
 | 
						||
<thead>
 | 
						||
<tr class="header">
 | 
						||
<th>Status bits</th>
 | 
						||
<th>Description</th>
 | 
						||
<th>logic 0</th>
 | 
						||
<th>logic 1</th>
 | 
						||
</tr>
 | 
						||
</thead>
 | 
						||
<tbody>
 | 
						||
<tr class="odd">
 | 
						||
<td>0</td>
 | 
						||
<td>Heater status</td>
 | 
						||
<td>heater off</td>
 | 
						||
<td>heater on</td>
 | 
						||
</tr>
 | 
						||
<tr class="even">
 | 
						||
<td>1</td>
 | 
						||
<td>Temp/humidity update</td>
 | 
						||
<td>every 20 minutes</td>
 | 
						||
<td>every 2 seconds</td>
 | 
						||
</tr>
 | 
						||
<tr class="odd">
 | 
						||
<td>2</td>
 | 
						||
<td>Heater algorithm</td>
 | 
						||
<td>disabled</td>
 | 
						||
<td>enabled</td>
 | 
						||
</tr>
 | 
						||
</tbody>
 | 
						||
</table>
 | 
						||
<p>The ModBus registers are 16 bit wide. For better precision, some
 | 
						||
units are scaled by a factor of 10 or 100. This way, values with up to
 | 
						||
two decimal points can be stored as 16 bit integer values. Just divide
 | 
						||
by 10 or 100 to get the floating point values.</p>
 | 
						||
<h3 id="output-coils-write-only">Output coils (write only)</h3>
 | 
						||
<p>Output coils registers are numbered 1 to 9999 but have data addresses
 | 
						||
0x000 to 0x270E. The default value of a register is 0.</p>
 | 
						||
<table>
 | 
						||
<thead>
 | 
						||
<tr class="header">
 | 
						||
<th>Address</th>
 | 
						||
<th>Description</th>
 | 
						||
<th>logic 0</th>
 | 
						||
<th>logic 1</th>
 | 
						||
</tr>
 | 
						||
</thead>
 | 
						||
<tbody>
 | 
						||
<tr class="odd">
 | 
						||
<td>0</td>
 | 
						||
<td>Heater algorithm</td>
 | 
						||
<td>disabled</td>
 | 
						||
<td>enabled</td>
 | 
						||
</tr>
 | 
						||
</tbody>
 | 
						||
</table>
 | 
						||
<h1 id="prototype">Prototype</h1>
 | 
						||
<p>I wanted to locate the weather station at about 100 meters from the
 | 
						||
house. That meant that interfacing the weather station was not just a
 | 
						||
matter of connecting a wire to it. And 100 meters is a bit much for a
 | 
						||
wifi connection either. As I already had experience with LoRa I opted
 | 
						||
for that. But not LoRaWAN, but LoRa APRS. This is a ham radio network
 | 
						||
that I often use. I even run my own digipeater. So LoRa APRS it is.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/prototype_block_diagram.svg"
 | 
						||
title="Block diagram of the prototype"
 | 
						||
alt="Block diagram of the prototype" />
 | 
						||
<figcaption aria-hidden="true">Block diagram of the
 | 
						||
prototype</figcaption>
 | 
						||
</figure>
 | 
						||
<p>The weather station’s RS-485 interface is connected to a Raspberry Pi
 | 
						||
Zero 2W running the aprx digipeater software, as well as some specially
 | 
						||
written Python programs to interface the build in LoRa transceiver, the
 | 
						||
GPS module and the weather station itself. Every 10 minutes the
 | 
						||
digipeater will read the weather station’s registers and sends the data
 | 
						||
as PE1RXF telemetry messages over the APRS network to a server, which
 | 
						||
presents the data in a Grafana dashboard. The digipeater can also send
 | 
						||
standardized APRS weather reports over the APRS network. But more about
 | 
						||
this project can be found here: <a
 | 
						||
href="https://www.meezenest.nl/mees-elektronica/RPi_LoRa_shield.html">https://www.meezenest.nl/mees-elektronica/RPi_LoRa_shield.html</a></p>
 | 
						||
<figure>
 | 
						||
<img src="./images/prototype_overview_small.jpg"
 | 
						||
title="The prototype in the garden" alt="The prototype in the garden" />
 | 
						||
<figcaption aria-hidden="true">The prototype in the garden</figcaption>
 | 
						||
</figure>
 | 
						||
<p>As a housing for the prototype, I used an old beehive. These are
 | 
						||
weatherproof and I had one laying around.</p>
 | 
						||
<figure>
 | 
						||
<img src="./images/prototype_sensors_small.jpg"
 | 
						||
title="Closeup of the sensors" alt="Closeup of the sensors" />
 | 
						||
<figcaption aria-hidden="true">Closeup of the sensors</figcaption>
 | 
						||
</figure>
 | 
						||
<figure>
 | 
						||
<img src="./images/prototype_inside_annotations_small.jpg"
 | 
						||
title="Inside the beehive" alt="Inside the beehive" />
 | 
						||
<figcaption aria-hidden="true">Inside the beehive</figcaption>
 | 
						||
</figure>
 | 
						||
<h1 id="specifications">Specifications</h1>
 | 
						||
<h2 id="wind">Wind</h2>
 | 
						||
<ul>
 | 
						||
<li><p>Wind speed is measured by taking 3 second averages from the cup
 | 
						||
anemometer and using these samples to calculate the average over a 10
 | 
						||
minute periode.</p></li>
 | 
						||
<li><p>Wind gust is measured by taking 3 second averages from the cup
 | 
						||
anemometer.</p></li>
 | 
						||
<li><p>Wind vane has 8 main directions and another 8 directions in
 | 
						||
between. But these last do not have the same weight, eg. these positions
 | 
						||
are not as likely to be measured as the main directions. This is due to
 | 
						||
the construction of the wind vane: it has eight reed switches for the
 | 
						||
main directions and if the wind direction happens to sit exactly in
 | 
						||
between two reed switches, both switches are closed giving the extra 8
 | 
						||
sub directions. Not great, but it is what it is…</p></li>
 | 
						||
</ul>
 | 
						||
<h2 id="rain">Rain</h2>
 | 
						||
<pre><code>Resolution: 0.2794 mm/impulse</code></pre>
 | 
						||
<h2 id="humidity-2">Humidity</h2>
 | 
						||
<pre><code>Operating range   :  0 - 100 % RH
 | 
						||
Recommended range : 20 - 80 % RH
 | 
						||
Accuracy          : +/- 3 % RH (0-80 % RH)
 | 
						||
                    +/- 4.5 % (max when > 80 % RH)
 | 
						||
 | 
						||
Heater to drive of moisture (can be enabled via ModBus)</code></pre>
 | 
						||
<h2 id="pressure">Pressure</h2>
 | 
						||
<pre><code>Operating range : 300 - 1100 hPa
 | 
						||
Accuracy        : +/- 1.0 hPa (0 - 65 °C)
 | 
						||
                  +/- 1.7 hPa (-20 - 0 °C)</code></pre>
 | 
						||
<h2 id="temperature-2">Temperature</h2>
 | 
						||
<pre><code>Main sensor
 | 
						||
-----------
 | 
						||
 | 
						||
Operating range : -10 - 85 °C (typ)
 | 
						||
                  -40 - 85 °C (max)
 | 
						||
Accuracy        : +/- 0.3 °C (typ)
 | 
						||
                  +/- 0.4 °C (max)
 | 
						||
                  +/- 0.5 °C (max when < -10°C)
 | 
						||
 | 
						||
Backup sensor
 | 
						||
-------------
 | 
						||
 | 
						||
Operating range :   0 - 65 °C (typ)
 | 
						||
                  -40 - 85 °C (max)
 | 
						||
Accuracy        : +/- 0.5 °C (25 °C)
 | 
						||
                  +/- 1.0 °C (0 - 65 °C)</code></pre>
 | 
						||
<h2 id="modbus-1">ModBus</h2>
 | 
						||
<pre><code>Physical : RS-485 simplex RTU
 | 
						||
Settings : 9600 bd 8N1
 | 
						||
Address  : 14</code></pre>
 | 
						||
<h1 id="schematic">Schematic</h1>
 | 
						||
<p><a href="./images/weather_station_schematic.pdf"><img
 | 
						||
src="./images/weather_station_schematic.svg" alt="Schematic" /></a></p>
 | 
						||
<!---
 | 
						||
# Bill of materials
 | 
						||
 | 
						||
# Component placement
 | 
						||
 | 
						||
# Cables and pinouts
 | 
						||
-->
 | 
						||
<h1 id="software-dependencies">Software dependencies</h1>
 | 
						||
<ul>
 | 
						||
<li>Arduino IDE</li>
 | 
						||
</ul>
 | 
						||
<h2 id="arduino-libraries">Arduino libraries</h2>
 | 
						||
<ul>
 | 
						||
<li>https://github.com/sparkfun/SparkFun_Weather_Meter_Kit_Arduino_Library</li>
 | 
						||
<li>https://github.com/orgua/iLib</li>
 | 
						||
<li>https://github.com/epsilonrt/modbus-arduino</li>
 | 
						||
<li>https://github.com/epsilonrt/modbus-serial</li>
 | 
						||
</ul>
 | 
						||
<p>Libraries are included with the source code of this project</p>
 | 
						||
<h1 id="license">License</h1>
 | 
						||
<p>Copyright (C) 2023, 2024 M.T. Konstapel</p>
 | 
						||
<p><a
 | 
						||
href="https://meezenest.nl/mees/">https://meezenest.nl/mees/</a></p>
 | 
						||
<p>The software is published as open-source software (GPL). The hardware
 | 
						||
is published as open-source hardware (OSH).</p>
 | 
						||
<h2 id="software">Software</h2>
 | 
						||
<p>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 3 of the License, or (at your
 | 
						||
option) any later version.</p>
 | 
						||
<h2 id="hardware-and-documentation">Hardware and documentation</h2>
 | 
						||
<p>This work is licensed under a Creative Commons Attribution-ShareAlike
 | 
						||
4.0 International License.</p>
 | 
						||
<hr>
 | 
						||
</article>
 | 
						||
</main>
 | 
						||
<footer>
 | 
						||
<p>©
 | 
						||
 2024-01-22
 | 
						||
 M.T. Konstapel
 | 
						||
 <a href="https://meezenest.nl/mees/">https://meezenest.nl/mees/</a>
 | 
						||
</p><p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
 | 
						||
</p>
 | 
						||
</footer>
 | 
						||
</body>
 | 
						||
</html>
 |