Mitch K
Published © CC BY-NC-SA

Wireless Weather Monitor

This is a semi-outdoor temperature & humidity monitor that runs on 3.7v batteries. I say semi because it needs to be protected from rain.

BeginnerShowcase (no instructions)2 hours1,219
Wireless Weather Monitor

Things used in this project

Hardware components

D1 Mini Pro
×1
D1 Mini Button Shield
×1
D1 Mini LiPo Charger Shield
×1
D1 Mini proto shield
×1
D1 Mini SHT3X Shield
×1
3.7 V LiPo Battery
×1
Resistor 3.3k
×1
Resistor 12K
×1

Software apps and online services

Cayenne
myDevices Cayenne

Story

Read more

Schematics

Schematic

Code

weather monitor

Arduino
#include "Arduino.h"
// #define CAYENNE_DEBUG Serial
// #define CAYENNE_PRINT Serial
#include <Wire.h>
#include <CayenneMQTTESP8266.h>
#include <ESP8266WiFi.h>
#include <EEPROM.h>


RF_MODE(RF_NO_CAL);// tells the ESP to just turn on radio, no calibration which extra takes power


char ssid[] = "IoT";
char wifiPassword[] = "pass";

char username[] = "username";
char password[] = "password";
char clientID[] = "id";

#define Address         0x45 // wire address for the SHT3x
#define eepromAddress   0 // where sleep cycle status is stored
#define sleepDisablePin D3
#define voltPin A0

// resistor values for volt divider
// R1 = 11910;
// R2 = 3260;
// voltFactor = R2 / (R1 + R2);

float voltFactor = 0.212;
float voltage;
unsigned int rawVolt;

bool online;

unsigned long onlineTime;
unsigned long prevTime;
unsigned long time1;

unsigned int data[6];
unsigned int disco = 0;

byte buttonEnabled = 0;
byte sleepDisabled = 1;
byte sleepNow = 0;
byte restartChip = 0;

float cTemp = 0.0;
float fTemp = 0.0;
float humidity = 0.0;




void setup()
{
	pinMode(BUILTIN_LED, OUTPUT);
	pinMode(sleepDisablePin, INPUT_PULLUP);  // jumper for sleep override
	pinMode(voltPin, INPUT);

	for (int i = 0; i < 3; i++)  // LED blinks to show booting
	  {
		  digitalWrite(BUILTIN_LED, 0);
		  delay(100);
		  digitalWrite(BUILTIN_LED, 1);
		  delay(100);
	  }

	Wire.begin();
	EEPROM.begin(512);  // to store sleep state
	// Serial.begin(9600);

	buttonEnabled = EEPROM.read(eepromAddress);  // checks if it is in a sleep cycle
	sleepDisabled = digitalRead(sleepDisablePin); // checks for sleep cycle bypass

	Cayenne.begin(username, password, clientID, ssid, wifiPassword);

	if (sleepDisabled == 0) // stops sleep cycle if jumper LOW
	  {
		  sleepNow = 0;
		  buttonEnabled = 0;
		  Cayenne.virtualWrite(0, 0, "digital_sensor", "d"); // sends sleep cycle status to sleep button on dashboard
	  }

	time1 = millis();

} // setup


void loop()
{
	Cayenne.loop();

	if (millis() - time1 > 20000) // loop to get & send data every 20 seconds when awake
	  {
		  getTemp();
		  execute();
	  }

	if (online == true && sleepNow == 1)  // blinks LED if online about every 1 sec if in sleep mode
	  {
		  digitalWrite(BUILTIN_LED, LOW);
		  delay(10);
		  digitalWrite(BUILTIN_LED, HIGH);
	  }

	if (online == true && sleepNow == 0)
	  {
		  digitalWrite(BUILTIN_LED, LOW);
	  }

	if (online == false)
	  {
		  digitalWrite(BUILTIN_LED, HIGH);
	  }

} // loop


void getTemp()  // pulls temp & humidity via i2c per datasheet, gets voltage
{
	Wire.beginTransmission(Address);

	Wire.write(0x2C);
	Wire.write(0x06);

	Wire.endTransmission();
	delay(500);

	Wire.requestFrom(Address, 6);  // get data

	if (Wire.available() == 6)
	  {
		  data[0] = Wire.read();
		  data[1] = Wire.read();
		  data[2] = Wire.read();
		  data[3] = Wire.read();
		  data[4] = Wire.read();
		  data[5] = Wire.read();
	  }


	cTemp = ( ( ( ( data[0] * 256.0 ) + data[1] ) * 175 ) / 65535.0 ) - 45;
	fTemp = ( cTemp * 1.8 ) + 32;
	humidity = ( ( ( ( data[3] * 256.0 ) + data[4] ) * 100 ) / 65535.0 );

	rawVolt = analogRead(voltPin);
	voltage = ( float(rawVolt) / 1024 ) * 3.3;
	voltage = voltage / voltFactor;

} // getTemp




void execute()
{
	time1 = millis(); // record transmit time

// temp, humidity, and batt voltage
	Cayenne.virtualWrite(5, fTemp, "Fahrenheit", "f");
	Cayenne.virtualWrite(6, humidity, "Percent", "p");
	Cayenne.virtualWrite(8, fTemp, "analog_sensor", "null");
	Cayenne.virtualWrite(9, humidity, "analog_sensor", "null");

	Cayenne.virtualWrite(7, voltage, "analog_sensor", "null");
	Cayenne.virtualWrite(10, voltage, "analog_sensor", "null");

// system info
	Cayenne.virtualWrite(23, disco, "counter", "null");

	int time2 = ( millis() / 1000 ) / 60;
	Cayenne.virtualWrite(24, time2, "counter", "null");

	onlineTime = ( ( millis() - prevTime ) / 1000 ) / 60;
	Cayenne.virtualWrite(25, onlineTime, "counter", "null");

	delay(1000);

	if (sleepNow == 1) // if sleep is active, chip sleeps after data transmit
	  {
		  ESP.deepSleep(1200000 * 1000); // sleeps for 20 min
	  }

} // execute


CAYENNE_CONNECTED()
{
	online = true;
	prevTime = millis();

	if (buttonEnabled == 1)   // checks if sleep cycle active
	  {
		  Cayenne.virtualWrite(0, 1, "digital_sensor", "d"); // sends value of sleep to dashboard
		  sleepNow = 1;
	  }
}

CAYENNE_DISCONNECTED()
{
	online = false;
	disco++;    // record disconnect
}




CAYENNE_IN(0)  // sleep button
{
	sleepNow = getValue.asInt();

	if (sleepNow == 1)   // save sleep cycle status to eeprom to read after reboot
	  {
		  EEPROM.write(eepromAddress, 1);
		  EEPROM.commit();
	  }
	else
	  {
		  EEPROM.write(eepromAddress, 0);
		  EEPROM.commit();
	  }

}

CAYENNE_IN(1) // trigger chip restart
{
	restartChip = getValue.asInt();
	delay(500);

	if (restartChip == 1)
	  {
		  Cayenne.virtualWrite(1, 0, "digital_sensor", "d");
		  Cayenne.loop(); // writes reboot button back low before restart
		  delay(1500);

		  ESP.restart();
	  }
}

Credits

Mitch K

Mitch K

10 projects • 34 followers
Maker, designer, & all around fun to be around!

Comments