Help Please- <Deque> not found

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();
}

Hello, do yourself a favour and please read How to get the best out of this forum and post accordingly (including code with code tags and necessary documentation for your ask like your exact circuit and power supply, links to components etc).

➜ we need to see the code

you need to install the deque library

I was looking for this in the IDE library section but nothing came up when I was searching for it, would you happen to know the name of the file or is it one I need to download from elsewhere?

Thank you, I will definitely look at the post, I literally made the account on here and asked the question.

Have updated question.

The STL is not available for AVR boards. So, you can't use std::deque unless you locate a third part implementation for AVR.

Try <deque.h>
BUT there is no such library. It will be a part of a larger list processing library with push pop, queue, deque

Where did you get the sketch from, parts of it are NOT Arduino code.

C++ libraries don't have a ".h". That's the name of a valid STL library ( https://en.cppreference.com/w/cpp/container/deque.html ), however (as I noted) it's not available for ARV-based boards.

Sorry, I am not C++ trained. In fact I didn't know you could use C++ headers or real C++ code files in Arduino. I know I have CPP files but there is no C++ code in them, they are simply containers for ino sketches.

After some massaging by the IDE (eg auto prototype generation), all Arduino files are compiled with an industry-standard C++ compiler. Even the most basic and common Arduino tasks are C++ - eg Serial.print().

Ah, I think of C++ as that inheritance stuff. Keep in mind, I first encountered C++ in the early to mid-80s and my computers did not have a C++ compiler. I guess I don't care what it's called as long as I can keep writing sketches like always.

1 Like

Funny that you should mention that. On a board like an Uno, Serial is an instance of the HardwareSerial class. It inherits from the (abstract) Stream class which in turn inherits from the (abstract) Print class.

When you call Serial.print(), it calls the print() function of the Print class which in turn calls the write() function of the HardwareSerial class as it overrides the (purely virtual) write() function in Print.

HEY, I am writing C++ after all! Still not putting it on my resume though.

2 Likes