Buffer overflow windspeed fixed

master
marcel 4 months ago
parent 74175ab241
commit e1331d6266
  1. 10
      CHANGELOG.md
  2. 4
      build-doc/weather_station.html
  3. 6
      build-doc/weather_station.md
  4. BIN
      datasheet/Handboek_H05_knmi_definities.pdf
  5. 63
      firmware/weather_station.ino

@ -41,3 +41,13 @@ All notable changes to this project will be documented in this file.
- ModBus read register 14: Status bits - ModBus read register 14: Status bits
- ModBus coil register 0 : enable/disable heather algorithm - ModBus coil register 0 : enable/disable heather algorithm
## [0.2.2] - 2023-01-21
### Fixed
- Buffer overflow when calculating average wind speed in AverageOfArray(). Fix: use 32 bit register for average_value.
### Changed
- Changed some variables to the propper standard (uint8_t, uint16_t, etc.)
- SparkFun wind interrupt now calculates over 3 seconds in stead of 1 second (KNMI standard)]

@ -745,8 +745,8 @@ 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 two decimal points can be stored as 16 bit integer values. Just divide
by 10 or 100 to get the floating point values.</p> by 10 or 100 to get the floating point values.</p>
<h3 id="output-coils-write-only">Output coils (write only)</h3> <h3 id="output-coils-write-only">Output coils (write only)</h3>
<p>Input registers are numbered 1 to 9999 but have data addresses 0x000 <p>Output coils registers are numbered 1 to 9999 but have data addresses
to 0x270E. The default value of a register is 0.</p> 0x000 to 0x270E. The default value of a register is 0.</p>
<table> <table>
<thead> <thead>
<tr class="header"> <tr class="header">

@ -16,7 +16,7 @@ abstract: >
# Why do you need a weather station? # Why do you need a weather station?
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 in 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. 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.
So the weather is fascinating and taking your own measurements is a lot of fun. So the weather is fascinating and taking your own measurements is a lot of fun.
@ -311,7 +311,7 @@ The ModBus registers are 16 bit wide. For better precision, some units are scale
### Output coils (write only) ### Output coils (write only)
Input registers are numbered 1 to 9999 but have data addresses 0x000 to 0x270E. The default value of a register is 0. Output coils registers are numbered 1 to 9999 but have data addresses 0x000 to 0x270E. The default value of a register is 0.
| Address | Description | logic 0 | logic 1 | | Address | Description | logic 0 | logic 1 |
|---------|------------------|----------|---------| |---------|------------------|----------|---------|
@ -346,6 +346,8 @@ Libraries are included with the source code of this project
Copyright (C) 2023, 2024 M.T. Konstapel Copyright (C) 2023, 2024 M.T. Konstapel
[https://meezenest.nl/mees/](https://meezenest.nl/mees/)
The software is published as open-source software (GPL). The hardware is published as open-source hardware (OSH). The software is published as open-source software (GPL). The hardware is published as open-source hardware (OSH).
## Software ## Software

@ -27,6 +27,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with weather_station. If not, see <https://www.gnu.org/licenses/>. * along with weather_station. If not, see <https://www.gnu.org/licenses/>.
* *
* 2023-01-21: - Buffer overflow when calculating average wind speed in AverageOfArray()
* Fix: use 32 bit register for average_value.
* - Changed some variables to the propper standard (uint8_t, uint16_t, etc.)
* - SparkFun wind interrupt now calculates over 3 seconds in stead of 1 second (KNMI standard)
*
**********************************************************************************/ **********************************************************************************/
#include <ModbusSerial.h> #include <ModbusSerial.h>
#include "SparkFun_Weather_Meter_Kit_Arduino_Library.h" #include "SparkFun_Weather_Meter_Kit_Arduino_Library.h"
@ -114,28 +119,28 @@ ModbusSerial mb (MySerial, SlaveId, TxenPin);
unsigned long ts; unsigned long ts;
unsigned long HourTimer; unsigned long HourTimer;
int WindGustData1[30]; uint16_t WindGustData1[30];
unsigned char WindGustData1Counter=0; uint8_t WindGustData1Counter=0;
int WindGustData2[10]; uint16_t WindGustData2[10];
unsigned char WindGustData2Counter=0; uint8_t WindGustData2Counter=0;
int WindAverageData1[30]; uint16_t WindAverageData1[30];
unsigned char WindAverageData1Counter=0; uint8_t WindAverageData1Counter=0;
int WindAverageData2[10]; uint16_t WindAverageData2[10];
unsigned char WindAverageData2Counter=0; uint8_t WindAverageData2Counter=0;
int RainPerHour[24]; uint16_t RainPerHour[24];
unsigned char RainPerHourCounter=0; uint8_t RainPerHourCounter=0;
struct MeasuredData { struct MeasuredData {
int WindDirection; uint16_t WindDirection;
int WindSpeed; uint16_t WindSpeed;
int WindGust; uint16_t WindGust;
int Rain; uint16_t Rain;
int RainLast24; uint16_t RainLast24;
int SensorRainSinceMidnight; uint16_t SensorRainSinceMidnight;
int Pressure; uint16_t Pressure;
int Luminosity; uint16_t Luminosity;
int StatusBits = 0; uint16_t StatusBits = 0;
unsigned int RainfallCounter = 0; uint16_t RainfallCounter = 0;
float Temperature; float Temperature;
float Humidity; float Humidity;
@ -287,7 +292,7 @@ void ReadBMP280 (void)
} }
int MaxOfArray (int array[], unsigned int length) int MaxOfArray (int array[], uint16_t length)
{ {
int maximum_value = 0; int maximum_value = 0;
@ -299,11 +304,11 @@ int MaxOfArray (int array[], unsigned int length)
return maximum_value; return maximum_value;
} }
int AverageOfArray (int array[], unsigned int length) uint16_t AverageOfArray (uint16_t array[], uint16_t length)
{ {
int tmp_value = 0; uint32_t tmp_value = 0;
unsigned char tmp_length = length; uint8_t tmp_length = length;
int average_value = 0; uint16_t average_value = 0;
while (length--) while (length--)
{ {
@ -329,7 +334,7 @@ void ReadSparkfunWeatherStation (void)
MeasuredData.Rain = tmpRegister; MeasuredData.Rain = tmpRegister;
// FIFO for calculating wind gust of last 10 minutes // FIFO for calculating wind gust of last 10 minutes
// to preserve valuable RAM we caanot store all measurements of the last 10 minutes. // to preserve valuable RAM we cannot store all measurements of the last 10 minutes.
// So we use a hack: store the last 30 values in a FIFO and every minute we store the maximum value from this FIFO in another FIFO. // So we use a hack: store the last 30 values in a FIFO and every minute we store the maximum value from this FIFO in another FIFO.
// This second FIFO is 10 deep: it stores the maximum values of the last 10 minutes. // This second FIFO is 10 deep: it stores the maximum values of the last 10 minutes.
// The maximum value from this FIFO is the maximum wind gust of the last 10 minutes. // The maximum value from this FIFO is the maximum wind gust of the last 10 minutes.
@ -446,7 +451,7 @@ void setup() {
mb.Ireg (SensorRainSinceMidnightIreg, 0); mb.Ireg (SensorRainSinceMidnightIreg, 0);
mb.Ireg (SensorSnowFallIreg, 0); mb.Ireg (SensorSnowFallIreg, 0);
Serial.println(F("Weather station v0.2.1")); Serial.println(F("Weather station v0.2.2"));
Serial.println(F("(C)2024 M.T. Konstapel")); Serial.println(F("(C)2024 M.T. Konstapel"));
Serial.println(F("This project is free and open source")); Serial.println(F("This project is free and open source"));
Serial.println(F("More details: https://meezenest.nl/mees/")); Serial.println(F("More details: https://meezenest.nl/mees/"));
@ -553,7 +558,9 @@ void setup() {
// is implemented in the library that averages the wind speed over a certain // is implemented in the library that averages the wind speed over a certain
// time period, which defaults to 1 second. Longer intervals result in more // time period, which defaults to 1 second. Longer intervals result in more
// accurate measurements, but cause delay in the measurement // accurate measurements, but cause delay in the measurement
calibrationParams.windSpeedMeasurementPeriodMillis = 1000; // Dutch metrology institute (KNMI) defines that the windspeed and gust should
// be calculated from 3 seconds measurements.
calibrationParams.windSpeedMeasurementPeriodMillis = 3000;
// Now we can set all the calibration parameters at once // Now we can set all the calibration parameters at once
weatherMeterKit.setCalibrationParams(calibrationParams); weatherMeterKit.setCalibrationParams(calibrationParams);

Loading…
Cancel
Save