Devices & Components
Arduino Uno Rev3
Breadboard - 840 contacts
40 colored male-female jumper wires
ZTS-3000-FSJT Wind Speed Sensor
BME280/BMP280
10kOhm potentiometer
PR-3000-FXJT Wind Direction Sensor
20x4 LCD
12V adapter
Software & Tools
Arduino IDE
Project description
Code
Whether Stations
cpp
1#include <LiquidCrystal.h> // for LCD 2#include <Wire.h> 3#include <Adafruit_Sensor.h> 4#include <Adafruit_BME280.h> 5#include <string.h> 6 7// Temperature sensor LCD pins 8#define LCD_RS_PIN 2 9#define LCD_E_PIN 3 10#define LCD_D4_PIN 4 11#define LCD_D5_PIN 6 12#define LCD_D6_PIN 7 13#define LCD_D7_PIN 8 14 15// Wind data LCD pins 16#define LCD_RS_PIN_wind 13 17#define LCD_E_PIN_wind 11 18#define LCD_D4_PIN_wind 12 19#define LCD_D5_PIN_wind 10 20#define LCD_D6_PIN_wind 9 21#define LCD_D7_PIN_wind A3 22 23// Wind sensors pins 24#define windPin A0 25#define dirPin A1 26 27 28unsigned long previous_time_temp_check = 0; 29unsigned long previous_time_wind_check = 0; 30 31 32unsigned int temp_array_count = 0; 33char temp_array[96]; 34 35unsigned int pres_array_count = 0; 36int pres_array[96]; 37 38unsigned int wind_speed_array_count = 0; 39char wind_speed_array[300]; 40 41unsigned int wind_direction_array_count = 0; 42int wind_direction_array[60]; 43 44// This is the amount that we will subtract from the voltage 45float voltage_offset = 0.14; 46 47 48// Create BME280 object for I2C 49Adafruit_BME280 bme; 50 51// Create LCD object 52LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 53LiquidCrystal lcd_wind(LCD_RS_PIN_wind, LCD_E_PIN_wind, LCD_D4_PIN_wind, LCD_D5_PIN_wind, LCD_D6_PIN_wind, LCD_D7_PIN_wind); 54 55 56 57void setup() { 58 Serial.begin(9600); 59 60 lcd.begin(20, 4); 61 lcd_wind.begin(20, 4); 62 63 64 Serial.println(F("BME280 I2C Test")); 65 66// Filling the array with values that are less than what could be in the temp. 67// This is so when the computer calculates the high and low it won’t use garbage 68// values that are automatically put into the array. That’s why I used -100. 69 for(int i = 0; i < 96; i++){ 70 temp_array[i] = -50; 71 } 72 73 // same as for the temp array 74 for(int i = 0; i < 96; i++){ 75 pres_array[i] = 100; 76 } 77 78 for(int i = 0; i < 300; i++){ 79 wind_speed_array[i] = 0; 80 } 81 82 // test to initialize the sensor 83 if (!bme.begin(0x76)) { // Use 0x76 (most modules) or 0x77 if needed 84 Serial.println(F("Could not find a valid BME280 sensor, check wiring!")); 85 while (1); // Stop here 86 } 87 88 // initial setup 89 lcd.setCursor(0, 0); 90 lcd.print(F("The temperature will show in 30 seconds")); 91 delay(30000); // to let the sensor stabilize before reading 92//---------------------------------------------------------------------------------------------------------------------- 93 int temp = bme.readTemperature(); 94 lcd.setCursor(0, 0); 95 lcd.print(F(" ")); 96 lcd.setCursor(0, 0); 97 lcd.print(F("Temp = ")); 98 lcd.print(temp); 99 lcd.print((char)223); 100//-------------------------------------------------------------------------------------------------------------------------- 101 float stationPressure = bme.readPressure() / 100.0; // BME280 gives Pa, convert to hPa 102 int altitude = 410; // meters 103 // I'm using int because I don't want the decimal place. 104 unsigned int seaLevelPressure = stationPressure * pow((1 - (altitude / 44330.0)), -5.255); 105 lcd.setCursor(0, 1); 106 lcd.print(F(" ")); 107 lcd.setCursor(0, 1); 108 lcd.print(F("Pres = ")); 109 lcd.print(seaLevelPressure); 110 lcd.print(F(" hPa")); 111 112//------------------------------------------------------------------------------------------------------------------------- 113 114 unsigned int humidity = bme.readHumidity(); 115 lcd.setCursor(0, 2); 116 lcd.print(F(" ")); 117 lcd.setCursor(0, 2); 118 lcd.print(F("Humidity = ")); 119 lcd.print(humidity); 120 lcd.print(F("%")); 121 122} 123 124void loop() { 125 unsigned long time_now = millis(); // Get the current time 126 127 if(time_now - previous_time_wind_check > 1000){ 128 129 // ===== Wind speed ===== 130 int analog_from_speed = analogRead(windPin); // 0–1023 131 float voltage_from_speed = analog_from_speed / 204.6 - voltage_offset; // 1023/5 ≈ 204.6 for each volt 132 // voltage_offset is an amount you want to subtract from the raw volts, because the sensor is not 0 when it is 133 // not moving and you want it to be 0. To fix that you use the offset. 134 135 int wind_kmph = voltage_from_speed * 12 * 3.6; // 5V -> 60 m/s => 12 m/s per volt then * 3.6 -> km/h 136 137 // Puts the wind speed value in the right array slot 138 int array_wind_place = wind_speed_array_count % 300; 139 wind_speed_array[array_wind_place] = wind_kmph; 140 wind_speed_array_count++; 141 142 // // this is only for testing the array place 143 // Serial.println("array place wind"); 144 // Serial.println(array_wind_place); 145 146 // This will only be accurate 5 minutes after start 147 148 int wind_average = 0; 149 150 for(int i = 0; i < 300; i++){ 151 wind_average += wind_speed_array[i]; 152 } 153 wind_average /= 300; 154 155 // //for testing 156 // Serial.println("wind average"); 157 // Serial.println(wind_average); 158 159 if(wind_kmph < 5){ 160 lcd_wind.setCursor(0, 0); 161 lcd_wind.print(F(" ")); 162 lcd_wind.setCursor(0, 0); 163 lcd_wind.print(F("Wind is light")); 164 }else{ 165 lcd_wind.setCursor(0, 0); 166 lcd_wind.print(F(" ")); 167 lcd_wind.setCursor(0, 0); 168 lcd_wind.print(F("Wind Speed: ")); 169 lcd_wind.print(wind_kmph); 170 lcd_wind.print(F("km")); 171 } 172 lcd_wind.setCursor(0, 1); 173 lcd_wind.print(F(" ")); 174 lcd_wind.setCursor(0, 1); 175 lcd_wind.print(F("5M wind avg: ")); 176 lcd_wind.print(wind_average); 177 lcd_wind.print(F("km")); 178 179 lcd_wind.setCursor(0, 3); 180 lcd_wind.print(F("V:")); 181 lcd_wind.print(voltage_from_speed, 2); 182 183 184 // Print results on serial for testing 185 // Serial.print("Raw ADC: "); 186 // Serial.print(rawSpeed); 187 // Serial.print(" | Voltage: "); 188 // Serial.print(voltSpeed, 2); 189 //Serial.print(F("Wind Speed: ")); 190 // Serial.print(windMs, 2); 191 // Serial.print(" m/s ("); 192 //Serial.print(wind_kmph); 193 //Serial.print(F(" km/h)")); 194 195 196 // ===== Wind direction ===== 197 int analog_from_direction = analogRead(dirPin); // 0–1023 198 float volts_from_direction = analog_from_direction / 204.6; 199 int wind_direction = (volts_from_direction / 5.0) * 360.0; 200 201 int North = 0; 202 int Northeast = 0; 203 int East = 0; 204 int Southeast = 0; 205 int South = 0; 206 int Southwest = 0; 207 int West = 0; 208 int Northwest = 0; 209 210 int array_place_direction = wind_direction_array_count % 60; 211 wind_direction_array[array_place_direction] = wind_direction; 212 wind_direction_array_count++; 213 214 for(int i = 0; i < 60; i++){ 215 int test = wind_direction_array[i]; 216 if(test > 341){ 217 North++; 218 } 219 else if(test < 30){ 220 Northeast++; 221 } 222 else if(test < 70){ 223 East++; 224 } 225 else if(test < 130){ 226 Southeast++; 227 } 228 else if(test < 180){ 229 South++; 230 } 231 else if(test < 230){ 232 Southwest++; 233 } 234 else if(test < 280){ 235 West++; 236 } 237 else if(test < 340){ 238 Northwest++; 239 } 240 } 241 242char direction[3] = "--"; // 2 letters max + null terminator 243 244// Checking which is the biggest. 245if (North > Northeast && North > East && North > Southeast && North > South && North > Southwest && North > West && North > Northwest) { 246 strcpy(direction, "N"); 247} 248else if (Northeast > North && Northeast > East && Northeast > Southeast && Northeast > South && Northeast > Southwest && Northeast > West && Northeast > Northwest) { 249 strcpy(direction, "NE"); 250} 251else if (East > North && East > Northeast && East > Southeast && East > South && East > Southwest && East > West && East > Northwest) { 252 strcpy(direction, "E"); 253} 254else if (Southeast > North && Southeast > Northeast && Southeast > East && Southeast > South && Southeast > Southwest && Southeast > West && Southeast > Northwest) { 255 strcpy(direction, "SE"); 256} 257else if (South > North && South > Northeast && South > East && South > Southeast && South > Southwest && South > West && South > Northwest) { 258 strcpy(direction, "S"); 259} 260else if (Southwest > North && Southwest > Northeast && Southwest > East && Southwest > Southeast && Southwest > South && Southwest > West && Southwest > Northwest) { 261 strcpy(direction, "SW"); 262} 263else if (West > North && West > Northeast && West > East && West > Southeast && West > South && West > Southwest && West > Northwest) { 264 strcpy(direction, "W"); 265} 266else if (Northwest > North && Northwest > Northeast && Northwest > East && Northwest > Southeast && Northwest > South && Northwest > Southwest && Northwest > West) { 267 strcpy(direction, "NW"); 268} 269 270 lcd_wind.setCursor(0, 2); 271 lcd_wind.print(F(" ")); 272 lcd_wind.setCursor(0, 2); 273 lcd_wind.print(F("wind direction: ")); 274 lcd_wind.print(direction); 275 276 277 // // This is just for testing 278 // Serial.print(" || Dir Raw: "); 279 // Serial.print(rawDir); 280 // Serial.print(" | Dir Volt: "); 281 // Serial.print(voltDir, 2); 282 // Serial.print(F("Wind Direction: ")); 283 // Serial.print(wind_direction); 284 // Serial.println(F(" deg")); 285 286 287 previous_time_wind_check += 1000; 288 } 289 290 291 if (time_now - previous_time_temp_check > 900000){ 292 293 294// ------------------------------------------------------------------------------------------------------------------------ 295 int temp = bme.readTemperature(); 296 297 lcd.setCursor(0, 0); 298 lcd.print(F(" ")); 299 lcd.setCursor(0, 0); 300 lcd.print(F("Temp = ")); 301 lcd.print(temp); 302 lcd.print((char)223); 303 304 // // Testing to see that the count works in serial 305 // Serial.println(F("temp array count")); 306 // Serial.println(temp_array_count); 307 308 // places the temp value in the right array slot 309 int array_place = temp_array_count % 96; 310 temp_array[array_place] = temp; 311 temp_array_count++; 312 313 // // this is only for testing the array place 314 // Serial.println(F("array place temp")); 315 // Serial.println(array_place); 316 317 // This whole chunk is for the high and low function 318 int high_temp = temp_array[0]; 319 int low_temp = temp_array[0]; 320 321 for(int i = 0; i < 96; i++){ 322 323 if(temp_array[i] < low_temp && temp_array[i] != -50){ 324 low_temp = temp_array[i]; 325 } 326 else if(temp_array[i] > high_temp){ 327 high_temp = temp_array[i]; 328 } 329 } 330 331 lcd.setCursor(12, 0); 332 lcd.print(F("H")); 333 lcd.print(high_temp); 334 lcd.print(F(" L")); 335 lcd.print(low_temp); 336 337//-------------------------------------------------------------------------------------------------------------------------- 338 339 // This gets the pressure and turns the station pressure into sea level pressure 340 float station_pressure = bme.readPressure() / 100.0; // BME280 gives Pa, convert to hPa 341 int altitude = 410; // meters 342 // I'm using int because I don't want the decimal place. 343 unsigned int sea_level_pressure = station_pressure * pow((1 - (altitude / 44330.0)), -5.255); 344 345 lcd.setCursor(0, 1); 346 lcd.print(F("Pres = ")); 347 lcd.print(sea_level_pressure); 348 lcd.print(F(" hPa")); 349 350 // Array placement 351 unsigned char array_place_pres = pres_array_count % 96; 352 pres_array[array_place_pres] = sea_level_pressure; 353 pres_array_count++; 354 355 // // This is just for testing 356 // Serial.println(F("pressure array place")); 357 // Serial.println(pres_array_count); 358 // Serial.println(F("array place presser")); 359 // Serial.println(F("array place pressure")); 360 361 362 unsigned int high_pres = pres_array[0]; 363 unsigned int low_pres = pres_array[0]; 364 365 for(int i = 0; i < 96; i++){ 366 if(pres_array[i] < low_pres && pres_array[i] != 100){ 367 low_pres = pres_array[i]; 368 } 369 else if(pres_array[i] > high_pres){ 370 high_pres = pres_array[i]; 371 } 372 } 373 374 lcd.setCursor(0, 2); 375 lcd.print(F(" ")); 376 lcd.setCursor(0, 2); 377 lcd.print(F("HP")); 378 lcd.print(high_pres); 379 lcd.print(F(" LP")); 380 lcd.print(low_pres); 381 382//------------------------------------------------------------------------------------------------------------------------ 383 // humidity check 384 // the int is so there should be no decimal 385 int humidity = bme.readHumidity(); 386 lcd.setCursor(0, 3); 387 lcd.print(F("Humidity = ")); 388 lcd.print(humidity); 389 lcd.print(F("%")); 390 391// ----------------------------------------------------------------------------------------------------------------------- 392 previous_time_temp_check += 900000; 393 } 394} 395 396 397 // lcd.setCursor(0, 3); 398 // lcd.print("Altitude = "); 399 // lcd.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); 400 // lcd.print(" m");
Comments
Only logged in users can leave comments