QingStation, Ultrasonic Anemometer/Weather Station

An opensource compact ultrasonic anemometer/weather station

Similar projects worth following
This is a compact, functional, opensource weather station, integrating with ultrasonic arrays for wind speed and direction measurement, infrared rain sensor, barometer, humidity sensor, light sensors, lightning sensor and others. It can record data locally or publish data through MQTT broker. Hardware/software at

About this project

The goal is to build a small and versatile weather station. But before introducing this project, I shall mention my other project DeepPlankter. DeepPlankter is a tiny autonomous water drone ship that could sail in the ocean for months using wave-propelled underwater wings. Sailing alone is fun though, if we can collect some meaningful data during the sailing will be even more exciting.

Thus, a weather station is perfect to fit this purpose! Imagine that the ship is measuring wind velocity on a 10 metres high wave at the centre of a storm. So challenging.

There are some goals of the weather station:

  • Low-power

The electronics on the ship is supplied by solar panels so is the weather station. The solar panels have a peak power rating of 10W, or 40Wh in a sunny summer day. However, this 10W will need to supply the main controller, GPS, satellite, rudder servos, and charge batteries for over-nights supplies.

A rough estimation is <100mA average current for the whole ship. The weather station should have a maximum 10mA average current.

  • Small & lightweight

The drone is small, with a deck width of only ~12cm. Ideally, the dimensions of the weather station should be less than the width of the deck. When installing it on the ship, it should be placed as high as possible. Elevating a large mass on the mast decreases the stability of the ship.

  • Versatile

While keeping it small, implement as many digital sensors as possible.

There are 2 DIY analogue sensors, the ultrasonic anemometer and infrared rain sensor onboard.


Features and functions

For the hardware V1.1


  • MCU: STM32L476RG
  • PCB dimension: Φ48 mm
  • SDCard
  • RTC

Sensor Integration:

  • Anemometer (2x2 Ultrasonic transducer array 40k/200kHz)
  • Rain sensor (IR Optical type)
  • Lighting sensor (AS3935)
  • IMU & eCampass (BMX160)
  • RGBI light sensor (APDS-9250)
  • Microphone (MP34DT05/6)
  • Barometer, humidity, temperature sensor (BME280)

Communication Interfaces:

  • 2x UART
  • I2C
  • SPI
  • USB (CDC and/or MassStorage)

Power Consumption

  • Normal 20~22mA
  • Normal + GNSS: ~45mA
  • Normal + GNSS + ESP8266(MQTT @ 1Hz): ~100mA
  • Sleep: unknown

External Communication

  • ESP8266 (AT)
  • ESP32 (AT)
  • SIM800c

Functions description

Digital sensors are used whenever it is available. Today's digital sensors are easy to use as long as they are connected to I2C correctly. The onboard sensors were all up in a day.

Analog sensor

The rain sensor is consist of a pair of an IR transmitter and a receiver. The method is to use the reflection of a piece of trapezoid glass (hand made..). When droplets land on the surfaces of glass, it will reduce the reflection, therefore the signal magnitude on the receiver will change. We can either use calibrated absolute value or use the covariance. This sensor will not be accurate. Even when on the sea, droplets from large waves can easily keep the sensor wet all the time.

Ultrasonic Anemometer is the most difficult sensor but also the most challenging sensor. The anemometer uses a reflection of the ultrasonic beam to measure the speed of air in 2 horizontal direction..ideally. The reality is much complicated, it well worth a separate document. A good project by Hardy Lau mentioned most of the principle and information.

One of the advantages of the ultrasonic anemometer is it needs NO MOVING PARTs to measure wind speed and wind direction.

Digital sensor

For the lighting sensor (AS3935), I could not make an easy test to validate my antenna design.

For the RGBIR sensor, we cannot calibrate the sensor using a cosine corrector which the light sensor usually used. I have no tools that can calibrate this sensor. RGBI sensor can provide colour data than a single lumen meter.

IMU and eCampass are not needed for a stationary mounted weather station. But in sailing, its high mounted location is perfect for navigation...

Read more »

x-zip-compressed - 3.67 MB - 05/30/2021 at 18:28


  • Over-the-Air (OTA) Firmware Upgrade through MQTT

    Jianjia Ma07/13/2021 at 10:31 0 comments

    Over the air firmware upgrading give QingStation a huge flexibility in a unmanned field application, For example, when the QingStation is installed on the roof of a building, it is really annoying to dismount everything and just to download an upgraded firmware.

    Supporting OTA means we can just sit in front of the PC and upgrade the firmware remotely, what a huge improvement!


    Since we already support MQTT to publish the weather data, we can make a minor modification to the existing MQTT to transfer firmware.

    • Add a subscription to topic ota_downstream to receive data.
    • Publish to topic ota_upstream to send acknowledge.

    On the PC side, a python script will perform the firmware segmenting and packaging. The MQTT client used here is Paho-MQTT.

    The script will split the the firmware to a size of 256 byte package. An package ID and checksum will be added and put into MQTT message payload.

    After every data package is sent, the script wait for an Ack package sent from QingStation. If validation is correct, it will send the next package, if not, it will resend the last one.


    This is the messages protocol that exchanges between QingStation and the python script. You can see that it is very simplified.

    • No Authorization.
    • No validation for payload expects the data package.
    • No handshake.
    • Dose not support resume from break point.

    All of them are to simplify the implementation.

    Flash Space Allocation

    The MCU we used STM32L476RG has 2 independent flash banks that can be read or written at the same time. The main applications is running on the bank 1, so we just use bank 2 to store the OTA firmware. (No need to store in SD card) After the transmission is finished, we can then use our bootloader to copy the OTA firmware to bank 1.

    Here is the memory allocation for the current setup.

    Firmware TAG

    In the above diagram, you might notice there are some sections call xxx tag. That is where the description of the firmware. It is stored in a readable string format separated by comma. The most important parts are:

    • MD5 checksum
    • Firmware size
    • package size
    • version

    Finishing the update

    Once all the firmware is transferred completed, the application destroys its own tag to mark the firmware invalid. Then it makes a software reset and handover to the bootloader.

    The bootloader will read the tags especially the MD5 checksum. It will perform a MD5 checksum through the Application and OTA space, and it will compare the MD5 with those tags.

    Once the bootloader checks and finds out that application space is invalid and OTA is valid, it will copy the firmware from OTA space to Application space. Or when both firmware are good and but OTA version > application version, it will also perform an update. (copy OTA to application).


    I did a test with the below setting: When using ESP8266 as the WIFI module and the broker from AWS located in the UK.

    • The uploading speed is 850Bytes/sec when using QS0 MQTT subscription and 530Bytes/sec for QS2.

    Not great but still faster than go to the roof and disassembling everything.

    PS: the bootloader also supports update from SD card. See dedicated document for detail (not ready).

  • Rain Sensor

    Jianjia Ma06/21/2021 at 17:32 0 comments



    Here we are building an Infrared Optical Rain Sensor, which is common in today's car automotive windshield wiper. The below diagram from the wiki shows the principle of these type of rain sensor.

    Rain_sensor diagram from wikipedia

    When the glass is dry, the IR travels through will be totally reflected between the top and bottom of the 2 pieces of glasses. When there are raindrops on the glass, the IR light will not be totally reflected, so the light intensity will decrease. We can then use a photodiode to measure the intensity of light to read the rain.

    There a few strategies that can convert the measurement to rain level.

    • Count how many drops (changes of measurement) in a time period.
    • Calculate the variance of continuous measurement.

    Since our sensor is small, it is expected that the "accuracy" will be low especially in small rain.

    Design and Practice

    The optical lens is the most difficult part for the rain sensor. I did not even try to use real glasses. The materials I selected is polycarbonate (PC), a clear and UV resistant plastic materials. It has better physical mechanical properties than acrylic, but only a bit more expensive.

    The optical part is consist of 2 pieces of PC sheet glued together. The top one is flat with right angle on all the side. The bottom one is smaller with 2 short sides at a 45 degree angle. 2 PC sheets are glued together by clear epoxy.

    Lens Assembly

    lens assembly

    lens assembly

    There are a few bubbles in between the glued surfaces, because of a mistake during the epoxy curing. The epoxy I brought was a very low viscosity, and it take ages to cure (~2days). So I add a little bit of heat to it (placed it on top of my PC's power unit.) When I check it a few hours later, the bubbles appeared.

    Anyway, as long as it works, that is fine.

    Photodiodes and measurement.

    Measure schematic is shown below. schmatics

    As you can see, it is very simple. An infrared LED driver and a photodiode receiver.

    ![PD204/B](figures/rain_pd204 black.png)

    A typical photodiode (e.g. PD204) has a reverse current at around 5~15uA. So a serial 100k resistor is capable to provide 0.5~1.5V dynamic ranges for ADC to measure. There is also a buffer capacitor for ADC to provide a more stable voltage measurement.

    After assembly and testing, with this setup, a 3ms short pulse is enough for producing a stable voltage. With a 5ms LED pulse, the ADC measurement is around 1000 in indoor.

    However, when outdoor with good sunlight, the measurement can go all the way up to 4000, already close the maximum range 4095. I think it is better to change the resistor to 47k to compensate the sunlight effect with this unnamed F3 diode. Apparently, the diode I used has a larger reverse current than the one I shown above. Later I changed it back to PD204/B

    I set the measurement frequency to 10 times per second, and use 10 seconds windows to calculate the variance. Since there is no physical unit so I use the raw ADC data to calculate the variance. That is, the variance is based on 100 ADC samples.



    I tried to use the shower to figure out the variance ranges in different rain levels.


    Here is the data. calibration

    The variance dose increase as more droplets lands one the sensor.

    The range I summarized is here:

    • Light rain: >15
    • Moderate rain: >70
    • Heavy rain: >200
    • Violent rain: >500

    Rain test

    Very luckily, there a rain is coming in the night of the calibration.

    The QingStation stay in the balcony for the whole night. The battery and charger are sealed in a zip bag.

    Solar panels.

    Rain sensor lens.

    The data of the overnight measurement is shown below.

    I was only able to capture the rain in the final bit (near noontime). When the middle 2 peaks are measured, I didn't wake up. The battery ran out in the afternoon since there is no enough direct sunlight.

    A few findings here:

    • The sunlight has some effect on the variance.
    • The calibration seems working well. 10~70 corresponds to the light rain which is the...
    Read more »

  • Ultrasonic Anemometer Development Log

    Jianjia Ma06/01/2021 at 21:52 0 comments

    Ultrasonic Anemometer Design and Practice

    This documentation is dedicated to the design and tuning of the ultrasonic anemometer.


    Anemometer is the most interesting sensor on QingStation. However, it is also very challenging for me since I got almost no experience in analog circuit design, while anemometer requires both analog amplifier and heavy data processing. (I don't even know how to use an operational amplifier at the beginning).

    A very good blog I learnt from time to time is the Anemometer by Hardy Lau. This blog is very informative and already cover most of the knowledge needed to build your own ultrasonic anemometer.

    The principle in short: when ultrasonic waves (pules) propagate in a flowing medium(air), the time that the waves reach the destination will be different. The time difference in forward and backward propagation is reflecting the speed of the medium flow, i.e. the wind speed. With 2 pairs of transducer placed perpendicular to each pair, the wind direction can also be calculated by using simple trigonometry.

    The advantage of ultrasonic anemometer compared to other types:

    • Ultrasonic anemometer is small compared to spinning type (cup anemometer).
    • Reasonable difficulty and cheap to DIY, also a good instruction available by Hardy.
    • It has NO MOVING PARTS! Moving parts are not very easy to DIY especially when waterproofing.


    Basic principle

    The principle is very simple, the sound wave that propagates in a medium (air) is affected by the movement of the medium. By using the known propagating path and the time of propagation, we can calculate the speed of the medium.

    In the above graph, we can see the travel of wind BC added to the sound propagation AB result in the travel path AC.

    Lau has posted all related equations (with different notation).

    In C language:

    alpha = atan(2*H/D);
    v = H/sin(alpha)*cos(alpha)*(1/t1 - 1/t2);// wind speed
    c = H/sin(alpha)*(1/t1 + 1/t2);           // sound speed

    To measure the wind direction, use arctan2 on 2 perpendicular pairs.

    beta = atan2(NS, EW);  // north->south, east->west

    Practical issues, solution and compromise

    In reality, things normally don't work as we want, especially with analog circuits.

    Mechanical design


    I use Fusion 360 to design the hardware and use my old crappy 3D printer to build them.

    The transducers are placed at the top side and facing down. The reflective plate just flat surfaces. Electronics and other sensors are located above the transducer in a shielded box.

    I even managed to make an airflow simulation using Simscale. The airflow speed is set to 30m/s equivalent to ~58knots, near a centre of a storm.


    As you can see, the airflow in between the top and the reflective plate is actually accelerated by ~3m/s. No idea if we need to take them into account in later processing. I don't have any access to a wind tunnel, so I could not do a test in a perfect experiment environment.

    Sound path

    As shown in the introduction, the sound beam should travel along the noted path. But the reality is a different story.

    • There is a direct sound propagate directly to the receiver transducer.
    • These sounds waves will mix together.
    • The 3D printed plastic is rigid and lightweight, perfect for amplifying a sound. The reflector might also be a speaker.

    The light-weight plastic is not a problem in Lau's works because his anemometer is based on a metal frame.


    These sound beams can be seen in the receiving signals. Adding some coins as a counterweight might help to reduce the magnitude of the other beams.

    Ultrasonic transducer, driver

    Here is the schematic of the second version(PCB v1.1), details will be explained in the following sections.

    A low-voltage 4052 analog switch controls which channel is selected as output and which is listening to the echo. Excitations are generated by a timer's PWM channel, while the echo output is amplified by op amps and measured by ADC.


    Read more »

  • PCB, Assembly and Solar Panel

    Jianjia Ma05/30/2021 at 18:26 0 comments

    This document recalls the assembly process.

    Circuit board

    PCB V1.0 (the one without MCU) and PCB V1.1 (all others).

    Most of the passive components are solder by JLC PCB assembly service. They can only assemble one side of the PCB, still, it did save a lot of my effort, since searching for components in a box takes much more time than the soldering.

    This side will be faced down when installing to the station. This side has ultrasonic transducer drivers, opa-amp, analog switch, barometer/humidity/temp sensor, lightning sensor, voltage regulators, all the connectors, CAN driver, MCU and reset and user buttons.


    A look from the other side (top). This side includes lightning antenna, IMU, light sensor, IR transmitter and receiver (Rain sensor), GNSS module, SD card slot.


    3 PCB assembled with transducers.


    Transducer assembly

    The aluminium transducers are the ones I selected, (40kHz closed-end, waterproof). Please see the anemometer development for detail.

    Those black ones are actually open-end transducers. It is not waterproof and has a much stronger signal. I am trying to test different transducers.


    I then sealed the transducer to a 3D printed case with soft silicone glue.



    This method is ok to do and it is actually not that difficult to assemble it. I first stick a tape to the bottom flat surface, then put the transducer in the mid of the circle. Finally, apply the glue and wait for 24 hours.

    The raw signal looks quite consistent across the different assembly.


    I designed a few different enclosures, but normally I use this one.

    Since the barometer/humidity sensor (BME280) is soldered directly onto the PCB. The measurement is affected by the PCB board temperatures. The PCB temperature is normally 3~5 degree C higher than the room temperature depending on the supply voltage. So a bladed enclosure it needed. However, this design failed at one of my motorway rain tests. (heavy rain/70mph)




    Assembly with Rain sensor lens attached (glued using epoxy)


    After a rain test.



    Solar panels

    I try to use a lithium ion battery (18650) to power the device. At the very beginning, every IC is working at maximum power, result in an average 150mA total power consumption (QingStation + GNSS module + ESP8266). A 18650 only last for a night.

    The panels are rated 12V 160mAh. I connect 2 of them in parallel through a Schottky diode to a CN3971 MPPT charger. The actual efficiency is another story. When the solar panels are laying flat, each of them produces 100mA in the noon. The CN3971 only manage to extract 450mA to charge the battery and power the station at 3.7V.

    This might be related to the sensing resistor in the crappy multimeter I used to measure the current. The actual charging current might be higher. In a sunny day test, it took 8 hours from 7:00 to 15:00 to charge a 2600mAh battery from 3.4V to 4.2V (with 150mA load from the station). I would estimate the average charging current is ~250mA. while the peak we measured is only 300mA (450-150). So the measurement must be wrong.

    Actually, even with the CN3971 has an efficiency factor at only around 0.8, we can still estimate the output from the input. As we measured, each solar panel produce 11.5V 0.1A, that is, 2.3W in total. The output should be around 2.3x0.7=1.61W. When the battery is at 3.7V, the current is 0.49A.



    In the dark


    With car magnet car mount


    To be continued..

View all 4 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