G+_Jim Hofmann Posted November 27, 2016 Share Posted November 27, 2016 Came across an interesting issue with the "map" command in Ardunio. There is always a need to convert units and eventually get it to a 0 to 255 output. +Fr. Robert Ballecer, SJ?? used it to control a LED's brightest. I was experimenting with a ping sensor and noted the LED changed brightest but just didn't look right. I was trying to go from 4" to 12", LED off to full brightest. x = map(inches, 4.0, 16.0, 0, 255); //Brighter as it moves away analogWrite(LED_PIN, constrain(x, 0, 255)); //Send cmd, 0 to 255 I found the map command uses Long data type, so all the math is integer and division is truncated. I was seeing brightest change in 21 count increments. My solution was to convert to milli-Inches, multiply input values by 1000. x = map(inches * 1000, 4000, 16000, 0, 255); //Brighter as it moves away The input should have as many integers as the output. Hope this helps. Link to comment Share on other sites More sharing options...
G+_Ben Reese Posted November 27, 2016 Share Posted November 27, 2016 The map() function is documented as well, so it's possible to create your own for mapping floats. Here's one I found in a quick search: float mapfloat(long x, long in_min, long in_max, long out_min, long out_max) { return (float)(x - in_min) * (out_max - out_min) / (float)(in_max - in_min) + out_min; } Edit: just read that code and it looks like it's taking long as the parameters. Should be able to change those to float too and let it accept float inputs. Link to comment Share on other sites More sharing options...
G+_Jim Hofmann Posted November 28, 2016 Author Share Posted November 28, 2016 Yeah, thought about that too. Decided to go with adjusting the inputs. I was surprised Ardunio doesn't document this limitation. Thanks. Link to comment Share on other sites More sharing options...
G+_Ben Reese Posted November 28, 2016 Share Posted November 28, 2016 Hehe... Well, it actually does. Easy to miss though and probably not something most people would catch right away. Either way, multiplying by 1000 is a decent way around the constraint. Here's the documentation for the map() function. arduino.cc - Arduino - Map "The map() function uses integer math so will not generate fractions, when the math might indicate that it should do so. Fractional remainders are truncated, and are not rounded or averaged." They do give the code for the official function too, so it should be easy enough to fix it if you decide to go that route later. Link to comment Share on other sites More sharing options...
G+_Jim Hofmann Posted November 28, 2016 Author Share Posted November 28, 2016 Agreed. What they documented is good. Always like to see the magic. But I think it's too easy to miss the fact it uses Long. Just think they should point out if you have 255 possible outputs than you need at least 255 discrete inputs to have a smooth mapping. Or if you need float you will need to roll your own. Link to comment Share on other sites More sharing options...
Recommended Posts