82Views7Replies

# i want my motors speed to be constant with the temperature via an equation, its a school project. help!? Answered

my project is to make a fan that will be constant (speed) with the temperature of the surrounding, display the temperature on an lcd screen and have a servo tilt it up and down. I have made my code for now and it seems correct, i think my problem is with the clarity of my code or the power. lcd + motor + servo = aprox 15 volts, i use the aruinos 5v connected from my laptop to power the lcd screen and i have an external 9v battery for motor and servo. Please help me connect the battery correctly or change my code?

Speed = temp * 6.375
why? because= max speed is 255, and i think 40 *C is a max temperature + 10*C was the lowest temperature and 64 was lowest speed i preferred.
so 255%40 = 6.375
to test then i used lowest temp and speed.
64%10 = 6.4 so i thought 6.375 was good because any higher would mean it would reach a number higher than 255.

but this equation seems to give decimals, maybe arduino wont read decimals as speed? or am i coding for something different than what i want to accomplish?

english is my second language there fore it was probably a bit unclear to understand, sorry!

Copy of Code:

//Temperature Run fan with Servo angle tilter

#include <Servo.h> // Servo library of commands
#include <LiquidCrystal.h> //lcd library of commands
LiquidCrystal lcd(12,11,5,4,3,2); //set pins

const int temperaturePin = 0;

const int motorPin = 9;

Servo servo1;

int speed;

void setup()
{

servo1.attach(6);
lcd.begin(16, 2);
lcd.clear();
lcd.print("Temperature");

pinMode(motorPin,OUTPUT);

Serial.begin(9600);
}

void loop()
{
float voltage,degreesc, degreesF;
int position;

lcd.setCursor(0,1);

voltage = getVoltage (temperaturePin);

degreesc = (voltage - 0.5) * 100.0;

// Tell servo to go to 180 degrees, stepping by two degrees

for(position = 0; position < 180; position += 2)
{
servo1.write(position);  // Move to next position
delay(20);               // Short pause to allow it to move
}

speed = constrain(speed, 0, 255);

float (speed);
{

speed = degreesc * 6.375;

analogWrite(motorPin, speed);
}

lcd.print("  deg C: ");
lcd.print(degreesc);
Serial.print(degreesc);

}
float getVoltage (int pin)
{
}

Tags:

The forums are retiring in 2021 and are now closed for new topics and comments.

So I think you are asking basically how to control the fan speed to regulate temperature, correct? One way to do it is to have the fan turn all the way on when one threshold is reached (when it gets too hot), and turn back off when a lower threshold is reached (when it gets too cold.) This is how AC's work.

You can also do it with PID control, which you are sorta doing. PID is better in that it it can regulate something very precisely and adjust the speed of the fan as needed. It is "smarter." However, that is quite difficult (requiring an understanding of control theory and differential equations) and you probably do not need that complexity.

-----------------------------------------------

Basically you are trying to use the first part of PID, P, which means proportional. A proportional closed feedback controller will control the speed of the motor proportional to the temperature. That is to say as temperature increases so does the speed of the fan. Simple enough.

----------------------------------------------

So you need code that will

A) Measure and calculate the temperature ( in degrees C presumably)

B) set the speed of the motor appropriately

C) display the data.

--------------------------------------------

The first part I think you already have working, to convert the voltage to a *C value. Do you use the variable "Voltage" more than once? It may be more efficient to just write: degreesc = (getVoltage(temperaturePin) - 0.5) * 100.0; And like Steve said, it is best to remove unused variables that needlessly take up space.

The next part is where the real math hides. Luckily In this case, this is also reasonably easy. don't forget there already is a convenient "map()" function available, which might be easier to use than trying to do a bunch of algebra to get it right. Be careful though, the map() function does not constrain the inputs! So if the input gets too close to the limits then it can pontenially wrap around. Say if the temperature keeps steadily rising, once it gets up to 255 (maximum speed) then once the temperature rises a little more it may wrap around back to 0 and start from there again!

And the last part is just displaying data. I think you got that code working. You can make custom characters for the LCD module, and there is a ASCII character for degrees you can use, if you want.

Absolutely used your way of writing the command for temperature, thank you. i am using a map function a the moment but cant test as i have broken my diode and cant get any equipment until tomorrow. One problem i have been facing with the 9v battery for the motor is that it is interrupting with the lcd ( it shows random symbols) and the temperature readings randomly go up to 200!? this is because i conected the ground from the 9v to the arduino, thats what you do right? i tried not connecting the grounds together but my motor wont turn then.

What do you need a diode for? for EMF protection from the motor? Salvage one out of some broken thinga-ma-jig. To test/debug your code more quickly, you could try to connect a potentiometer instead of a temperature sensor to get values from 0 to 1023. Of course it goes without saying you can map that range to whatever values you want within reason. I don't want to give you too many clues since it is a school project, and it is better if you learn how to do it yourself. Good luck! :)

Usually no help for homework here but...
You could simplify the problem with the MAP command.
Fan PWM control is usually done the simple way with a 8bit signal offering values from 0-255.
The trick is define the temp range you need to cover, for example:
15° and below = fan off
35° and above = fan full power
You will have a value on your inputs for these values - they are the other part you need.
Now you can use the map command to set the values you need.
I know sounds complicated - but it isn't, check the code example for it.
You only need to add a bit more code so define that everything below the min value is zero and everything above the max value 255 - or limit it already while reading the temp makes no real difference.

using this method at the moment, it is great. i don't trully understand how PWM works but i will research about it once i am free. thank you for your help!

What a very nicely asked question, even if I am not quite sure what you want to fix ! Your English is very good too.

You don't use degreesF, so don't declare the variable.

speed = constrain(speed, 0, 255); is in the wrong place - do it after the calculation of speed.

and

analogWrite(motorPin, speed);

could be

analogWrite(motorPin, int(speed) );

Appreciate your help thank you, i have used a different method but have not tested it yet, so far the compiling seems good. the method was, instead of constraining the numbers there, at the start of the code i defined the Min and Max (int tempMin = 10).