Skip to content

Conversation

dok-net
Copy link
Contributor

@dok-net dok-net commented Jan 21, 2020

Inspired by Servo.cpp's improved_map, this superseded that code, and has better performance (identical to prior WMath implementation).
I expect this is better used to replace the core implementation, then drop "improved_map" from Servo.cpp, than keep it local and have a map() function that may be compatible but works horribly ;-)

@dok-net
Copy link
Contributor Author

dok-net commented Jan 21, 2020

Here's the sketch for testing correctness and timing:

uint32_t expired; uint32_t iterations; void setup() {	Serial.begin(115200); while (!Serial);	Serial.println("check map");	expired = 0;	iterations = 0; } constexpr int imin = 0; constexpr int imax = 180; constexpr int omin = 1000; constexpr int omax = 2000; int i = 0; int fails = 0; void loop() {	++iterations;	i = (i + 1) % (imax + 1); #if defined(ESP8266) || defined(ESP32) cli(); volatile auto start = ESP.getCycleCount(); #else // Set Timer 1 to normal mode at F_CPU.	TCCR1A = 0;	TCCR1B = 1; cli(); volatile uint16_t start = TCNT1; #endif volatile auto o = map(i, imin, imax, omin, omax); #if defined(ESP8266) || defined(ESP32) sei(); volatile auto cycles = ESP.getCycleCount() - start; #else sei(); volatile uint16_t finish = TCNT1; uint16_t cycles = finish - start; #endif	expired += cycles; if (i != map(o, omin, omax, imin, imax))	{	++fails;	} if (iterations > 100000)	{	Serial.print("Cycles per map(...) = ");	Serial.print(expired / iterations);	Serial.print(", fails = ");	Serial.print(fails);	Serial.println();	expired = 0;	iterations = 0;	fails = 0;	} }
@dok-net
Copy link
Contributor Author

dok-net commented Jan 21, 2020

…ion. Greatly reduces error rate (half, or 0 zero errors, depends on in/out ranges) for round-trip mapping at the same performance.
Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@earlephilhower earlephilhower merged commit 56b90a2 into esp8266:master Feb 9, 2020
const long divisor = in_max - in_min;
const long delta = x - in_min;

return (delta * dividend + (divisor / 2)) / divisor + out_min;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't handle divisor == 0.

@dok-net dok-net deleted the wmath_map branch February 13, 2020 12:21
@dok-net
Copy link
Contributor Author

dok-net commented Sep 30, 2020

This today got merged into Arduino Core for ESP32, espressif/arduino-esp32#3655

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants