Hi All,
I was wondering if I could get some help as i'm new to coding. I have worked on a code to be able to control a PWM Fan based on Humidity, but when I go to program the Arduino Uno board, i get a message:
fatal error: deque: No such file or directory
#include
^~~~~~~
compilation terminated.
exit status 1
Compilation error: deque: No such file or directory
And I am at a loss on how to rectify the issue.
I am using IDE 2.3.6 if that makes any difference.
Many thanks in advance.
Update Code & Components:
Board: Arduino Uno
Sensors:
DHT11 Temp & Humidity Sensor
Adafruit 555 PWM Output STEMMA
#include "DHT.h"
#include <RunningAverage.h>
#include <deque>
// --- Fan Control Pin Definitions ---
const int pwmPin = 9; // You can change this to any suitable PWM pin on your Arduino
const int forwardPin = 10;
const int reversePin = 11;
// --- DHT11 Sensor Definitions ---
#define DHTPIN 2 // Digital pin connected to the DHT11 sensor
#define DHTTYPE DHT11 // DHT 11
// --- Sampling and Averaging Definitions ---
#define SAMPLE_INTERVAL 2000 // Milliseconds between readings (2 seconds)
#define AVERAGING_PERIOD 120000 // Milliseconds for averaging (2 minutes)
#define NUM_SAMPLES AVERAGING_PERIOD / SAMPLE_INTERVAL
#define HUMIDITY_THRESHOLD_INCREASE 0.03 // 3% increase threshold (as a decimal)
// --- Historical Data Storage ---
#define HISTORY_DURATION 7200000UL // 2 hours in milliseconds
#define HISTORY_SAMPLE_INTERVAL AVERAGING_PERIOD
const int HISTORY_SIZE = HISTORY_DURATION / HISTORY_SAMPLE_INTERVAL;
std::deque<float> humidityHistory;
unsigned long lastHistoryUpdateTime = 0;
// --- Fan Speed to RPM Mapping (Forward) ---
struct RPMMap {
int pwmPercentage;
int rpm;
};
const RPMMap forwardRPMMap[] = {
{0, 3500},
{10, 3275},
{20, 2450},
{30, 1650},
{40, 875},
{50, 0} // Approximate stop range
};
const int numForwardRPMPoints = sizeof(forwardRPMMap) / sizeof(forwardRPMMap[0]);
// --- Fan Speed to RPM Mapping (Reverse) ---
const RPMMap reverseRPMMap[] = {
{60, 825},
{70, 1550},
{80, 2350},
{90, 3150},
{100, 3500}
};
const int numReverseRPMPoints = sizeof(reverseRPMMap) / sizeof(reverseRPMMap[0]);
// --- Global Variables ---
DHT dht(DHTPIN, DHTTYPE);
RunningAverage absoluteHumidityAvg(NUM_SAMPLES);
float currentAverageHumidity = 0.0;
bool firstRun = true;
bool fanForward = true; // Current fan direction
int currentPWMPerc = 0; // Current PWM percentage (0-100)
unsigned long startupTimer = 0;
bool startupSequenceComplete = false;
// --- Function Declarations ---
void setFanSpeed(int pwmValue);
void setFanDirection(bool forward);
float calculateAbsoluteHumidity(float temperature, float humidity);
int mapPercentageToPWM(int percentage);
int mapRPMtoPWM(int targetRPM, bool forwardDirection);
void controlFanBasedOnHumidity();
void runStartupSequence();
float getAverageHumidityOverHistory();
// --- Fan Control Functions ---
// Function to set the fan speed using PWM (0-255)
void setFanSpeed(int pwmValue) {
analogWrite(pwmPin, pwmValue);
}
// Function to set the fan direction (assuming HIGH enables the direction)
void setFanDirection(bool forward) {
digitalWrite(forwardPin, forward ? HIGH : LOW);
digitalWrite(reversePin, forward ? LOW : HIGH);
fanForward = forward;
}
// Function to map a percentage (0-100) to a PWM value (0-255)
int mapPercentageToPWM(int percentage) {
return map(percentage, 0, 100, 0, 255);
}
// Function to map a target RPM to a PWM value (0-255) based on the direction
int mapRPMtoPWM(int targetRPM, bool forwardDirection) {
if (forwardDirection) {
for (int i = 0; i < numForwardRPMPoints - 1; i++) {
if (targetRPM >= forwardRPMMap[i+1].rpm && targetRPM <= forwardRPMMap[i].rpm) {
return map(targetRPM, forwardRPMMap[i+1].rpm, forwardRPMMap[i].rpm, mapPercentageToPWM(forwardRPMMap[i+1].pwmPercentage), mapPercentageToPWM(forwardRPMMap[i].pwmPercentage));
}
}
// Handle cases outside the defined range
if (targetRPM > forwardRPMMap[0].rpm) return 255;
if (targetRPM < forwardRPMMap[numForwardRPMPoints - 1].rpm) return 0;
} else { // Reverse direction
for (int i = 0; i < numReverseRPMPoints - 1; i++) {
if (targetRPM >= reverseRPMMap[i].rpm && targetRPM <= reverseRPMMap[i+1].rpm) {
return map(targetRPM, reverseRPMMap[i].rpm, reverseRPMMap[i+1].rpm, mapPercentageToPWM(reverseRPMMap[i].pwmPercentage), mapPercentageToPWM(reverseRPMMap[i+1].pwmPercentage));
}
}
// Handle cases outside the defined range
if (targetRPM > reverseRPMMap[numReverseRPMPoints - 1].rpm) return 255;
if (targetRPM < reverseRPMMap[0].rpm) return 0;
}
return 0; // Default to 0 if no match found
}
// --- DHT11 Sensor and Absolute Humidity Functions ---
// Function to calculate absolute humidity (in g/m^3)
float calculateAbsoluteHumidity(float temperature, float humidity) {
// Constants for water vapor properties
float a = 6.112; // Vapor pressure constant (hPa)
float b = 17.67; // Vapor pressure constant
float c = 243.5; // Vapor pressure constant (degrees Celsius)
float Mv = 18.015; // Molar mass of water vapor (g/mol)
float R = 8.314; // Universal gas constant (J/(mol*K))
// Convert temperature to Kelvin
float T_kelvin = temperature + 273.15;
// Calculate saturation vapor pressure (P_sat) in hPa using the Antoine equation
float P_sat = a * exp((b * temperature) / (c + temperature));
// Calculate actual vapor pressure (P_v) in hPa
float P_v = (humidity / 100.0) * P_sat;
// Calculate absolute humidity (AH) in g/m^3
return (P_v * Mv) / (R * T_kelvin) * 100.0;
}
// --- Startup Sequence Function ---
void runStartupSequence() {
if (millis() - startupTimer < 60000) {
Serial.println("Startup: Running fan in Reverse at 90% PWM (approx. 3150 RPM)...");
setFanDirection(false);
setFanSpeed(mapPercentageToPWM(90));
} else if (!startupSequenceComplete) {
Serial.println("Startup: Switching fan to Forward at 30% PWM (approx. 1650 RPM)...");
setFanDirection(true);
setFanSpeed(mapPercentageToPWM(30));
startupSequenceComplete = true;
}
}
// --- Historical Average Humidity Function ---
float getAverageHumidityOverHistory() {
if (humidityHistory.empty()) {
return 0.0; // Or some other default value if no history
}
float sum = 0;
for (float val : humidityHistory) {
sum += val;
}
return sum / humidityHistory.size();
}
// --- Humidity Based Fan Control Function ---
void controlFanBasedOnHumidity() {
if (startupSequenceComplete && absoluteHumidityAvg.getCount() == NUM_SAMPLES) {
currentAverageHumidity = absoluteHumidityAvg.getAverage();
float historicalAverage = getAverageHumidityOverHistory();
if (historicalAverage > 0 && currentAverageHumidity > (historicalAverage * (1 + HUMIDITY_THRESHOLD_INCREASE))) {
Serial.println("*** Significant Absolute Humidity Increase Detected (compared to 2-hour average)! ***");
Serial.print("Historical Average (2 hours): ");
Serial.print(historicalAverage);
Serial.print(" g/m^3, Current Average (2 min): ");
Serial.print(currentAverageHumidity);
Serial.println(" g/m^3");
Serial.println("Turning fan to Reverse at 90% PWM (approx. 3150 RPM) due to humidity increase.");
setFanDirection(false);
setFanSpeed(mapPercentageToPWM(90));
} else if (historicalAverage > 0 && currentAverageHumidity < (historicalAverage * (1 + HUMIDITY_THRESHOLD_INCREASE))) {
// Only switch back if the humidity has dropped below the threshold
if (!fanForward) {
Serial.println("Absolute humidity dropped below threshold (compared to 2-hour average), switching fan to Forward at 30% PWM (approx. 1650 RPM).");
setFanDirection(true);
setFanSpeed(mapPercentageToPWM(30));
}
}
}
// Update History
if (millis() - lastHistoryUpdateTime >= HISTORY_SAMPLE_INTERVAL && absoluteHumidityAvg.getCount() == NUM_SAMPLES) {
humidityHistory.push_back(currentAverageHumidity);
if (humidityHistory.size() > HISTORY_SIZE) {
humidityHistory.pop_front();
}
lastHistoryUpdateTime = millis();
}
// Reset Running Average for the next 2-minute period
if (absoluteHumidityAvg.getCount() == NUM_SAMPLES) {
absoluteHumidityAvg.clear();
}
}
// --- Setup Function ---
void setup() {
Serial.begin(9600);
Serial.println("Reversible Fan Control with Specific RPM Mapping and DHT11 Monitoring");
// --- Fan Control Setup ---
pinMode(pwmPin, OUTPUT);
pinMode(forwardPin, OUTPUT);
pinMode(reversePin, OUTPUT);
setFanSpeed(0); // Initialize stopped
setFanDirection(true); // Initial direction (will be overridden by startup)
// --- DHT11 Sensor Setup ---
dht.begin();
absoluteHumidityAvg.clear(); // Initialize the running average
// --- Startup Timer ---
startupTimer = millis();
lastHistoryUpdateTime = millis(); // Initialize history update time
}
// --- Main Loop ---
void loop() {
delay(SAMPLE_INTERVAL);
// --- Run Startup Sequence ---
if (!startupSequenceComplete) {
runStartupSequence();
return; // Skip sensor readings and humidity control during startup
}
// --- Read DHT11 Sensor ---
float h = dht.readHumidity();
float t = dht.readTemperature();
// Check if any reads failed
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// --- Calculate and Average Absolute Humidity (over 2 minutes) ---
float currentAbsoluteHumidity = calculateAbsoluteHumidity(t, h);
absoluteHumidityAvg.addValue(currentAbsoluteHumidity);
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" % \tTemperature: ");
Serial.print(t);
Serial.print(" *C \tCurrent Absolute Humidity: ");
Serial.print(currentAbsoluteHumidity);
Serial.print(" g/m^3 \tAverage Absolute Humidity (2 min): ");
Serial.print(absoluteHumidityAvg.getAverage());
Serial.println(" g/m^3");
// --- Control Fan Based on Humidity ---
controlFanBasedOnHumidity();
}