Clock using 7seg 4dig + DS3231 + DHT11 + HC-SR501 PIR

Good day...

I have relatively good knowledge on basic electronics but I'am still very very new to programming and I'm trying to program a 7 seg 4dig steampunk clock that I'm building.

Hardware I'm using:
Arduino NANO
DHT 11
DS3231
HC-SR501 PIR
2 x momentary push buttons
7Seg4Dig common cathode

Libraries I'm trying to combine:
DHT-sensor-library-master
Arduino-DS3231-master
SevSeg

I'm not sure if I'm using the wrong keywords but I can't find an example of what I'm trying to do any where on the web. I would like to display the time (hours:minuts) for 15 seconds then temp (°C) for 5 seconds then relative humidity for 5 seconds and feels like temp (°C) also for 5 seconds.Separately everything works fine in the serial monitor and the display works fine with the example sketches of the SevSeg library and I was able to get the temp or humidity to display,but thats it...

Then I want the display to go off between x time and y time and come on when motion is detected for z amount of seconds.

Then I want the main clock and motion sensor times to be adjustable with the two push buttons,one for enter settings/select and the other to adjust.

So if someone can please help me combine the libraries that I quoted or direct me to where someone has already done something exactly the same as what I'm trying to do I would really appreciate it a lot.

I have also included a schematic of my design.I hope its ok...

Thank you so much for your time.

Regards SPYFLY.

You are already getting it, you just need to work a little more on your logical thinking.

Make small parts of each advance. Make the base code with the most complex part and then add the less complex parts to this base code, like buttons.

This is a relatively complex project for a beginner. I think your best approach to tackling this is to get a few things working then add the next bit, and then the next bit, etc.

The trick is to build this in such a way that allows you to modify it easily when you add the next component... that takes a bit of thinking about the overall solution. Otherwise you'll be completely rewriting it at each step.

In my mind I would break it down like this...

At the highest level you have a couple of "modes"

  • setup mode (where you can adjust times, durations.)
  • running mode (where the clock just does its thing).

Within setup mode, you have 2 sub modes

  • change clock mode
  • change sensor duration mode

With only 2 push buttons you'll need to think creatively about how you want the buttons to work...

  • you need to be able to select the mode
  • you need to be able to select the sub-mode
  • you need to be able to change the setting... how will you do up/down ? (hard with only 2 buttons total)... because you also need 1 for the next item.
  • you need to be able to indicate when you're done.

Think about whether you can do this with just 2 buttons... 3 or even 4 will make it much easier.

Then we get to "Running mode"... this is probably a bit easier.

This is also split into 2 sub modes, depending on the time of day...

  • Awake mode (where it just cycles though time, temp, humidity, feels-like)
  • Sleep mode
    • Wait for sensor
    • Do the stuff as per Awake mode
    • Go to sleep after a certain period of time

I would try and build a skeleton program as per the above first... then fill in the detail underneath.

For anything that requires timing, you will need to learn how to use millis() and some fairly basic code to do things at a certain time without blocking your code... this is fairly fundamental ... suggest looking at the BlinkWIthoutDelay example to get started.

Good luck.

Thank you for the advice.I must admit that I didn't think through the complexity of the coding side before I started the project,now that the assembly side is done and started with the coding side I realized I bit off more than I can chew at the moment.

I still have pins A6 and A7 open for two more buttons if needed.

I'd worry about the setup stuff later... and you can always use the A6/7 pins as digital pins.

One step at a time....

You'll get there.

No, you can't. These are analog inputs only!

Agreed... my response was badly worded... what I meant to say was that these pins could be used as button inputs.

But you should mention that you cannot read them the usual way. You must read the buttons as analog values (analogRead()) even if you read a digital value as a button press. Beginners (as the OP) won't realize that themselves and will be surprised that digitalRead() doesn't work.

Thank you to everyone's comments,I'am aware on how the analog pins work,but thank you for your concern,my biggest problem that I'm having is fusing the library's that I mentioned together.

A6 and A7 doesn't work like the other analog pins! You can use

digitalRead(A0);

or

pinMode(A1, OUTPUT);
digitalWrite(A1, HIGH);

but the same won't work for A6. Are you aware of that?

Did you try the hints mentioned above? Starting with one feature and then adding one after the other? If yes, post the code you have so far and tell us what problems you're facing.

Thank you,no I was not aware of that,I'm still busy trying what was recommended and will post the code if I can't figure it out on my own...

@SPYFLY

Follow SSS Strategy as pointed in post #3 @red_car. SSS refers to Small Start Strategy.

1. Operate the DS3231 Clock and showing the time (HRS:MIN) on Serial Monitor.
sketch:
please, post your codes:

2. Add codes as needed in the sketch of Step-1 to show time Hrs:Min on the following 4-digit display unit (Fig-1 is same as your of post #1 with T1-T4 removed). You don't need those T1-T4 transistors as an IO pin of NANO can source/sink 20 ma current. This is fine you are using SevSeg.h Library.

4digitds3231clk
Figure-1:

Sketch:
Please, post your display test codes using SevSeg.h Library

I hope to show you a working sketch with DS3231 and SevSeg.h Library.

And yet these two line can be used to connect/operate push buttons as per Fig-1.
A6NanoSw1
Figure-1:

Test Sketch:

void setup()
{
  Serial.begin(9600);
  while (analogRead(A6) != 0)
  {
    ;
  }
  Serial.print("K1 is pressed.");
}

void loop()
{

}

Monitor Output:

K1 is pressed.

@GolamMostafa

Correct me if I am wrong...but won't the digit pins eg. pin 5 on my layout,have to sink 70ma if if all the segments (set to 10ma per segment) are lit on that digit?

Thank you it means a lot to me,will post as soon as I can.

It is multiplexed display unit, run the project and check if you are happy with the brightness. The average current per display unit will be less than 20 mA as there are 8x2.2k current limiting resistors with the segments.

@GolamMostafa

YAY,Ok got some time to look at SSS as you and @red_car suggested and have successfully got the time to display correctly on my 7seg4dig...now trying to code the colon blink in.

Here is what I got so far

#include "SevSeg.h"
#include <Wire.h>
#include <DS3231.h>

SevSeg sevseg; //Instantiate a seven segment controller object
DS3231 clock;
RTCDateTime dt;


void setup() {
  byte numDigits = 4;
  byte digitPins[] = {5, 6, 9, 10};
  byte segmentPins[] = {7, 8, 13, 11, 12, 2, 4, 3};
  bool resistorsOnSegments = true; // 'false' means resistors are on digit pins
  byte hardwareConfig = N_TRANSISTORS; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
  
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(10);

  Serial.begin(9600);

  // Initialize DS3231
  Serial.println("Initialize DS3231");
  clock.begin();

  //Set sketch compiling time
  //clock.setDateTime(__DATE__, __TIME__);

}

void loop() {

  dt = clock.getDateTime();
  
    Serial.print(dt.hour);   Serial.print(":");
    Serial.println(dt.minute); 
    
    sevseg.setNumber(dt.hour * 100 + dt.minute,2);

    sevseg.refreshDisplay(); // Must run repeatedly
}

/// END ///

Ok,so far so good.I got the colon to blink just as I wanted it...but I have a problem that I can't seem to figure out with the DHT 11 sensor part.

  1. I can't get the temp and °C to display together,its ether one or the other and I can't get the temp in the rite location on the display.

  2. Then each time the "DHTSensorRearInterval" is triggered the display flashes off/on,like a glitch flash.

This is where I'm at so far:

#include "SevSeg.h"
#include <Wire.h>
#include <DS3231.h>
#include "DHT.h"

SevSeg sevseg; //Instantiate a seven segment controller object
DS3231 clock;
RTCDateTime dt;

byte colon = 3;
bool colonState = HIGH;
int colonOnDuration = 500;
int colonOffDuration = 500;
int DHTSensorRearInterval = 5000;
unsigned long rememberMillis = 0;

#define DHTTYPE DHT11
#define DHTPIN A3
DHT dht(DHTPIN, DHTTYPE);

void setup() {

  
  pinMode(colon,OUTPUT);
  digitalWrite(colon,colonState);
  byte numDigits = 4;
  byte digitPins[] = {5, 6, 9, 10};
  byte segmentPins[] = {7, 8, 13, 11, 12, 2, 4};
  bool resistorsOnSegments = true; // 'false' means resistors are on digit pins
  byte hardwareConfig = N_TRANSISTORS; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
  
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(10);
 
  clock.begin();
  dht.begin();

  Serial.begin(9600);
  //Set sketch compiling time
  //clock.setDateTime(__DATE__, __TIME__);

}

void loop() {

/* dt = clock.getDateTime(); 
    
  sevseg.setNumber(dt.hour * 100 + dt.minute,2);

    if( colonState == HIGH )
    {
       if( (millis() - rememberMillis) >= colonOnDuration){   
       colonState = LOW;
       rememberMillis = millis();
       }
    }
    else
    {   
       if( (millis() - rememberMillis) >= colonOffDuration){     
       colonState = HIGH;
       rememberMillis = millis();
       }
    }

   digitalWrite(colon,colonState);
*/


 // Wait a few seconds between measurements.
 if( (millis() - rememberMillis) >= DHTSensorRearInterval){   
       

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  int h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  int t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  //  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  int hic = dht.computeHeatIndex(t, h, false);

  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F(" Heat index: "));
  Serial.print(hic);
  Serial.println(F("°C "));
 
  sevseg.setNumber(t);
  sevseg.setChars("  *C");

  
  rememberMillis = millis();
 }
 
  sevseg.refreshDisplay(); // Must run repeatedly
}

/// END ///

1. DHT11 has a temperature sensor and DS3231 has a temperature sensor as well. When you say temp and degC, then which one belongs to which?

2. The behavior of Display Unit.
(1) Show current time in this format: HR.MN (dot will be ON or OFF) for 15 seconds
(2) temp (from DHT11 or DS3231) in this format (xx.yy) or in this format (xx) for 5 seconds.
(3) Humidity (xx.yy format or xx) for 5 seconds.
(4) Display goes blank for how long?
(5) Display comes on with current time when HC-SR501 PIR detects object movement.

(6) Process repeats.

Make a heck list and do one-by-one and put tick mark when done.

@GolamMostafa

I only want data from DHT 11.

Time format displays perfectly,I must still code for cycle between Time,Temp,Humidity.I want to get everything to display correctly separately first.

Temp from DHT 11 only to display 27°C on display and 44rH for humidity.But this is as far as I get.I can't get the temp and humidity to display correctly :




Thank you for the help so far,it means alot to me.

Your display unit of post #19 is different from that of post #1; where, the post #1 has no : block.