This is the second configuration of the weather station.

Originally the station was housed in a case with a transparent lid to allow light measurement. This was situated on my garage roof. However that behaved like a mini green house and gave, sometimes, extremely high temperature readings.

Now the electronic components are housed in a capped piece of drainage pipe on the side of the garage. There, it should avoid most of the direct sun’s rays.



The components can easily be slid in and out the bottom of the pipe to allow battery changing.



These are the components it is constructed from.

An ESP01 is at the heart of the station. It processes and communicates with the data server, hosted by HostPapa, over the WIFI. Normally an ESP01 has only two input/output pins but the RX pin has been programmed as a third input/output, GPIO3.

An MCP1700 regulates the voltage going into the ESP01 to 3.3V.



Two sensors connect via an I2C bus to the ESP01.
They are a BME280 which measures temperature, air pressure and humidity and a MAX44009 which measures light intensity.

This the layout on a Stripboard.


And this is the motherboard after construction. Pardon my awful soldering. My sight is not what it was and my hands are not as steady as they were. Also you will see an extra link I had to solder in horizontally where I had cut the wrong track!




To be done – the MAX44009 light sensor has to be fixed to a length of cable to be on the roof of the garage. It will be in a housing with a glass cover which will not degrade in sunlight. That is what happened with the previous perspex or plastic housing leading to a decrease in the recorded light intensity.

Acknowledgement – my project is based  on that shown on this this website – Battery Powered Weather Station. It is a very elegant and slightly simpler weather station project. I pinched a lot of the code and ideas from this.

It is a very clever project. Thank you GLSK.

Here is the code for my station.

—————————————————————————————————————

Server side

This PHP script is called up every 15 minutes when the ESP01 wakes and simply loads the data sent from the weather station into a MYSQL database. The voltage being measured is the regulated voltage, so reads 3.3V until the battery is almost depleted. It is not possible to connect the battery voltage to be measured by the ESP01.

<?php
//Creates new record as per request
//Connect to database
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “weatherdata”;
 
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die(“Database Connection failed: ” . $conn->connect_error);
}
 
if(!empty($_POST[‘pres’]) && !empty($_POST[‘temp’]) && !empty($_POST[‘humd’]) && !empty($_POST[‘light’]) && !empty($_POST[‘vcc’]))
{
$pres = $_POST[‘pres’];
$temp = $_POST[‘temp’];
$humd = $_POST[‘humd’];
$light = $_POST[‘light’];
$vcc = $_POST[‘vcc’];
// $vcc = 3.3; for testing
$sql = “INSERT INTO data (pres, temp, humd, light, vcc)
VALUES (‘$pres’, ‘$temp’, ‘$humd’, ‘$light’, ‘$vcc’)”;
 
if ($conn->query($sql) === TRUE) {
echo “OK”;
} else {
echo “Error: ” . $sql . “<br>” . $conn->error;
}
}
 
$conn->close();
if($vcc < “3.2”)
{
$to_email = ‘mail@example.co.uk’;
$subject = ‘Weather Station Alert’;
$message = ‘Battery voltage is low: voltage = ‘. $vcc;
$headers = ‘From: mail@example.co.uk’;
mail($to_email,$subject,$message,$headers);
}
?>



—————————————————————————————————————

ESP01

The ESP01 was programmed using the Arduino IDE and a USB adapter.

// ESP8266 put into Deep-sleep mode
// HTTP Client POST Request
// Send BMP data to server

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>

#include <Wire.h>
#include <MAX44009.h>
#include <Adafruit_BME280.h>

ADC_MODE(ADC_VCC);
MAX44009 light;
Adafruit_BME280 bme;

#define a 94.5 //altitude of station in meters

float p, p0, t, h, l, v;
char p0ch[8], tch[8], hch[8], lch[8], vch[8];
String p0str, tstr, hstr, lstr, vstr;

/* Set these to your desired credentials. */
const char* ssid = “TALKTALK00000”; // Enter SSID here
const char* password = “PPPPPPPP”; //Enter Password here

//Web/Server address to read/write from
const char *host = “65.66.67.68”; // IP address of server

void setup() {
Serial.begin(115200);

pinMode(3, OUTPUT); // Power BME280 and MAX44009 via RX (GPIO3).
digitalWrite(3, HIGH);

Wire.pins(0, 2);
Wire.begin(0, 2);

delay(500);

if(light.begin())
{
Serial.println(“Could not find a valid MAX44009 sensor, check wiring!”);
while(1);
}

if (!bme.begin(0x76)) {
Serial.println(“Could not find a valid BME280 sensor, check wiring!”);
while (1);
}
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA); //This line hides the viewing of ESP as wifi hotspot
WiFi.begin(ssid, password); //Connect to your WiFi router
IPAddress ip(192,168,1,5);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
IPAddress dns(8,8,8,8);
WiFi.config(ip, gateway, subnet, dns);
int i = 0;
while (WiFi.status() != WL_CONNECTED && i<10) // Wait for the Wi-Fi to connect
{
delay(500);
}
if (WiFi.status() == WL_CONNECTED)
{
//=======================================================================
// Main routine to send data to server
//=======================================================================

HTTPClient http; //Declare object of class HTTPClient

String postdata;
p = bme.readPressure();
t = bme.readTemperature();
h = bme.readHumidity();

l = light.get_lux();

//p = 1000;
//t = 20;
//h = 50;

//l = 3000;

digitalWrite(3, LOW);

p = p/100;
p0 = p*pow((1-((0.0065*a)/(t+(0.0065*a)+273.15))),-5.257);

v=ESP.getVcc()/1024.0;

dtostrf(p0, 4, 1, p0ch);
dtostrf(t, 4, 1, tch);
dtostrf(h, 4, 1, hch);
dtostrf(l, 4, 1, lch);
dtostrf(v, 4, 1, vch);

p0str = String(p0ch);
tstr = String(tch);
hstr = String(hch);
lstr = String(lch);
vstr = String(vch);


//Post Data
postdata = “pres=” + p0str + “&temp=” + tstr + “&humd=” + hstr + “&light=” + lstr + “&vcc=” + vstr + “”;

http.begin(“http://hferrier.co.uk/esp01_vcc.php”); //Specify request destination
delay(1000);
http.addHeader(“Content-Type”, “application/x-www-form-urlencoded”); //Specify content-type header

int httpCode = http.POST(postdata); //Send the request
String payload = http.getString(); //Get the response payload

http.end(); //Close connection
}
ESP.deepSleep(900e6); // 15 minutes
}

void loop() {
}


—————————————————————————————————————

WordPress Page (what the viewers sees)

The gauges shown on the weather information page are produce using RGraph.

RGraph could have been used to produce the graphs of the data but I found Google Charts to be easier and give the output I liked.

The only way I could show the code without WordPress trying to interpret it was to use a PDF file.




—————————————————————————————————————

PHP Code

The original practice version of this was written as an HTML page containing PHP scripts. WordPress Pages do not permit PHP scripts to be within the HTML.
I used the plugin – Insert PHP Code Snippet whenever a piece of PHP code had to be used.

These are the PHP Code Snippets I used.

PHP Code Snippets

1. grlight2

<?php
global $data8;
echo $data8;
?>



2. grlight

<?php
global $data4;
echo $data4;
?>



3. vcc

<?php
global $vcc;
echo $vcc;
?>



4. light

<?php
global $light;
echo $light;
?>



5. grhumd2

<?php
global $data7;
echo $data7;
?>



6. grtemp2

<?php
global $data6;
echo $data6;
?>



7. grpres2

<?php
global $data5;
echo $data5;
?>



8. time

<?php
global $datetime;
echo $datetime;
?>



9. grhumd

<?php
global $data3;
echo $data3;
?>



10. grtemp

<?php
global $data2;
echo $data2;
?>



11. grpres

<?php
global $data1;
echo $data1;
?>



12. graphdata

<?php
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “weatherdata”;

global $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die(“Connection failed: ” . $conn->connect_error);
}

$qry1 = “SELECT pres, temp, humd, light, vcc, datetime FROM data WHERE datetime > DATE_SUB(NOW(), INTERVAL 24 HOUR) AND datetime <= NOW()”;

$result = $conn->query($qry1);

if($result === FALSE) {
echo mysqli_errno($result) .”: “. mysqli_error($result) .”/n”;
die(mysqli_error());
}
$i = 0; //iteration counter – start at 0

$totalRows = mysqli_num_rows($result); // we need this to know when to change the output
$targetRows = $totalRows – 1; //row indies start from 0, not 1.

foreach ($result as $row){

if ($targetRows == $i) { // if the index is the same value as the target (ie, it’s the last row)…
// echo “[‘”.$row[‘vdate’].”‘,”.$row[‘count’].”],”;

$pres = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘pres’]).”]”. PHP_EOL;
$temp = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘temp’]).”]”. PHP_EOL;
$humd = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘humd’]).”]”. PHP_EOL;
$light = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘light’]).”]”. PHP_EOL;

} else {
$pres = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘pres’]).”],”. PHP_EOL;
$temp = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘temp’]).”],”. PHP_EOL;
$humd = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘humd’]).”],”. PHP_EOL;
$light = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘light’]).”],”. PHP_EOL;
}
$i = $i + 1;
$rows1[] = $pres;
$rows2[] = $temp;
$rows3[] = $humd;
$rows4[] = $light;
}

$table1 = $rows1;
$table2 = $rows2;
$table3 = $rows3;
$table4 = $rows4;

$data1 = implode($table1);
$data2 = implode($table2);
$data3 = implode($table3);
$data4 = implode($table4);


$qry2 = “SELECT pres, temp, humd, light, vcc, datetime FROM data WHERE datetime > DATE_SUB(NOW(), INTERVAL 28 DAY) AND datetime <= NOW()”;

$result = $conn->query($qry2);

if($result === FALSE) {
echo mysqli_errno($result) .”: “. mysqli_error($result) .”/n”;
die(mysqli_error());
}
$i = 0; //iteration counter – start at 0

$totalRows = mysqli_num_rows($result); // we need this to know when to change the output
$targetRows = $totalRows – 1; //row indies start from 0, not 1.

foreach ($result as $row){

if ($targetRows == $i) { // if the index is the same value as the target (ie, it’s the last row)…
// echo “[‘”.$row[‘vdate’].”‘,”.$row[‘count’].”],”;

$pres = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘pres’]).”]”. PHP_EOL;
$temp = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘temp’]).”]”. PHP_EOL;
$humd = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘humd’]).”]”. PHP_EOL;
$light = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘light’]).”]”. PHP_EOL;

} else {
$pres = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘pres’]).”],”. PHP_EOL;
$temp = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘temp’]).”],”. PHP_EOL;
$humd = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘humd’]).”],”. PHP_EOL;
$light = “[new Date(‘”.($row[‘datetime’]).”‘),”.($row[‘light’]).”],”. PHP_EOL;
}
$i = $i + 1;
$rows5[] = $pres;
$rows6[] = $temp;
$rows7[] = $humd;
$rows8[] = $light;
}

$table5 = $rows5;
$table6 = $rows6;
$table7 = $rows7;
$table8 = $rows8;

$data5 = implode($table5);
$data6 = implode($table6);
$data7 = implode($table7);
$data8 = implode($table8);



13. humd

<?php
global $humd;
echo $humd;
?>



14. temp

<?php
global $temp;
echo $temp;
?>



15. pres

<?php
global $pres;
echo $pres;
?>



16. readsql

<?php
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “weatherdata”;

global $temp, $pres, $humd, $light, $vcc, $datetime;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die(“Connection failed: ” . $conn->connect_error);
}

// attempts to get last record
$sql = “SELECT pres, temp, humd, light, vcc, datetime FROM data WHERE id = (SELECT MAX(id) FROM data)”;

$result = $conn->query($sql);

if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$pres = $row[“pres”];
$temp = $row[“temp”];
$humd = $row[“humd”];
$light = $row[“light”];
$vcc = $row[“vcc”];


$datetime = $row[“datetime”];

}
}else {
echo “0 results”;
}

$conn->close();
?>



17. weatherdisplay

<?php
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “weatherdata”;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die(“Connection failed: ” . $conn->connect_error);
}

echo ‘<table id=”weather” class=”center” style=”width: 60%;”>
<tr>
<th> Pressure (mb) </td>
<th> Temperature (°C) </td>
<th> Humidity (%) </td>
<th> Light (lux) </td>
<th> Date/Time </td>
</tr>’;

//select the last 24 hours
$sql = “SELECT pres, temp, humd, light, datetime FROM data WHERE datetime > DATE_SUB(NOW(), INTERVAL 24 HOUR) AND datetime <= NOW()”;
$result = $conn->query($sql);

if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$pres = $row[“pres”];
$temp = $row[“temp”];
$humd = $row[“humd”];
$light = $row[“light”];
$datetime = $row[“datetime”];

echo ‘<tr>
<td>’.$pres.'</td>
<td>’.$temp.'</td>
<td>’.$humd.'</td>
<td>’.$light.'</td>
<td>’.$datetime.'</td>
</tr>’;
}

echo ‘</table>’;

}else {
echo “0 results”;
}

$conn->close();