Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/arduino-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: arduino/arduino-lint-action@v1
- uses: actions/checkout@v6
- uses: arduino/arduino-lint-action@v2
with:
library-manager: update
compliance: strict
3 changes: 1 addition & 2 deletions .github/workflows/arduino_test_runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ jobs:
runTest:
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/jsoncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ on:
paths:
- '**.json'
pull_request:
paths:
- '**.json'

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: json-syntax-check
uses: limitusus/json-syntax-check@v2
with:
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.0] - 2026-02-23
- fix #13, allow size to be 65535 (uint16_t)
- add patch for possible interpolation under/overflows.
- add multi type **multiMapCache<T1, T2>** as it was missing.
- update readme.md
- update GitHub actions
- minor edits

----

## [0.2.1] - 2025-07-17
- update readme.md
- add multiMap_demo.ino
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2011-2025 Rob Tillaart
Copyright (c) 2011-2026 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
Expand Down
86 changes: 74 additions & 12 deletions MultiMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
//
// FILE: MultiMap.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// VERSION: 0.3.0
// DATE: 2011-01-26
// PURPOSE: Arduino library for fast non-linear mapping or interpolation of values
// URL: https://github.com/RobTillaart/MultiMap
// URL: http://playground.arduino.cc/Main/MultiMap



#define MULTIMAP_LIB_VERSION (F("0.2.1"))
#define MULTIMAP_LIB_VERSION (F("0.3.0"))


#include "Arduino.h"
Expand All @@ -22,21 +22,23 @@
//
// note: the in array must have increasing values
template<typename T>
T multiMap(T value, T* _in, T* _out, uint8_t size)
T multiMap(T value, T* _in, T* _out, uint16_t size)
{
// output is constrained to out array
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] already tested
uint16_t pos = 1; // _in[0] already tested
while(value > _in[pos]) pos++;

// this will handle all exact "points" in the _in array
if (value == _in[pos]) return _out[pos];

// interpolate in the right segment for the rest
return (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
// if interpolation overflows use this line
// return T(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
}


Expand All @@ -49,7 +51,7 @@ T multiMap(T value, T* _in, T* _out, uint8_t size)
// e.g. 2 2 2 2 2 3 3 3 3 5 5 5 5 5 5 8 8 8 8 5 5 5 5 5
// implements a minimal cache of the lastValue.
template<typename T>
T multiMapCache(T value, T* _in, T* _out, uint8_t size)
T multiMapCache(T value, T* _in, T* _out, uint16_t size)
{
static T lastValue = -1; // possible bug for 1st call
static T cache = -1;
Expand All @@ -72,7 +74,7 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
else
{
// search right interval; index 0 _in[0] already tested
uint8_t pos = 1;
uint16_t pos = 1;
while(value > _in[pos]) pos++;

// this will handle all exact "points" in the _in array
Expand All @@ -84,6 +86,8 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
{
// interpolate in the right segment for the rest
cache = (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
// if interpolation overflows use this line
// cache = T(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
}
}
return cache;
Expand All @@ -99,7 +103,7 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
//
// note: the in array must have increasing values
template<typename T>
T multiMapBS(T value, T* _in, T* _out, uint8_t size)
T multiMapBS(T value, T* _in, T* _out, uint16_t size)
{
// output is constrained to out array
if (value <= _in[0]) return _out[0];
Expand All @@ -110,12 +114,14 @@ T multiMapBS(T value, T* _in, T* _out, uint8_t size)
uint16_t upper = size - 1;
while (lower < upper - 1)
{
uint8_t mid = (lower + upper) / 2;
uint16_t mid = (lower + upper) / 2;
if (value >= _in[mid]) lower = mid;
else upper = mid;
}

// interpolate in the right segment for the rest
return (value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower]) + _out[lower];
// if interpolation overflows use this line
// return T(float(value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower])) + _out[lower];
}


Expand All @@ -125,7 +131,7 @@ T multiMapBS(T value, T* _in, T* _out, uint8_t size)
//
// note: the in array must have increasing values
template<typename T1, typename T2>
T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)
T2 multiMap(T1 value, T1* _in, T2* _out, uint16_t size)
{
// output is constrained to out array
if (value <= _in[0]) return _out[0];
Expand All @@ -140,6 +146,60 @@ T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)

// interpolate in the right segment for the rest
return (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
// if interpolation overflows use this line
// return T2(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
}


////////////////////////////////////////////////////////////////////////
//
// MULTITYPE TYPE MULTIMAP CACHE - LINEAR SEARCH
//
// note: the in array must have increasing values
// performance optimized version if inputs do not change often
// e.g. 2 2 2 2 2 3 3 3 3 5 5 5 5 5 5 8 8 8 8 5 5 5 5 5
// implements a minimal cache of the lastValue.
template<typename T1, typename T2>
T2 multiMapCache(T1 value, T1* _in, T2* _out, uint16_t size)
{
static T1 lastValue = -1; // possible bug for 1st call
static T2 cache = -1;

if (value == lastValue)
{
return cache;
}
lastValue = value;

// output is constrained to out array
if (value <= _in[0])
{
cache = _out[0];
}
else if (value >= _in[size-1])
{
cache = _out[size-1];
}
else
{
// search right interval; index 0 _in[0] already tested
uint16_t pos = 1;
while(value > _in[pos]) pos++;

// this will handle all exact "points" in the _in array
if (value == _in[pos])
{
cache = _out[pos];
}
else
{
// interpolate in the right segment for the rest
cache = (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
// if interpolation overflows use this line
// return T2(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
}
}
return cache;
}


Expand All @@ -151,7 +211,7 @@ T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)
//
// note: the in array must have increasing values
template<typename T1, typename T2>
T2 multiMapBS(T1 value, T1* _in, T2* _out, uint8_t size)
T2 multiMapBS(T1 value, T1* _in, T2* _out, uint16_t size)
{
// output is constrained to out array
if (value <= _in[0]) return _out[0];
Expand All @@ -166,8 +226,10 @@ T2 multiMapBS(T1 value, T1* _in, T2* _out, uint8_t size)
if (value >= _in[mid]) lower = mid;
else upper = mid;
}

// interpolate in the right segment for the rest
return (value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower]) + _out[lower];
// if interpolation overflows use this line
// return T2(float(value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower])) + _out[lower];
}


Expand Down
Loading