Introduction: ESP8266 Weatherstation

I decided show my school work of my own board for weather station based on ESP8266 - 12 with BME280 (as temperature, humidity and pressure sensor) and with photoresistor as detector of sunlight. I add ADC 1115 for get voltage from voltage divider (sunlight measure and voltage from battery).

Pros:

Using solar cell to charge Lithium - ion battery (18650)

Using Wi-Fi to connect ThingSpeak

Step 1: BOM

Parts (affiliate links):

ESP8266 - 12 (you can buy ESP8266 - 7)

ESP8266

ESP8266

ESP8266

White adapter for ESP8266 - 12 (need solder esp chip to board)

White adapter (1 piece)

White adapter (10 pcs)

3.3 V Voltage regulator

Voltage regulator

new regulator (not affiliate) 3 V with low quescient current

3.3 regulator (not affiliate)

ADS1115

Analog - digital converter, which is ude for measure voltage from battery and for get value of sunlight.

ADS1115

ADS1115

BME280

BME280

Fake BME280= BMP280 (not sure if it is not fake BME280 = BMP280!)

Capacitors

capacitors

Diode

diode (for protection solar cell from reversing current)


Tactile push buttons

tactile push button

Dip swtich (just 1 way needed or any switch)

http://s.click.aliexpress.com/e/PdRW7ze

NPN BC337

NPN BC337

Set of NPN transistors (set)

Resistors

4.7K 2.2K 10K 10K D1160_12 0.46K 1M 1M

Resistors

Resistors

TP4056

TP4056 (5 pcs) (5 pcs)

TP4056

Solar cell (I prefer 6 V better then 5V, 1W give maximum 160 mA, which is not enough for winter, better buy with more Watts )

Solar cell 1W, 6V

Solar cell 1W, 6V

6 V solar cells

18650 battery

18650 battery

18650 battery

18650 holder

18650 holder

18650 holders (10 pcs)

Waterproof case

waterproof case

(works good, I try in my previous instructable project) (works good, I try in my previous instructable project)

Cables

Cables

if you dont create Eagle and want using universal PCB

universal PCB


Step 2: Code

I graph diagram of code for better understanding. For programming, here is code, don't forgot to change ssid, password, ThingSpeak apikey, and in setup body also ssid code.

// Wifi commands
#include "WiFiConfig.h"
const char* WiFi_hostname = "weatherstation1";
const char* ssid = "xyz"; // here write your wifi "WIFI-MA"; 
const char* password = "mypassword to xyz";  // here password from your wifi;  
const char* server = "api.thingspeak.com"; 
const char* api_key = "myapikeyfromthingspeak";  // here write apikey from ThingSpeak
WiFiClient client;


#include <Wire.h><br>
#include <SPI.h>

// bme 280 
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define BME280_ADRESA (0x76) // adress of BME280
Adafruit_BME280 bme;

//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

// bme variable 

float temp;
float humidity;
float pressure;

// esp voltage reference = get voltage from ADC pin on esp 
// = input voltage to esp from regulator
int refvolt; 
ADC_MODE(ADC_VCC);

//sleep
#define SLEEP_TIME_SECONDS 600
#define ALLOWED_CONNECT_CYCLES 40 // if wifi is not avalaible, esp go to sleep
uint8_t counter


// ADS1115 for measure voltage of battery and sunlight
#include Adafruit_ADS1115 ads(0x49); 
float rawlux = 0;
float rawvolt = 0;

// wifi variable for getting number of wifi networks
//+ get strength of connected xyz wifi network
int strength;
int n;
// setting of bme 280 sensitivity
// Forced mode as recommended for weather station usage by Bosch (sec 5.5.1)
// Settings have to be written to the sensor before every sampling

void bme_ini(){
    bme.setTemperatureSampling(Adafruit_BME280::Sampling_x1);
    bme.setPressureSampling(Adafruit_BME280::Sampling_x1);
    bme.setHumiditySampling(Adafruit_BME280::Sampling_x1);
    bme.setFilter(Adafruit_BME280::Filter_Off);
    bme.setMode(Adafruit_BME280::Forced); //Forced or Sleep
    bme.begin(BME280_ADRESA);
}
void setup()
{
  //Serial.begin(115200);
  //Serial.println(F("BME280 test"));
  
 ///////////////////////        measurements     ////////////////////////
  
  pinMode(14,OUTPUT);     // set pin 14 as output for powering sensors
  digitalWrite(14,HIGH); // power sensors with digital pin 14
  delay(10);
  
 refvolt = ESP.getVcc();  // measure input voltage to esp, usually should be 3.3 V
 delay(10);
  //Wire.begin(13, 12); 
  //for set i2c pin, Wire.begin(sda,scl), default GPIO4 SDA, GPIO5 scl
  
 ////////////////// BME280 = temperature, humidity and pressure //////////////
  bme_ini();
  delay(100);// before read temperate and firts value important is wait some time
  temp = bme.readTemperature();
  delay(10);
  humidity = bme.readHumidity();
  delay(10);
  pressure = bme.readPressure() / 100.0F;
  delay(10);
  

  ///////////////// voltage and sunglight /////////////////////
  int16_t adc0, adc2, adc3;
  ads.setGain(GAIN_TWOTHIRDS);
  ads.begin(); 
  delay(100);
  rawlux  = ads.readADC_SingleEnded(0);  // read sunglight = read signal from voltage divider
  delay(100);
  rawvolt = ads.readADC_SingleEnded(2);  // read voltage of battery from voltage divider
  delay(10); 
  

  /////////////////////// write values to one variable - dataToThingspeak///////////
  String dataToThingSpeak = "";
  dataToThingSpeak += "GET /update?api_key=";
  dataToThingSpeak += api_key; 
  dataToThingSpeak += "&field1=";
  dataToThingSpeak += temp;        // writing to field 1 temperature from first sensor
  dataToThingSpeak += "&field2=";
  dataToThingSpeak += humidity;     // writing to field 2 temperature from second sensor
  dataToThingSpeak += "&field3=";
  dataToThingSpeak += pressure;
  dataToThingSpeak += "&field4=";
  dataToThingSpeak += rawlux;
  dataToThingSpeak += "&field6=";
  dataToThingSpeak += rawvolt;
  dataToThingSpeak += "&field7=";
  dataToThingSpeak += refvolt;
  

  /////////// connect to WiFi, if can't, then go to sleep (after 40 cycles)///////////////
  WiFi.hostname();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");counter++;
    if (counter > ALLOWED_CONNECT_CYCLES) {
      Serial.print("sleep");
      ESP.deepSleep(SLEEP_TIME_SECONDS * 1000000); //sleeping if can't connect
    }
  }
  //Serial.println("WiFi connected");
  
  // WiFi.disconnect();      // ADC values fluctuate, they are crazy, problem can be in wifi connection, so try to disconnect it
  //WiFi.mode(WIFI_OFF);     //uncomment if you have problems with ADC
  // WiFi.forceSleepBegin(); // uncomment if you have proble
 // ESP.eraseConfig();
 
////////////////// measure number of Wifi networks, and strength of connected////////// 
if (client.connect(server, 80))
  {
   int n = WiFi.scanNetworks();
   for (int thisNet = 0; thisNet < n; thisNet++) 
    {
      if (WiFi.SSID(thisNet) = "xyz")  // replace xyz with ssid in beginning
      {
       strength= WiFi.RSSI(thisNet);   // get strength of wifi in d
      }

  }
  
  dataToThingSpeak += "&field5="; 
  dataToThingSpeak += strength;
  dataToThingSpeak += "&field8=";
  dataToThingSpeak += n; // write to field 8 number of wifi networks
  //dataToThingSpeak+="&field8=";
  //dataToThingSpeak+=WiFi.RSSI();
  dataToThingSpeak += " HTTP/1.1\r\nHost: a.c.d\r\nConnection: close\r\n\r\n"; // just write this line
  dataToThingSpeak += "";
  

  ////////////////// sending to thingspeak variable dataToThingspeak///////////
  client.print(dataToThingSpeak); 
  //Serial.print(dataToThingSpeak);
  
  delay(100); // wait 1 second = 1000 miliseconds
  
 
 /////////////////////// show data at serial monitor, uncoment! ///////////////////
 /*
 Serial.println( temp);
 Serial.println(humidity);
 Serial.println( pressure);
 Serial.println(rawlux);
 Serial.println(rawvolt);
 // or //
 Serial.println(dataToThingspeak)
 Serial.println(WiFi.macAddress()); 
*/

//////////////////////// power off sensors + go to sleep //////////////////////////
digitalWrite(14,LOW);
///Serial.print("sleep");
ESP.deepSleep(SLEEP_TIME_SECONDS*1000000); //sleeping
}
// end of void setup and sleep for SLEEP_TIME_SECONDS, then restart
void loop()
{

}

Step 3: Circuit

1. I connect ESP8266 - 12 with regulator (from 5V to 3.3 V) to battery. Also, I add two push buttons, one for restart, second for set programming mode.

2. I power BME280, ADS1115 and photoresistor with regulator. But I switch off/on them witn NPN transistor, because they drain battery too.

3. I measure sunlight with voltage divider (one resistor is 0,46 kohm, second is photoresistor).

4. I measure voltage of battery with voltage divider (used pair of 1 Mohm resistors).

5. ADS1115, BME280 communicated with esp using I2C.

6. I charger battery with solar cell (6 V) and TP4056 board.

7. For turn off/on device, I use one dip switch (slide type).

8. Female programme pins are 3 inputs for programming ESP chip - Tx, Rx, GND.


Step 4: Voltage Divides (examples on Arduino)

I measure voltage of battery and sunlight using voltage divider.
Instead of ADS1115 with analog pins, I show you basic principle using Arduino UNO, which has also analog pins.

Example of battery:

1. two resistors must be connected to create votlage divider (2x 10 kOhm) to one node (joint).

2. That node is connected to analog pin.

3. Then one resistor connect to + terminal of battery, another resistor to - terminal of battery.

Example of photoresistor:

1. One end of photoresistor connect to 3.3 Voltage.

2. One end of resistor connect to GND of Arduino.

3. Node of photoresistor and resistor connect to analog pin. It needs calibrate, but I don't do that.

Step 5: PCB

I design and create own PCB in Eagle.

Step 6: Thingspeak Server

I use ThingSpeak for visualize data.

1. I measure temperature of air. It need better cooling during hot days or radiation shield for sure.

2. Relative humidity sensor work one year. Then it degrade.

3. Pressure sensor works good, and is for predict cloudiness or rain. It works with 2 - 3 days prediction! Nice.

4. Photoresistor depend on temperature and degrade with time. I don't think is good solution.

5. All resistors in voltage divides (measure sunlight and voltage of battery) should be temperature independent. I use classical resisistors, not good. Also, check % of error of resistance of resistors. 5 % resistance is not good, because is hard to get real voltage of battery.

Step 7: Laboratory Sample

Step 8: Graphs

As you can see, I can make some graphs using Google Tables:

1. Temperature - need solar shield because of preheated.

2. Humidity - after some time (1 - 2 years) it degrade.

3. Temperature and Humidity - you can see, when temperature is highest, humidity is lowest and when temperature is lowest, humidity is highest.

4. Sunlight - because I have weather station on balcony, Sun is sometimes hidden behind house. Sun beams don't fall to photoresistor, mostly in morning and evening. That's why you can see steps, when suddenly beam fall to photoresistor.

5. Pressure - I measure local pressure of air, so it needs calibrate to air pressure reduced to sea level.

Check this nice online calculator. https://keisan.casio.com/exec/system/1224575267

Sea - level pressure depend on temperature of air, altitude of weather station, and local pressure.

6. Battery level - I don't calibrate, you can see, that it depends on temperature.

IoT Challenge

Participated in the
IoT Challenge