
The function to do this is called inverse interpolation, or InvLerp()
// takes in a value between a and b, and spits out
// a fraction between 0 and 1, proportional to a and b
// InvLerp(10, 20, 10.8) = 0.08
float InvLerp( float a, float b, float v ) {
return ( v - a ) / ( b - a );
}
FastLED has some really fast lerp
functions
But first, there is one Arduino-robotics-example complication to resolve...
After all, map
is actually just an InvLerp()
and a Lerp()
function glued together.
The next step (following this process anyway) is to break that map up, and interpolate input
and output
separately
float map( float v, float iMin, float iMax, float oMin, float oMax ) {
float t = InvLerp( iMin, iMax, v );
return Lerp( oMin, oMax, t );
}
It is the fastest way to test if and how our microcontroller is, in fact, controlling the movement of our mover.
Whenever I start working with some kind of motion animation, I always end up starting with a map()
function
float position = 0.8
means 80% of the way between whatever our minimum and maximum range is for our application
1.0
179
From here on out, when you see input
or position
, they are fractions between 0 and 1.
If you want to learn more about linear interpolation (and it is an important subject for animation!) please see these videos and articles
// takes in values a and b, and a fraction between 0 and 1 t,
// and returns a value between a and b, proportional to t
// Lerp(10, 20, 0.08) = 10.8
float Lerp( float a, float b, float t ) {
return ( 1.0f - t ) * a + b * t;
}
0.527
Likewise, we store position
as a fraction between 0 and 1 and translate it to whatever range our mover requires
The function to do this is called linear interpolation
or Lerp()
(34 - -128) / (179 - -128)
34
Regardless of how we receive our raw input, we translate that to a fraction between 0 and 1 and store it as input
NUM_LEDS
The upshot of this process
0.0
179
166
And we take that and convert it to whatever range our particular kind of system accepts.
-128
We do the same for position
: we store a value between 0 and 1 for it
34
0
leds[]
pixel coordinate range:
-128
Specifically, we will translate input
into a float
to store a value between 0 and 1
accel_x
range (from accelerometer):
Instead, we want to take whatever value from whatever range in input
and convert it to a predictable range

credit to Freya Holmer

But! If we do that, then position
will always map rigidly to our input
value, with no room for personality or character of movement
wouldn’t it be great to just store that relative position and work with that?
notice how they are both about 66% of the way between their ranges?
Actually, probably not all of this and I should just put this into its own space and reconsider it
and this is our position
if this is our input
val = map(val, 0, 2048, 0, 180);
In lots of Arduino tutorials, we solve that using a function called map()
to connect the two values
180
70
0
In order to control movement with these ranges, we have to be able to compare them.
Rework this part with someone to make it clear what I am trying to say and why
servo angle position range
2048
798
0
And the position parameters for different kinds of movers will be, well, different
analogRead()
input range:
Sensor values will arrive in all sorts of ranges out of our control