Yes this is true
at the bottom of your loop there is a delay(2000);
// update Sequenz DHT11
delay(2000);
lcd.clear();
}
This means that all and every action only happends after 2 seconds.
Your code is one of that very often occuring cases where the command delay is delaying the development-process much more than taking time to learn non-blocking timing.
@Arduino-Team: take out the command delay() out of EVERY example-code!
take in a non-blocking version of timing.
There are very good reasons to execute parts of the code only once every two seconds or even longer time-intervals. This should be programmed using non-blocking timing.
There might be users that don't like my version of non-blocking timing
my opinion:
The advantages far outweigh the disadvantages because the external function is fairly easy to understand. And this is what is important for beginners.
As your programming knowledge grows, you will also understand the inner workings.
And I made a very conscious decision by posting my version very often to try to make it the new de-facto-standard against the common used version.
If somebody feels the need to go against this. Of course you are free to do so. I claim: most users are just used to use the "standard"-nonblocking timing and are too lazy to learn my version. Users you will have to give up lazyness and take the effort of posting your version including easy to understand explanations each time.
Back to programming:
the basic principle of non-blocking timing is to check if a defined timeinterval
has passed by.
This can be done by using the function millis()
The function millis() gives back the amount of milliseconds (hence the name millis)
that have passed by since power-up of the microcontroller.
It counts up to 2^32 which means reaching the max-value is reached after 49 days.
There is a calculation-technique that even "rollover" from max to zero is handled
automatically the right way
This non-blocking timing needs a timer-variable which is used for taking
snapshots of time as a comparison-point
The variable-type for this variable MUST be of type unsigned long
to make it work reliably all the time
unsigned long myLcdUpdateTimer;
now the following construction executes the code inside the if-condition
only once every two seconds
if ( TimePeriodIsOver(myLcdUpdateTimer,2000) ) {
// time for timed action
}
Here is the modified version of your function loop()
void loop() {
// Read temperature und humidity from DHT11 and Print to LCD
solltemperatur = 0; // The manually set temperature
temperatur = dht.readTemperature(); // The environment temperature
luftfeuchtigkeit = dht.readHumidity(); // The environment humidity (not in use atm)
//lcd.clear();
// read the "now" value
clkaktuell = digitalRead(CLK);
// notice turns
if (clkaktuell != clkletzter) {
// count up if CLK is triggered first
if (digitalRead(DT) != clkaktuell) {
solltemperatur ++;
}
// count down if DT is triggered first
else {
solltemperatur --;
}
}
// low end limit of set temperature
if (solltemperatur < 25) {
solltemperatur = 25;
}
// high end limit of set temperature
if (solltemperatur > 70) {
solltemperatur = 70;
}
// turn the relay on if the environment temperature is lower
// than the set temperature
if (solltemperatur < temperatur) {
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
// turn of if not
else {
digitalWrite(10, LOW);
digitalWrite(11, LOW);
}
// update Sequenz DHT11
//delay(2000);
if ( TimePeriodIsOver(myLcdUpdateTimer, 2000) ) {
printToLCD(); // update LCD only once every 2000 milliseconds
}
the difference is at the bottom: This code makes the loop "looping at high speed but updates the LCD only once every 2 seconds. This enables to detect turning the rotary-encoder again.
But I want to add something: The basic intention of understanding code is good. But If a part of the code works 100% reliably and is used in always the same manner it can be hided away.
Example
digitalWrite(10,HIGH);
there is a lt of going on "under the hood" to switch an IO-pin HIGH
but you simply don't know the details and you don't feel any need to do so.
It is the same thing with libraries.
Did you analyse a single line of code inside the files
LiquidCrystal_I2C.h // LiquidCrystal_I2C.cpp
I'm pretty sure you didn't even know that there is a second file LiquidCrystal_I2C.cpp
So with the timing function "IfTimePeriodIsOver() that I inserted into your code it is the same. Still understanding this function is 90% easy. (There are 10% left caused by the "&"-symbol in front of the first parameter)
Here is the full code that compiles. I have marked each part that has been modified by me with a looooong line like this
// ********************************************************************
// Doofenschmirtz Dörrinator
// Mads Duggen
// Interactive Prototyping 2021
// Muthesius Kunsthochschule
// ARDUINO PIN USAGE
// LCD with I2C module
// A5 - SCL
// A4 - SDA
// 5v - VCC
// GND - GND
// DHT 11 sensor
// 8 - OUTPUT
// 5v - VCC
// GND - GND
// Heater and fan relay CH1 & CH2
// 10 - CH1
// 11 - CH2
// 5v - DC+
// GND - DC-
// KY-040 rotary encoder
// 3 - CLK
// 4 - DT
// 5 - SW
// 5v - +
// GND - GND
//Utilised libarys
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// Data-Pin and sensortype
#define DHTPIN 8
#define DHTTYPE DHT11
// KY-040 pins
int CLK = 3;
int DT = 4;
int SW = 5;
int solltemperatur;
int temperatur;
float luftfeuchtigkeit;
int clkletzter;
int clkaktuell;
// LCD und DHT objects
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
//***********************************************
unsigned long myLcdUpdateTimer;
//*****************************************************************
// helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - expireTime >= TimePeriod )
{
expireTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
// ********************************************************************
void setup() {
// initialising relay pins
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
// initialising KY-040 pins
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT);
digitalWrite(CLK, true);
digitalWrite(DT, true);
digitalWrite(SW, true);
//initial read CLK pin
clkletzter = digitalRead(CLK);
// Welcoming Screen
dht.begin(); // initialising DHT11 sensor
lcd.backlight(); // Start backlight
lcd.begin(); // initialising LCD
delay(2000);
lcd.setCursor( 0, 0);
lcd.print(" Doofenschmirtz");
lcd.setCursor( 0, 1);
lcd.print(" Doerrinator");
delay(5000);
}
//**************************************************
// each part of the code that form a senseful unit
// should be inside its own function
void printToLCD() {
lcd.clear();
//print the environment temperature to the first row of the LCD
lcd.setCursor( 0, 0);
lcd.print("Temp. :");
lcd.print(temperatur);
lcd.print("C");
//print the environment humidity to the second row of the LCD
lcd.setCursor( 0, 1);
lcd.print("Soll. :");
lcd.print(solltemperatur); // Changeable Value representing the set temperature of the Dehydrator
lcd.print("C");
}
// **********************************************************************
void loop() {
// Read temperature und humidity from DHT11 and Print to LCD
solltemperatur = 0; // The manually set temperature
temperatur = dht.readTemperature(); // The environment temperature
luftfeuchtigkeit = dht.readHumidity(); // The environment humidity (not in use atm)
//lcd.clear();
// read the "now" value
clkaktuell = digitalRead(CLK);
// notice turns
if (clkaktuell != clkletzter) {
// count up if CLK is triggered first
if (digitalRead(DT) != clkaktuell) {
solltemperatur ++;
}
// count down if DT is triggered first
else {
solltemperatur --;
}
}
// low end limit of set temperature
if (solltemperatur < 25) {
solltemperatur = 25;
}
// high end limit of set temperature
if (solltemperatur > 70) {
solltemperatur = 70;
}
// turn the relay on if the environment temperature is lower
// than the set temperature
if (solltemperatur < temperatur) {
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
// turn of if not
else {
digitalWrite(10, LOW);
digitalWrite(11, LOW);
}
// update Sequenz DHT11
//delay(2000);
if ( TimePeriodIsOver(myLcdUpdateTimer, 2000) ) {
printToLCD(); // update LCD only once every 2000 milliseconds
}
}
best regards Stefan