non linear mapping help

Hey guys so I have searched for days and days on how to map non linear, It seems an array is the best option. like this guy is doing MultiMap. So I have tried copying this guys code and I get error after error. first that _in is not declared the _out, then "size" not declared.... So Its well of or Im way off but still... could anyone help me?

I just need a 32ish long array that can equal another, Im mapping 50ish-700ish(analog reading) to 25-120c I have is all written down as to what analog value is actually equaling what degree Celsius that is 32 long, Im just not sure how to map this correctly/use these "arrays" appropriately. can someone help explain how to do this correctly? Seems everyones code online has some error or flat out wont work.

Thank you in advance!

Please be more specific. What type of nonlinear mapping do you need and why?

Are you reading a thermistor?

HI
Post your code, it could be a simple edit error.
What Arduino are you coding for?

Thanks.. Tom.. :slight_smile:

I need to map a analogreading(thermocoupler) with 39k pullup to a Temperature value. This is for a 3D printers hot plate. I got a simple relay opening and closing when temp is lower or above 2 degrees. This board heats super slow so this relay only clicks every 3-4 mins or so. my issue is when i directly map my lowest pot reading when at ambient temp 25 degrees is 722. My highest value temp is 120 which reads 50ish (analog). if I map these values map(SensorIn, 50, 722,25,120); I do not get correct reading from ambient to top temp. so the temp, as it rises is not linear to the thermocouplers voltage increase.

for simplicity if you could explain this in a way where I can see it happening on serial monitor. this was on arduino reference for arrays, So If I want the computer to increment mySensVals but to print what

mySensVals is = to …then what
myPins is = to

this will, in the easiest way, show me how to do this… Thanks again!

int myInts[6];
 int myPins[] = {8,7 , 4, 3, 1,0};
  int mySensVals[6] = {0, 1, 2, 3, 4,5};
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:



for ( mySensVals = 0;  mySensVals < 5;  mySensVals =  mySensVals + 1) {
 Serial.print("mySensVals-->  ");
Serial.println(mySensVals);
Serial.print("myPins-->  ");
 Serial.println(myPins);
}
}

Your "thermocoupler" is probably a thermistor, in which case you use the Steinhart-Hart formula to map the resistance to temperature.

Follow this tutorial. You may need to estimate the coefficients from your thermistor, which can do with this on line calculator Steinhart–Hart equation calculator

Okay Sweet! Ya that looks like exactly what I need! Ill give it a shot, thank you!!!

Okay so when I copied the code over and changed the resistor value to 10000. I am getting inf as the output of average. So to me it looks like there doing a mathematical equation for your analog reading to convert to a resistance reading. So im just getting confused in this code on where I change my resistance values according to temp. In there code they said “For this one we only need to know To (which is room temperature, 25 °C = 298.15 K)” so Im guessing since im getting inf as my output that something isnt calibrated right? what in this code do I change?

or am I getting ahead of myself here. Do I use there first code that does print your thermal resistance? then heat my plate take temp to resistance recordings and thats how I find my coefficient? is that what changes?

// which analog pin to connect
#define THERMISTORPIN A0         
// resistance at 25 degrees C
#define THERMISTORNOMINAL 32000      
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25   
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 32000    
 
uint16_t samples[NUMSAMPLES];
 
void setup(void) {
  Serial.begin(9600);
  analogReference(EXTERNAL);
}
 
void loop(void) {
  uint8_t i;
  float average;
 
  // take N samples in a row, with a slight delay
  for (i=0; i< NUMSAMPLES; i++) {
   samples[i] = analogRead(THERMISTORPIN);
   delay(10);
  }
 
  // average all the samples out
  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
     average += samples[i];
  }
  average /= NUMSAMPLES;
 
  Serial.print("Average analog reading "); 
  Serial.println(average);
 
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
  Serial.print("Thermistor resistance "); 
  Serial.println(average);
 
  float steinhart;
  steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C
 
  Serial.print("Temperature "); 
  Serial.print(steinhart);
  Serial.println(" *C");
 
  delay(1000);
}

nissan20det:
Okay so when I copied the code over and changed the resistor value to 10000.

The code shows a thermistor value of 32kohm@25C and a fixed resistor of 32kohm.
And external Aref in setup(), which is unusual for a ratiometric sensor.

Fixed resistor value should be about the same as the thermistor at or near the temp of interrest,
for max resolution at working temp.

Why did you set Aref to external?
Leo..

okay well when I do the first code on that page I tried a 10k resistor and get a hi reading of 134000 so i when back to a 32000, I get 27333 as a thermal resistance, If I try a 32000 in the second coding I get inf.

I think its because he is using this at 3.3 using analog ref to be less noisy. Im using a pro mini inland. it doesnt have a vref or 3.3 pin. so What are my options? will this woek or do i need a board with vref and a 3.3?

I didnt that what how they set there code

I think im close the ambent value is 102000 of thermistor. Im using a 32k

Please measure the resistance of your thermistor at 3 different temperatures in the range of interest, and report those values to us.

Not a problem to set Aref to EXTERNAL, and connect the Aref pin to the 3.3volt pin.
(must do both to not damage the MCU).
As long as you also power the thermistor/resistor from the same 3.3volt pin.

As jremington said, measure the thermistor at 25C (nominal value), and if possible at 100C.
It seems you have a 100k thermistor.
Leo..

okay so sry this thing heats so slow... for abs i need temps of 90-120c im this far at 14mins 25c@102k 50c@39k 54@25k 57@22k 64 @17.5 67@16k 70@14k 72@13k 75@12k 77@11k 82@10k 83@9.2 84@9k 90@8.5k

and actually shouldnt I want a resitor thats in the middle? so if im going from 100 to 5-4k it seems wouldnt I want a 40-50k that would show me voltages from 100k-50k@5v=1.667 the 4k-50k@5v=4.63v. Thats a bigger voltage span then using a 100k-4k to 4k-4k that only like .192-2.5??

94@7.5k

this seems like my top temp after 30mins jeeeeeez

okay so with that what do i do?

I would probably use a fixed resistor value of 10k.

#define THERMISTORNOMINAL 100000
#define SERIESRESISTOR 10000

Leo…

as you can see tho, thats still very non linear even with resistance to temp… probly cuz my thermistor isnt contacting anything. it has a hole in pcb just floats in it. also probly 0.020-0.080 from glass

The Steinhart-Hart formula will take care of non-linearity.
Take care that the circuit board and wiring are not draining heat from the sensor.

For temps <125C you can also try a DS18B20.
Constant resolution across it’s whole temp range, and calibrated to 0.5C.
Leo…

i need temps of 90-120c

Please report the resistance of the thermistor at 105C and at 120C.

probly cuz my thermistor isnt contacting anything

For proper mapping, you must know the temperature of the thermistor for these measurements. It seems that you don't.

okay ya 100c is my top temp @ 6k. So nows where im confused. in the calculator you posted is that for those values i just posted? or is it for reading from the first code of 3 on that link?

okay it looks like it works!!Sweet

Temps look right on! awesomeness! thanks guys!!

// which analog pin to connect
#define THERMISTORPIN A0         
// resistance at 25 degrees C
#define THERMISTORNOMINAL 100000      
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25   
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000    
 
uint16_t samples[NUMSAMPLES];
 
void setup(void) {
  Serial.begin(9600);
  
}
 
void loop(void) {
  uint8_t i;
  float average;
 
  // take N samples in a row, with a slight delay
  for (i=0; i< NUMSAMPLES; i++) {
   samples[i] = analogRead(THERMISTORPIN);
   delay(10);
  }
 
  // average all the samples out
  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
     average += samples[i];
  }
  average /= NUMSAMPLES;
 
  Serial.print("Average analog reading "); 
  Serial.println(average);
 
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
  Serial.print("Thermistor resistance "); 
  Serial.println(average);
 
  float steinhart;
  steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C
 
  Serial.print("Temperature "); 
  Serial.print(steinhart);
  Serial.println(" *C");
 
  delay(1000);
}