Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: map() returns different values on arduino vs. teensy

  1. #1

    map() returns different values on arduino vs. teensy

    After spending a night trying to debug an issue I was having, I narrowed it down the map() on my Teensy returning an incorrect value.

    map(1,0, 1, 100, 0); // returns 51 on teensy, 0 on arduino.

    I'd expect this to return 0, but the function returns 51 on my Teensy 3.2, Teensy LC and Teensy 3.0. I tested it with an Arduino Uno and this command returns 0 as expected.

    Interestingly, the Teensy works correctly if I do some fudgery:

    (int)map((float)1,0,1,100,0); // returns 0.

    I am using arduino 1.8.13, teensyduino 1.53

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    385
    The code in wiring.h is
    Code:
    long map(T _x, A _in_min, B _in_max, C _out_min, D _out_max, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
    {
    	long x = _x, in_min = _in_min, in_max = _in_max, out_min = _out_min, out_max = _out_max;
    	// Arduino's traditional algorithm
    	//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    	// st42's suggestion: https://github.com/arduino/Arduino/issues/2466#issuecomment-69873889
    	// more conversation:
    	// https://forum.pjrc.com/threads/44503-map()-function-improvements
    	if ((in_max - in_min) > (out_max - out_min)) {
    		return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min;
    	} else {
    		return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    	}
    }
    and it looks like the test for expansion v. contraction is wrong and should be:

    Code:
    	if (abs(in_max - in_min) > abs(out_max - out_min)) {
    BTW the variable names are poorly chosen, as they are not maximum and minimums, but definitions
    of number ranges. This probably explains the error creeping in.

  3. #3
    Quote Originally Posted by MarkT View Post
    The code in wiring.h is
    Code:
    long map(T _x, A _in_min, B _in_max, C _out_min, D _out_max, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
    {
    	long x = _x, in_min = _in_min, in_max = _in_max, out_min = _out_min, out_max = _out_max;
    	// Arduino's traditional algorithm
    	//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    	// st42's suggestion: https://github.com/arduino/Arduino/issues/2466#issuecomment-69873889
    	// more conversation:
    	// https://forum.pjrc.com/threads/44503-map()-function-improvements
    	if ((in_max - in_min) > (out_max - out_min)) {
    		return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min;
    	} else {
    		return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    	}
    }
    and it looks like the test for expansion v. contraction is wrong and should be:

    Code:
    	if (abs(in_max - in_min) > abs(out_max - out_min)) {
    BTW the variable names are poorly chosen, as they are not maximum and minimums, but definitions
    of number ranges. This probably explains the error creeping in.
    Hey Mark, thanks for replying.. I didn't know the code was different than the arduino map() on purpose and looking at the "more conversation" thread linked in the commented code, it looks like Paul is aware of this exact issue as of May 2020. It also seems like someone else posted the fudgery (float) correction. I will stick with that until this issue is corrected, and I appreciate knowing that others have had this same problem.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •