Components and supplies
DSD Tech DHT22 AM2302 Temperature and Humidity Sensor
Arduino Mega 2560
Robojax BMP280
Kuman K15 Ethernet Shield W5100
SainSmart LCD Module For Arduino 20 X 4
3.3V-5V 4 Channel Logic Level Converter
Project description
Code
weather.php
php
This is the page which displays the information. Bring it up by typing IP_ADDRESS\weather.php in your browser.
1<?php 2 3$link = mysqli_connect("127.0.0.1", "username", "password", "weatherdata"); 4 5//in the query I want to split the contents of the timestamp field and just take the time portion 6//$query = "SELECT CONCAT(HOUR(timestamp), ':', MINUTE(timestamp)) as dbTime, temperature, pressure, humidity FROM master ORDER BY uid DESC LIMIT 24"; 7$query = "SELECT uid, TIME(timestamp) as dbTime, temperature, pressure, humidity FROM master ORDER BY uid DESC LIMIT 24"; 8 9//query above is executed 10//i'm not doing any error checking' 11$result = mysqli_query($link, $query); 12 13//declare arrays 14//not really necessary 15$timestamps = array(); 16$temperatures = array(); 17$pressure = array(); 18$humidity = array(); 19$pixelHeights = array(); 20$pixelHeightsP = array(); 21 22//18 cols @ 10 min intervals = 3 hrs, indexed from 0 23$columnRange = 17; 24 25//dump the db results into separate arrays so we can use them later 26while ($db = mysqli_fetch_array($result)) 27{ 28 //chop off the seconds portion of the time value 29 $pieces = explode(':', $db['dbTime']); 30 $formattedTime = $pieces[0] . ':' . $pieces[1]; 31 32 $timestampsTime[] = $formattedTime; 33 $temperatures[] = $db['temperature']; 34 $pressure[] = $db['pressure']; 35 $humidity[] = $db['humidity']; 36 $uid[] = $db['uid']; 37} 38 39//find the min and max temps in the range and 40//define the scale of the graph to display 41$mintemp = 50; 42$maxtemp = -50; 43for ($i = 0; $i <= $columnRange; $i++) 44{ 45 if ($mintemp > $temperatures[$i]) 46 { 47 $mintemp = $temperatures[$i]; 48 $minTempTime = $timestampsTime[$i]; 49 } 50 51 if ($maxtemp < $temperatures[$i]) 52 { 53 $maxtemp = $temperatures[$i]; 54 $maxTempTime = $timestampsTime[$i]; 55 } 56} 57 58$rangeHigh = $maxtemp + 1; 59$rangeLow = $mintemp - 1; 60 61//calculate the height for each data point 62//I add 50 to keep all values above zero, the difference between amounts remains the same 63//The bars are then displayed as 10px wide and x% high using a single pixel as a base 64//I got my pixel graphics from this site: 1x1px.me 65for ($i = 0; $i <= $columnRange; $i++) 66{ 67 $currentTemp = ($temperatures[$i] + 50) - ($rangeLow + 50); 68 $pixelHeights[$i] = round($currentTemp / (($rangeHigh + 50) - ($rangeLow + 50)) * 100); 69} 70 71 72//pressure calculations, same as temperature 73$minpress = 150; 74$maxpress = 50; 75for ($i = 0; $i <= $columnRange; $i++) 76{ 77 if ($minpress > $pressure[$i]) 78 { 79 $minpress = $pressure[$i]; 80 $minPressTime = $timestampsTime[$i]; 81 } 82 83 if ($maxpress < $pressure[$i]) 84 { 85 $maxpress = $pressure[$i]; 86 $maxPressTime = $timestampsTime[$i]; 87 } 88} 89 90$rangeHighP = $maxpress + 1; 91$rangeLowP = $minpress - 1; 92 93$pressureChange = $pressure[0] - $pressure[$columnRange]; 94 95for ($i = 0; $i <= $columnRange; $i++) 96{ 97 $currentPressure = $pressure[$i] - $rangeLowP; 98 $pixelHeightsP[$i] = round($currentPressure / ($rangeHighP - $rangeLowP) * 100); 99} 100 101//calculate rates of change for temperature and pressure 102$rateOfChangePressure1 = ($pressure[0] - $pressure[5]); 103$rateOfChangePressure3 = ($pressure[0] - $pressure[$columnRange]) / 3; 104$rateOfChangeTemp1 = ($temperatures[0] - $temperatures[5]); 105 106//determines the rising/falling/equality graphic 107//graphics came from flaticon.com/authors/elegant-themes 108function showArrowGraphic($val) { 109 110 if ($val > 0) 111 { 112 $arrowGraphic = 'up-sign.png'; 113 } 114 elseif ($val < 0) 115 { 116 $arrowGraphic = 'down-arrow-outline.png'; 117 } 118 else 119 { 120 $arrowGraphic = 'up-and-down-arrow.png'; 121 } 122 return $arrowGraphic; 123 124} 125 126 127 128/* 129All calculations are done above so HTML output starts after the closing PHP tag 130From this point on, PHP is interspersed as needed 131*/ 132?> 133 134 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 135 136<html> 137<head> 138<title>LAN WeatherStation v.1</title> 139</head> 140 141<body> 142<h1>LAN WeatherStation v.1</h1> 143<h2>Current conditions:</h2> 144 145<!-- Summary table --> 146 147<table> 148 <tr> 149 <td width='200'><b>Temperature:</b></td><td><?php echo round($temperatures[0], 1); ?> °C</td> 150 </tr> 151 <tr> 152 <td><b>Barometric pressure:</b> </td><td><?php echo round($pressure[0], 2); ?> kPa 153 <img src='<?php echo $arrow = showArrowGraphic($pressureChange); ?>' alt='arrow'></td> 154 </tr> 155 <tr> 156 <td><b>Relative humidity:</b></td><td><?php echo round($humidity[0], 1); ?> %</td> 157 </tr> 158 <tr> 159 <td valign='bottom' height='25'><b>°C rate of change (1 hr)</b></td><td valign='bottom' height='25'><?php echo round($rateOfChangeTemp1, 1); ?> °C/hr 160 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangeTemp1); ?>' alt='arrow'></td> 161 </tr> 162 <tr> 163 <td><b>kPa rate of change (1 hr)</b></td><td><?php echo round($rateOfChangePressure1, 2); ?> kPa/hr 164 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangePressure1); ?>' alt='arrow'></td> 165 </tr> 166 <tr> 167 <td><b>kPa rate of change (3 hrs)</b></td><td><?php echo round($rateOfChangePressure3, 2); ?> kPa/hr 168 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangePressure3); ?>' alt='arrow'></td> 169 </tr> 170 <tr> 171 <td valign='bottom' height='25' colspan='2'>Last updated at <?php echo $timestampsTime[0]; ?></td> 172 </tr> 173</table> 174 175 176<br> 177 178<!-- Temperature trend --> 179 180<table style='border: 1px solid black;'> 181 <tr> 182 <td colspan='20'><b>Temperature trend (past 3 hours)</b></td> 183 </tr> 184 <tr> 185 <td colspan='20'> </td> 186 </tr> 187 <tr> 188 <td width='150'> 189 <b>Current:</b> <?php echo round($temperatures[0], 1); ?> °C <br> 190 <b style='color:red'>High:</b> <?php echo round($maxtemp, 1); ?> °C <br> 191 <b style='color:blue'>Low:</b> <?php echo round($mintemp, 1); ?> °C 192 </td> 193 <!-- add empty column for spacing --> 194 <td width='10'> 195 196 </td> 197 198 <?php 199 200 //Here we loop over the array of temperature values. 201 //The corresponding values for pixelHeights is at the same index in its array so we stretch our single pixel 202 //graphic to be 10px wide and $pixelHeights[x] high 203 //We also determine which column will be high and low for the range and set the colours accordingly 204 for ($i = 0; $i <= $columnRange; $i++) 205 { 206 if ($temperatures[$i] == $maxtemp) 207 { 208 echo "<td valign='bottom'><img src='red.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 209"; 210 } 211 elseif ($temperatures[$i] == $mintemp) 212 { 213 echo "<td valign='bottom'><img src='blue.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 214"; 215 } 216 else 217 { 218 echo "<td valign='bottom'><img src='black.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 219"; 220 } 221 } 222 ?> 223 224 </tr> 225 <tr> 226 <td colspan='2'> </td> 227 <td colspan='9'><img src='up-sign.png' width='12' alt='arrow'> <?php echo $timestampsTime[0]; ?></td> 228 <td colspan='9' align='right'><?php echo $timestampsTime[$columnRange]; ?> <img src='up-sign.png' width='12' alt='arrow'></td> 229 </tr> 230</table> 231 232 233<br> 234 235<!-- Barometric trend --> 236 237<table style='border: 1px solid black;' > 238 <tr> 239 <td colspan='20'><b>Barometric pressure trend (past 3 hours)</b></td> 240 </tr> 241 <tr> 242 <td colspan='20'> </td> 243 </tr> 244 <tr> 245 <td width='150'> 246 <b>Current:</b> <?php echo round($pressure[0], 2); ?> kPa <br> 247 <b style='color:red'>High:</b> <?php echo round($maxpress, 2); ?> kPa <br> 248 <b style='color:blue'>Low:</b> <?php echo round($minpress, 2); ?> kPa 249 </td> 250 <!-- add empty column for spacing --> 251 <td width='10'> 252 253 </td> 254 255 <?php 256 257 //same as for temperature above 258 for ($i = 0; $i <= $columnRange; $i++) 259 { 260 if ($pressure[$i] == $maxpress) 261 { 262 echo "<td valign='bottom'><img src='red.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 263"; 264 } 265 elseif ($pressure[$i] == $minpress) 266 { 267 echo "<td valign='bottom'><img src='blue.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 268"; 269 } 270 else 271 { 272 echo "<td valign='bottom'><img src='black.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 273"; 274 } 275 } 276 ?> 277 278 </tr> 279 <tr> 280 <td colspan='2'> </td> 281 <td colspan='9'><img src='up-sign.png' width='12' alt='arrow'> <?php echo $timestampsTime[0]; ?></td> 282 <td colspan='9' align='right'><?php echo $timestampsTime[$columnRange]; ?> <img src='up-sign.png' width='12' alt='arrow'></td> 283 </tr> 284</table> 285 286</body> 287</html>
processincoming.php
php
This is the script that processes incoming data.
1<?php 2 3//establish a link to the database 4$link = mysqli_connect("127.0.0.1", "username", "password", "weatherdata"); 5 6//grab the values sent in the GET request 7$temp = round($_GET['t'], 1); 8$press = round($_GET['p'], 2); 9$hum = round($_GET['h'], 1); 10 11 12//this is the query string to send to mysql. the now() function will record the system datetime in the timestamp field 13//a sensible person would be sanitizing his or her inputs before doing this 14$query = "INSERT INTO master (timestamp, temperature, pressure, humidity) VALUES (NOW(), '$temp', '$press', '$hum')"; 15 16//execute the query/commit to the db 17$result = mysqli_query($link, $query); 18 19//close the connection 20mysqli_close($link); 21 22?>
WeatherStation_v1_webclient_no_lcd.ino
arduino
Slimmed down version with no LCD output. For smaller memory boards.
1#include <Wire.h> 2#include <dht.h> 3#include "i2c.h" 4#include "i2c_BMP280.h" 5#include <SPI.h> 6#include <Ethernet.h> 7 8dht DHT; 9BMP280 bmp280; 10 11//specify the temp sensor 12#define DHTTYPE DHT22; 13#define DHT22_PIN 6 14 15float currentTemp; 16float currentHumid; 17 18float baroPressure; 19float currentPressure; 20 21//engineeringtoolbox.com/barometers-elevation-compensation-d_1812.html 22float altitudeAdjustment = 1; 23 24//ethernet client vars 25IPAddress server(192,168,1,35); 26IPAddress ip(192, 168, 1, 36); //in case of DHCP failure 27IPAddress myDns(192, 168, 1, 1); 28EthernetClient client; 29 30byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 31String urlString; 32String temperatureToDB; 33String pressureToDB; 34String humidityToDB; 35 36 37 38void setup() { 39 40 Serial.begin(9600); 41 42 //wait for sensors to be ready 43 delay(3000); 44 45 //Check if BMP 280 is ready 46 if (bmp280.initialize()) 47 { 48 Serial.println("Barometer ready"); 49 } 50 else 51 { 52 Serial.println("Barometer error"); 53 } 54 55 //check if DHT22 is ready 56 int chk = DHT.read22(DHT22_PIN); 57 switch (chk) 58 { 59 case DHTLIB_OK: 60 Serial.println("Temp sensor ready"); 61 break; 62 63 case DHTLIB_ERROR_CHECKSUM: 64 Serial.println("Temp checksum error"); 65 break; 66 67 case DHTLIB_ERROR_TIMEOUT: 68 Serial.println("Temp timeout"); 69 break; 70 71 default: 72 Serial.println("Temp sensor error"); 73 break; 74 } 75 76 bmp280.setEnabled(0); 77 bmp280.triggerMeasurement(); 78 79 DHT.read22(DHT22_PIN); 80 81 if (Ethernet.begin(mac) == 0) 82 { 83 Serial.print("Failed to configure Ethernet using DHCP"); 84 // Check for Ethernet hardware present 85 if (Ethernet.hardwareStatus() == EthernetNoHardware) 86 { 87 Serial.println("Ethernet shield not found"); 88 //show failure flag 89 } 90 91 if (Ethernet.linkStatus() == LinkOFF) 92 { 93 Serial.println("Ethernet cable not connected."); 94 } 95 96 // try to congifure using IP address instead of DHCP: 97 Ethernet.begin(mac, ip, myDns); 98 } 99 else 100 { 101 Serial.print("Got IP via DHCP: "); 102 Serial.println(Ethernet.localIP()); 103 } 104 105 //wait for sensors again 106 delay(3000); 107} 108 109void loop() { 110 111 bmp280.triggerMeasurement(); 112 bmp280.getPressure(baroPressure); 113 114 DHT.read22(DHT22_PIN); 115 currentTemp = DHT.temperature; 116 currentHumid = DHT.humidity; 117 118 currentPressure = (baroPressure / 1000) + altitudeAdjustment; //output kPa 119 120 //build the string to send to the server 121 temperatureToDB = currentTemp; 122 pressureToDB = currentPressure; 123 humidityToDB = currentHumid; 124 125 //send the data 126 urlString = "GET /processincoming.php?t=" + temperatureToDB + "&p=" + pressureToDB + "&h=" + humidityToDB + " HTTP/1.1"; 127 sendDataToServer(urlString); 128 129 //wait 10 minutes 130 for (int i = 0; i < 599; i++) 131 { 132 delay (1000); 133 } 134} 135 136void sendDataToServer(String stringToSend) 137{ 138 Serial.println(stringToSend); 139 if (client.connect(server, 80)) 140 { 141 client.println(stringToSend); 142 client.println("Host: 192.168.1.35"); 143 client.println("Connection: close"); 144 client.println(); 145 } 146 else 147 { 148 Serial.println("connection failed"); 149 } 150} 151
processincoming.php
php
This is the script that processes incoming data.
1<?php 2 3//establish a link to the database 4$link = mysqli_connect("127.0.0.1", 5 "username", "password", "weatherdata"); 6 7//grab the values sent in the 8 GET request 9$temp = round($_GET['t'], 1); 10$press = round($_GET['p'], 2); 11$hum 12 = round($_GET['h'], 1); 13 14 15//this is the query string to send to mysql. 16 the now() function will record the system datetime in the timestamp field 17//a 18 sensible person would be sanitizing his or her inputs before doing this 19$query 20 = "INSERT INTO master (timestamp, temperature, pressure, humidity) VALUES (NOW(), 21 '$temp', '$press', '$hum')"; 22 23//execute the query/commit to the db 24$result 25 = mysqli_query($link, $query); 26 27//close the connection 28mysqli_close($link); 29 30?>
WeatherStation_v1_webclient_no_lcd.ino
arduino
Slimmed down version with no LCD output. For smaller memory boards.
1#include <Wire.h> 2#include <dht.h> 3#include "i2c.h" 4#include "i2c_BMP280.h" 5#include <SPI.h> 6#include <Ethernet.h> 7 8dht DHT; 9BMP280 bmp280; 10 11//specify the temp sensor 12#define DHTTYPE DHT22; 13#define DHT22_PIN 6 14 15float currentTemp; 16float currentHumid; 17 18float baroPressure; 19float currentPressure; 20 21//engineeringtoolbox.com/barometers-elevation-compensation-d_1812.html 22float altitudeAdjustment = 1; 23 24//ethernet client vars 25IPAddress server(192,168,1,35); 26IPAddress ip(192, 168, 1, 36); //in case of DHCP failure 27IPAddress myDns(192, 168, 1, 1); 28EthernetClient client; 29 30byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 31String urlString; 32String temperatureToDB; 33String pressureToDB; 34String humidityToDB; 35 36 37 38void setup() { 39 40 Serial.begin(9600); 41 42 //wait for sensors to be ready 43 delay(3000); 44 45 //Check if BMP 280 is ready 46 if (bmp280.initialize()) 47 { 48 Serial.println("Barometer ready"); 49 } 50 else 51 { 52 Serial.println("Barometer error"); 53 } 54 55 //check if DHT22 is ready 56 int chk = DHT.read22(DHT22_PIN); 57 switch (chk) 58 { 59 case DHTLIB_OK: 60 Serial.println("Temp sensor ready"); 61 break; 62 63 case DHTLIB_ERROR_CHECKSUM: 64 Serial.println("Temp checksum error"); 65 break; 66 67 case DHTLIB_ERROR_TIMEOUT: 68 Serial.println("Temp timeout"); 69 break; 70 71 default: 72 Serial.println("Temp sensor error"); 73 break; 74 } 75 76 bmp280.setEnabled(0); 77 bmp280.triggerMeasurement(); 78 79 DHT.read22(DHT22_PIN); 80 81 if (Ethernet.begin(mac) == 0) 82 { 83 Serial.print("Failed to configure Ethernet using DHCP"); 84 // Check for Ethernet hardware present 85 if (Ethernet.hardwareStatus() == EthernetNoHardware) 86 { 87 Serial.println("Ethernet shield not found"); 88 //show failure flag 89 } 90 91 if (Ethernet.linkStatus() == LinkOFF) 92 { 93 Serial.println("Ethernet cable not connected."); 94 } 95 96 // try to congifure using IP address instead of DHCP: 97 Ethernet.begin(mac, ip, myDns); 98 } 99 else 100 { 101 Serial.print("Got IP via DHCP: "); 102 Serial.println(Ethernet.localIP()); 103 } 104 105 //wait for sensors again 106 delay(3000); 107} 108 109void loop() { 110 111 bmp280.triggerMeasurement(); 112 bmp280.getPressure(baroPressure); 113 114 DHT.read22(DHT22_PIN); 115 currentTemp = DHT.temperature; 116 currentHumid = DHT.humidity; 117 118 currentPressure = (baroPressure / 1000) + altitudeAdjustment; //output kPa 119 120 //build the string to send to the server 121 temperatureToDB = currentTemp; 122 pressureToDB = currentPressure; 123 humidityToDB = currentHumid; 124 125 //send the data 126 urlString = "GET /processincoming.php?t=" + temperatureToDB + "&p=" + pressureToDB + "&h=" + humidityToDB + " HTTP/1.1"; 127 sendDataToServer(urlString); 128 129 //wait 10 minutes 130 for (int i = 0; i < 599; i++) 131 { 132 delay (1000); 133 } 134} 135 136void sendDataToServer(String stringToSend) 137{ 138 Serial.println(stringToSend); 139 if (client.connect(server, 80)) 140 { 141 client.println(stringToSend); 142 client.println("Host: 192.168.1.35"); 143 client.println("Connection: close"); 144 client.println(); 145 } 146 else 147 { 148 Serial.println("connection failed"); 149 } 150} 151
weather.php
php
This is the page which displays the information. Bring it up by typing IP_ADDRESS\weather.php in your browser.
1<?php 2 3$link = mysqli_connect("127.0.0.1", "username", "password", "weatherdata"); 4 5//in the query I want to split the contents of the timestamp field and just take the time portion 6//$query = "SELECT CONCAT(HOUR(timestamp), ':', MINUTE(timestamp)) as dbTime, temperature, pressure, humidity FROM master ORDER BY uid DESC LIMIT 24"; 7$query = "SELECT uid, TIME(timestamp) as dbTime, temperature, pressure, humidity FROM master ORDER BY uid DESC LIMIT 24"; 8 9//query above is executed 10//i'm not doing any error checking' 11$result = mysqli_query($link, $query); 12 13//declare arrays 14//not really necessary 15$timestamps = array(); 16$temperatures = array(); 17$pressure = array(); 18$humidity = array(); 19$pixelHeights = array(); 20$pixelHeightsP = array(); 21 22//18 cols @ 10 min intervals = 3 hrs, indexed from 0 23$columnRange = 17; 24 25//dump the db results into separate arrays so we can use them later 26while ($db = mysqli_fetch_array($result)) 27{ 28 //chop off the seconds portion of the time value 29 $pieces = explode(':', $db['dbTime']); 30 $formattedTime = $pieces[0] . ':' . $pieces[1]; 31 32 $timestampsTime[] = $formattedTime; 33 $temperatures[] = $db['temperature']; 34 $pressure[] = $db['pressure']; 35 $humidity[] = $db['humidity']; 36 $uid[] = $db['uid']; 37} 38 39//find the min and max temps in the range and 40//define the scale of the graph to display 41$mintemp = 50; 42$maxtemp = -50; 43for ($i = 0; $i <= $columnRange; $i++) 44{ 45 if ($mintemp > $temperatures[$i]) 46 { 47 $mintemp = $temperatures[$i]; 48 $minTempTime = $timestampsTime[$i]; 49 } 50 51 if ($maxtemp < $temperatures[$i]) 52 { 53 $maxtemp = $temperatures[$i]; 54 $maxTempTime = $timestampsTime[$i]; 55 } 56} 57 58$rangeHigh = $maxtemp + 1; 59$rangeLow = $mintemp - 1; 60 61//calculate the height for each data point 62//I add 50 to keep all values above zero, the difference between amounts remains the same 63//The bars are then displayed as 10px wide and x% high using a single pixel as a base 64//I got my pixel graphics from this site: 1x1px.me 65for ($i = 0; $i <= $columnRange; $i++) 66{ 67 $currentTemp = ($temperatures[$i] + 50) - ($rangeLow + 50); 68 $pixelHeights[$i] = round($currentTemp / (($rangeHigh + 50) - ($rangeLow + 50)) * 100); 69} 70 71 72//pressure calculations, same as temperature 73$minpress = 150; 74$maxpress = 50; 75for ($i = 0; $i <= $columnRange; $i++) 76{ 77 if ($minpress > $pressure[$i]) 78 { 79 $minpress = $pressure[$i]; 80 $minPressTime = $timestampsTime[$i]; 81 } 82 83 if ($maxpress < $pressure[$i]) 84 { 85 $maxpress = $pressure[$i]; 86 $maxPressTime = $timestampsTime[$i]; 87 } 88} 89 90$rangeHighP = $maxpress + 1; 91$rangeLowP = $minpress - 1; 92 93$pressureChange = $pressure[0] - $pressure[$columnRange]; 94 95for ($i = 0; $i <= $columnRange; $i++) 96{ 97 $currentPressure = $pressure[$i] - $rangeLowP; 98 $pixelHeightsP[$i] = round($currentPressure / ($rangeHighP - $rangeLowP) * 100); 99} 100 101//calculate rates of change for temperature and pressure 102$rateOfChangePressure1 = ($pressure[0] - $pressure[5]); 103$rateOfChangePressure3 = ($pressure[0] - $pressure[$columnRange]) / 3; 104$rateOfChangeTemp1 = ($temperatures[0] - $temperatures[5]); 105 106//determines the rising/falling/equality graphic 107//graphics came from flaticon.com/authors/elegant-themes 108function showArrowGraphic($val) { 109 110 if ($val > 0) 111 { 112 $arrowGraphic = 'up-sign.png'; 113 } 114 elseif ($val < 0) 115 { 116 $arrowGraphic = 'down-arrow-outline.png'; 117 } 118 else 119 { 120 $arrowGraphic = 'up-and-down-arrow.png'; 121 } 122 return $arrowGraphic; 123 124} 125 126 127 128/* 129All calculations are done above so HTML output starts after the closing PHP tag 130From this point on, PHP is interspersed as needed 131*/ 132?> 133 134 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 135 136<html> 137<head> 138<title>LAN WeatherStation v.1</title> 139</head> 140 141<body> 142<h1>LAN WeatherStation v.1</h1> 143<h2>Current conditions:</h2> 144 145<!-- Summary table --> 146 147<table> 148 <tr> 149 <td width='200'><b>Temperature:</b></td><td><?php echo round($temperatures[0], 1); ?> °C</td> 150 </tr> 151 <tr> 152 <td><b>Barometric pressure:</b> </td><td><?php echo round($pressure[0], 2); ?> kPa 153 <img src='<?php echo $arrow = showArrowGraphic($pressureChange); ?>' alt='arrow'></td> 154 </tr> 155 <tr> 156 <td><b>Relative humidity:</b></td><td><?php echo round($humidity[0], 1); ?> %</td> 157 </tr> 158 <tr> 159 <td valign='bottom' height='25'><b>°C rate of change (1 hr)</b></td><td valign='bottom' height='25'><?php echo round($rateOfChangeTemp1, 1); ?> °C/hr 160 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangeTemp1); ?>' alt='arrow'></td> 161 </tr> 162 <tr> 163 <td><b>kPa rate of change (1 hr)</b></td><td><?php echo round($rateOfChangePressure1, 2); ?> kPa/hr 164 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangePressure1); ?>' alt='arrow'></td> 165 </tr> 166 <tr> 167 <td><b>kPa rate of change (3 hrs)</b></td><td><?php echo round($rateOfChangePressure3, 2); ?> kPa/hr 168 <img src='<?php echo $arrow = showArrowGraphic($rateOfChangePressure3); ?>' alt='arrow'></td> 169 </tr> 170 <tr> 171 <td valign='bottom' height='25' colspan='2'>Last updated at <?php echo $timestampsTime[0]; ?></td> 172 </tr> 173</table> 174 175 176<br> 177 178<!-- Temperature trend --> 179 180<table style='border: 1px solid black;'> 181 <tr> 182 <td colspan='20'><b>Temperature trend (past 3 hours)</b></td> 183 </tr> 184 <tr> 185 <td colspan='20'> </td> 186 </tr> 187 <tr> 188 <td width='150'> 189 <b>Current:</b> <?php echo round($temperatures[0], 1); ?> °C <br> 190 <b style='color:red'>High:</b> <?php echo round($maxtemp, 1); ?> °C <br> 191 <b style='color:blue'>Low:</b> <?php echo round($mintemp, 1); ?> °C 192 </td> 193 <!-- add empty column for spacing --> 194 <td width='10'> 195 196 </td> 197 198 <?php 199 200 //Here we loop over the array of temperature values. 201 //The corresponding values for pixelHeights is at the same index in its array so we stretch our single pixel 202 //graphic to be 10px wide and $pixelHeights[x] high 203 //We also determine which column will be high and low for the range and set the colours accordingly 204 for ($i = 0; $i <= $columnRange; $i++) 205 { 206 if ($temperatures[$i] == $maxtemp) 207 { 208 echo "<td valign='bottom'><img src='red.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 209"; 210 } 211 elseif ($temperatures[$i] == $mintemp) 212 { 213 echo "<td valign='bottom'><img src='blue.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 214"; 215 } 216 else 217 { 218 echo "<td valign='bottom'><img src='black.png' height='" . $pixelHeights[$i] . "' width='10' alt='pixel'></td> \ 219"; 220 } 221 } 222 ?> 223 224 </tr> 225 <tr> 226 <td colspan='2'> </td> 227 <td colspan='9'><img src='up-sign.png' width='12' alt='arrow'> <?php echo $timestampsTime[0]; ?></td> 228 <td colspan='9' align='right'><?php echo $timestampsTime[$columnRange]; ?> <img src='up-sign.png' width='12' alt='arrow'></td> 229 </tr> 230</table> 231 232 233<br> 234 235<!-- Barometric trend --> 236 237<table style='border: 1px solid black;' > 238 <tr> 239 <td colspan='20'><b>Barometric pressure trend (past 3 hours)</b></td> 240 </tr> 241 <tr> 242 <td colspan='20'> </td> 243 </tr> 244 <tr> 245 <td width='150'> 246 <b>Current:</b> <?php echo round($pressure[0], 2); ?> kPa <br> 247 <b style='color:red'>High:</b> <?php echo round($maxpress, 2); ?> kPa <br> 248 <b style='color:blue'>Low:</b> <?php echo round($minpress, 2); ?> kPa 249 </td> 250 <!-- add empty column for spacing --> 251 <td width='10'> 252 253 </td> 254 255 <?php 256 257 //same as for temperature above 258 for ($i = 0; $i <= $columnRange; $i++) 259 { 260 if ($pressure[$i] == $maxpress) 261 { 262 echo "<td valign='bottom'><img src='red.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 263"; 264 } 265 elseif ($pressure[$i] == $minpress) 266 { 267 echo "<td valign='bottom'><img src='blue.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 268"; 269 } 270 else 271 { 272 echo "<td valign='bottom'><img src='black.png' height='" . $pixelHeightsP[$i] . "' width='10' alt='pixel'></td> \ 273"; 274 } 275 } 276 ?> 277 278 </tr> 279 <tr> 280 <td colspan='2'> </td> 281 <td colspan='9'><img src='up-sign.png' width='12' alt='arrow'> <?php echo $timestampsTime[0]; ?></td> 282 <td colspan='9' align='right'><?php echo $timestampsTime[$columnRange]; ?> <img src='up-sign.png' width='12' alt='arrow'></td> 283 </tr> 284</table> 285 286</body> 287</html>
WeatherStation_20x4_v1_webclient.ino
arduino
Full version with LCD output
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#include <SPI.h> 8#include <Ethernet.h> 9 10dht DHT; 11BMP280 bmp280; 12 13//specify the temp sensor 14#define DHTTYPE DHT22; 15#define DHT22_PIN 6 16 17#define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is 18#define BACKLIGHT_PIN 3 19#define En_pin 2 20#define Rw_pin 1 21#define Rs_pin 0 22#define D4_pin 4 23#define D5_pin 5 24#define D6_pin 6 25#define D7_pin 7 26 27LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin); 28 29//total delay = (lcdDelayScreen1 + lcdDelayScreen2 + lcdDelayScreen3) * loopCount (in seconds) 30int lcdDelayScreen1 = 44; //seconds displaying primary info 31int lcdDelayScreen2 = 8; //seconds displaying secondary info 32int lcdDelayScreen3 = 8; //seconds displaying secondary info 33 34//these all have to match 35int loopCount = 60; //total loops 36float dataPointT[60]; //temperature data points 37float dataPointB[60]; //pressure data points 38 39int mainLoop; //primary loop 40int loopBaroGraph; //secondary loop 41int loopTempGraph; //secondary loop 42 43float currentTemp; 44float currentHumid; 45 46float baroPressure; 47float currentPressure; 48 49float tempDifference = 0; 50float tempValueComparative; 51 52int offset; 53int mt; 54int mp; 55 56float pressDifference = 0; 57float pressValueComparative; 58 59//engineeringtoolbox.com/barometers-elevation-compensation-d_1812.html 60float altitudeAdjustment = 1; 61 62float minTemp; 63float maxTemp; 64float minPressure; 65float maxPressure; 66 67int rangeLowGraph; 68int rangeHighGraph; 69 70float percentOfCol; 71float pixelHeightPercent; 72int pixelHeight; 73 74bool firstLoopComplete = false; 75 76//ethernet client vars 77IPAddress server(192,168,1,35); 78IPAddress ip(192, 168, 1, 250); 79IPAddress myDns(192, 168, 1, 1); 80EthernetClient client; 81byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 82String urlString; 83String temperatureToDB; 84String pressureToDB; 85String humidityToDB; 86 87 88//define characters for temperature indicators 89byte arrowUp[8] = { 90 B00100, 91 B01110, 92 B10101, 93 B00100, 94 B00100, 95 B00100, 96 B00100, 97 B00100, 98}; 99 100byte arrowDown[8] = { 101 B00100, 102 B00100, 103 B00100, 104 B00100, 105 B00100, 106 B10101, 107 B01110, 108 B00100, 109}; 110 111byte equalSign[8] = { 112 B00100, 113 B01110, 114 B10101, 115 B00100, 116 B00100, 117 B10101, 118 B01110, 119 B00100, 120}; 121 122byte row1[8] = { 123 B00000, 124 B00000, 125 B00000, 126 B00000, 127 B00000, 128 B00000, 129 B00000, 130 B11111, 131}; 132 133byte row2[8] = { 134 B00000, 135 B00000, 136 B00000, 137 B00000, 138 B00000, 139 B00000, 140 B11111, 141 B11111, 142}; 143 144byte row3[8] = { 145 B00000, 146 B00000, 147 B00000, 148 B00000, 149 B00000, 150 B11111, 151 B11111, 152 B11111, 153}; 154 155byte row4[8] = { 156 B00000, 157 B00000, 158 B00000, 159 B00000, 160 B11111, 161 B11111, 162 B11111, 163 B11111, 164}; 165 166byte row5[8] = { 167 B00000, 168 B00000, 169 B00000, 170 B11111, 171 B11111, 172 B11111, 173 B11111, 174 B11111, 175}; 176 177byte row6[8] = { 178 B00000, 179 B00000, 180 B11111, 181 B11111, 182 B11111, 183 B11111, 184 B11111, 185 B11111, 186}; 187 188byte row7[8] = { 189 B00000, 190 B11111, 191 B11111, 192 B11111, 193 B11111, 194 B11111, 195 B11111, 196 B11111, 197}; 198 199byte row8[8] = { 200 B11111, 201 B11111, 202 B11111, 203 B11111, 204 B11111, 205 B11111, 206 B11111, 207 B11111, 208}; 209 210void setup() { 211 212 int setupLoop; 213 bool dotPosition = true; 214 215 Serial.begin(9600); 216 217 lcd.begin (20,4); 218 219 //Switch on the backlight 220 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); 221 lcd.setBacklight(HIGH); 222 lcd.home (); 223 224 //delay a few seconds so the sensors are ready 225 for (setupLoop = 1; setupLoop < 8; setupLoop++) 226 { 227 lcd.clear(); 228 229 if (dotPosition) 230 { 231 lcd.print("Initializing ."); 232 lcd.setCursor(0, 1); 233 lcd.print("WeatherStation v.1"); 234 235 } 236 else 237 { 238 lcd.print("Initializing ."); 239 lcd.setCursor(0, 1); 240 lcd.print("WeatherStation v.1"); 241 } 242 243 dotPosition = !dotPosition; 244 delay(500); 245 } 246 247 //Check if BMP 280 is ready 248 lcd.setCursor(0, 2); 249 if (bmp280.initialize()) 250 { 251 lcd.print("Barometer ready"); 252 } 253 else 254 { 255 lcd.print("Barometer error"); 256 } 257 258 lcd.setCursor(0, 3); 259 260 //check if DHT22 is ready 261 int chk = DHT.read22(DHT22_PIN); 262 switch (chk) 263 { 264 case DHTLIB_OK: 265 lcd.print("Temp sensor ready"); 266 break; 267 268 case DHTLIB_ERROR_CHECKSUM: 269 lcd.print("Temp checksum error"); 270 break; 271 272 case DHTLIB_ERROR_TIMEOUT: 273 lcd.print("Temp timeout"); 274 break; 275 276 default: 277 lcd.print("Temp sensor error"); 278 break; 279 } 280 281 //leave info on screen long enough 282 delay(2000); 283 284 bmp280.setEnabled(0); 285 bmp280.triggerMeasurement(); 286 287 bmp280.awaitMeasurement(); 288 bmp280.getPressure(baroPressure); 289 DHT.read22(DHT22_PIN); 290 291 //populate baseline datapoints with startup values 292 int p; 293 for (p = 0; p <= loopCount - 1; p++) 294 { 295 dataPointT[p] = DHT.temperature; 296 dataPointB[p] = (baroPressure / 1000) + altitudeAdjustment; 297 } 298 299 300 lcd.clear(); 301 if (Ethernet.begin(mac) == 0) 302 { 303 lcd.print("Failed to configure Ethernet using DHCP"); 304 // Check for Ethernet hardware present 305 if (Ethernet.hardwareStatus() == EthernetNoHardware) 306 { 307 lcd.println("Ethernet shield not found"); 308 //show failure flag 309 } 310 311 if (Ethernet.linkStatus() == LinkOFF) 312 { 313 lcd.print("Ethernet cable not connected."); 314 } 315 316 // try to congifure using IP address instead of DHCP: 317 Ethernet.begin(mac, ip, myDns); 318 } 319 else 320 { 321 lcd.print("Got IP via DHCP:"); 322 lcd.setCursor(0, 1); 323 lcd.print(Ethernet.localIP()); 324 } 325 326 //keep display up 327 delay(2000); 328} 329 330void loop() { 331 332 for (mainLoop = 0; mainLoop <= loopCount - 1; mainLoop++) 333 { 334 bmp280.awaitMeasurement(); 335 336 DHT.read22(DHT22_PIN); 337 currentTemp = DHT.temperature; 338 currentHumid = DHT.humidity; 339 340 bmp280.getPressure(baroPressure); 341 bmp280.triggerMeasurement(); 342 currentPressure = (baroPressure / 1000) + altitudeAdjustment; 343 344 //read and store the array value before overwriting it 345 tempValueComparative = dataPointT[mainLoop]; 346 dataPointT[mainLoop] = currentTemp; 347 tempDifference = currentTemp - tempValueComparative; 348 349 pressValueComparative = dataPointB[mainLoop]; 350 dataPointB[mainLoop] = currentPressure; 351 pressDifference = currentPressure - pressValueComparative; 352 353 //create lcd chars defined above 354 lcd.createChar(0, arrowUp); 355 lcd.createChar(1, arrowDown); 356 lcd.createChar(2, equalSign); 357 358 //LCD Output begin 359 lcd.clear(); 360 lcd.print(currentTemp, 1); 361 lcd.print((char)223); 362 lcd.print("C "); 363 364 //determine which trend indicator to display 365 showTrendIndicator(tempDifference); 366 367 lcd.print(" "); 368 369 //then display the temperature diff 370 lcd.print(tempDifference); 371 372 //move to the next line and display humidity 373 lcd.setCursor(0, 1); 374 lcd.print(currentPressure, 1); 375 lcd.print(" kPa "); 376 377 showTrendIndicator(pressDifference); 378 379 lcd.print(" "); 380 381 lcd.print(pressDifference); 382 383 lcd.setCursor(0, 2); 384 lcd.print(currentHumid, 1); 385 lcd.print(" % Rel Hum"); 386 387 lcd.setCursor(0, 3); 388 lcd.print("Data age: "); 389 390 //this ensures the 'data age' value displays the max after the first loop completes 391 if (!firstLoopComplete) 392 { 393 if (mainLoop < (loopCount - 1)) 394 { 395 lcd.print(mainLoop); 396 } 397 else 398 { 399 lcd.print(loopCount); 400 firstLoopComplete = true; 401 } 402 } 403 else 404 { 405 lcd.print(loopCount); 406 } 407 408 lcd.print(" m"); 409 410 //send data to server every 10 minutes 411 if ((mainLoop == 0) || (mainLoop % 10 == 0)) 412 { 413 temperatureToDB = currentTemp; 414 pressureToDB = currentPressure; 415 humidityToDB = currentHumid; 416 urlString = "GET /processincoming.php?t=" + temperatureToDB + "&p=" + pressureToDB + "&h=" + humidityToDB + " HTTP/1.1"; 417 sendDataToServer(urlString); 418 } 419 420 //countdown until next screen 421 screenWaitRight(lcdDelayScreen1); 422 423 //+++++++++++++++Screen 1 End+++++++++++++++ 424 425 426 //+++++++++++++++Screen 2 Start+++++++++++++++ 427 428 //bar chart characters 429 lcd.createChar(0, row1); 430 lcd.createChar(1, row2); 431 lcd.createChar(2, row3); 432 lcd.createChar(3, row4); 433 lcd.createChar(4, row5); 434 lcd.createChar(5, row6); 435 lcd.createChar(6, row7); 436 lcd.createChar(7, row8); 437 438 //initialize to something these will never be 439 minTemp = 50; 440 maxTemp = -50; 441 //find min and max temps 442 for (mt = 0; mt <= loopCount - 1; mt++) 443 { 444 //offset value translates a negative result for 'mainLoop - mt' into the appropriate 445 //value in the array sequence 446 offset = getOffsetValue(mainLoop - mt); 447 if (minTemp > dataPointT[offset]) 448 { 449 minTemp = dataPointT[offset]; 450 } 451 } 452 453 for (mt = 0; mt <= loopCount - 1; mt++) 454 { 455 offset = getOffsetValue(mainLoop - mt); 456 if (maxTemp < dataPointT[offset]) 457 { 458 maxTemp = dataPointT[offset]; 459 } 460 } 461 462 //this sets the min/max range that the graph will show 463 rangeLowGraph = minTemp - 1.5; 464 rangeHighGraph = maxTemp + 1.5; 465 466 lcd.clear(); 467 lcd.setCursor(0, 0); 468 lcd.print((char)223); 469 lcd.print("C "); 470 lcd.setCursor(0, 1); 471 lcd.print("H"); 472 lcd.print(maxTemp, 1); 473 lcd.setCursor(0, 2); 474 lcd.print("L"); 475 lcd.print(minTemp, 1); 476 477 for (loopTempGraph = 0; loopTempGraph <= loopCount - 1; loopTempGraph += 4) 478 { 479 offset = getOffsetValue(mainLoop - loopTempGraph); 480 currentTemp = dataPointT[offset]; 481 //i add 50 so the values never go below zero 482 currentTemp = (currentTemp + 50) - (rangeLowGraph + 50); 483 percentOfCol = currentTemp / ((rangeHighGraph + 50) - (rangeLowGraph + 50)); 484 //32 = total pixels vertical 485 pixelHeightPercent = 32 * percentOfCol; 486 pixelHeight = pixelHeightPercent; 487 showGraphColumn(pixelHeight, loopTempGraph / 4); 488 } 489 490 screenWaitLeft(lcdDelayScreen2); 491 492 //+++++++++++++++Screen 2 End+++++++++++++++ 493 494 495 //+++++++++++++++Screen 3 Start+++++++++++++++ 496 497 //initialize to something these will never be 498 minPressure = 250; 499 maxPressure = 75; 500 //find min and max pressure 501 for (mp = 0; mp <= loopCount - 1; mp++) 502 { 503 offset = getOffsetValue(mainLoop - mp); 504 if (minPressure > dataPointB[offset]) 505 { 506 minPressure = dataPointB[offset]; 507 } 508 } 509 510 for (mp = 0; mp <= loopCount - 1; mp++) 511 { 512 offset = getOffsetValue(mainLoop - mp); 513 if (maxPressure < dataPointB[offset]) 514 { 515 maxPressure = dataPointB[offset]; 516 } 517 } 518 519 lcd.clear(); 520 lcd.setCursor(0, 0); 521 lcd.print("kPa"); 522 lcd.setCursor(0, 1); 523 //lcd.print("H"); //doesn't fit on screen :( 524 lcd.print(maxPressure, 1); 525 lcd.setCursor(0, 2); 526 //lcd.print("L"); //doesn't fit on screen :( 527 lcd.print(minPressure, 1); 528 529 for (loopBaroGraph = 0; loopBaroGraph <= loopCount - 1; loopBaroGraph += 4) 530 { 531 offset = getOffsetValue(mainLoop - loopBaroGraph); 532 currentPressure = dataPointB[offset]; 533 currentPressure = currentPressure - (minPressure - 1.5); 534 percentOfCol = currentPressure / ((maxPressure + 1.5) - (minPressure - 1.5)); 535 pixelHeightPercent = 32 * percentOfCol; 536 pixelHeight = pixelHeightPercent; 537 showGraphColumn(pixelHeight, loopBaroGraph / 4); 538 } 539 540 screenWaitLeft(lcdDelayScreen3); 541 542 } //main for loop end 543} 544 545void sendDataToServer(String stringToSend) 546{ 547 Serial.println(stringToSend); 548 if (client.connect(server, 80)) 549 { 550 client.println(stringToSend); 551 client.println("Host: 192.168.1.35"); 552 client.println("Connection: close"); 553 client.println(); 554 } 555 else 556 { 557 // if you didn't get a connection to the server: 558 Serial.println("connection failed"); 559 } 560} 561 562int getOffsetValue(int z) 563{ 564 if (z < 0) 565 { 566 return z + 60; 567 } 568 else 569 { 570 return z; 571 } 572} 573 574void screenWaitRight(int secondsR) 575{ 576 int a; 577 for (a = secondsR; a >= 0; a--) 578 { 579 lcd.setCursor(18, 3); 580 if(a >= 10) 581 { 582 lcd.print(a); 583 } 584 else 585 { 586 lcd.print(" "); 587 lcd.print(a); 588 } 589 delay(1000); 590 } 591} 592 593void screenWaitLeft(int secondsL) 594{ 595 int b; 596 for (b = secondsL; b >= 0; b--) 597 { 598 lcd.setCursor(0, 3); 599 if(b >= 10) 600 { 601 lcd.print(b); 602 } 603 else 604 { 605 lcd.print(b); 606 lcd.print(" "); 607 } 608 delay(1000); 609 } 610} 611 612 613void showTrendIndicator(float val) 614{ 615 if (val > 0) 616 { 617 lcd.write(byte(0)); 618 } 619 else if (val < 0) 620 { 621 lcd.write(byte(1)); 622 } 623 else 624 { 625 lcd.write(byte(2)); 626 } 627} 628 629 630void showGraphColumn(int pixelHeight, int c) 631{ 632 switch (pixelHeight) 633 { 634 case 1: 635 lcd.setCursor(c + 5, 3); 636 lcd.write(byte(0)); 637 break; 638 639 case 2: 640 lcd.setCursor(c + 5, 3); 641 lcd.write(byte(1)); 642 break; 643 644 case 3: 645 lcd.setCursor(c + 5, 3); 646 lcd.write(byte(2)); 647 break; 648 649 case 4: 650 lcd.setCursor(c + 5, 3); 651 lcd.write(byte(3)); 652 break; 653 654 case 5: 655 lcd.setCursor(c + 5, 3); 656 lcd.write(byte(4)); 657 break; 658 659 case 6: 660 lcd.setCursor(c + 5, 3); 661 lcd.write(byte(5)); 662 break; 663 664 case 7: 665 lcd.setCursor(c + 5, 3); 666 lcd.write(byte(6)); 667 break; 668 669 case 8: 670 lcd.setCursor(c + 5, 3); 671 lcd.write(byte(7)); 672 break; 673 674 case 9: 675 lcd.setCursor(c + 5, 3); 676 lcd.write(byte(7)); 677 678 lcd.setCursor(c + 5, 2); 679 lcd.write(byte(0)); 680 break; 681 682 case 10: 683 lcd.setCursor(c + 5, 3); 684 lcd.write(byte(7)); 685 686 lcd.setCursor(c + 5, 2); 687 lcd.write(byte(1)); 688 break; 689 690 case 11: 691 lcd.setCursor(c + 5, 3); 692 lcd.write(byte(7)); 693 694 lcd.setCursor(c + 5, 2); 695 lcd.write(byte(2)); 696 break; 697 698 case 12: 699 lcd.setCursor(c + 5, 3); 700 lcd.write(byte(7)); 701 702 lcd.setCursor(c + 5, 2); 703 lcd.write(byte(3)); 704 break; 705 706 case 13: 707 lcd.setCursor(c + 5, 3); 708 lcd.write(byte(7)); 709 710 lcd.setCursor(c + 5, 2); 711 lcd.write(byte(4)); 712 break; 713 714 case 14: 715 lcd.setCursor(c + 5, 3); 716 lcd.write(byte(7)); 717 718 lcd.setCursor(c + 5, 2); 719 lcd.write(byte(5)); 720 break; 721 722 case 15: 723 lcd.setCursor(c + 5, 3); 724 lcd.write(byte(7)); 725 726 lcd.setCursor(c + 5, 2); 727 lcd.write(byte(6)); 728 break; 729 730 case 16: 731 lcd.setCursor(c + 5, 3); 732 lcd.write(byte(7)); 733 734 lcd.setCursor(c + 5, 2); 735 lcd.write(byte(7)); 736 break; 737 738 case 17: 739 lcd.setCursor(c + 5, 3); 740 lcd.write(byte(7)); 741 742 lcd.setCursor(c + 5, 2); 743 lcd.write(byte(7)); 744 745 lcd.setCursor(c + 5, 1); 746 lcd.write(byte(0)); 747 break; 748 749 case 18: 750 lcd.setCursor(c + 5, 3); 751 lcd.write(byte(7)); 752 753 lcd.setCursor(c + 5, 2); 754 lcd.write(byte(7)); 755 756 lcd.setCursor(c + 5, 1); 757 lcd.write(byte(1)); 758 break; 759 760 case 19: 761 lcd.setCursor(c + 5, 3); 762 lcd.write(byte(7)); 763 764 lcd.setCursor(c + 5, 2); 765 lcd.write(byte(7)); 766 767 lcd.setCursor(c + 5, 1); 768 lcd.write(byte(2)); 769 break; 770 771 case 20: 772 lcd.setCursor(c + 5, 3); 773 lcd.write(byte(7)); 774 775 lcd.setCursor(c + 5, 2); 776 lcd.write(byte(7)); 777 778 lcd.setCursor(c + 5, 1); 779 lcd.write(byte(3)); 780 break; 781 782 case 21: 783 lcd.setCursor(c + 5, 3); 784 lcd.write(byte(7)); 785 786 lcd.setCursor(c + 5, 2); 787 lcd.write(byte(7)); 788 789 lcd.setCursor(c + 5, 1); 790 lcd.write(byte(4)); 791 break; 792 793 case 22: 794 lcd.setCursor(c + 5, 3); 795 lcd.write(byte(7)); 796 797 lcd.setCursor(c + 5, 2); 798 lcd.write(byte(7)); 799 800 lcd.setCursor(c + 5, 1); 801 lcd.write(byte(5)); 802 break; 803 804 case 23: 805 lcd.setCursor(c + 5, 3); 806 lcd.write(byte(7)); 807 808 lcd.setCursor(c + 5, 2); 809 lcd.write(byte(7)); 810 811 lcd.setCursor(c + 5, 1); 812 lcd.write(byte(6)); 813 break; 814 815 case 24: 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 break; 825 826 case 25: 827 lcd.setCursor(c + 5, 3); 828 lcd.write(byte(7)); 829 830 lcd.setCursor(c + 5, 2); 831 lcd.write(byte(7)); 832 833 lcd.setCursor(c + 5, 1); 834 lcd.write(byte(7)); 835 836 lcd.setCursor(c + 5, 0); 837 lcd.write(byte(0)); 838 break; 839 840 case 26: 841 lcd.setCursor(c + 5, 3); 842 lcd.write(byte(7)); 843 844 lcd.setCursor(c + 5, 2); 845 lcd.write(byte(7)); 846 847 lcd.setCursor(c + 5, 1); 848 lcd.write(byte(7)); 849 850 lcd.setCursor(c + 5, 0); 851 lcd.write(byte(1)); 852 break; 853 854 case 27: 855 lcd.setCursor(c + 5, 3); 856 lcd.write(byte(7)); 857 858 lcd.setCursor(c + 5, 2); 859 lcd.write(byte(7)); 860 861 lcd.setCursor(c + 5, 1); 862 lcd.write(byte(7)); 863 864 lcd.setCursor(c + 5, 0); 865 lcd.write(byte(2)); 866 break; 867 868 case 28: 869 lcd.setCursor(c + 5, 3); 870 lcd.write(byte(7)); 871 872 lcd.setCursor(c + 5, 2); 873 lcd.write(byte(7)); 874 875 lcd.setCursor(c + 5, 1); 876 lcd.write(byte(7)); 877 878 lcd.setCursor(c + 5, 0); 879 lcd.write(byte(3)); 880 break; 881 882 case 29: 883 lcd.setCursor(c + 5, 3); 884 lcd.write(byte(7)); 885 886 lcd.setCursor(c + 5, 2); 887 lcd.write(byte(7)); 888 889 lcd.setCursor(c + 5, 1); 890 lcd.write(byte(7)); 891 892 lcd.setCursor(c + 5, 0); 893 lcd.write(byte(4)); 894 break; 895 896 case 30: 897 lcd.setCursor(c + 5, 3); 898 lcd.write(byte(7)); 899 900 lcd.setCursor(c + 5, 2); 901 lcd.write(byte(7)); 902 903 lcd.setCursor(c + 5, 1); 904 lcd.write(byte(7)); 905 906 lcd.setCursor(c + 5, 0); 907 lcd.write(byte(5)); 908 break; 909 910 case 31: 911 lcd.setCursor(c + 5, 3); 912 lcd.write(byte(7)); 913 914 lcd.setCursor(c + 5, 2); 915 lcd.write(byte(7)); 916 917 lcd.setCursor(c + 5, 1); 918 lcd.write(byte(7)); 919 920 lcd.setCursor(c + 5, 0); 921 lcd.write(byte(6)); 922 break; 923 924 case 32: 925 lcd.setCursor(c + 5, 3); 926 lcd.write(byte(7)); 927 928 lcd.setCursor(c + 5, 2); 929 lcd.write(byte(7)); 930 931 lcd.setCursor(c + 5, 1); 932 lcd.write(byte(7)); 933 934 lcd.setCursor(c + 5, 0); 935 lcd.write(byte(7)); 936 break; 937 } 938} 939
Downloadable files
Weather Station v1
Weather Station v1
Weather Station v1
Weather Station v1
Comments
Only logged in users can leave comments
ragingradish
0 Followers
•0 Projects
Table of contents
Intro
16
0