Mittwoch, 19. August 2015

Simple weather station on Arduino

To refresh some basic knowledge about electronics and Arduino platform we will implement a weather station.

Let's define requirements we'll have to out weather station. It should:
  • Display current temperature and humidity
  • Display current time and date
  • Set time and date manually using buttons
We will need following components:
  • Arduino-compatible microcontroller
  • DHT11 temperature/humidity sensor
  • Real-time clock module
  • Small breadboard
  • 2 small push buttons
  • 2 1kOhm resistors
  • Bunch of wires
  • 5V DC power adapter

At first let's connect everything together like it is shown on the picture below.

The upload following sketch.

1:  #include <stdio.h>  
2:  #include <DS1302.h>  
3:  #include <Wire.h>   
4:  #include <LiquidCrystal_I2C.h>  
5:  #include "DHT.h"  
6:    
7:  DHT dht;  
8:  LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display  
9:    
10:  // Set the appropriate digital I/O pin connections. These are the pin  
11:  // assignments for the Arduino as well for as the DS1302 chip. See the DS1302  
12:  // datasheet:  
13:  //  
14:  //  http://datasheets.maximintegrated.com/en/ds/DS1302.pdf  
15:  const int kCePin  = 5; // Chip Enable  
16:  const int kIoPin  = 6; // Input/Output  
17:  const int kSclkPin = 7; // Serial Clock  
18:    
19:  // Create a DS1302 object.  
20:  DS1302 rtc(kCePin, kIoPin, kSclkPin);  
21:    
22:  long debouncing_time = 15;  
23:  volatile unsigned long last_micros;  
24:  volatile int pos = 0;  
25:  volatile int value = 0;  
26:  int maxPos = 6;  
27:    
28:  String dayAsString(const Time::Day day) {  
29:   switch (day) {  
30:    case Time::kSunday: return "Sun";  
31:    case Time::kMonday: return "Mon";  
32:    case Time::kTuesday: return "Tue";  
33:    case Time::kWednesday: return "Wed";  
34:    case Time::kThursday: return "Thu";  
35:    case Time::kFriday: return "Fri";  
36:    case Time::kSaturday: return "Sat";  
37:   }  
38:   return "(unknown day)";  
39:  }  
40:    
41:  void printTime() {  
42:   // Get the current time and date from the chip.  
43:   Time t = rtc.time();  
44:    
45:   // Name the day of the week.  
46:   const String day = dayAsString(t.day);  
47:    
48:   char humidity[10];  
49:   char temperature[10];  
50:     
51:   dtostrf(dht.getHumidity(), 2, 0, humidity);  
52:   dtostrf(dht.getTemperature(), 2, 0, temperature);  
53:    
54:   // Format the time and date and insert into the temporary buffer.  
55:   char line1[17], line2[17];  
56:    
57:   snprintf(line2, sizeof(line2), "        ");  
58:   switch (pos) {  
59:    case 0:  
60:     snprintf(line1, sizeof(line1), " %s %04d-%02d-%02d ",  
61:        day.c_str(), t.yr, t.mon, t.date);  
62:     snprintf(line2, sizeof(line2), "%02d:%02d:%02d T%s H%s ",  
63:          t.hr, t.min, t.sec, temperature, humidity);  
64:     break;  
65:    case 1:  
66:     if (value > 0) {  
67:      t.yr += value;  
68:      if (t.yr > 2030) t.yr = 2010;  
69:      rtc.time(t);  
70:     }  
71:     snprintf(line1, sizeof(line1), "Year: %04d   ", t.yr);  
72:     break;  
73:    case 2:  
74:     if (value) {  
75:      t.mon += value;  
76:      if (t.mon > 12) t.mon = 1;  
77:      rtc.time(t);  
78:     }  
79:     snprintf(line1, sizeof(line1), "Month: %02d   ", t.mon);  
80:     break;  
81:    case 3:  
82:     if (value) {  
83:      t.date += value;  
84:      if (t.date > 31) t.date = 1;  
85:      rtc.time(t);  
86:     }  
87:     snprintf(line1, sizeof(line1), "Date: %02d   ", t.date);  
88:     break;  
89:    case 4:  
90:     if (value) {  
91:      t.hr += value;  
92:      if (t.hr > 23) t.date = 0;  
93:      rtc.time(t);  
94:     }  
95:     snprintf(line1, sizeof(line1), "Hour: %02d   ", t.hr);  
96:     break;  
97:    case 5:  
98:     if (value) {  
99:      t.min += value;  
100:      if (t.min > 59) t.min = 0;  
101:      rtc.time(t);  
102:     }  
103:     snprintf(line1, sizeof(line1), "Minute: %02d   ", t.min);  
104:     break;  
105:    case 6:  
106:     if (value) {  
107:      t.sec += value;  
108:      if (t.sec > 59) t.sec = 0;  
109:      rtc.time(t);  
110:     }  
111:     snprintf(line1, sizeof(line1), "Second: %02d   ", t.sec);  
112:     break;  
113:   }  
114:   value = 0;  
115:   // Print a message to the LCD.  
116:   lcd.backlight();  
117:   lcd.setCursor(0,0);  
118:   lcd.print(line1);  
119:   lcd.setCursor(0,1);  
120:   lcd.print(line2);  
121:  }  
122:    
123:  void setup() {  
124:   Serial.begin(9600);  
125:   lcd.init();           // initialize the lcd   
126:   dht.setup(4); // data pin 4  
127:     
128:   // Initialize a new chip by turning off write protection and clearing the  
129:   // clock halt flag. These methods needn't always be called. See the DS1302  
130:   // datasheet for details.  
131:  // rtc.writeProtect(false);  
132:  // rtc.halt(false);  
133:   // Make a new time object to set the date and time.  
134:  // Time t(2010, 1, 1, 0, 0, 0, Time::kFriday);  
135:   // Set the time and date on the chip.  
136:  // rtc.time(t);  
137:    
138:   attachInterrupt(0, changePos, RISING);  
139:   attachInterrupt(1, changeValue, RISING);  
140:  }  
141:    
142:  void changePos() {  
143:   if((long)(micros() - last_micros) >= debouncing_time * 1000) {  
144:    pos++;  
145:    if (pos > maxPos) pos = 0;  
146:    last_micros = micros();  
147:   }  
148:  }  
149:    
150:  void changeValue() {  
151:   if((long)(micros() - last_micros) >= debouncing_time * 1000) {  
152:    value = true;  
153:    last_micros = micros();  
154:   }  
155:  }  
156:    
157:  // Loop and print the time every second.  
158:  void loop() {  
159:   delay(dht.getMinimumSamplingPeriod());  
160:   printTime();  
161:  }  

That's it.

Sources: http://bit.ly/1MD7raH