An open source/hardware meteo station, also monitoring other environemental parameters

Public Chat
Similar projects worth following
The goal of this project is to create an environemental measurement station. At start, i will be monitoring ordinary meterological parameters, such as temperature, moisture, wind speed/direction, pressure, etc. Later on, i plan to add, other sensors, measuring atmospheric composition (CO, CO2, etc), air particle density, etc.

I already own a meteorological station, and i think that i can do better, cheaper, with more options. I will also try to create some instruments (such as an anemometer), and provide a calibration method for those who don't have access to a calibrated instrument.

This project is modular, so that there is a base station for collecting all data, and multiple modules that can be connected to it to transmit whatever measurements are required.

Comunications can be made wirelessly or via wire, depending on the modules position.

Wireless outdoor modules are designed to be low power, in order to be able to work on battery, recharged via the sun or wind.

HOW it is going to be done?

Meteo stations are cool. However, they are most often expensive, closed hardware, and, well, limited to basic meteorological stuff. My goal with this project is to address some of these concerns.


First of all : open source software all the way. Furthermore, there should be some kind of abstraction so that the software is not too dependent of the hardware. Thus, we can replace sensors if needs be, without the fear of beeing stuck with a discontinued sensor. For sure, consistent measures require consistent sensors, or at least calibrated ones. But to some extent, it would be great to be hardware independent. If we manage to do that, we could then even make a database with the most popular sensors, specs, and actual precision reached.

Wherever possible, we'll also seek to use open hardware, or at least documented hardware. By building a project on those solid foundations, we can reach some hardware abstraction, and thus all the positive side effects that come with it.


Openness brings modularity. If one can swap a sensor for another one without much hassle, it is possible to adapt the realization to whatever the needs of the user. Furthermore, this allows the user to progressively build his environmental station, adding whatever sensors are required when they are, or when they become available. This means that we're not stuck with a product whose specifications are set in stone.


This leads directly to the question of costs. Considering that there won't be simple one or two versions of Milapli, it's up to the user to select whatever he needs, or can afford. Depending on the budget and desired accuracy, one can settle for few high precision sensors, lots or lesser ones, or any combination. Of course, there will be a core hardware, so there will be a minimal investment to build this. However, past this cost, it's on the user to decide how much he wants to spend on additional hardware. That may seem obvious for us hackers, but my goal is that even non hackers become able to do so following the documentation, without having to become a h4xx0rz.

Field of use

Considering that we're building a system to measure stuff, why limit ourselves to just classic meteorological sensors? Furthermore, since we're going modular and as open as possible, we may as well generalize the project a bit, and make it an sensor station rather than just a meteo station. An example of another application of this is my other project, Rlieh, that manages my aquariums for me. Basically it is a stripped down version Milapli, with fewer aquarium-focused sensors. Another example of an application is another project of mine : Domochevsky, a smart house project. How would you make a house "smart", if not by adding sensors to be able to react to the users?


Considering the IoT trend, we might as well jump in, right? More seriously, there are two main reasons for me to want to have this being a network capable system (i said capable, but nothing prevents anyone for using it with one node, offline):

1 - At LAN scale, it enables the user to have redundant sensors for more accuracy, monitor various places, etc. But also, the idea is that we may as well use other projects as nodes of this. Considering that i have aquariums with sensors and the core hardware in it, why not use those sensors for Milapli as well? When each room in my house have a node for open domotics, why not add a few cheap sensors, and expand the possibilities of Milapli? Another example of this convergence is another project of mine, whose goal (among others) is to make a cheap network camera out of a Raspberry pi.

Once i put one or two of these around the house, i may as well add a few sensors, and this can thus serve both the sensor station AND the smart house project.

2 - At WAN scale, this project can benefit network connections to measure wider phenomenons. indeed, with a few stations in some places, we'll be able to determine if a phenomenon is local...

Read more »

  • 1 × ATmega328p Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers
  • 1 × DHT11 Sensors / Temperature-humidity, Thermal, hygrometric
  • 1 × DHT22 Sensors / Temperature-humidity, Thermal, hygrometric
  • 1 × BMP085 Sensors / Barometers
  • 2 × DS18B20 Sensors / Temperature, Thermal

View all 6 components

  • About sensors

    Audrey Robinel03/15/2016 at 02:11 0 comments

    I used DHT22 sensors for a while. I'll continue to use it in some project, and i'll keep supporting those for this project, because they're cheap and easy to come by. However, those are not really good sensors. Why? Because of their weird communication protocol, low accuracy, and variance between multiple sensors. They are good enough to know if it's hot, wet, etc, but not so much to measure those parameters.

    MCP9808We're trying to build a meteorological station/network of sensors here, so let's up the standards. I have bought an MCP9808 from Adafruit, that is given to have a good precision, and a guaranteed 0.5 max error at common temps. It's also I2C, a standard and and widespread protocol. For 5$ it should be more reliable than what we get from the DHT22/DHT11, and we'll see how it compares to the DS18B20.


    I also ordered a BME280 from Adafruit for 20$, and it is supposed to be much more accurate about temperature, pressure and hydrometry. I also ordered this version of the BME280 from Aliexpress for 7$. When i get all those sensors, i'll make a measurement box with data logging and compare the results of all sensors (including the DHT11, DHT22, DS18B20, etc).

    That's for the basic sensors. I don't have a way to compare loads of anemometers, rain meters, or wind direction sensors. I'll use what i have, and what can be easily found : the sparkfun kit.

    I decided to make this more of a environnemental measurement station than just a meteorological station, meaning that we won't restrict ourselves to classic sensors.

    I will measure the amount of dust in the air, using a cheap sensor with the GP2Y1010AU0F, that i bought from aliexpress at 8$ for a 2-pack. Again, i have nothing to compare those to, but at least i can check for consistency over time and among multiple sensors.

    I also plan to include lux sensors, UV radiation sensors, and even a radioactivity sensor.

    So, we'll make everything possible to support the most common sensors, but also try to use higher quality sensors if available.

  • Adding interrupt routines for the interface

    Audrey Robinel11/20/2014 at 02:21 0 comments

    As of today, i had a little box showing some parameters. After some time, it would show another parameter on the second line. However, what if i wanted to check another parameter when i want?

    For that, i need to have a button to change what is shown on the LCD. The problem is that reading the sensors is made in a blocking way, meaning that i can't just poll the button state, because i will often miss the presses. A solution to this problem would be to modify the libraries so that it becomes non-blocking, but i don't feel like doing so. Another solution is to use interrupts.

    Indeed, Atmega chips can handle multiple interrupts, and i can have a function executed whenever a pin status change occurs. Nick Gammon wrote a nice tutoriel about it here. Using this trick, i was able to capture the button presses.

    In interrupts, delay() is disabled, as it relies on interrupts too. You can enable interrupts within interrupts, but it can be complicated. So to debounce the button, i have declared a variable as "volatile long" to store the last button press time (obtained with "millis()"). If enough time has passed since the last button press, my function does something, otherwise nothing happens.

    When a good button press is recorded, i reverse the value of a volatile int variable, and end my function there.

    In the loop function, a parameter or another is printed, depending on the value of the int variable.

    Variable used by an interrupt must be declared as "volatile", so that the chip loads the variable value each time it uses it, instead of using the previously loaded value. As the interrupt can alter those variables any time, i ensures that the latest value is used.

    Thanks to interrupts, one can design an user interface for a project , whatever the chip is programmed to do. It is possible to check any pin in the interrupts.

    I will later include github links to the code for this example.

  • Luminosity - lux sensor

    Audrey Robinel08/27/2014 at 01:18 0 comments

    I have recieved my order from Sparkfun. Among the stuff i ordered was a luminosity sensor,  the TLS2561. Sparkfun made a great tutorial for it. Rather than soldering pins to plug it to a breadboard, i soldered female jumper wires. Since this sensor has to be exposed to light, a little lenght of wire will make it much more simple.

    This sensor works on I2C, and is easy to use, thanks to the provided library.

    Depending on the conditions, you can set a gain, and exposition time, so that it can be used in low light condition as well as in bright light.

    I have tested it indoor, but i lack another lux sensor to compare the accuracy. However, it will do for now to obtain an idea of the sun level. I have been able to measure 1 lux up to aproximately 60 000 lux.

    I plan on screwing the breakout board on a little support, and add some transparant material in front so that i can measure outdoor luminosity without fear of rain or moisture. 

  • new temperature sensor

    Audrey Robinel08/23/2014 at 04:16 0 comments

    Today i added a much better temperature sensor : a DS18B20. It is really simple to interface : the left wire goes to the ground, the middle wire goes to the GPIO and to VCC via a 4.7K resistor, and the left wire goes to VCC. This disposition is for when you look at the flat side of the probe, with the leads on the bottom.

    Of course, in my case, the data pin goes into a Atmega328p rather than a picaxe.

    Software side is a bit more complex, hopefully, there are libraries available :

    From there i use a function to read the temperature (can't remember where i found it) :

    float getAirTemp()


    //returns the temperature from one DS18S20 in DEG Celsius

    byte data[12];

    byte addr[8];

    if ( ! {

    //no more sensors on chain, reset search


    return -1000;


    if ( OneWire::crc8( addr, 7) != addr[7]) {

    Serial.println("CRC is not valid!");

    return -1000;


    if ( addr[0] != 0x10 && addr[0] != 0x28) {

    Serial.print("Device is not recognized");

    return -1000;



    ds.write(0x44,1); // start conversion, with parasite power on at the end

    byte present = ds.reset();;

    ds.write(0xBE); // Read Scratchpad

    for (int i = 0; i < 9; i++) { // we need 9 bytes

    data[i] =;



    byte MSB = data[1];

    byte LSB = data[0];

    float tempRead = ((MSB << 8) | LSB); //using two's compliment

    float TemperatureSum = tempRead / 16;

    return TemperatureSum;


    From there, i can read the temperature using this function.

    The temperatures that i get from this probe are a lot more accurate than those of the DS18B20, or the BMP085. Furthermore, i now have tenths of degrees rather than full degrees steps.

  • Battery power

    Audrey Robinel08/20/2014 at 06:46 0 comments

    This first module is not intended to be the "main" module. I will thus probably modify it later on to put it in remote locations. However, as of now, i want to be able to take it wherever i need it, in order to obtain measurements in various places. Hence the need for a battery.  I added a 2000mAh LiPo battery (1S, 3.7V), and a "S7V7F5", a 5V pololu switching regulator (step-up and step-down : I like it because it is able to boost the voltage as well as lower it, and has around 80-90% efficiency. It is also straightforward to use, as it can be used in the same fashion of a LM7805.

    With the LCD on, and a fully charged battery, i achieved between one an two days of autonomy. I will later measure the current accurately to perform precise estimations of what to expect.

    In order to charge it, i'm using a simple circuit from adafruit : , an "Adafruit Micro Lipo - USB LiIon/LiPoly charger".

    I splitted the wires from the battery leads, and thus i can have it plugged while charging. According to adafruit's tech support, it can be done :

    I tested it, and it works.

    I thus have a USB or battery powered device.

    I will have to conduct further experiments on battery life, without the LCD backlight, and probably with a 3.3V VCC rather than 5V. Indeed, this drastically reduces the current needed by the atmega.

    I may use a solar panel later on to keep the battery charged.

  • Adding an interface

    Audrey Robinel08/20/2014 at 06:31 0 comments

    In order to visualize the measurements, i included an LCD screen. I had a few laying around, so i picked a 2*16 char lcd with white backlight. This one has a pretty good contrast, and can easily be read outdoor, even under the sun.

    On the first light, i print the humidity and temperature, and on the second line is the atmospheric pressure and the luminosity.

    I also did 3D print a bezel for the LCD, found on thingiverse. I will probably design my own later on.

    I also added a button in order to issue commands to the system, but it doesn't work as of now, for a simple reason : i am using a DHT11 library that is blocking when reading. Indeed, with this library, if i ask a read, it does wait for aproximately 1000ms, before continuing. I thus spend most of the time waiting, rather than reading my button state. I will have to either find a non-blocking version of this, or later modify this library for non blocking readings.

  • First sensors

    Audrey Robinel08/20/2014 at 06:22 0 comments

    The first module measures a few parameters : temperature, humidity, atmospheric pressure, and luminosity.

    Temperature and humidity measurements are provided by a DHT11 sensor. However, i'm using the DHT11 mainly for humidity, as the temperature measurement are not really accurate. Temperature measurements will be handled by a DS18B20 later, as i found those to be more accurate and reliable.

    Atmoshperic pressure measurements are provided by an adafruit BMP085 module ( This sensor is now discontinuated, and can be replaced by the BMP180 ( with the same code, wirering, etc.

    The light level measurements are provided by a light dependent resistor. However, i used this because i had a few, and had ADC pins left. Indeed, those sensors are not very accurate, and i don't really see how to translate  the measurements in lux. Those can however be useful in order to detect if it is dark or not.

  • First module : the processor

    Audrey Robinel08/20/2014 at 06:10 0 comments

    Every project has to start somewhere. So here, the start is rolling a atmega on breadboard. I am using an ATmega328p, with optiboot. It is set to run an 8Mhz, using the internal crystal, because i don't need more power, and i want to reduce the parts count.

    So for this, i have an Atmega328p, 3x 100nF capacitors, a 4.7KOhm resistor, a breadboard, and some wire. I program it with an USB to serial bridge, using Arduino sowftware.

    The main chip unit is not really important here, i used an Atmega because i had a few available, but later on it could be replaced with an ATtiny. I will stay with Atmel chips, because i know how to program those, it is easy to use and powerful, and also the fact that the code can be used easily by other people, be it with a small Attiny, or a full Arduino Uno, Mega or whatever.

View all 8 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates