diff --git a/libraries/MultiMap/.arduino-ci.yml b/libraries/MultiMap/.arduino-ci.yml index ff5659b9..cecf5850 100644 --- a/libraries/MultiMap/.arduino-ci.yml +++ b/libraries/MultiMap/.arduino-ci.yml @@ -2,6 +2,10 @@ compile: # Choosing to run compilation tests on 2 different Arduino platforms platforms: - uno - - leonardo - - due - - zero + # - due + # - zero + # - leonardo + - m4 + - esp32 + # - esp8266 + # - mega2560 diff --git a/libraries/MultiMap/.github/workflows/arduino_test_runner.yml b/libraries/MultiMap/.github/workflows/arduino_test_runner.yml index 476456bb..096b975b 100644 --- a/libraries/MultiMap/.github/workflows/arduino_test_runner.yml +++ b/libraries/MultiMap/.github/workflows/arduino_test_runner.yml @@ -4,10 +4,14 @@ name: Arduino CI on: [push, pull_request] jobs: - arduino_ci: + runTest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: Arduino-CI/action@master - # Arduino-CI/action@v0.1.1 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/MultiMap/LICENSE b/libraries/MultiMap/LICENSE index cfc58f98..8a10ac68 100644 --- a/libraries/MultiMap/LICENSE +++ b/libraries/MultiMap/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2011-2021 Rob Tillaart +Copyright (c) 2011-2022 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libraries/MultiMap/MultiMap.h b/libraries/MultiMap/MultiMap.h index c5a9ee1d..50325b47 100644 --- a/libraries/MultiMap/MultiMap.h +++ b/libraries/MultiMap/MultiMap.h @@ -2,7 +2,7 @@ // // FILE: MultiMap.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.4 +// VERSION: 0.1.5 // DATE: 2011-01-26 // PURPOSE: Arduino library for fast non-linear mapping or interpolation of values // URL: https://github.com/RobTillaart/MultiMap @@ -10,37 +10,39 @@ // // HISTORY: // 0.0.1 2011-01-26 initial version (see forum) -// ..... +// ..... eons passed ... // 0.1.0 2015-03-29 // 0.1.1 2020-04-09 // 0.1.2 2020-06-19 fix library.json -// 0.1.3 2021-01-02 add arduino-CI -// 0.1.4 2021-05-27 fix arduino-lint +// 0.1.3 2021-01-02 add Arduino-CI +// 0.1.4 2021-05-27 fix Arduino-lint +// 0.1.5 2021-12-22 update library.json, readme, license, minor edits -#define MULTIMAP_LIB_VERSION (F("0.1.4")) +#define MULTIMAP_LIB_VERSION (F("0.1.5")) #include "Arduino.h" + // note: the in array should have increasing values template -T multiMap(T val, T* _in, T* _out, uint8_t size) +T multiMap(T value, T* _in, T* _out, uint8_t size) { // take care the value is within range - // val = constrain(val, _in[0], _in[size-1]); - if (val <= _in[0]) return _out[0]; - if (val >= _in[size-1]) return _out[size-1]; + // value = constrain(value, _in[0], _in[size-1]); + if (value <= _in[0]) return _out[0]; + if (value >= _in[size-1]) return _out[size-1]; // search right interval - uint8_t pos = 1; // _in[0] allready tested - while(val > _in[pos]) pos++; + uint8_t pos = 1; // _in[0] already tested + while(value > _in[pos]) pos++; // this will handle all exact "points" in the _in array - if (val == _in[pos]) return _out[pos]; + if (value == _in[pos]) return _out[pos]; // interpolate in the right segment for the rest - return (val - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1]; + return (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1]; } @@ -50,24 +52,24 @@ T multiMap(T val, T* _in, T* _out, uint8_t size) // note: the in array should have increasing values template -T multiMap(T val, T* _in, T* _out, uint8_t size) +T multiMap(T value, T* _in, T* _out, uint8_t size) { static T lastvalue = -1; static T cache = -1; - if (val == lastvalue) + if (value == lastvalue) { return cache; } - lastvalue = val; + lastvalue = value; // take care the value is within range - // val = constrain(val, _in[0], _in[size-1]); - if (val <= _in[0]) + // value = constrain(value, _in[0], _in[size-1]); + if (value <= _in[0]) { cache = _out[0]; } - else if (val >= _in[size-1]) + else if (value >= _in[size-1]) { cache = _out[size-1]; } @@ -75,17 +77,17 @@ T multiMap(T val, T* _in, T* _out, uint8_t size) { // search right interval; index 0 _in[0] already tested uint8_t pos = 1; - while(val > _in[pos]) pos++; + while(value > _in[pos]) pos++; // this will handle all exact "points" in the _in array - if (val == _in[pos]) + if (value == _in[pos]) { cache = _out[pos]; } else { // interpolate in the right segment for the rest - cache = (val - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1]; + cache = (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1]; } } return cache; @@ -94,3 +96,4 @@ T multiMap(T val, T* _in, T* _out, uint8_t size) // -- END OF FILE -- + diff --git a/libraries/MultiMap/README.md b/libraries/MultiMap/README.md index e1b4eec7..9f070dd5 100644 --- a/libraries/MultiMap/README.md +++ b/libraries/MultiMap/README.md @@ -1,8 +1,11 @@ [![Arduino CI](https://github.com/RobTillaart/MultiMap/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/MultiMap/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MultiMap/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/MultiMap/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MultiMap/actions/workflows/jsoncheck.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MultiMap/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/RobTillaart/MultiMap.svg?maxAge=3600)](https://github.com/RobTillaart/MultiMap/releases) + # MultiMap Arduino library for fast non-linear mapping or interpolation of values @@ -12,7 +15,8 @@ Arduino library for fast non-linear mapping or interpolation of values In Arduino applications often the value of a sensor is mapped upon a more usable value. E.g. the value of analogRead() is mapped onto 0 .. 5.0 Volt. -This is done by the map function which does a linear interpolation. This means +This is done by the map function which does a linear interpolation. +This means in code: ```cpp output = C1 + input * C2 @@ -25,14 +29,15 @@ two variables runtime from two given mappings. output = map(input, I1, I2, O1, O2): ``` -In many cases when there is no linear mapping possible, as the 'points' are not on a single line. -One needs non-linear math to calculate the output, **Multimap()** just does that. +In many cases when there is no linear mapping possible, as the 'points' are not on a single straight line. +One needs non-linear math to calculate the output, **Multimap()** just simulates that. -**out = Multimap(value, input, output, size)** needs two equal sized arrays of reference 'points', **input\[\]** and **output\[\]**, it looks up the +**out = Multimap(value, input, output, size)** needs two equal sized arrays of reference 'points', +**input\[\]** and **output\[\]**, it looks up the input value in the input\[\] array and if needed it linear interpolates between two points of the output\[\] array. -- The **input\[\]** array must have increasing values, +- The **input\[\]** array must have increasing values, there is no such restriction for the **output\[\]** array. - **Multimap()** automatically constrains the output to the first and last value in the **output\[\]** array. @@ -44,6 +49,15 @@ See examples Please note the fail example as this shows that in the intern math overflow can happen. -## TODO +## Future + +- Investigate class implementation for performance / footprint +- flag if input value was "IN_MIN" < input < "IN_MAX", + now it is constrained without user being informed. +- extend unit tests + + +**wont** +- should the lookup tables be merged into one array of pairs? + - you cannot reuse e.g. the input array then. (memory footprint) -Investigate class implementation for performance. diff --git a/libraries/MultiMap/examples/multimap_NTC/multimap_NTC.ino b/libraries/MultiMap/examples/multimap_NTC/multimap_NTC.ino index 836836f0..8d7966f0 100644 --- a/libraries/MultiMap/examples/multimap_NTC/multimap_NTC.ino +++ b/libraries/MultiMap/examples/multimap_NTC/multimap_NTC.ino @@ -1,11 +1,11 @@ // // FILE: multimap_NTC.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 // PURPOSE: demo // DATE: 2020-04-09 // (c) : MIT // +// example uses multiMap to calculate the temperature from an 10K NTC. #include "MultiMap.h" @@ -22,11 +22,13 @@ volatile float x, y, z; float in[] = { 0, 1, 3, 8, 13, 20, 25, 32, 50, 60, 72, 85, 100, 145, 200, 250, 300, 400, 500, 600, 650, 700, 753, 800, 830, 870, 900, 936, 964, 985, 1000, 1017, 1023 }; + float out[] = { -273.15, -71.65, -60.69, -49.81, -43.97, -38.50, -35.54, -32.16, -25.72, -22.95, -20.08, -17.37, -14.62, -7.90, -1.43, 3.57, 8.08, 16.34, 24.30, 32.64, 37.17, 42.13, 48.05, 54.19, 58.75, 66.03, 72.87, 83.85, 96.51, 111.46, 129.49, 182.82, 301.82 }; + int sz = 33; @@ -87,3 +89,4 @@ float val(int sensorValueA1) // -- END OF FILE -- + diff --git a/libraries/MultiMap/examples/multimap_NTC_int_FAIL/multimap_NTC_int_FAIL.ino b/libraries/MultiMap/examples/multimap_NTC_int_FAIL/multimap_NTC_int_FAIL.ino index e64d920d..f47859a9 100644 --- a/libraries/MultiMap/examples/multimap_NTC_int_FAIL/multimap_NTC_int_FAIL.ino +++ b/libraries/MultiMap/examples/multimap_NTC_int_FAIL/multimap_NTC_int_FAIL.ino @@ -1,16 +1,15 @@ // // FILE: multimap_NTC_int_FAIL.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 // PURPOSE: demo of faulty optimizing // DATE: 2020-04-09 // (c) : MIT // - +// // NOTE: // use integers instead of floats to minimize RAM. uses ~320 bytes PROGMEM ~120 bytes RAM less on UNO than float version // -// this example is added to show how to reduce memory but also how it can FAIL due to math overflow +// this example is added to show how to reduce memory but also how it can FAIL due to math overflow // E.g. see around 196-200; 340-400 // to prevent this one must have more values which increases the memory usage again. // @@ -27,6 +26,7 @@ volatile float x, y, z; int in[] = { 0, 1, 3, 8, 13, 20, 25, 32, 50, 60, 72, 85, 100, 145, 200, 250, 300, 400, 500, 600, 650, 700, 753, 800, 830, 870, 900, 936, 964, 985, 1000, 1017, 1023 }; + int out[] = { -27315, -7165, -6069, -4981, -4397, -3850, -3554, -3216, -2572, -2295, -2008, -1737, -1462, -790, -143, 357, 808, 1634, 2430, 3264, 3717, 4213, 4805, 5419, 5875, 6603, 7287, 8385, 9651, 11146, 12949, 18282, 30182 @@ -91,3 +91,4 @@ float val(int sensorValueA1) // -- END OF FILE -- + diff --git a/libraries/MultiMap/examples/multimap_distance/multimap_distance.ino b/libraries/MultiMap/examples/multimap_distance/multimap_distance.ino index ffc8a5b3..839eadcf 100644 --- a/libraries/MultiMap/examples/multimap_distance/multimap_distance.ino +++ b/libraries/MultiMap/examples/multimap_distance/multimap_distance.ino @@ -1,10 +1,10 @@ // // FILE: multimap_distance.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 // PURPOSE: demo // DATE: 2020-04-09 // +// example simulates the lookup graph of a distance sensor #include "MultiMap.h" @@ -48,3 +48,4 @@ float sharp2cm(int val) // -- END OF FILE -- + diff --git a/libraries/MultiMap/examples/multimap_functions/multimap_functions.ino b/libraries/MultiMap/examples/multimap_functions/multimap_functions.ino index db9e1a13..df1871d9 100644 --- a/libraries/MultiMap/examples/multimap_functions/multimap_functions.ino +++ b/libraries/MultiMap/examples/multimap_functions/multimap_functions.ino @@ -1,11 +1,12 @@ // // FILE: multimap_functions.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 // PURPOSE: demo (use serial plotter)... // DATE: 2020-04-09 // (c) : MIT // +// example show use of multiMap to approximate some well known functions. + #include "MultiMap.h" @@ -53,7 +54,7 @@ void test_normal_distribution() void test_sinus() { - // one sinus wave, amplitudo 1023 + // one sinus wave, amplitude 1023 long sinus[] = {0, 316, 601, 827, 972, 1023, 972, 827, 601, 316, 0, -316, -601, -827, -972, -1023, -972, -827, -601, -316, 0 }; //21 long in[21]; for (int i = 0; i < 21; i++) in[i] = round(i * 1000.0 / 20); @@ -136,3 +137,4 @@ void test_sawtooth() // -- END OF FILE -- + diff --git a/libraries/MultiMap/examples/multimap_timing/multimap_timing.ino b/libraries/MultiMap/examples/multimap_timing/multimap_timing.ino index f32d6a81..90e81b0c 100644 --- a/libraries/MultiMap/examples/multimap_timing/multimap_timing.ino +++ b/libraries/MultiMap/examples/multimap_timing/multimap_timing.ino @@ -1,11 +1,11 @@ // // FILE: multimap_timing.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 // PURPOSE: demo // DATE: 2020-04-09 // (c) : MIT // +// example measures the performance of multiMap vs #include "MultiMap.h" @@ -30,6 +30,7 @@ void setup() start = micros(); float x = multiMap(12, in, out, 3); stop = micros(); + Serial.print("time : \t"); Serial.println(stop - start); Serial.println(x, 4); delay(10); // make sure print has ended @@ -37,8 +38,12 @@ void setup() start = micros(); float y = multiMap(12, fin, fout, 3); stop = micros(); + Serial.print("time : \t"); Serial.println(stop - start); Serial.println(y, 4); + delay(10); // make sure print has ended + + Serial.println("\ndone..."); } @@ -48,3 +53,4 @@ void loop() // -- END OF FILE -- + diff --git a/libraries/MultiMap/keywords.txt b/libraries/MultiMap/keywords.txt index 27117d85..bc68c319 100644 --- a/libraries/MultiMap/keywords.txt +++ b/libraries/MultiMap/keywords.txt @@ -1,6 +1,6 @@ -# Syntax Coloring Map For multiMap +# Syntax Colouring Map For multiMap -# Datatypes (KEYWORD1) +# Data types (KEYWORD1) # Methods and Functions (KEYWORD2) diff --git a/libraries/MultiMap/library.json b/libraries/MultiMap/library.json index c1bf0f6d..2702e0b3 100644 --- a/libraries/MultiMap/library.json +++ b/libraries/MultiMap/library.json @@ -15,8 +15,9 @@ "type": "git", "url": "https://github.com/RobTillaart/MultiMap.git" }, - "version": "0.1.4", + "version": "0.1.5", "license": "MIT", "frameworks": "arduino", - "platforms": "*" + "platforms": "*", + "headers": "MultiMap.h" } diff --git a/libraries/MultiMap/library.properties b/libraries/MultiMap/library.properties index f751a4ca..e4e7abae 100644 --- a/libraries/MultiMap/library.properties +++ b/libraries/MultiMap/library.properties @@ -1,5 +1,5 @@ name=MultiMap -version=0.1.4 +version=0.1.5 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library for fast non-linear interpolation by means of two arrays. diff --git a/libraries/MultiMap/test/unit_test_001.cpp b/libraries/MultiMap/test/unit_test_001.cpp index 62d3b32b..e7384228 100644 --- a/libraries/MultiMap/test/unit_test_001.cpp +++ b/libraries/MultiMap/test/unit_test_001.cpp @@ -37,6 +37,7 @@ unittest_setup() { + fprintf(stderr, "MULTIMAP_LIB_VERSION: %s\n", (char *) MULTIMAP_LIB_VERSION); } @@ -58,10 +59,8 @@ unittest(test_new_operator) */ -unittest(test_all) +unittest(test_float) { - fprintf(stderr, "VERSION: %s\n", MULTIMAP_LIB_VERSION); - // based on the distance example // out[] holds the distances in cm float out[] = {150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20}; @@ -78,6 +77,25 @@ unittest(test_all) } +/* todo +unittest(test_uint32_t) +{ + // based on the distance example + // out[] holds the distances in cm + uint32_t out[] = {150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20}; + // in[] holds the measured analogRead() values for that distance + uint32_t in[] = { 90, 97, 105, 113, 124, 134, 147, 164, 185, 218, 255, 317, 408, 506}; + + assertEqual(150, multiMap(80, in, out, 14) ); + assertEqual(136, multiMap(100, in, out, 14) ); + assertEqual( 65, multiMap(200, in, out, 14) ); + assertEqual( 42, multiMap(300, in, out, 14) ); + assertEqual( 30, multiMap(400, in, out, 14) ); + assertEqual( 20, multiMap(500, in, out, 14) ); + assertEqual( 20, multiMap(600, in, out, 14) ); +} +*/ + unittest_main()