I am using a DHT11 temperature/humidity sensor to control the speed at which a mini dc water pump runs. The higher the temperature, the faster the pump motor will run. But the sensor can only be sampled at a max frequency of once every two seconds. The motor would have to be controlled constantly. I modeled part of my code after the BlinkWithoutDelay example sketch for an LED. But now whenever I run it, the motor is always spinning at top speed, and not slowing when the temperature is low.
Here's what I have so far: Any tips?
#include <dht11.h>
#include <Versalino.h>
dht11 DHT11;
const unsigned int temp_sensor_pin = 2; //will connect the sensor to digital pin 2
const unsigned int in3 = 10; //in3 pin on the motor driver is connected to digital pin 10
const unsigned int in4 = 11; //in4 pin on the motor driver is connected to digital pin 11
const unsigned int baud_rate = 9600;
float current_temp = 0.0;
unsigned long last_measurement = millis();
void setup(){
Serial.begin(baud_rate);
pinMode(in3, OUTPUT); //to control the motor driver pins
pinMode(in4, OUTPUT);
pinMode(temp_sensor_pin, INPUT_PULLUP);
DHT11.attach(temp_sensor_pin);
}
void loop(){
unsigned long current_millis = millis();
if(abs(current_millis - last_measurement) >= 1000){
current_temp = getTemp();
last_measurement = current_millis;
}
float previous_temp = current_temp; //don't really know if this makes sense, but I'm thinking that there should be a temporary variable to store the last known temperature value
if(previous_temp <= 70){ //run at low speed if temp is cool
analogWrite(in3, 85);
digitalWrite(in4, LOW);
}
if(previous_temp > 70 && previous_temp <= 80){ //run at medium speed if temp is warm
analogWrite(in3, 128);
digitalWrite(in4, LOW);
}
if(previous_temp > 80){ //run at full speed if temp is high
analogWrite(in3, 255);
digitalWrite(in4, LOW);
}
}
float getTemp(){
int check = DHT11.read();
switch(check){ //switch case statement to perform self check
case 0: Serial.println("OK"); break;
case -1: Serial.println("Checksum error"); break;
case -2: Serial.println("Time out error"); break;
default: Serial.println("Unknown error"); break;
}
float result = DHT11.fahrenheit();
Serial.print("Temp: ");
Serial.print(result);
Serial.println(" F");
return result;
}
I think my main problem is that the concurrently running code segments are dependent on each other. The value returned from one section dictates what will happen in the other.
Hmm, so I hit the reset button and somehow it's working. I also changed the code a bit, but I don't think it was anything time related. Here's what I have now:
#include <dht11.h>
#include <Versalino.h>
dht11 DHT11;
const unsigned int temp_sensor_pin = 2; //will connect the sensor to digital pin 2
const unsigned int in3 = 10; //in3 pin on the motor driver is connected to digital pin 10
const unsigned int in4 = 11; //in4 pin on the motor driver is connected to digital pin 11
const unsigned int baud_rate = 9600;
float current_temp = 0.0;
unsigned long last_measurement = millis();
void setup(){
Serial.begin(baud_rate);
pinMode(in3, OUTPUT); //to control the motor driver pins
pinMode(in4, OUTPUT);
pinMode(temp_sensor_pin, INPUT_PULLUP);
DHT11.attach(temp_sensor_pin);
}
void loop(){
unsigned long current_millis = millis();
if(abs(current_millis - last_measurement) >= 2000){
current_temp = getTemp();
last_measurement = current_millis;
}
float previous_temp = current_temp; //don't really know if this makes sense, but I'm thinking that there should be a temporary variable to store the last known temperature value
if(previous_temp < 65){ //completely turn off if temp is cold
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
if(previous_temp <= 70 && previous_temp >= 65){ //run at low speed if temp is cool
analogWrite(in3, 70);
digitalWrite(in4, LOW);
}
if(previous_temp > 70 && previous_temp <= 80){ //run at medium speed if temp is warm
analogWrite(in3, 128);
digitalWrite(in4, LOW);
}
if(previous_temp > 80){ //run at full speed if temp is high
analogWrite(in3, 255);
digitalWrite(in4, LOW);
}
}
float getTemp(){ //get temperature reading from DHT11
int check = DHT11.read();
switch(check){ //switch case statement to perform self check
case 0: Serial.println("OK"); break;
case -1: Serial.println("Checksum error"); break;
case -2: Serial.println("Time out error"); break;
default: Serial.println("Unknown error"); break;
}
float result = DHT11.fahrenheit();
Serial.print("Temp: ");
Serial.print(result);
Serial.println(" F");
return result;
}
Do you know if INPUT_PULLUP should be used on line 13? I read that the DHT11 should be connected so that a pull-up resistor is attached to the signal pin.
I don't understand this. When you set a digital pin producing a PWM output, the pin keeps doing that until you change it. You don't have any information to change the value until you read the sensor again.
@PaulS: I guess I answered my own question. They don't interfere with each other, actually.
@Nick Gammon: What will the different pull-up values do to the sensor or its readings? I've read several spec sheets and some say on some models of the sensor, a pull-up R is recommended, but on others it's not. Would adding a pull-up result in a more stable sensor reading?