DHT controlled stepper motor

Hi there,

I am building a humidity/temperature controlled fan with iris+stepper motor for my basement where humidty is really high. Using Arduino UNO, L298N driver and 28BYJ-48 stepper motor.
In my code I am using temperature sensor to work with not the humidity.
The aim would be when the sensor value (hum) goes up higher than the threshold (32%) then the stepper motor open the iris and starts the ventillation. It keeps in this phase until the humidity goes back under the threshold. If reaches a lower value than 32% it closes the iris and stops the ventillation. This is the concept and this is my code. Is it a good approach or my code is already a crap? Can you advise how to move forward?

#include <AccelStepper.h>
#include "DHT.h"
#define DHTPIN 7
#define DHTTYPE DHT11

AccelStepper stepper; // Defaults to AccelStepper (4 pins) on 2, 3, 4, 5
DHT dht(DHTPIN, DHTTYPE);

//Termometer Icon
byte tempchar1[8] = {B00000, B00001, B00010, B00100, //Row 0, Col 2
                     B00100, B00100, B00100, B00111,
                    };
byte tempchar2[8] = {B00111, B00111, B00111, B01111, //Row 1, Col 2
                     B11111, B11111, B01111, B00011,
                    };
byte tempchar3[8] = {B00000, B10000, B01011, B00100, //ROW 0, Col 3
                     B00111, B00100, B00111, B11100,
                    };
byte tempchar4[8] = {B11111, B11100, B11100, B11110, //Row 1, Col 3
                     B11111, B11111, B11110, B11000,
                    };
//Humidity Icon
byte humchar1[8] = {B00000, B00001, B00011, B00011, //Row 0, Col 2
                    B00111, B01111, B01111, B11111,
                   };
byte humchar2[8] = {B11111, B11111, B11111, B01111, //Row 1, Col 2
                    B00011, B00000, B00000, B00000,
                   };
byte humchar3[8] = {B00000, B10000, B11000, B11000, //ROW 0, Col 3
                    B11100, B11110, B11110, B11111,
                   };
byte humchar4[8] = {B11111, B11111, B11111, B11110, //Row 1, Col 3
                    B11100, B00000, B00000, B00000,
                   };

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 4);

void setup() {
  dht.begin();
  lcd.backlight();
  lcd.init();
  lcd.clear();
  Serial.begin(9600);
  stepper.setMaxSpeed(200); //Stepper MaxSpeed
  stepper.setAcceleration(40); //Stepper Acceleration
  stepper.moveTo(2000); //Stepper MaxSteps
}

void dht_lcd() {
  lcd.createChar(1, tempchar1);
  lcd.createChar(2, tempchar2);
  lcd.createChar(3, tempchar3);
  lcd.createChar(4, tempchar4);
  lcd.setCursor(0, 0);
  lcd.write(1);
  lcd.setCursor(0, 1);
  lcd.write(2);
  lcd.setCursor(1, 0);
  lcd.write(3);
  lcd.setCursor(1, 1);
  lcd.write(4);
  lcd.setCursor(3, 0);
  lcd.print((float)dht.readTemperature());//print the temperature
  lcd.print("C");
  lcd.createChar(5, humchar1);
  lcd.createChar(6, humchar2);
  lcd.createChar(7, humchar3);
  lcd.createChar(8, humchar4);
  lcd.setCursor(11, 0);
  lcd.write(5);
  lcd.setCursor(11, 1);
  lcd.write(6);
  lcd.setCursor(12, 0);
  lcd.write(7);
  lcd.setCursor(12, 1);
  lcd.write(8);
  lcd.setCursor(14, 0);
  lcd.print((float)dht.readHumidity());//print the humidity
  lcd.print("%");
  delay(500);
  lcd.clear();
}

void open() {
  stepper.moveTo(2000);
  while (stepper.currentPosition() != 1800) // Full speed up to 1800
    stepper.run();
  stepper.stop(); // Stop as fast as possible: sets new target
  stepper.runToPosition();
  stepper.stop();
}

void close() {
  stepper.moveTo(0);
  while (stepper.currentPosition() != 200) // Full speed back to 0
    stepper.run();
  stepper.stop(); // Stop as fast as possible: sets new target
  stepper.runToPosition();
  stepper.stop();
}

void loop() {
  dht_lcd();
  int temp_threshold = 24;
  int hum_thershold = 32;
  float hum_sens = dht.readHumidity();
  float temp_sens = dht.readTemperature();
  if (temp_sens >= temp_threshold) {
    open();
  }
  else if ( temp_sens < temp_threshold) {
    close();
  }
}

Why not do this in setup?

What happens when you test your code on your hardware?

Please remember to use code tags when posting code.

Sorry I forgot the code tag. I just created a void for the LCD as it does not work when the motor is running. Maybe it is not the best solution and it is not working also. I am gonna put it back to setup.

My code works for the open sequence only, related to temp what I am measuring now in the code if temp goes up higher than 24 degrees it opens the iris, start the fan, but code stucks here. Does not step to the close sequence when temp drops under 24 degrees. Maybe it is not that simple as I imagined.

Generally, it helps debugging if the value that you display, and the value that you use to compare with your threshold are the same; in other words, read once per loop cycle, and store to a variable - display the value of the variable and compare the variable to the threshold

No, you created a function.

Most libraries only allow custom characters 0..7

Understand also the LCD related answers. Thank you!

Regarding the core function not the LCD do you have any advice if I go with the same structure or use other?
How would be the code more efficient ? I am beginner programming Arduino and learning it.

If something isn't greater than or equal to something else, then it must be less than the something else; no need to test it.

How can I achieve to check the open and close sequence of the iris and fan if I don't use e.g. if ...else if?

There seems to be one too many "if"s in that sentence...and your code :wink:

Yeah I know, I would like to consolidate somehow to be transparent and more efficient, but don't know which way could be the best of coding this concept. Could you help me at least with an example if you have? I tried to find examples when DHT controlles motors but for stepper I have not found anything. That is the reason why I turned to this forum for support. If I have a better knowledge about the framework what should be used, then I can extend it with my ideas.

I'm not sure what you're asking, but

if (temp_sens >= temp_threshold) {
  open();
} else  {
  close();
}

looks to me to be sufficient.
It's not really a question of efficiency, more of making the code as simple as it can be, and that way, bugs have fewer dark corners to hide in.

You didn't answer my earlier question about which LCD allows more than eight custom characters.

And about those missing code tags...you can edit them into your earlier post.

LCD is a 4*20 display and I am using custom 2x2 icons.
Code tag fixed

if (temp_sens >= temp_threshold) {
open();
} else {
close();
}

I tried to be simple and use simple if...else conditions, but when it opens the iris on DHT demand it will close it and repeat until the value drop below threshold. I'd like to keep it open until the value drops under threshold, so in my logic need to keep it in the "loop" or cycle until the value will be not valid for the first condition and then initiate the close procedure. In my logic.. I think I made it too complex and this causes issues.

And does it permit more than eight custom characters?

I think the other concept you may need to Google is "hysteresis".

LCD is a 4*20 display

Yes it allows 8 but more I did not tried.
I search for that hysteresis. Thanks!

 lcd.createChar(8, humchar4);

That looks like a try to me.