Ingo Lohs
Published © GPL3+

MyLCD20x4 Clock with Value-Added Information - SHT31-D

Use a Particle Photon, a SHT31-D sensor, and a cheap LCD20x4 to start your own clock project.

BeginnerProtip1 hour1,087
MyLCD20x4 Clock with Value-Added Information - SHT31-D

Things used in this project

Hardware components

Photon
Particle Photon
×1
Breadboard (generic)
Breadboard (generic)
×1
Adafruit SHT31-D
×1
Jumper wires (generic)
Jumper wires (generic)
×1
LCD-Adapter I2C
×1
LCD-Display 20x4
×1

Story

Read more

Custom parts and enclosures

LCD 2004 Housing

Code

myClock-SHT31D-LCD-I2C

C/C++
v1.0
// Ingo Lohs, myclock-sht31d-lcd-i2c works with Particle Photon v0.6.2
// a digital watch with Adafruits SHT31-D on I2C
// 01.09.2018, v1.0

// LIBs
#include "math.h"
#include <adafruit-sht31.h>
#include <LiquidCrystal_I2C_Spark.h>

// Objects
LiquidCrystal_I2C *lcd;
Adafruit_SHT31 sht31 = Adafruit_SHT31();

// Definitions
const unsigned long UPDATE_PERIOD_MS = 5000;
unsigned long lastUpdate = 0;

// for the values
char buf[64];
String Wochentag;

// *********************************

void setup()
{
    Serial.begin(9600);
    
    Serial.println(F("SHT31-D + LCDisplay 1602 / 2004"));

    if (!sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr
    Serial.println("Couldn't find SHT31");
    }
  
    // The address is typically 0x27. I2C Address: 0x3F
    // https://www.sainsmart.com/new-sainsmart-iic-i2c-twi-1602-serial-lcd-module-display-for-arduino-uno-mega-r3.html
    lcd = new LiquidCrystal_I2C(0x3F /*address*/, 20 /*columns*/, 4/*rows*/); // > for LCD2004
    lcd->init();
    lcd->backlight();
    lcd->clear();
    Time.zone(isDST() ? +2.00 : +1.00);  
}
    
// *********************************

void loop() { 

  lcd->setCursor(0 /*columns*/,0 /*rows*/);
  lcd->print(Time.format(Time.now(), "%d.%m.%y")); // %A für Weekday = English Output
  
  if ((Time.format(Time.now(), "%H:%M:%S")) == "00:00:00")
  {
        lcd->clear();
  }

  // https://docs.particle.io/reference/firmware/photon/#weekday-
  int wDayName = Time.weekday();
  
  if (wDayName != wDayName)
  {
      lcd->clear();
  }
  
  if (wDayName == 1) 
  {
      Wochentag = "Sonntag";
  }
  else if (wDayName == 2) 
  {
      Wochentag = "Montag";
  }
  else if (wDayName == 3) 
  {
      Wochentag = "Dienstag";
  }
  else if (wDayName == 4) 
  {
      Wochentag = "Mittwoch";
  }
  else if (wDayName == 5) 
  {
      Wochentag = "Donnerstag";
  }
  else if (wDayName == 6) 
  {
      Wochentag = "Freitag";
  }
   else if (wDayName == 7) 
  {
      Wochentag = "Samstag";
  }
   
  lcd->setCursor(9,0);
  lcd->print(Wochentag);
  
  lcd->setCursor(0,1);
  lcd->print(Time.format(Time.now(), "KW: %W"));
  lcd->setCursor(9,1);
  lcd->print(Time.format(Time.now(), "%H:%M:%S"));

    // read the SHT31 sensor
	if (millis() - lastUpdate >= UPDATE_PERIOD_MS) {
		lastUpdate = millis();

       float temp = sht31.readTemperature();     // Celsius
       float humidity = sht31.readHumidity();    // Humidity
       float tF = (temp * 9) / 5.0 + 32.0;       // from Celsius to Fahrenheit

       // Output for Serial Monitor > install Particle CLI on your Desktop > command "particle serial monitor"
       if (!isnan(temp)) {  // check if 'is not a number'
         //Temperature in C
       Serial.print("Temp *C = "); Serial.println(temp);
        //Temperature in F
       Serial.print("Temp *F = "); Serial.println(tF);
       } else { 
           Serial.println("Failed to read temperature");
       }
      
       if (!isnan(humidity)) {  // check if 'is not a number'
           Serial.print("Humi. % = "); Serial.println(humidity);
       } else { 
       Serial.println("Failed to read humidity");
       }
       Serial.println();

       // check for value
	   if (temp != NULL) {
	    
	   // print out to LCD 
	   snprintf(buf, sizeof(buf), "%.2f *C", temp);
	   lcd->setCursor(0,2);
	   lcd->print(buf);

	   snprintf(buf, sizeof(buf), "%.2f %%", humidity);
       lcd->setCursor(9,2);
	   lcd->print(buf);

   	   snprintf(buf, sizeof(buf), "%.2f *F", tF);
	   lcd->setCursor(0,3);
	   lcd->print(buf);

       // in case of error during sensor reading
       }
       else {
      	    lcd->clear();
		    lcd->setCursor(0,3);
			lcd->print("Problem with SHT31-D!");
       }
  		
	}
}

// FUNCTION TO CHECK SUMMER/WINTER-TIME ---------------------

bool isDST()
{ // Central European Summer Timer calculation
  int dayOfMonth = Time.day();
  int month = Time.month();
  int dayOfWeek = Time.weekday() - 1; // make Sunday 0 .. Saturday 6

  if (month >= 4 && month <= 9)
  { // March to September definetly DST
    return true;
  }
  else if (month < 3 || month > 10)
  { // before March or after October is definetly normal time
    return false;
  }

  // March and October need deeper examination
  boolean lastSundayOrAfter = (dayOfMonth - dayOfWeek > 24);
  if (!lastSundayOrAfter)
  { // before switching Sunday
    return (month == 10); // October DST will be true, March not
  }

  if (dayOfWeek)
  { // AFTER the switching Sunday
    return (month == 3); // for March DST is true, for October not
  }

  int secSinceMidnightUTC = Time.now() % 86400;
  boolean dayStartedAs = (month == 10); // DST in October, in March not
                                        // on switching Sunday we need to consider the time
  if (secSinceMidnightUTC >= 1 * 3600)
  { // 1:00 UTC (=2:00 CET/3:00 CEST)
    return !dayStartedAs;
  }

  return dayStartedAs;
}

Credits

Ingo Lohs

Ingo Lohs

182 projects • 194 followers
I am well over 50 years and come from the middle of Germany.

Comments