Hello,
i am new to this forum and this is my first message, hope i am posting it right; I am a beginner to Arduino.
I have tried to search for a similiar issue i am having and have seen different earlier interesting conversations which improved my understandign, however none of them apparently solved completely my problem.
The excercise i am attempting to do is very simple and it is running with Arduino UNO wired to the following hardware :
- Dallas DS18B20 sensor.
- Fan Delta AFC0912D. This fan accept a 20kHz PWM control with variable duty cycle to set the speed.
- Simple 4.7k resistor and some wiring, plus a 12V battery.
The idea is the following: the user set a desired temperature to reach.
Periodically (at user decision in terms of delta time) the Dallas sensor is interrogated to read the ambient temperature and based on the desired temperature and the actual ambient temperature a kind of error is generated. The duty cycle of a PWM is then calculated based on that error and the PWM wave created.
The idea is to have a proportional type of control, however i am going to fine tune that aspect later.
I appreciated that the Dallas sensor may take up to 750ms delay to process the data reading, however this is delaying my PWM wave. Effectively the program run and the duty cycle is adjusted based on temperature, but every 800ms the fan stops and then re-start. Which is not right.
I would like to have the reading of the sensor (then the 750ms) in background, while the PWM is running. But i do not know how to do that.
Is there anyone that can help or have experienced this issue before? Posting the code if can help.
Many thanks,
Ado.
#include <OneWire.h> // Call out the relevant library for the temperature sensor
#include <DallasTemperature.h> // Call out library Dallas
#define ONE_WIRE_BUS 2 // Data wire is plugged into pin 2 on the Arduino
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
float temperature; //This variable is the actual temperature read by the sensor
float desired_T = 10; //This is the desired temperature that the user can input to set
int T = 50; //This is the period of the square wave of PWM, 20kHz frequency = 1/20000 x 1 millio. This is the preferred PWM fan frequency of Delta AFC0912D, 20 KHz
float onDelayUs,offDelayUs; //declare the on and off time variable type for the PWM
float dutyCycle; //PWM duty cycle in percentage
int delayInMillis = 800; // This variable in milliseconds will define how long time will be between two temperature readings
unsigned long earlier_time = millis(); // This variable is the earlier time bucket so that we can go and read the temperature only after 800ms
void setup()
{
sensors.begin(); // Start up the library for the sensor
pinMode(11,OUTPUT); // Set the pin 11 as an output, since we will use it to make the PWM pulse
Serial.begin(9600); //Initialize the serial, just for trouble shooting purpose.
sensors.requestTemperatures(); // Send the command to get temperatures, this is the first value to kick off the programm
temperature = sensors.getTempCByIndex(0); //assign the value just requested to the variable called temperature
dutyCycle=(temperature-desired_T)/temperature*100; //Calculate the first dutycycle to kick off the fan, it will be refreshed every 800ms
onDelayUs=T*dutyCycle/100; // on delay in microsecond, based on previous duty cycle calculated
offDelayUs=T*(100-dutyCycle)/100; // Off delay in Microsecond, based on previous duty cycle calculated
}
void loop() {
//The following "if" loop will execute the request temperature and read temperature from the dallas sensor only every delayInMillis time.
//It will record the earlier_time, so that it can do the difference and go through the loop only if that difference is larger than delayInMillis
if (millis()- earlier_time > delayInMillis) {
sensors.requestTemperatures(); //Request the temperature to the sensor
temperature = sensors.getTempCByIndex(0); //Read the temperature from the sensor
dutyCycle=(temperature-desired_T)/temperature*100; //Update a dutyCycle based on the new temperature and the desired. it is a kind of proportional control
earlier_time = millis(); //save into a bucket the earlier_time so that at the next loop we know when delayInMillis is passed
}
// the following portion of code is just the PWM control of the fan. The duty cycle should have been adjusted based
// on the temperature reading of the "if" loop above.
onDelayUs=T*dutyCycle/100; // on delay in microsecond, calculated based on the duty cycle
offDelayUs=T*(100-dutyCycle)/100; // off delay in Microsecond, calculated based on the duty cycle
digitalWrite(11, HIGH); // Set the pin 11 to high
delayMicroseconds(onDelayUs); // Wait for the on time
digitalWrite(11, LOW); // Set the pin 11 to low
delayMicroseconds(offDelayUs); //wait for the off time
}