Problems mapping the temperature range of hot air gun

Hello.
I'm building a project on a hot air gun station. Now the basic premise is that the hot air gun's internal temperature sensor will constantly show a reading on a 7 segment display.

two buttons are used to increase or decrease the set temperature. If the set temperature is more than the heater's temperature sensor reading it turns on the heater until it reaches the same temp.

I have averaged the temperature sensor reading (for smoothness) and mapped it like so:

for(int i = 0; i < TempSamples; i++)
  {
    TempIndexreadtotal += analogRead(TempSensorPin);
  }
  TempAverage = TempIndexreadtotal / TempSamples;
  TempIndexreadtotal = 0;
  delay(1);  // delay in between reads for stability
  // int TempmappedValue = map(TempAverage, MinSetHeaterTemp, MaxSetHeaterTemp, TempRangeMin, TempRangeMax);
  int TempmappedValue = map(TempAverage, 202, 434, 200, 400);

Now the mapping is done like this because I want the minimum temp to be 200 and maximum temp to be 400.
Upon calibration with an RTD and Max31865, I have managed to map the bottom end accurately (i.e. from 200 - 300 degrees the values are matching the one shown my max31865). But whenever I read closer to the top end (350+) the deviation just keeps increasing (i.e. at 400 degrees it shows 450 and keeps increasing). If i lower the top end value of the temperature range it then messes with my bottom end calibration (i.e. what was earlier showing 205 at 200 degrees now shows 180).

I am just not able to calibrate it successfully. Any advice and suggestions would be useful.

Did you read the documentation page for map()? It sounds like you are conflating it with constrain().

I don't want to constarin my values. I just want it so that the temperature I set from my buttons is the actual temperature the heater is throwing. Like it can go below 200 and above 400 but I want it to display it accurately on the seven segment display. right now if i set it to 250 its shows 255 (I dont mind a +-10 degree deviation). But when I set it to 380 it shows something like 420.

PS: when i say "its showing 255" i mean on the serial monitor of the max31865 code. The hot air gun is on a separate board.

Your explanation may seem clear to you, but it isn't to others. How do you know the result of map() is wrong, for example?

It sounds like the sensor you are using gives an output that is not very linear with temperature, especially in the upper part of the range you want to measure. The map() function will only work with linear relationships.

You may need to collect a dataset showing how the sensor reading changes with temperature over the range you need, and plot these on a chart to help you visualise the relationship. Hopefully you can fit a curve to the dataset. Excel may be useful for this.

2 Likes

Please if you could let me know which parts are not clear I can provide more explanation on the code. I will try to be more precise here. I am comparing the result of map() to the temperature reading by the Max31865 and a PT-100 2 Wire RTD sensor. So I first map the bottom range i.e.200 by setting the hot air gun at 200.

map(value, fromLow, fromHigh, toLow, toHigh)

I then alter the fromLow value so that the temperature value in the RTD sensor matches 200.

I then go to the top end range i.e. 400 and change my fromHigh value accordingly.

But upon changing the fromHigh value it also alters my fromLow calibration. So when I set it to 200 it no longer matches with the RTD value.

I hope its clearer now. Thanks for helping!

I'm not familiar with these, but they seem to have a digital output. You are using analogRead(). What is the analog pin connected to?

Where have these values 202 and 434 come from?

This part makes no sense to me. Altering the fromHigh value should have zero effect on the output of map() when the input is equal to fromLow. When the input is equal to fromLow, the output of map() will always be toLow. The value of fromHigh can't affect that. It can affect the output of map() for values not equal to fromLow.

Have you checked the individual results from analogRead()? Maybe they are so noisy, or have a non-normal distribution, which makes taking the average meaningless?

1 Like

I'm not familiar with these, but they seem to have a digital output. You are using analogRead(). What is the analog pin connected to?

I'm using the Adafruit Max31865 header file and it uses SPI to send data to arduino.
Here's the code.

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);

Pin 10,11,12,13 are the pins connected on an Arduino Nano.

Where have these values 202 and 434 come from?

These were initially 0, 1023 but as I was mapping to get the desired temperature reading I reached this. So with fromLow set at 202 at temperature set values between 200 - 300 I get accurate temperature readings via the RTD sensor (i.e. for 250 degrees set the sensor shows 250).

Altering the fromHigh value should have zero effect on the output of map() when the input is equal to fromLow. When the input is equal to fromLow, the output of map() will always be toLow. The value of fromHigh can't affect that. It can affect the output of map() for values not equal to fromLow.

this is also the part where I'm left head scratching and came here. Why is altering the fromHigh messing the input matches with fromLow.

Have you checked the individual results from analogRead()? Maybe they are so noisy, or have a non-normal distribution, which makes taking the average meaningless?

I have actually. They are quite noisy but have normal distribution. Lots of fluctuations in value (i.e. if set at 200, keeps jumping from 199 to 202 and does not stay constant). But I was under the impression that this was quite normal when reading analog signals and was told to average it so that the fluctuations reduce.

But your code in post #1 does an analogRead, not SPI
Exactly how do you have the RTD connected to an analog input?

1 Like

These are two different circuits. The temperature sensor in post #1 is the internal sensor of the hot air gun, which is powered by a custom PCB. The RTD used to calibrate the temperature is connected to a separate arduino.

Then I expect that the custon PCB and/or RTD is non-linear or not intended to operate above 300 degrees. So you may need to linearize the output.

Finally we are starting to see some of the missing jigsaw pieces.

This is what is connected to the Arduino analog pin?

The two Arduino are not connected? The second Arduino circuit is providing hopefully accurate temp readings that you want to use to calibrate the first Arduino circuit?

It is, but it only works if the readings have a more-or-less normal distribution. If not, the average is meaningless.

When you roll a dice, the average score is 4.0. It's true (assuming it's not a loaded dice!) but it's a meaningless average. Similarly, if the data from analogRead() gives every reading from 0 to 1023 with equal frequency, the average would be 511.5, but an utterly useless number.

When you analysed the analogRead() results and found the distribution to be normal, did you calculate the typical standard deviation?

1 Like

I dont think its either. since the PT100 can detect temperatures till well over 700 degrees and my hot air gun's heater is also capable of outputting uptill 550 degrees (without blowing up that is).

plus the RTD is already defined in the Adafruit library.
https://learn.adafruit.com/adafruit-max31865-rtd-pt100-amplifier/arduino-code

Ive attached the used code along with explanation from adafruit's website here.

Even so, how would I go about changing the linearization?

Back to post #5.

First, you need to establish if the relationship between the averaged analogRead() results and the results from the digital temp sensor is linear. If they are, you can use map(). If they are not, you need to fit a curve to the data.

Then how do you explain the discrepancy?

This is what is connected to the Arduino analog pin?
Yes, the temperature sensor pin of the hot air fun is connected to the analogRead pin.

The two Arduino are not connected? The second Arduino circuit is providing hopefully accurate temp readings that you want to use to calibrate the first Arduino circuit?

Yes they're not connected and act separately. and yes, thats exactly what I'm doing, using one arduino for accurate temp readings and calibrating the initial circuits temperature readings with that.

When you analysed the analogRead() results and found the distribution to be normal, did you calculate the typical standard deviation?

No I haven't done this

It's precisely why I'm here :sweat_smile:.
trying to understand why varying the fromHigh value in the map function alters my already set lower input value calibration. But I guess from both of you in this thread its possibly due to the temp sensor values not being linear. I'll look into that now

That's my guess. We know nothing about the actual RTD or this custom board. PT100 only tell you it's 100 ohms, not the usable temperature range or how linear it is.

It may turn out that the readings are not linear with temp, but that doesn't explain the problem you describe with map().

If the relationship has a curve, and you are fitting a line to that curve, using map(), it should still be accurate at 2 points, even if it isn't accurate for any other values. Changing one of those points should not affect the other point in any way. But that's what you have described, so I think we still don't fully understand what's happening here.

1 Like

Having had a lot of hot air guns, I wonder why you have not mentioned the internal fan and the volume of air being forced through the heating element. On many of our hot air guns, the fan motor was in series with the heating element, so there would NEVER be a heat without a fan. Therefor the air volume was never a consistent value.

1 Like