Advertisement
Brendan_Bode

Fan Unit Code

May 11th, 2025
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.04 KB | None | 0 0
  1. //================================== Libraries Needed ==================================
  2.  
  3. #include <SPI.h>
  4. #include "RF24.h"
  5.  
  6. //==================================  NRF Pins ==================================
  7.  
  8. #define CE_PIN 3
  9. #define CSN_PIN 5
  10.  
  11. // ================================== Relay Control Pin ==================================
  12.  
  13. #define fanRelay 4
  14.  
  15. // ================================== NRF24L01 Vairables ==================================
  16.  
  17. RF24 radio(CE_PIN, CSN_PIN);
  18. uint8_t address[][6] = { "1Node", "2Node" }; //1Node
  19. bool radioNumber = 0; // This is Radio 0
  20.  
  21. // ================================== NRF24L01 Recovery ==================================
  22.  
  23. unsigned long lastReceiveTime = 0;    // Used to calculate change in time for timers
  24. unsigned long recoveryStartTime = 0;
  25.  
  26. bool inRecovery = false;
  27. bool awaitingNewData = false; // Used to force the fan to actually recieve new data when recovering from transmission error before resuming operation
  28.  
  29. // ================================== Incoming Data Structure from Reciever ==================================
  30.  
  31. struct SensorData {
  32.   float ambientTemp;
  33.   float objectTemp;
  34.   uint16_t CO2; // Not being used in this device, but if another device was using it from same transmission, would be important
  35.   uint16_t TVOC;
  36.   bool flameDetected;
  37. };
  38.  
  39. SensorData receivedData;
  40.  
  41. // ================================== Designating fan PWM pin ==================================
  42.  
  43. const int fan_control_pin = 9;  // analog value from 0 to 255 to control rpm of fan, higher number ='s higher rpm
  44.  
  45. // ================================== Flame Detector ==================================
  46.  
  47. bool flameCooldown = false;                
  48. unsigned long flameCooldownStart = 0;      
  49.  
  50. // ================================== Enter Setup ==================================
  51.  
  52. void setup() {
  53.   pinMode(fan_control_pin, OUTPUT);  
  54.   pinMode(fanRelay, OUTPUT);
  55.   Serial.begin(115200);
  56.  
  57.   if (!radio.begin()) {
  58.     Serial.println("Radio hardware not responding!");
  59.     while (1); // If Radio isn't working, stalls out program
  60.   }
  61.  
  62.   radio.setAutoAck(true);         //Setup for Transciever
  63.   radio.enableDynamicPayloads();
  64.   radio.setRetries(5, 15);
  65.   radio.setPALevel(RF24_PA_LOW);
  66.   radio.setDataRate(RF24_1MBPS);
  67.  
  68.   Serial.println(F("This is Radio 0 - Receiver"));
  69.  
  70.   radio.openWritingPipe(address[radioNumber]);
  71.   radio.openReadingPipe(1, address[!radioNumber]);
  72.   radio.startListening();
  73.  
  74.   lastReceiveTime = millis();
  75. }
  76.  
  77. // ================================== Enter Main Loop ==================================
  78. void loop() {
  79.  
  80.   if (flameCooldown) { // If a flame has been detected, "pause" system for 10 seconds
  81.   unsigned long elapsed = millis() - flameCooldownStart;
  82.     if (elapsed >= 10000) {
  83.       flameCooldown = false;
  84.       Serial.println("Flame cooldown ended. Resuming fan operation.");
  85.     } else {
  86.     unsigned long secondsLeft = (10000 - elapsed) / 1000;
  87.     Serial.print("Flame detected! Cooling down... ");
  88.     Serial.print(secondsLeft); Serial.println("s left.");
  89.     }
  90.   }
  91.   // Check for new data
  92.   if (radio.available()) {
  93.     radio.read(&receivedData, sizeof(SensorData));
  94.     Serial.println("Received data:");
  95.     Serial.print("Ambient: "); Serial.print(receivedData.ambientTemp); Serial.println(" C ");
  96.     Serial.print("Object: "); Serial.print(receivedData.objectTemp); Serial.println(" C ");
  97.     Serial.print("TVOC: "); Serial.print(receivedData.TVOC); Serial.println(" ppb ");
  98.     Serial.print("Flame: "); Serial.println(receivedData.flameDetected ? "Yes" : "No");
  99.  
  100.     lastReceiveTime = millis(); // Sets the time that a message was last recieved, used to calculate if more then 20 seconds has passed later on
  101.  
  102.     if (receivedData.flameDetected && !flameCooldown) { //If a flame is being seen by sensor, and the device is currently not reacting to it turn off fan and start timer
  103.       Serial.println("Flame detected — turning off fan for 10 seconds!");
  104.       digitalWrite(fanRelay, LOW);
  105.       analogWrite(fan_control_pin, 0);
  106.       flameCooldown = true;
  107.       flameCooldownStart = millis(); // Assigns a time to flameCooldownStart
  108.     }
  109.     // Exit recovery mode if needed by seeing if new data has popualted in memory
  110.     if (awaitingNewData) {  
  111.       Serial.println("New data received — exiting recovery mode.");
  112.       awaitingNewData = false;
  113.       inRecovery = false;
  114.     }
  115.     // Only control the fan if not in recovery or flame cooldown
  116.     if (!inRecovery && !flameCooldown) {
  117.       handleFan(receivedData.TVOC, receivedData.ambientTemp, receivedData.objectTemp); // Fan Logic elsewhere to keep this area clean
  118.     }
  119.   }
  120.   if (!inRecovery && millis() - lastReceiveTime > 20000) {                                   // If new data hasn't been recieved in the last 20 seconds,
  121.     Serial.println("No data received for 20s — entering recovery mode. Turning off fan.");   // trys to reboot the device in order to get it working again
  122.     digitalWrite(fanRelay, LOW);
  123.     analogWrite(fan_control_pin, 0);
  124.     Serial.println("Resetting NRF24L01 module...");
  125.     radio.powerDown();
  126.     delay(1000);
  127.     radio.powerUp();
  128.     radio.startListening();
  129.  
  130.     inRecovery = true;
  131.     recoveryStartTime = millis();
  132.   }
  133.   // Delay recovery mode resume
  134.   if (inRecovery && !awaitingNewData && millis() - recoveryStartTime > 5000) {
  135.     Serial.println("Recovery mode active. Waiting for new data before restarting fan.");
  136.     awaitingNewData = true;
  137.   }
  138.   delay(500);
  139. }
  140.  
  141. // ================================== handleFan Function ==================================
  142.  
  143. void handleFan(float TVOC, float ambientTemp, float objectTemp) {
  144.   float tempDelta = objectTemp - ambientTemp; // Comparing the temperature of whats being sensed to the temperature of the area around the sensor
  145.   float fanPWM = TVOC * .2;   // TVOC Value is multiplied by scaling coefficient to optimize having a variety of values for PWM output to fan
  146.  
  147.   if (fanPWM < 60) {  //If TVOC value after being scaled by the scaling coefficient is still less then 60, fan stays/turns off
  148.     digitalWrite(fanRelay, LOW);
  149.     analogWrite(fan_control_pin, 0);
  150.     Serial.println("RELAY OFF (low TVOC)");
  151.     Serial.println();
  152.     return;
  153.   }
  154.   if (tempDelta > 5.0) {  //If the difference in ambient temperature from the temperature being sensed is more then 5 degrees Celsius, scale up PWM output
  155.     fanPWM *= 1.25; // Increase 25%
  156.     Serial.println("Object temp much higher than ambient — boosting fan.");
  157.   }
  158.   if (fanPWM > 254){ //If output exceeds what it can possibly be, clamps the highest value at 255, which is max Output for the fan
  159.     Serial.println("Due to simulating enviroment for capstone presentation, value exceeds normal expected range: Clamping at 255");
  160.     Serial.print("Current value: ");
  161.     Serial.print(fanPWM);
  162.     fanPWM = 255;
  163.   }
  164.   digitalWrite(fanRelay, HIGH);  //Makes sure the fan is on
  165.   analogWrite(fan_control_pin, fanPWM); //Fan is told to run at value of fanPWM after it had been scaled
  166.   Serial.print("Fan running at PWM: "); Serial.println(fanPWM);
  167.   Serial.println();
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement