Map function - curve?

I'm using the map function to map values from 0 - 1023 to 0 - 255 from an FSR sensor. I was wondering if it is possible to change the curve of the mapping? i'm guessing the initial map is linear? is it possible to be logarithmic or exponential or anything in between ?

The (or a possible) implementation is included in the documentation:

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

If you need anything else, my guess is that writing your own mapping function would be easiest.

1 Like

not with the map() function which is just a linear interpolation with trunking the result to the integral value.

You'll need your own indeed

1 Like

I doubt a fsr sensor will have great precision, so I'd be inclined to do your conversion as integer.
In which case you can create a table and use linear interpolation to do a piecewise conversion.

Couldn't you just use a shift for that?

:thinking:

what is a shift?

I'm not sure I understand what does it means. Any example for that?

So that is the formula for a linear interpolation between points? what is the formula for logarithmic or exponential interpolation?

Here is an example. You se a limited table of data points, and in between calculate what the value would be.
image

There are (uncountable) infinitely many functions that fit this definition.

You may want to have a look at the following thread, where we use a polynomial function for interpolation.

If you have a specific set of points, I can calculate the polynomial for you.

0-1023 uses 10 bits; 0-255 uses 8 bits. The simplest way to do this is just to "lose" the bottom 2 bits of the 10-bit value - by shifting it to the right:

value >>= 2;

It's equivalent to dividing the value by 4 (ie, by 22)

Arithmetic operators - cppreference.com - scroll down to " Bitwise shift operators"

This what I got from ChatGPT asking for map function that is exponential:

long expMap(long x, long in_min, long in_max, long out_min, long out_max, float exponent) {
  // Apply exponential transformation to the original input value x
  float normalized = (float)(x - in_min) / (in_max - in_min);
  float scaled = pow(normalized, exponent);

  // Map the scaled value to the output range
  return (long)(scaled * (out_max - out_min) + out_min);
}

1 Like

Hi,
What is the application?

Can you really get FSR measurements from 0 to 1023, open circuit to short circuit?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hi,
The maximum value I managed to read from FSR is not 1023 rather 1000-1007 at max

I want to mapped this input data to number between 0 - 255 so I could control the speed of a motor. The thing I try to achieve is to have more control over the low range of the output if that make sense

How fine do you want this control to be?

eg, for just a "low", "medium", and "high" range you could do

if( value < low )
{
   // use map for "low" range
}
else if( value < medium )
{
   // use map for "medium" range
}
else
{
   // use map for "high" range
}
1 Like

That is great! I just thought about it hat for input values between lets say 0 - 200 I don't much care the output to be linear because in anwy the motor will not move much. I want the finest control between the medium range

@hk_jh this may be of interest, it's @awneil's idea from #14 above

Multimap

I don't use map() anymore, I've never used multimap().

a7

1 Like

Implements a few variations including a binary search which is faster if the number of points is large.
Note: the input array must always be in a non-decreasing order.

1 Like

@robtillaart in the house!

I take an opportunity to thank you for all the work of yours I have exploited and learned from.

a7

1 Like

@alto777
Thanks, you're welcome.

1 Like

I've explained here