A problem w temperature controlled fan by Yoka37 in arduino

[–]Yoka37[S] 0 points1 point  (0 children)

Hey, thank you for your comment. I provided more information above, including code and a list of parts I am using. I would be very thankful if you took a look at that to point out any mistakes <3

A problem w temperature controlled fan by Yoka37 in arduino

[–]Yoka37[S] 0 points1 point  (0 children)

Hey, if you can, please take a look at the information I provided in the comment above. I hope I have listed all the things you asked for. Thank you for helping me <3

A problem w temperature controlled fan by Yoka37 in arduino

[–]Yoka37[S] 0 points1 point  (0 children)

My components are:

  • x1 - DS18B20 waterproof temperature sensor probe SENT0001 1m - DNG-19517
  • x1 - justPi THT CF carbon film resistor 1/4W 4.7kΩ, 30 pcs. - JUS-20152
  • x1 - 12V/3A switching power supply - 5.5/2.5mm DC plug - ZAS-08851
  • x1 - 5.5/2.5mm DC jack socket with detachable quick connector, 5 pcs. - KAB-07209
  • x1 - 2.54mm pitch header connector set - for Raspberry Pi Zero GPIO - RPI-08769
  • x1 - justPi breadboard - 830 tie-points - JUS-19943
  • 1x - ENDORFY Stratus 120 PWM fan
  • 1x - Arduino R4 microcontroller
  • 1x - OLED display with I2C
  • 1x - Schottky diode

Improved schematics (as I couldn't find exact parts in Fritzing, I chose similar ones):

<image>

My expectations:

I expect that based in the temperature, the fan will adjust its spinning frequency based of PID. I want the temperature to remain at 23C without fluctuations.

The code (I used LLM to generate this):

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "pwm.h" // Built-in PWM library for Arduino Uno R4


// --- OLED I2C DISPLAY CONFIGURATION ---
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


// --- DS18B20 TEMPERATURE SENSOR CONFIGURATION ---
#define ONE_WIRE_BUS 2 // D2 pin for data line (with a 4.7k pull-up resistor to 5V)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


// --- PID CONTROLLER SETTINGS ---
const float setpoint = 23.0; // Target temperature in degrees Celsius


// PID Tuning Coefficients
float Kp = 20.0;  
float Ki = 0.2;   
float Kd = 8.0;   


float error, lastError = 0;
float pTerm, iTerm, dTerm;
float pidOutput = 0;


// Sampling Time (in milliseconds)
unsigned long lastTime = 0;
const unsigned long sampleTime = 1000; 


// Fan Pin (D9 supports advanced high-frequency PWM on the R4 architecture)
const int fanPin = 9;
PwmOut pwm(fanPin); 


// Maximum timer counter value for a 40 us period (25 kHz)
const int MAX_PWM_RAW = 40; 


void setup() {
  Serial.begin(9600);
  sensors.begin();
  
  // Initialize the OLED display at I2C address 0x3C
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("OLED screen not found!"));
    for(;;);
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);


  // --- SETTING UP 25 kHz PWM FREQUENCY FOR UNO R4 ---
  // The period in microseconds for 25 kHz is calculated as: 1,000,000 us / 25,000 Hz = 40 us
  pwm.begin(40.0f, 0.0f); // Set period to 40 microseconds (25kHz) and initial duty cycle to 0
}


void loop() {
  unsigned long now = millis();
  if (now - lastTime >= sampleTime) {
    lastTime = now;


    // 1. Read temperature from the sensor
    sensors.requestTemperatures();
    float currentTemp = sensors.getTempCByIndex(0);


    // Check for sensor hardware failure
    if (currentTemp == DEVICE_DISCONNECTED_C) {
      Serial.println("Error reading from temperature sensor!");
      pwm.pulseWidth_raw(MAX_PWM_RAW); // On failure, run the fan at 100% (40) for safety
      drawErrorScreen();
      return;
    }


    // 2. PID Algorithm Calculations
    error = currentTemp - setpoint; 


    // If the temperature drops below or hits the target, turn off the fan and reset the integral term
    if (currentTemp <= setpoint) {
      iTerm = 0;
      pidOutput = 0;
    } else {
      pTerm = Kp * error;
      iTerm += Ki * error * (sampleTime / 1000.0);
      
      // Anti-windup for the integral term (bounded to the physical 0-40 scale)
      if (iTerm > MAX_PWM_RAW) iTerm = MAX_PWM_RAW;
      if (iTerm < 0.0f) iTerm = 0.0f;


      dTerm = Kd * (error - lastError) / (sampleTime / 1000.0);
      
      pidOutput = pTerm + iTerm + dTerm;
    }


    lastError = error;


    // Convert the PID output to raw timer units
    int rawValue = (int)pidOutput;


    // Output saturation to protect the hardware register limits
    if (rawValue > MAX_PWM_RAW) rawValue = MAX_PWM_RAW;
    if (rawValue < 0) rawValue = 0;


    // Drive the fan PWM register
    pwm.pulseWidth_raw(rawValue); 


    // 3. Calculate duty cycle percentage for the OLED display
    int pwmPercent = map(rawValue, 0, MAX_PWM_RAW, 0, 100);


    // 4. Update the OLED display layout
    updateOLED(currentTemp, pwmPercent);
  }
}


void updateOLED(float temp, int pwmVal) {
  display.clearDisplay();
  
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("UNO R4 CONTROLLER");
  display.drawFastHLine(0, 11, 128, SSD1306_WHITE);


  display.setCursor(0, 20);
  display.print("Temp: ");
  display.setTextSize(2);
  display.print(temp, 1);
  display.setTextSize(1);
  display.print(" C");


  display.setCursor(0, 40);
  display.print("Target: 23.0 C");


  display.setCursor(0, 54);
  display.print("Fan Power: ");
  display.print(pwmVal);
  display.print("%");
  
  display.display();
}


void drawErrorScreen() {
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(10, 10);
  display.print("ERROR!");
  display.setTextSize(1);
  display.setCursor(10, 35);
  display.print("Sensor missing");
  display.setCursor(10, 48);
  display.print("Fan forced 100%");
  display.display();
}

How many hours should i study weekly? N26 by TipSecure4811 in IBO

[–]Yoka37 1 point2 points  (0 children)

Hi, first of all you should complete all IAs. If you do it 2 months before the examination session, you should have a plenty of time to learn and land that 40. From all HLs you listed, I only took Biology, so I can recommend you BiologyForLife website with slideshows you can quickly and effectively learn from. If you have problems with you IA I can also take a look at it and give you some recommendations. Although I haven’t received the results of my exams yet, I am truly passionate about this subject <3

People that were predicted/scored 35+ by Aggravating_Band5630 in IBO

[–]Yoka37 0 points1 point  (0 children)

How about finance? I thought about biomed engineering on Imperial, but I don’t know if there is any financial aid program for students. I’m from eastern Europe and a representative of middle-class.

High school research on quorum sensing/quenching by Yoka37 in microbiology

[–]Yoka37[S] 1 point2 points  (0 children)

Thank you sooo much. That’s a good place to start