Components and supplies
Robojax BMP280
SainSmart LCD Module For Arduino 20 X 4
DSD Tech DHT22
3.3V-5V 4 Channels Logic Level Converter
Arduino UNO
Project description
Code
WeatherStation_20x4_v7_final.ino
arduino
1#include <LCD.h> 2#include <LiquidCrystal_I2C.h> 3//#include <Wire.h> 4#include <dht.h> 5#include "i2c.h" 6#include "i2c_BMP280.h" 7 8dht DHT; 9BMP280 bmp280; 10 11//specify the temp sensor 12#define DHTTYPE DHT22; 13#define DHT22_PIN 6 14 15#define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is 16#define BACKLIGHT_PIN 3 17#define En_pin 2 18#define Rw_pin 1 19#define Rs_pin 0 20#define D4_pin 4 21#define D5_pin 5 22#define D6_pin 6 23#define D7_pin 7 24 25LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin); 26 27//total delay = (lcdDelayScreen1 + lcdDelayScreen2 + lcdDelayScreen3) * loopCount (in seconds) 28int lcdDelayScreen1 = 44; //seconds displaying primary info 29int lcdDelayScreen2 = 8; //seconds displaying secondary info 30int lcdDelayScreen3 = 8; //seconds displaying secondary info 31 32//these all have to match 33int loopCount = 60; //total loops 34float dataPointT[60]; //temperature data points 35float dataPointB[60]; //pressure data points 36 37int mainLoop; //primary loop 38int loopBaroGraph; //secondary loop 39int loopTempGraph; //secondary loop 40 41float currentTemp; 42float currentHumid; 43 44float baroPressure; 45float currentPressure; 46 47float tempDifference = 0; 48float tempValueComparative; 49 50int offset; 51int mt; 52int mp; 53 54float pressDifference = 0; 55float pressValueComparative; 56 57//engineeringtoolbox.com/barometers-elevation-compensation-d_1812.html 58float altitudeAdjustment = 1; 59 60float minTemp; 61float maxTemp; 62float minPressure; 63float maxPressure; 64 65int rangeLowGraph; 66int rangeHighGraph; 67 68float percentOfCol; 69float pixelHeightPercent; 70int pixelHeight; 71 72bool firstLoopComplete = false; 73 74//define characters for temperature indicators 75byte arrowUp[8] = { 76 B00100, 77 B01110, 78 B10101, 79 B00100, 80 B00100, 81 B00100, 82 B00100, 83 B00100, 84}; 85 86byte arrowDown[8] = { 87 B00100, 88 B00100, 89 B00100, 90 B00100, 91 B00100, 92 B10101, 93 B01110, 94 B00100, 95}; 96 97byte equalSign[8] = { 98 B00100, 99 B01110, 100 B10101, 101 B00100, 102 B00100, 103 B10101, 104 B01110, 105 B00100, 106}; 107 108byte row1[8] = { 109 B00000, 110 B00000, 111 B00000, 112 B00000, 113 B00000, 114 B00000, 115 B00000, 116 B11111, 117}; 118 119byte row2[8] = { 120 B00000, 121 B00000, 122 B00000, 123 B00000, 124 B00000, 125 B00000, 126 B11111, 127 B11111, 128}; 129 130byte row3[8] = { 131 B00000, 132 B00000, 133 B00000, 134 B00000, 135 B00000, 136 B11111, 137 B11111, 138 B11111, 139}; 140 141byte row4[8] = { 142 B00000, 143 B00000, 144 B00000, 145 B00000, 146 B11111, 147 B11111, 148 B11111, 149 B11111, 150}; 151 152byte row5[8] = { 153 B00000, 154 B00000, 155 B00000, 156 B11111, 157 B11111, 158 B11111, 159 B11111, 160 B11111, 161}; 162 163byte row6[8] = { 164 B00000, 165 B00000, 166 B11111, 167 B11111, 168 B11111, 169 B11111, 170 B11111, 171 B11111, 172}; 173 174byte row7[8] = { 175 B00000, 176 B11111, 177 B11111, 178 B11111, 179 B11111, 180 B11111, 181 B11111, 182 B11111, 183}; 184 185byte row8[8] = { 186 B11111, 187 B11111, 188 B11111, 189 B11111, 190 B11111, 191 B11111, 192 B11111, 193 B11111, 194}; 195 196void setup() { 197 198 int setupLoop; 199 bool dotPosition = true; 200 201 Serial.begin(9600); 202 203 lcd.begin (20,4); 204 205 //Switch on the backlight 206 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); 207 lcd.setBacklight(HIGH); 208 lcd.home (); 209 210 //delay a few seconds so the sensors are ready 211 for (setupLoop = 1; setupLoop < 8; setupLoop++) 212 { 213 lcd.clear(); 214 215 if (dotPosition) 216 { 217 lcd.print("Initializing ."); 218 lcd.setCursor(0, 1); 219 lcd.print("WeatherStation v.1"); 220 221 } 222 else 223 { 224 lcd.print("Initializing ."); 225 lcd.setCursor(0, 1); 226 lcd.print("WeatherStation v.1"); 227 } 228 229 dotPosition = !dotPosition; 230 delay(500); 231 } 232 233 //Check if BMP 280 is ready 234 if (bmp280.initialize()) 235 { 236 lcd.setCursor(0, 2); 237 lcd.print("Barometer ready"); 238 } 239 else 240 { 241 lcd.print("Barometer error"); 242 } 243 244 lcd.setCursor(0, 3); 245 246 //check if DHT22 is ready 247 int chk = DHT.read22(DHT22_PIN); 248 switch (chk) 249 { 250 case DHTLIB_OK: 251 lcd.print("Temp sensor ready"); 252 break; 253 254 case DHTLIB_ERROR_CHECKSUM: 255 lcd.print("Temp checksum error"); 256 break; 257 258 case DHTLIB_ERROR_TIMEOUT: 259 lcd.print("Temp timeout"); 260 break; 261 262 default: 263 lcd.print("Temp sensor error"); 264 break; 265 } 266 267 //leave info on screen long enough 268 delay(2000); 269 270 bmp280.setEnabled(0); 271 bmp280.triggerMeasurement(); 272 273 bmp280.awaitMeasurement(); 274 bmp280.getPressure(baroPressure); 275 DHT.read22(DHT22_PIN); 276 277 //populate baseline datapoints with startup values 278 int p; 279 for (p = 0; p <= loopCount - 1; p++) 280 { 281 dataPointT[p] = DHT.temperature; 282 dataPointB[p] = (baroPressure / 1000) + altitudeAdjustment; 283 } 284 285 //wait for sensors to be ready again 286 delay(500); 287} 288 289void loop() { 290 291 for (mainLoop = 0; mainLoop <= loopCount - 1; mainLoop++) 292 { 293 bmp280.awaitMeasurement(); 294 295 DHT.read22(DHT22_PIN); 296 currentTemp = DHT.temperature; 297 currentHumid = DHT.humidity; 298 299 bmp280.getPressure(baroPressure); 300 bmp280.triggerMeasurement(); 301 currentPressure = (baroPressure / 1000) + altitudeAdjustment; 302 303 //read and store the array value before overwriting it 304 tempValueComparative = dataPointT[mainLoop]; 305 dataPointT[mainLoop] = currentTemp; 306 tempDifference = currentTemp - tempValueComparative; 307 308 pressValueComparative = dataPointB[mainLoop]; 309 dataPointB[mainLoop] = currentPressure; 310 pressDifference = currentPressure - pressValueComparative; 311 312 //create lcd chars defined above 313 lcd.createChar(0, arrowUp); 314 lcd.createChar(1, arrowDown); 315 lcd.createChar(2, equalSign); 316 317 //LCD Output begin 318 lcd.clear(); 319 lcd.print(currentTemp, 1); 320 lcd.print((char)223); 321 lcd.print("C "); 322 323 //determine which trend indicator to display 324 showTrendIndicator(tempDifference); 325 326 lcd.print(" "); 327 328 //then display the temperature diff 329 lcd.print(tempDifference); 330 331 //move to the next line and display humidity 332 lcd.setCursor(0, 1); 333 lcd.print(currentPressure, 1); 334 lcd.print(" kPa "); 335 336 showTrendIndicator(pressDifference); 337 338 lcd.print(" "); 339 340 lcd.print(pressDifference); 341 342 lcd.setCursor(0, 2); 343 lcd.print(currentHumid, 1); 344 lcd.print(" % Rel Hum"); 345 346 lcd.setCursor(0, 3); 347 lcd.print("Data age: "); 348 349 //this ensures the 'data age' value displays the max after the first loop completes 350 if (!firstLoopComplete) 351 { 352 if (mainLoop < (loopCount - 1)) 353 { 354 lcd.print(mainLoop); 355 } 356 else 357 { 358 lcd.print(loopCount); 359 firstLoopComplete = true; 360 } 361 } 362 else 363 { 364 lcd.print(loopCount); 365 } 366 367 lcd.print(" m"); 368 369 //countdown until next screen 370 screenWaitRight(lcdDelayScreen1); 371 372 //+++++++++++++++Screen 1 End+++++++++++++++ 373 374 375 //+++++++++++++++Screen 2 Start+++++++++++++++ 376 377 //bar chart characters 378 lcd.createChar(0, row1); 379 lcd.createChar(1, row2); 380 lcd.createChar(2, row3); 381 lcd.createChar(3, row4); 382 lcd.createChar(4, row5); 383 lcd.createChar(5, row6); 384 lcd.createChar(6, row7); 385 lcd.createChar(7, row8); 386 387 //initialize to something these will never be 388 minTemp = 50; 389 maxTemp = -50; 390 //find min and max temps 391 for (mt = 0; mt <= loopCount - 1; mt++) 392 { 393 //offset value translates a negative result for 'mainLoop - mt' into the appropriate 394 //value in the array sequence 395 offset = getOffsetValue(mainLoop - mt); 396 if (minTemp > dataPointT[offset]) 397 { 398 minTemp = dataPointT[offset]; 399 } 400 } 401 402 for (mt = 0; mt <= loopCount - 1; mt++) 403 { 404 offset = getOffsetValue(mainLoop - mt); 405 if (maxTemp < dataPointT[offset]) 406 { 407 maxTemp = dataPointT[offset]; 408 } 409 } 410 411 //this sets the min/max range that the graph will show 412 rangeLowGraph = minTemp - 1.5; 413 rangeHighGraph = maxTemp + 1.5; 414 415 lcd.clear(); 416 lcd.setCursor(0, 0); 417 lcd.print((char)223); 418 lcd.print("C "); 419 lcd.setCursor(0, 1); 420 lcd.print("H"); 421 lcd.print(maxTemp, 1); 422 lcd.setCursor(0, 2); 423 lcd.print("L"); 424 lcd.print(minTemp, 1); 425 426 for (loopTempGraph = 0; loopTempGraph <= loopCount - 1; loopTempGraph += 4) 427 { 428 offset = getOffsetValue(mainLoop - loopTempGraph); 429 currentTemp = dataPointT[offset]; 430 //i add 50 so the values never go below zero 431 currentTemp = (currentTemp + 50) - (rangeLowGraph + 50); 432 percentOfCol = currentTemp / ((rangeHighGraph + 50) - (rangeLowGraph + 50)); 433 //32 = total pixels vertical 434 pixelHeightPercent = 32 * percentOfCol; 435 pixelHeight = pixelHeightPercent; 436 showGraphColumn(pixelHeight, loopTempGraph / 4); 437 } 438 439 screenWaitLeft(lcdDelayScreen2); 440 441 //+++++++++++++++Screen 2 End+++++++++++++++ 442 443 444 //+++++++++++++++Screen 3 Start+++++++++++++++ 445 446 //initialize to something these will never be 447 minPressure = 250; 448 maxPressure = 75; 449 //find min and max pressure 450 for (mp = 0; mp <= loopCount - 1; mp++) 451 { 452 offset = getOffsetValue(mainLoop - mp); 453 if (minPressure > dataPointB[offset]) 454 { 455 minPressure = dataPointB[offset]; 456 } 457 } 458 459 for (mp = 0; mp <= loopCount - 1; mp++) 460 { 461 offset = getOffsetValue(mainLoop - mp); 462 if (maxPressure < dataPointB[offset]) 463 { 464 maxPressure = dataPointB[offset]; 465 } 466 } 467 468 lcd.clear(); 469 lcd.setCursor(0, 0); 470 lcd.print("kPa"); 471 lcd.setCursor(0, 1); 472 //lcd.print("H"); //doesn't fit on screen :( 473 lcd.print(maxPressure, 1); 474 lcd.setCursor(0, 2); 475 //lcd.print("L"); //doesn't fit on screen :( 476 lcd.print(minPressure, 1); 477 478 for (loopBaroGraph = 0; loopBaroGraph <= loopCount - 1; loopBaroGraph += 4) 479 { 480 offset = getOffsetValue(mainLoop - loopBaroGraph); 481 currentPressure = dataPointB[offset]; 482 currentPressure = currentPressure - (minPressure - 1.5); 483 percentOfCol = currentPressure / ((maxPressure + 1.5) - (minPressure - 1.5)); 484 pixelHeightPercent = 32 * percentOfCol; 485 pixelHeight = pixelHeightPercent; 486 showGraphColumn(pixelHeight, loopBaroGraph / 4); 487 } 488 489 screenWaitLeft(lcdDelayScreen3); 490 491 } //main for loop end 492} 493 494 495int getOffsetValue(int z) 496{ 497 if (z < 0) 498 { 499 return z + 60; 500 } 501 else 502 { 503 return z; 504 } 505} 506 507void screenWaitRight(int secondsR) 508{ 509 int a; 510 for (a = secondsR; a >= 0; a--) 511 { 512 lcd.setCursor(18, 3); 513 if(a >= 10) 514 { 515 lcd.print(a); 516 } 517 else 518 { 519 lcd.print(" "); 520 lcd.print(a); 521 } 522 delay(1000); 523 } 524} 525 526void screenWaitLeft(int secondsL) 527{ 528 int b; 529 for (b = secondsL; b >= 0; b--) 530 { 531 lcd.setCursor(0, 3); 532 if(b >= 10) 533 { 534 lcd.print(b); 535 } 536 else 537 { 538 lcd.print(b); 539 lcd.print(" "); 540 } 541 delay(1000); 542 } 543} 544 545 546void showTrendIndicator(float val) 547{ 548 if (val > 0) 549 { 550 lcd.write(byte(0)); 551 } 552 else if (val < 0) 553 { 554 lcd.write(byte(1)); 555 } 556 else 557 { 558 lcd.write(byte(2)); 559 } 560} 561 562 563void showGraphColumn(int pixelHeight, int c) 564{ 565 switch (pixelHeight) 566 { 567 case 1: 568 lcd.setCursor(c + 5, 3); 569 lcd.write(byte(0)); 570 break; 571 572 case 2: 573 lcd.setCursor(c + 5, 3); 574 lcd.write(byte(1)); 575 break; 576 577 case 3: 578 lcd.setCursor(c + 5, 3); 579 lcd.write(byte(2)); 580 break; 581 582 case 4: 583 lcd.setCursor(c + 5, 3); 584 lcd.write(byte(3)); 585 break; 586 587 case 5: 588 lcd.setCursor(c + 5, 3); 589 lcd.write(byte(4)); 590 break; 591 592 case 6: 593 lcd.setCursor(c + 5, 3); 594 lcd.write(byte(5)); 595 break; 596 597 case 7: 598 lcd.setCursor(c + 5, 3); 599 lcd.write(byte(6)); 600 break; 601 602 case 8: 603 lcd.setCursor(c + 5, 3); 604 lcd.write(byte(7)); 605 break; 606 607 case 9: 608 lcd.setCursor(c + 5, 3); 609 lcd.write(byte(7)); 610 611 lcd.setCursor(c + 5, 2); 612 lcd.write(byte(0)); 613 break; 614 615 case 10: 616 lcd.setCursor(c + 5, 3); 617 lcd.write(byte(7)); 618 619 lcd.setCursor(c + 5, 2); 620 lcd.write(byte(1)); 621 break; 622 623 case 11: 624 lcd.setCursor(c + 5, 3); 625 lcd.write(byte(7)); 626 627 lcd.setCursor(c + 5, 2); 628 lcd.write(byte(2)); 629 break; 630 631 case 12: 632 lcd.setCursor(c + 5, 3); 633 lcd.write(byte(7)); 634 635 lcd.setCursor(c + 5, 2); 636 lcd.write(byte(3)); 637 break; 638 639 case 13: 640 lcd.setCursor(c + 5, 3); 641 lcd.write(byte(7)); 642 643 lcd.setCursor(c + 5, 2); 644 lcd.write(byte(4)); 645 break; 646 647 case 14: 648 lcd.setCursor(c + 5, 3); 649 lcd.write(byte(7)); 650 651 lcd.setCursor(c + 5, 2); 652 lcd.write(byte(5)); 653 break; 654 655 case 15: 656 lcd.setCursor(c + 5, 3); 657 lcd.write(byte(7)); 658 659 lcd.setCursor(c + 5, 2); 660 lcd.write(byte(6)); 661 break; 662 663 case 16: 664 lcd.setCursor(c + 5, 3); 665 lcd.write(byte(7)); 666 667 lcd.setCursor(c + 5, 2); 668 lcd.write(byte(7)); 669 break; 670 671 case 17: 672 lcd.setCursor(c + 5, 3); 673 lcd.write(byte(7)); 674 675 lcd.setCursor(c + 5, 2); 676 lcd.write(byte(7)); 677 678 lcd.setCursor(c + 5, 1); 679 lcd.write(byte(0)); 680 break; 681 682 case 18: 683 lcd.setCursor(c + 5, 3); 684 lcd.write(byte(7)); 685 686 lcd.setCursor(c + 5, 2); 687 lcd.write(byte(7)); 688 689 lcd.setCursor(c + 5, 1); 690 lcd.write(byte(1)); 691 break; 692 693 case 19: 694 lcd.setCursor(c + 5, 3); 695 lcd.write(byte(7)); 696 697 lcd.setCursor(c + 5, 2); 698 lcd.write(byte(7)); 699 700 lcd.setCursor(c + 5, 1); 701 lcd.write(byte(2)); 702 break; 703 704 case 20: 705 lcd.setCursor(c + 5, 3); 706 lcd.write(byte(7)); 707 708 lcd.setCursor(c + 5, 2); 709 lcd.write(byte(7)); 710 711 lcd.setCursor(c + 5, 1); 712 lcd.write(byte(3)); 713 break; 714 715 case 21: 716 lcd.setCursor(c + 5, 3); 717 lcd.write(byte(7)); 718 719 lcd.setCursor(c + 5, 2); 720 lcd.write(byte(7)); 721 722 lcd.setCursor(c + 5, 1); 723 lcd.write(byte(4)); 724 break; 725 726 case 22: 727 lcd.setCursor(c + 5, 3); 728 lcd.write(byte(7)); 729 730 lcd.setCursor(c + 5, 2); 731 lcd.write(byte(7)); 732 733 lcd.setCursor(c + 5, 1); 734 lcd.write(byte(5)); 735 break; 736 737 case 23: 738 lcd.setCursor(c + 5, 3); 739 lcd.write(byte(7)); 740 741 lcd.setCursor(c + 5, 2); 742 lcd.write(byte(7)); 743 744 lcd.setCursor(c + 5, 1); 745 lcd.write(byte(6)); 746 break; 747 748 case 24: 749 lcd.setCursor(c + 5, 3); 750 lcd.write(byte(7)); 751 752 lcd.setCursor(c + 5, 2); 753 lcd.write(byte(7)); 754 755 lcd.setCursor(c + 5, 1); 756 lcd.write(byte(7)); 757 break; 758 759 case 25: 760 lcd.setCursor(c + 5, 3); 761 lcd.write(byte(7)); 762 763 lcd.setCursor(c + 5, 2); 764 lcd.write(byte(7)); 765 766 lcd.setCursor(c + 5, 1); 767 lcd.write(byte(7)); 768 769 lcd.setCursor(c + 5, 0); 770 lcd.write(byte(0)); 771 break; 772 773 case 26: 774 lcd.setCursor(c + 5, 3); 775 lcd.write(byte(7)); 776 777 lcd.setCursor(c + 5, 2); 778 lcd.write(byte(7)); 779 780 lcd.setCursor(c + 5, 1); 781 lcd.write(byte(7)); 782 783 lcd.setCursor(c + 5, 0); 784 lcd.write(byte(1)); 785 break; 786 787 case 27: 788 lcd.setCursor(c + 5, 3); 789 lcd.write(byte(7)); 790 791 lcd.setCursor(c + 5, 2); 792 lcd.write(byte(7)); 793 794 lcd.setCursor(c + 5, 1); 795 lcd.write(byte(7)); 796 797 lcd.setCursor(c + 5, 0); 798 lcd.write(byte(2)); 799 break; 800 801 case 28: 802 lcd.setCursor(c + 5, 3); 803 lcd.write(byte(7)); 804 805 lcd.setCursor(c + 5, 2); 806 lcd.write(byte(7)); 807 808 lcd.setCursor(c + 5, 1); 809 lcd.write(byte(7)); 810 811 lcd.setCursor(c + 5, 0); 812 lcd.write(byte(3)); 813 break; 814 815 case 29: 816 lcd.setCursor(c + 5, 3); 817 lcd.write(byte(7)); 818 819 lcd.setCursor(c + 5, 2); 820 lcd.write(byte(7)); 821 822 lcd.setCursor(c + 5, 1); 823 lcd.write(byte(7)); 824 825 lcd.setCursor(c + 5, 0); 826 lcd.write(byte(4)); 827 break; 828 829 case 30: 830 lcd.setCursor(c + 5, 3); 831 lcd.write(byte(7)); 832 833 lcd.setCursor(c + 5, 2); 834 lcd.write(byte(7)); 835 836 lcd.setCursor(c + 5, 1); 837 lcd.write(byte(7)); 838 839 lcd.setCursor(c + 5, 0); 840 lcd.write(byte(5)); 841 break; 842 843 case 31: 844 lcd.setCursor(c + 5, 3); 845 lcd.write(byte(7)); 846 847 lcd.setCursor(c + 5, 2); 848 lcd.write(byte(7)); 849 850 lcd.setCursor(c + 5, 1); 851 lcd.write(byte(7)); 852 853 lcd.setCursor(c + 5, 0); 854 lcd.write(byte(6)); 855 break; 856 857 case 32: 858 lcd.setCursor(c + 5, 3); 859 lcd.write(byte(7)); 860 861 lcd.setCursor(c + 5, 2); 862 lcd.write(byte(7)); 863 864 lcd.setCursor(c + 5, 1); 865 lcd.write(byte(7)); 866 867 lcd.setCursor(c + 5, 0); 868 lcd.write(byte(7)); 869 break; 870 } 871} 872
WeatherStation_20x4_v7_final.ino
arduino
1#include <LCD.h> 2#include <LiquidCrystal_I2C.h> 3//#include <Wire.h> 4#include <dht.h> 5#include "i2c.h" 6#include "i2c_BMP280.h" 7 8dht DHT; 9BMP280 bmp280; 10 11//specify the temp sensor 12#define DHTTYPE DHT22; 13#define DHT22_PIN 6 14 15#define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is 16#define BACKLIGHT_PIN 3 17#define En_pin 2 18#define Rw_pin 1 19#define Rs_pin 0 20#define D4_pin 4 21#define D5_pin 5 22#define D6_pin 6 23#define D7_pin 7 24 25LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin); 26 27//total delay = (lcdDelayScreen1 + lcdDelayScreen2 + lcdDelayScreen3) * loopCount (in seconds) 28int lcdDelayScreen1 = 44; //seconds displaying primary info 29int lcdDelayScreen2 = 8; //seconds displaying secondary info 30int lcdDelayScreen3 = 8; //seconds displaying secondary info 31 32//these all have to match 33int loopCount = 60; //total loops 34float dataPointT[60]; //temperature data points 35float dataPointB[60]; //pressure data points 36 37int mainLoop; //primary loop 38int loopBaroGraph; //secondary loop 39int loopTempGraph; //secondary loop 40 41float currentTemp; 42float currentHumid; 43 44float baroPressure; 45float currentPressure; 46 47float tempDifference = 0; 48float tempValueComparative; 49 50int offset; 51int mt; 52int mp; 53 54float pressDifference = 0; 55float pressValueComparative; 56 57//engineeringtoolbox.com/barometers-elevation-compensation-d_1812.html 58float altitudeAdjustment = 1; 59 60float minTemp; 61float maxTemp; 62float minPressure; 63float maxPressure; 64 65int rangeLowGraph; 66int rangeHighGraph; 67 68float percentOfCol; 69float pixelHeightPercent; 70int pixelHeight; 71 72bool firstLoopComplete = false; 73 74//define characters for temperature indicators 75byte arrowUp[8] = { 76 B00100, 77 B01110, 78 B10101, 79 B00100, 80 B00100, 81 B00100, 82 B00100, 83 B00100, 84}; 85 86byte arrowDown[8] = { 87 B00100, 88 B00100, 89 B00100, 90 B00100, 91 B00100, 92 B10101, 93 B01110, 94 B00100, 95}; 96 97byte equalSign[8] = { 98 B00100, 99 B01110, 100 B10101, 101 B00100, 102 B00100, 103 B10101, 104 B01110, 105 B00100, 106}; 107 108byte row1[8] = { 109 B00000, 110 B00000, 111 B00000, 112 B00000, 113 B00000, 114 B00000, 115 B00000, 116 B11111, 117}; 118 119byte row2[8] = { 120 B00000, 121 B00000, 122 B00000, 123 B00000, 124 B00000, 125 B00000, 126 B11111, 127 B11111, 128}; 129 130byte row3[8] = { 131 B00000, 132 B00000, 133 B00000, 134 B00000, 135 B00000, 136 B11111, 137 B11111, 138 B11111, 139}; 140 141byte row4[8] = { 142 B00000, 143 B00000, 144 B00000, 145 B00000, 146 B11111, 147 B11111, 148 B11111, 149 B11111, 150}; 151 152byte row5[8] = { 153 B00000, 154 B00000, 155 B00000, 156 B11111, 157 B11111, 158 B11111, 159 B11111, 160 B11111, 161}; 162 163byte row6[8] = { 164 B00000, 165 B00000, 166 B11111, 167 B11111, 168 B11111, 169 B11111, 170 B11111, 171 B11111, 172}; 173 174byte row7[8] = { 175 B00000, 176 B11111, 177 B11111, 178 B11111, 179 B11111, 180 B11111, 181 B11111, 182 B11111, 183}; 184 185byte row8[8] = { 186 B11111, 187 B11111, 188 B11111, 189 B11111, 190 B11111, 191 B11111, 192 B11111, 193 B11111, 194}; 195 196void setup() { 197 198 int setupLoop; 199 bool dotPosition = true; 200 201 Serial.begin(9600); 202 203 lcd.begin (20,4); 204 205 //Switch on the backlight 206 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); 207 lcd.setBacklight(HIGH); 208 lcd.home (); 209 210 //delay a few seconds so the sensors are ready 211 for (setupLoop = 1; setupLoop < 8; setupLoop++) 212 { 213 lcd.clear(); 214 215 if (dotPosition) 216 { 217 lcd.print("Initializing ."); 218 lcd.setCursor(0, 1); 219 lcd.print("WeatherStation v.1"); 220 221 } 222 else 223 { 224 lcd.print("Initializing ."); 225 lcd.setCursor(0, 1); 226 lcd.print("WeatherStation v.1"); 227 } 228 229 dotPosition = !dotPosition; 230 delay(500); 231 } 232 233 //Check if BMP 280 is ready 234 if (bmp280.initialize()) 235 { 236 lcd.setCursor(0, 2); 237 lcd.print("Barometer ready"); 238 } 239 else 240 { 241 lcd.print("Barometer error"); 242 } 243 244 lcd.setCursor(0, 3); 245 246 //check if DHT22 is ready 247 int chk = DHT.read22(DHT22_PIN); 248 switch (chk) 249 { 250 case DHTLIB_OK: 251 lcd.print("Temp sensor ready"); 252 break; 253 254 case DHTLIB_ERROR_CHECKSUM: 255 lcd.print("Temp checksum error"); 256 break; 257 258 case DHTLIB_ERROR_TIMEOUT: 259 lcd.print("Temp timeout"); 260 break; 261 262 default: 263 lcd.print("Temp sensor error"); 264 break; 265 } 266 267 //leave info on screen long enough 268 delay(2000); 269 270 bmp280.setEnabled(0); 271 bmp280.triggerMeasurement(); 272 273 bmp280.awaitMeasurement(); 274 bmp280.getPressure(baroPressure); 275 DHT.read22(DHT22_PIN); 276 277 //populate baseline datapoints with startup values 278 int p; 279 for (p = 0; p <= loopCount - 1; p++) 280 { 281 dataPointT[p] = DHT.temperature; 282 dataPointB[p] = (baroPressure / 1000) + altitudeAdjustment; 283 } 284 285 //wait for sensors to be ready again 286 delay(500); 287} 288 289void loop() { 290 291 for (mainLoop = 0; mainLoop <= loopCount - 1; mainLoop++) 292 { 293 bmp280.awaitMeasurement(); 294 295 DHT.read22(DHT22_PIN); 296 currentTemp = DHT.temperature; 297 currentHumid = DHT.humidity; 298 299 bmp280.getPressure(baroPressure); 300 bmp280.triggerMeasurement(); 301 currentPressure = (baroPressure / 1000) + altitudeAdjustment; 302 303 //read and store the array value before overwriting it 304 tempValueComparative = dataPointT[mainLoop]; 305 dataPointT[mainLoop] = currentTemp; 306 tempDifference = currentTemp - tempValueComparative; 307 308 pressValueComparative = dataPointB[mainLoop]; 309 dataPointB[mainLoop] = currentPressure; 310 pressDifference = currentPressure - pressValueComparative; 311 312 //create lcd chars defined above 313 lcd.createChar(0, arrowUp); 314 lcd.createChar(1, arrowDown); 315 lcd.createChar(2, equalSign); 316 317 //LCD Output begin 318 lcd.clear(); 319 lcd.print(currentTemp, 1); 320 lcd.print((char)223); 321 lcd.print("C "); 322 323 //determine which trend indicator to display 324 showTrendIndicator(tempDifference); 325 326 lcd.print(" "); 327 328 //then display the temperature diff 329 lcd.print(tempDifference); 330 331 //move to the next line and display humidity 332 lcd.setCursor(0, 1); 333 lcd.print(currentPressure, 1); 334 lcd.print(" kPa "); 335 336 showTrendIndicator(pressDifference); 337 338 lcd.print(" "); 339 340 lcd.print(pressDifference); 341 342 lcd.setCursor(0, 2); 343 lcd.print(currentHumid, 1); 344 lcd.print(" % Rel Hum"); 345 346 lcd.setCursor(0, 3); 347 lcd.print("Data age: "); 348 349 //this ensures the 'data age' value displays the max after the first loop completes 350 if (!firstLoopComplete) 351 { 352 if (mainLoop < (loopCount - 1)) 353 { 354 lcd.print(mainLoop); 355 } 356 else 357 { 358 lcd.print(loopCount); 359 firstLoopComplete = true; 360 } 361 } 362 else 363 { 364 lcd.print(loopCount); 365 } 366 367 lcd.print(" m"); 368 369 //countdown until next screen 370 screenWaitRight(lcdDelayScreen1); 371 372 //+++++++++++++++Screen 1 End+++++++++++++++ 373 374 375 //+++++++++++++++Screen 2 Start+++++++++++++++ 376 377 //bar chart characters 378 lcd.createChar(0, row1); 379 lcd.createChar(1, row2); 380 lcd.createChar(2, row3); 381 lcd.createChar(3, row4); 382 lcd.createChar(4, row5); 383 lcd.createChar(5, row6); 384 lcd.createChar(6, row7); 385 lcd.createChar(7, row8); 386 387 //initialize to something these will never be 388 minTemp = 50; 389 maxTemp = -50; 390 //find min and max temps 391 for (mt = 0; mt <= loopCount - 1; mt++) 392 { 393 //offset value translates a negative result for 'mainLoop - mt' into the appropriate 394 //value in the array sequence 395 offset = getOffsetValue(mainLoop - mt); 396 if (minTemp > dataPointT[offset]) 397 { 398 minTemp = dataPointT[offset]; 399 } 400 } 401 402 for (mt = 0; mt <= loopCount - 1; mt++) 403 { 404 offset = getOffsetValue(mainLoop - mt); 405 if (maxTemp < dataPointT[offset]) 406 { 407 maxTemp = dataPointT[offset]; 408 } 409 } 410 411 //this sets the min/max range that the graph will show 412 rangeLowGraph = minTemp - 1.5; 413 rangeHighGraph = maxTemp + 1.5; 414 415 lcd.clear(); 416 lcd.setCursor(0, 0); 417 lcd.print((char)223); 418 lcd.print("C "); 419 lcd.setCursor(0, 1); 420 lcd.print("H"); 421 lcd.print(maxTemp, 1); 422 lcd.setCursor(0, 2); 423 lcd.print("L"); 424 lcd.print(minTemp, 1); 425 426 for (loopTempGraph = 0; loopTempGraph <= loopCount - 1; loopTempGraph += 4) 427 { 428 offset = getOffsetValue(mainLoop - loopTempGraph); 429 currentTemp = dataPointT[offset]; 430 //i add 50 so the values never go below zero 431 currentTemp = (currentTemp + 50) - (rangeLowGraph + 50); 432 percentOfCol = currentTemp / ((rangeHighGraph + 50) - (rangeLowGraph + 50)); 433 //32 = total pixels vertical 434 pixelHeightPercent = 32 * percentOfCol; 435 pixelHeight = pixelHeightPercent; 436 showGraphColumn(pixelHeight, loopTempGraph / 4); 437 } 438 439 screenWaitLeft(lcdDelayScreen2); 440 441 //+++++++++++++++Screen 2 End+++++++++++++++ 442 443 444 //+++++++++++++++Screen 3 Start+++++++++++++++ 445 446 //initialize to something these will never be 447 minPressure = 250; 448 maxPressure = 75; 449 //find min and max pressure 450 for (mp = 0; mp <= loopCount - 1; mp++) 451 { 452 offset = getOffsetValue(mainLoop - mp); 453 if (minPressure > dataPointB[offset]) 454 { 455 minPressure = dataPointB[offset]; 456 } 457 } 458 459 for (mp = 0; mp <= loopCount - 1; mp++) 460 { 461 offset = getOffsetValue(mainLoop - mp); 462 if (maxPressure < dataPointB[offset]) 463 { 464 maxPressure = dataPointB[offset]; 465 } 466 } 467 468 lcd.clear(); 469 lcd.setCursor(0, 0); 470 lcd.print("kPa"); 471 lcd.setCursor(0, 1); 472 //lcd.print("H"); //doesn't fit on screen :( 473 lcd.print(maxPressure, 1); 474 lcd.setCursor(0, 2); 475 //lcd.print("L"); //doesn't fit on screen :( 476 lcd.print(minPressure, 1); 477 478 for (loopBaroGraph = 0; loopBaroGraph <= loopCount - 1; loopBaroGraph += 4) 479 { 480 offset = getOffsetValue(mainLoop - loopBaroGraph); 481 currentPressure = dataPointB[offset]; 482 currentPressure = currentPressure - (minPressure - 1.5); 483 percentOfCol = currentPressure / ((maxPressure + 1.5) - (minPressure - 1.5)); 484 pixelHeightPercent = 32 * percentOfCol; 485 pixelHeight = pixelHeightPercent; 486 showGraphColumn(pixelHeight, loopBaroGraph / 4); 487 } 488 489 screenWaitLeft(lcdDelayScreen3); 490 491 } //main for loop end 492} 493 494 495int getOffsetValue(int z) 496{ 497 if (z < 0) 498 { 499 return z + 60; 500 } 501 else 502 { 503 return z; 504 } 505} 506 507void screenWaitRight(int secondsR) 508{ 509 int a; 510 for (a = secondsR; a >= 0; a--) 511 { 512 lcd.setCursor(18, 3); 513 if(a >= 10) 514 { 515 lcd.print(a); 516 } 517 else 518 { 519 lcd.print(" "); 520 lcd.print(a); 521 } 522 delay(1000); 523 } 524} 525 526void screenWaitLeft(int secondsL) 527{ 528 int b; 529 for (b = secondsL; b >= 0; b--) 530 { 531 lcd.setCursor(0, 3); 532 if(b >= 10) 533 { 534 lcd.print(b); 535 } 536 else 537 { 538 lcd.print(b); 539 lcd.print(" "); 540 } 541 delay(1000); 542 } 543} 544 545 546void showTrendIndicator(float val) 547{ 548 if (val > 0) 549 { 550 lcd.write(byte(0)); 551 } 552 else if (val < 0) 553 { 554 lcd.write(byte(1)); 555 } 556 else 557 { 558 lcd.write(byte(2)); 559 } 560} 561 562 563void showGraphColumn(int pixelHeight, int c) 564{ 565 switch (pixelHeight) 566 { 567 case 1: 568 lcd.setCursor(c + 5, 3); 569 lcd.write(byte(0)); 570 break; 571 572 case 2: 573 lcd.setCursor(c + 5, 3); 574 lcd.write(byte(1)); 575 break; 576 577 case 3: 578 lcd.setCursor(c + 5, 3); 579 lcd.write(byte(2)); 580 break; 581 582 case 4: 583 lcd.setCursor(c + 5, 3); 584 lcd.write(byte(3)); 585 break; 586 587 case 5: 588 lcd.setCursor(c + 5, 3); 589 lcd.write(byte(4)); 590 break; 591 592 case 6: 593 lcd.setCursor(c + 5, 3); 594 lcd.write(byte(5)); 595 break; 596 597 case 7: 598 lcd.setCursor(c + 5, 3); 599 lcd.write(byte(6)); 600 break; 601 602 case 8: 603 lcd.setCursor(c + 5, 3); 604 lcd.write(byte(7)); 605 break; 606 607 case 9: 608 lcd.setCursor(c + 5, 3); 609 lcd.write(byte(7)); 610 611 lcd.setCursor(c + 5, 2); 612 lcd.write(byte(0)); 613 break; 614 615 case 10: 616 lcd.setCursor(c + 5, 3); 617 lcd.write(byte(7)); 618 619 lcd.setCursor(c + 5, 2); 620 lcd.write(byte(1)); 621 break; 622 623 case 11: 624 lcd.setCursor(c + 5, 3); 625 lcd.write(byte(7)); 626 627 lcd.setCursor(c + 5, 2); 628 lcd.write(byte(2)); 629 break; 630 631 case 12: 632 lcd.setCursor(c + 5, 3); 633 lcd.write(byte(7)); 634 635 lcd.setCursor(c + 5, 2); 636 lcd.write(byte(3)); 637 break; 638 639 case 13: 640 lcd.setCursor(c + 5, 3); 641 lcd.write(byte(7)); 642 643 lcd.setCursor(c + 5, 2); 644 lcd.write(byte(4)); 645 break; 646 647 case 14: 648 lcd.setCursor(c + 5, 3); 649 lcd.write(byte(7)); 650 651 lcd.setCursor(c + 5, 2); 652 lcd.write(byte(5)); 653 break; 654 655 case 15: 656 lcd.setCursor(c + 5, 3); 657 lcd.write(byte(7)); 658 659 lcd.setCursor(c + 5, 2); 660 lcd.write(byte(6)); 661 break; 662 663 case 16: 664 lcd.setCursor(c + 5, 3); 665 lcd.write(byte(7)); 666 667 lcd.setCursor(c + 5, 2); 668 lcd.write(byte(7)); 669 break; 670 671 case 17: 672 lcd.setCursor(c + 5, 3); 673 lcd.write(byte(7)); 674 675 lcd.setCursor(c + 5, 2); 676 lcd.write(byte(7)); 677 678 lcd.setCursor(c + 5, 1); 679 lcd.write(byte(0)); 680 break; 681 682 case 18: 683 lcd.setCursor(c + 5, 3); 684 lcd.write(byte(7)); 685 686 lcd.setCursor(c + 5, 2); 687 lcd.write(byte(7)); 688 689 lcd.setCursor(c + 5, 1); 690 lcd.write(byte(1)); 691 break; 692 693 case 19: 694 lcd.setCursor(c + 5, 3); 695 lcd.write(byte(7)); 696 697 lcd.setCursor(c + 5, 2); 698 lcd.write(byte(7)); 699 700 lcd.setCursor(c + 5, 1); 701 lcd.write(byte(2)); 702 break; 703 704 case 20: 705 lcd.setCursor(c + 5, 3); 706 lcd.write(byte(7)); 707 708 lcd.setCursor(c + 5, 2); 709 lcd.write(byte(7)); 710 711 lcd.setCursor(c + 5, 1); 712 lcd.write(byte(3)); 713 break; 714 715 case 21: 716 lcd.setCursor(c + 5, 3); 717 lcd.write(byte(7)); 718 719 lcd.setCursor(c + 5, 2); 720 lcd.write(byte(7)); 721 722 lcd.setCursor(c + 5, 1); 723 lcd.write(byte(4)); 724 break; 725 726 case 22: 727 lcd.setCursor(c + 5, 3); 728 lcd.write(byte(7)); 729 730 lcd.setCursor(c + 5, 2); 731 lcd.write(byte(7)); 732 733 lcd.setCursor(c + 5, 1); 734 lcd.write(byte(5)); 735 break; 736 737 case 23: 738 lcd.setCursor(c + 5, 3); 739 lcd.write(byte(7)); 740 741 lcd.setCursor(c + 5, 2); 742 lcd.write(byte(7)); 743 744 lcd.setCursor(c + 5, 1); 745 lcd.write(byte(6)); 746 break; 747 748 case 24: 749 lcd.setCursor(c + 5, 3); 750 lcd.write(byte(7)); 751 752 lcd.setCursor(c + 5, 2); 753 lcd.write(byte(7)); 754 755 lcd.setCursor(c + 5, 1); 756 lcd.write(byte(7)); 757 break; 758 759 case 25: 760 lcd.setCursor(c + 5, 3); 761 lcd.write(byte(7)); 762 763 lcd.setCursor(c + 5, 2); 764 lcd.write(byte(7)); 765 766 lcd.setCursor(c + 5, 1); 767 lcd.write(byte(7)); 768 769 lcd.setCursor(c + 5, 0); 770 lcd.write(byte(0)); 771 break; 772 773 case 26: 774 lcd.setCursor(c + 5, 3); 775 lcd.write(byte(7)); 776 777 lcd.setCursor(c + 5, 2); 778 lcd.write(byte(7)); 779 780 lcd.setCursor(c + 5, 1); 781 lcd.write(byte(7)); 782 783 lcd.setCursor(c + 5, 0); 784 lcd.write(byte(1)); 785 break; 786 787 case 27: 788 lcd.setCursor(c + 5, 3); 789 lcd.write(byte(7)); 790 791 lcd.setCursor(c + 5, 2); 792 lcd.write(byte(7)); 793 794 lcd.setCursor(c + 5, 1); 795 lcd.write(byte(7)); 796 797 lcd.setCursor(c + 5, 0); 798 lcd.write(byte(2)); 799 break; 800 801 case 28: 802 lcd.setCursor(c + 5, 3); 803 lcd.write(byte(7)); 804 805 lcd.setCursor(c + 5, 2); 806 lcd.write(byte(7)); 807 808 lcd.setCursor(c + 5, 1); 809 lcd.write(byte(7)); 810 811 lcd.setCursor(c + 5, 0); 812 lcd.write(byte(3)); 813 break; 814 815 case 29: 816 lcd.setCursor(c + 5, 3); 817 lcd.write(byte(7)); 818 819 lcd.setCursor(c + 5, 2); 820 lcd.write(byte(7)); 821 822 lcd.setCursor(c + 5, 1); 823 lcd.write(byte(7)); 824 825 lcd.setCursor(c + 5, 0); 826 lcd.write(byte(4)); 827 break; 828 829 case 30: 830 lcd.setCursor(c + 5, 3); 831 lcd.write(byte(7)); 832 833 lcd.setCursor(c + 5, 2); 834 lcd.write(byte(7)); 835 836 lcd.setCursor(c + 5, 1); 837 lcd.write(byte(7)); 838 839 lcd.setCursor(c + 5, 0); 840 lcd.write(byte(5)); 841 break; 842 843 case 31: 844 lcd.setCursor(c + 5, 3); 845 lcd.write(byte(7)); 846 847 lcd.setCursor(c + 5, 2); 848 lcd.write(byte(7)); 849 850 lcd.setCursor(c + 5, 1); 851 lcd.write(byte(7)); 852 853 lcd.setCursor(c + 5, 0); 854 lcd.write(byte(6)); 855 break; 856 857 case 32: 858 lcd.setCursor(c + 5, 3); 859 lcd.write(byte(7)); 860 861 lcd.setCursor(c + 5, 2); 862 lcd.write(byte(7)); 863 864 lcd.setCursor(c + 5, 1); 865 lcd.write(byte(7)); 866 867 lcd.setCursor(c + 5, 0); 868 lcd.write(byte(7)); 869 break; 870 } 871} 872
Downloadable files
WeatherStation
WeatherStation
Weather Station v1
Weather Station v1
WeatherStation
WeatherStation
Comments
Only logged in users can leave comments
ragingradish
0 Followers
•0 Projects
Table of contents
Intro
21
0