Notifications
Clear all

Mapping Floats

6 Posts
3 Users
0 Reactions
4,654 Views
(@ryano085)
Member
Joined: 5 years ago
Posts: 12
Topic starter  

Hi all,

i am new to the forum and electronics and wish to start off by asking a question about mapping a float value. i am under going a small project one which will involve an Arduino nano, DHT11, TM1637 & a 4-pin PC fan (ARTIC F14 25Khz) i have PWM.h changing the Arduino frequency.

I am familiar with the map function, albeit at a basic level. The aim of this project is to test the temperature, display it, map the temperature value to a PWM pin, then drive the fan (i assume there is a motor driver within the F14?? as i am not using one), which is powered by 12V. This project operates fine on the surface. 

However, when i print the PWM values to the monitor i see that the PWM value does not change until the temperature fills to a whole number. i will include a snippet of the code as it is long.

my expectations included a smooth map from 21.00c - 25.00c in a effect giving me 500 speed variations.

Am a making sense or is this all waffle?

 

 

void loop() {
//////// DHT ////////////////////////////////
float T = dht.readTemperature(); // Read temperature in Celsius.
float sum = 0.97;
float Tsum = T*sum;
Serial.println(Tsum);
///////////////////////// DHT ///////////////

//////// PWM FREQ //////////////////////////
float fan = map (Tsum, 21.00, 25.00, 40.00, 255.00);
if(Tsum > 25){pwmWrite(pwm,255);} // must use if/else if/ and else or will not work properly.
else if(Tsum < 21){pwmWrite(pwm,40);}
else {pwmWrite(pwm,fan);}
delay(500);
Serial.println(fan);
/////////////////////// PWM FREQ ///////////

   The "sum" is my crude way of calibrating the sensor with my home thermostat.


   
Quote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2336
 

@ryano085

Is this what you are trying to do?
https://forum.arduino.cc/index.php?topic=3922.0

 

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 


   
ReplyQuote
(@ryano085)
Member
Joined: 5 years ago
Posts: 12
Topic starter  

@robotbuilder

Hi Robotbuilder, thanks for your speedy reply, Because i am new to electronics and programming in general i have never seen return been used in a map function and it blows my mind lol.. however i have been working on it and this appears to have worked. i basiicaly multiplied the temp by 100.

Foe those whole are sensitive to bad coding look away!!

void loop() {
//////// DHT ////////////////////////////////
float T = dht.readTemperature(); // Read temperature in Celsius.
float sum = 0.97;
int multi = 100;
float Tsum = T*sum;
int TMsum = Tsum*multi;
Serial.print("Temp = ");
Serial.println(TMsum);
///////////////////////// DHT ///////////////

//////// PWM FREQ //////////////////////////
float fan = map (TMsum, 2100, 2500, 40, 255);
if(Tsum > 25){pwmWrite(pwm,255);} // must use if/else if/ and else or will not work properly.
else if(Tsum < 21){pwmWrite(pwm,40);}
else {pwmWrite(pwm,fan);}
delay(500);
Serial.print("PWM out = ");
Serial.println(fan);
/////////////////////// PWM FREQ ///////////

any advice would help, even just to  clean it up.

 


   
ReplyQuote
(@starnovice)
Member
Joined: 6 years ago
Posts: 110
 

@ryano085 The map function only does integer arithmetic https://www.arduino.cc/reference/en/language/functions/math/map/    hence the reason for @robotBuilder suggesting a floating point function to use instead.

Pat Wicker (Portland, OR, USA)


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2336
 

@ryano085

Hi Robotbuilder, thanks for your speedy reply, Because i am new to electronics and programming in general i have never seen return been used in a map function and it blows my mind lol.. however i have been working on it and this appears to have worked. i basiicaly multiplied the temp by 100.

Foe those whole are sensitive to bad coding look away!!

It is bad coding if you don't know how it works.  Multiplying by 100 is essentially moving the decimal point although I would have to look at your code again when I get time to see exactly what you have done.

map() is a function with its own return if you look at it in the include file.  Programmers however write their own functions,  as well as using functions written by other programmers. Essentially you are adding your own commands to your program when you write your own functions. The map() function comes with the Arduino c++ but you could just as easily written it yourself.

If you want 500 outputs between 21 and 25 they will be floats with increments of .008

21.000  21.008  21.016 and so on up to 25.000

To use the floatMap() function or any other function you just type it outside the loop.

 

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void loop() {
  //////// DHT ////////////////////////////////
  float T = dht.readTemperature(); // Read temperature in Celsius.
  float sum = 0.97;
  float Tsum = T*sum;
  Serial.println(Tsum);
  ///////////////////////// DHT ///////////////

  //////// PWM FREQ //////////////////////////
  
  float fan = mapfloat (Tsum, 21.00, 25.00, 40.00, 255.00);  // <---- changed here
  
  if(Tsum > 25){pwmWrite(pwm,255);} // must use if/else if/ and else or will not work properly.
  else if(Tsum < 21){pwmWrite(pwm,40);}
  else {pwmWrite(pwm,fan);}
  delay(500);
  Serial.println(fan);
  /////////////////////// PWM FREQ ///////////

 

 


   
ReplyQuote
(@ryano085)
Member
Joined: 5 years ago
Posts: 12
Topic starter  

@robotbuilder

ahh i see, thats interesting i can do it without the map function, ie doing your own math but the map just makes it much easier! so now i got a PWM decimal place on the serial monitor and cleaned up a couple % memory. thanks for your help!! 


   
ReplyQuote