I've put together a automatic watering system that also opens the door of the greenhouse with a servo motor, but the servo motor does not rotate once the temperature reaches the defines threshold of 30 degrees celcius. Why is that?
Here is the code:
#include <Servo.h>
#include <DHT.h>
// Constants
#define TEMP_THRESHOLD_HIGH 30
#define TEMP_THRESHOLD_LOW 20
// Pin Definitions
const int sensorpin = A0;
const int sensorpower = 12;
const int pumppin = 13;
const int servoPins[2] = {10, 11};
const int tempSensorPin = 9;
// DHT setup
#define DHTTYPE DHT22
DHT dht(tempSensorPin, DHTTYPE);
// Servo setup
Servo servos[2];
void setup() {
Serial.begin(9600);
// Initialize pump and sensor power pins
pinMode(sensorpower, OUTPUT);
pinMode(pumppin, OUTPUT);
// Initialize servos
for (int i = 0; i < 2; i++) {
servos[i].attach(servoPins[i]);
servos[i].write(0); // Set servos to 0 degrees initially
}
// Initialize DHT sensor
dht.begin();
}
void loop() {
// Read moisture sensor
digitalWrite(sensorpower, HIGH);
delay(10);
int sensor = analogRead(sensorpin);
digitalWrite(sensorpower, LOW);
Serial.println(sensor);
delay(10);
// Control pump based on sensor reading
if (sensor > 200) {
digitalWrite(pumppin, LOW); // Turn pump on
} else {
digitalWrite(pumppin, HIGH); // Turn pump off
}
// Read temperature from DHT22
float temperature = dht.readTemperature();
// Check if the reading was successful
if (isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Print temperature to the serial monitor
Serial.print("Temperature: ");
Serial.println(temperature);
// Control servos based on temperature
if (temperature >= TEMP_THRESHOLD_HIGH) {
for (int i = 0; i < 2; i++) {
servos[i].write(90); // Rotate servo to 90 degrees
}
} else if (temperature <= TEMP_THRESHOLD_LOW) {
for (int i = 0; i < 2; i++) {
servos[i].write(0); // Rotate servo back to 0 degrees
}
}
// Delay between readings
delay(2000);
}
how do you power the servos ?
add some prints to the Serial monitor to check what's going on
PS: (EDIT - don't read the below, I did not see it was 2 different constants )
there is no need for the second test
if (temperature >= TEMP_THRESHOLD_HIGH) {
for (int i = 0; i < 2; i++) {
servos[i].write(90); // Rotate servo to 90 degrees
}
} else if (temperature <= TEMP_THRESHOLD_LOW) {
for (int i = 0; i < 2; i++) {
servos[i].write(0); // Rotate servo back to 0 degrees
}
}
as if temperature is not >= TEMP_THRESHOLD_HIGH then it's <
if (temperature >= TEMP_THRESHOLD_HIGH) {
for (int i = 0; i < 2; i++) {
servos[i].write(90); // Rotate servo to 90 degrees
}
} else {
for (int i = 0; i < 2; i++) {
servos[i].write(0); // Rotate servo back to 0 degrees
}
}
you probably want to code an hysteresis otherwise near 30° your door risks to open an close every 2s as your reading might alternate between 29.95° and 30.05° for example....
Well, since you say the servos don't even initialize, put this
while(1);
at the very end of setup(), so that nothing further executes, and look at what the servos have done at that point. Is it true they didn't initialize, or is something in your loop() going awry right away?
If it is too hot
Turn on the A/C
If it is cold enough
Turn off the A/C
The else is fine and is slightly faster as it can "know" that if we are above the upper limit, we need not test for being below the lower limit.
I leave out the else, so sue me. It leaves the two actions standing alone, I find it easier to read and confirm as correct when reading. The inefficiency is minimal anyway, and it wouldn't surprise me if it got optimised and would skip the second test...
// Control servos based on temperature
if (temperature >= TEMP_THRESHOLD_HIGH) {
for (int i = 0; i < 2; i++) {
servos[i].write(90); // Rotate servo to 90 degrees
}
}
if (temperature <= TEMP_THRESHOLD_LOW) {
for (int i = 0; i < 2; i++) {
servos[i].write(0); // Rotate servo back to 0 degrees
}
}
What I meant about the temperature readings… are you seeing numbers which should trigger either of the conditions, and not seeing it happen?
Put some serial print statements right where you send to the servos, see what's really being said to them, or not.
type or paste code here
Have you said you made two servos sweep in the simplest sketch possible?
For now, can you omit the other sensor, or just leave it powered? Is 10 milliseconds warmup enough? I know you have expressed no trouble with that sensor, and also you don't have any hysteresis, which may be as you want.
yes, i'm reading the temperature from the temperature sensor. The servo motor does not react when the temperature reaches over the 30 degree threshold as it should. I can tell from the serial monitor that the temperature is above 30 degrees though.
WHat code do I write where in order to get a serial print of the servo motor?
I'll try with the while statement at the end of the setup part of the code.
if (temperature >= TEMP_THRESHOLD_HIGH) {
Serial.print("higher threshold exceeded, moving ");
for (int i = 0; i < 2; i++) {
Serial.print(i); Serial.print(" ");
servos[i].write(90); // Rotate servo to 90 degrees
}
Serial.println(".");
}
You do the other one. Imma bet those never get executed, or your servos need some changes.
You did not say (perhaps repeat) that you can make both servos sweep at the same time with a simple servo testing variation of the sweep examlke from the IDE.
I would make the change I suggested, run it, then change the starting angle to 30, for example, and repeat the process. If it succeeds in both, then at least you know that initial write works, and you can focus on what your code is doing wrong. My suspicion is, it's initializing to zero, but immediately getting some other setpoint from your code. Actually, just putting delay(2000) at the end of setup() will let you see a move, then another move. If it doesn't do either, then you know it's not even initializing in setup, and you can focus on what's wrong with your hardware.
For that,
two servos are way too much for the Arduino regulator. Do you have an external power supply, and if so, how is it wired? Power to servo+ and -? Is the - side of that power connected to the Arduino GND? If not, it should be.
And you have two sevrvos. So the same, except different.
What is the power supply that is just a block in "your" wiring picture?
Sometimes running heavier currents through a bread board is not a Good Idea.
If it prints a certain temperature that shoukd move the servos, and it isn't printing let alone trying to move the servos, you have some kind of problem that hasn't been discovered.Yet.
I actually only have one micro servo connected to pin 10.
The dht22 sensor stops working when I upload a new sketch with the while(1); code at the end of the setup. I don't think there is a correlation between the added code and the dht22 sensor not printing, yet the dht22 sensors seems unstable.
the power supply is the the USB cable connected to the Arduino and the Arduino 5v connected to the bread board and GND on the Arduino conncted to minus.
Oh, I just noticed that I had not connected GND to the bread board.
I raised the temp above 30 degrees and reversed the cables from the servo motor on the bread board and the servo rotated 180 degrees (?). The DHT22 printed "Failed to read from DHT sensor!" after the servo had rotated.
The servo should rotate back once the temp drops below 20 degrees.