mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.0 GAMMA
This commit is contained in:
parent
ef7e288adf
commit
0832418993
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,12 +1,16 @@
|
||||
|
||||
[![Arduino CI](https://github.com/RobTillaart/GAMMA/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
||||
[![Arduino-lint](https://github.com/RobTillaart/GAMMA/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/GAMMA/actions/workflows/arduino-lint.yml)
|
||||
[![JSON check](https://github.com/RobTillaart/GAMMA/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/GAMMA/actions/workflows/jsoncheck.yml)
|
||||
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/GAMMA/blob/master/LICENSE)
|
||||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/GAMMA.svg?maxAge=3600)](https://github.com/RobTillaart/GAMMA/releases)
|
||||
|
||||
|
||||
# GAMMA
|
||||
|
||||
Arduino Library for the GAMMA function to adjust brightness of LED's etc.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
This library is provides a gamma lookup class. It is typical used to
|
||||
@ -23,41 +27,50 @@ The size can be as small as 2 which is pretty inaccurate.
|
||||
In this latter case the curve is approximated by only two linear interpolations.
|
||||
In short, choose the size that fits your application.
|
||||
|
||||
The library has a **setGamma()** function that allows an application to change
|
||||
the gamma value runtime. This allows adjustments that a fixed table does not have.
|
||||
The library has a **setGamma(float gamma)** function that allows an application
|
||||
to change the gamma value runtime.
|
||||
This allows adjustments that a fixed table does not have.
|
||||
|
||||
The class can be used to dump the internal table e.g. to place in PROGMEM.
|
||||
|
||||
Note: tested on UNO and ESP32 only.
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
### Core functions
|
||||
|
||||
- **GAMMA(size = 32)** constructor, gets the size of the internal
|
||||
array as parameter. The array is initialized with a gamma == 2.8 which
|
||||
is an often used value.
|
||||
The default for size = 32 as this is a good balance between performance
|
||||
and size ot the internal array.
|
||||
The size parameter must be in {2, 4, 8, 16, 32, 64, 128, 256 }
|
||||
- **GAMMA(uint16_t size = 32)** constructor, gets the size of the internal
|
||||
array as parameter. The default for size = 32 as this is a good balance between performance
|
||||
and size of the internal array. The size parameter must be in {2, 4, 8, 16, 32, 64, 128, 256 }.
|
||||
- **begin()** The array is initialized with a gamma == 2.8 which is an often used value.
|
||||
**begin()** must be called before any other function.
|
||||
- **setGamma(float gamma)** calculates and fills the array with new values.
|
||||
This can be done runtime so runtime adjustment of gamma mapping.
|
||||
This function relative quite some time.
|
||||
This function takes relative quite some time.
|
||||
The parameter **gamma** must be > 0. The value 1 gives an 1:1 mapping.
|
||||
- **getGamma()** returns the set gamma value.
|
||||
- **operator \[\]** allows the GAMMA object to be accessed as an array.
|
||||
like ```x = G[40];``` Makes it easy to switch with a real array.
|
||||
|
||||
|
||||
### Development functions
|
||||
|
||||
- **size()** returns size of the internal array.
|
||||
- **distinct()** returns the number of distinct values in the table.
|
||||
- **distinct()** returns the number of distinct values in the table. Especially with larger internal tables this will happen.
|
||||
- **dump()** dumps the internal table to Serial. Can be useful to create
|
||||
a direct usable array in RAM, PROGMEM or wherever.
|
||||
an array in RAM, PROGMEM or wherever.
|
||||
|
||||
## Future ideas
|
||||
|
||||
- look for optimizations
|
||||
- uint16 version?
|
||||
-
|
||||
|
||||
## Operation
|
||||
|
||||
See example
|
||||
|
||||
|
||||
## Future ideas
|
||||
|
||||
- test other platforms
|
||||
- improve documentation
|
||||
- look for optimizations
|
||||
- uint16 version?
|
||||
-
|
||||
|
@ -1,13 +1,14 @@
|
||||
//
|
||||
// FILE: GammaErrorAnalysis.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.2.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-08-08
|
||||
|
||||
|
||||
#include "gamma.h"
|
||||
|
||||
|
||||
GAMMA gt1(256);
|
||||
GAMMA gt2(128);
|
||||
GAMMA gt3(64);
|
||||
@ -20,11 +21,21 @@ GAMMA gt8(2);
|
||||
uint32_t start, d1;
|
||||
volatile int x;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
gt1.begin();
|
||||
gt2.begin();
|
||||
gt3.begin();
|
||||
gt4.begin();
|
||||
gt5.begin();
|
||||
gt6.begin();
|
||||
gt7.begin();
|
||||
gt8.begin();
|
||||
|
||||
Serial.println("\nError Analysis 256 elements = reference\n");
|
||||
Serial.println("Size\tErrors\tMaximum");
|
||||
test_error(gt1);
|
||||
@ -40,6 +51,7 @@ void setup()
|
||||
Serial.println("\ndone...\n");
|
||||
}
|
||||
|
||||
|
||||
void test_error(GAMMA gt)
|
||||
{
|
||||
int count = 0;
|
||||
@ -59,8 +71,11 @@ void test_error(GAMMA gt)
|
||||
Serial.println(maxdiff);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
//
|
||||
// FILE: gammaPerformance.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.2.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-08-08
|
||||
|
||||
|
||||
#include "gamma.h"
|
||||
|
||||
|
||||
GAMMA gt1(256);
|
||||
GAMMA gt2(128);
|
||||
GAMMA gt3(64);
|
||||
@ -17,13 +18,19 @@ GAMMA gt5(16);
|
||||
uint32_t start, d1;
|
||||
volatile int x;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
Serial.println("\ntiming in microseconds\n");
|
||||
gt1.begin();
|
||||
gt2.begin();
|
||||
gt3.begin();
|
||||
gt4.begin();
|
||||
gt5.begin();
|
||||
|
||||
Serial.println("\ntiming in microseconds\n");
|
||||
|
||||
Serial.println("SETGAMMA");
|
||||
Serial.println("SIZE\tTIME\tTIME per element");
|
||||
@ -34,7 +41,6 @@ void setup()
|
||||
test_setGamma(gt5);
|
||||
Serial.println();
|
||||
|
||||
|
||||
Serial.println("SETGAMMA II");
|
||||
Serial.println("SIZE\tTIME\tTIME per element");
|
||||
test_setGamma(gt1);
|
||||
@ -44,7 +50,6 @@ void setup()
|
||||
test_setGamma(gt5);
|
||||
Serial.println();
|
||||
|
||||
|
||||
Serial.println("GET[]");
|
||||
Serial.println("SIZE\tTIME\tTIME per element");
|
||||
test_index(gt1);
|
||||
@ -54,10 +59,10 @@ void setup()
|
||||
test_index(gt5);
|
||||
Serial.println();
|
||||
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
void test_setGamma(GAMMA & gt)
|
||||
{
|
||||
start = micros();
|
||||
@ -71,6 +76,7 @@ void test_setGamma(GAMMA & gt)
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
void test_index(GAMMA & gt)
|
||||
{
|
||||
start = micros();
|
||||
@ -92,4 +98,5 @@ void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -1,26 +1,39 @@
|
||||
//
|
||||
// FILE: gamma_test.ino
|
||||
// FILE: gammaFast.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.2.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-08-08
|
||||
|
||||
|
||||
#include "gamma.h"
|
||||
|
||||
|
||||
GAMMA gt1(256);
|
||||
|
||||
// fastGamma is based upon values found with GAMMA(8).setGamma(2.8);
|
||||
// it is however not that fast...
|
||||
|
||||
// it is however not fast enough...
|
||||
// binary search
|
||||
int fastGamma(uint8_t idx)
|
||||
{
|
||||
if (idx < 32) return map(idx, 0, 31, 0, 1);
|
||||
if (idx < 64) return map(idx, 32, 63, 1, 5);
|
||||
if (idx < 96) return map(idx, 64, 31, 5, 17);
|
||||
if (idx < 128) return map(idx, 96, 127, 17, 37);
|
||||
if (idx < 160) return map(idx, 128, 159, 37, 69);
|
||||
if (idx < 192) return map(idx, 160, 191, 69, 115);
|
||||
if (idx < 128)
|
||||
{
|
||||
if (idx < 64)
|
||||
{
|
||||
if (idx < 32) return map(idx, 0, 31, 0, 1);
|
||||
return map(idx, 32, 63, 1, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idx < 96) return map(idx, 64, 95, 5, 17);
|
||||
return map(idx, 96, 127, 17, 37);
|
||||
}
|
||||
}
|
||||
if (idx < 192)
|
||||
{
|
||||
if (idx < 160) return map(idx, 128, 159, 37, 69);
|
||||
return map(idx, 160, 191, 69, 115);
|
||||
}
|
||||
if (idx < 224) return map(idx, 192, 223, 115, 177);
|
||||
return map(idx, 224, 255, 177, 255);
|
||||
}
|
||||
@ -30,32 +43,46 @@ void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
gt1.begin();
|
||||
gt1.setGamma(2.8);
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
Serial.println("\n\ttest fastGamma()");
|
||||
Serial.println("\ti \tgt1[] \tfast \tdelta");
|
||||
for (int i = 0; i < 256; i ++ )
|
||||
{
|
||||
Serial.print('\t');
|
||||
Serial.print(i);
|
||||
Serial.print('\t');
|
||||
Serial.print(gt1[i]);
|
||||
Serial.print('\t');
|
||||
Serial.print(fastGamma(i));
|
||||
Serial.print(fastGamma(i));
|
||||
Serial.print('\t');
|
||||
Serial.print(gt1[i] - fastGamma(i));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
volatile int x;
|
||||
volatile uint32_t x = 0;
|
||||
uint32_t start = micros();
|
||||
for (int i = 0; i < 256; i++) x += gt1[i];
|
||||
uint32_t d1 = micros() - start;
|
||||
Serial.println();
|
||||
Serial.print(" 256 x gt1[i] : ");
|
||||
Serial.println(d1);
|
||||
Serial.print(" x : ");
|
||||
Serial.println(x);
|
||||
delay(10);
|
||||
|
||||
x = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < 256; i++) x += fastGamma(i);
|
||||
d1 = micros() - start;
|
||||
Serial.print(" 256 x fast : ");
|
||||
Serial.println(d1);
|
||||
Serial.print(" x : ");
|
||||
Serial.println(x);
|
||||
delay(10);
|
||||
|
||||
Serial.println(x);
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
@ -63,4 +90,5 @@ void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -1,23 +1,31 @@
|
||||
//
|
||||
// FILE: gamma_test.ino
|
||||
// FILE: gammaTest.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.2.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-08-08
|
||||
|
||||
|
||||
#include "gamma.h"
|
||||
|
||||
|
||||
GAMMA gt1(256);
|
||||
GAMMA gt2(128);
|
||||
GAMMA gt3(64);
|
||||
GAMMA gt4(32); // default
|
||||
GAMMA gt5(16);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
gt1.begin();
|
||||
gt2.begin();
|
||||
gt3.begin();
|
||||
gt4.begin();
|
||||
gt5.begin();
|
||||
|
||||
gt1.setGamma(2.8);
|
||||
gt2.setGamma(2.8);
|
||||
gt3.setGamma(2.8);
|
||||
@ -39,12 +47,15 @@ void setup()
|
||||
Serial.print(gt5[i]);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
Serial.println("\ndone...\n");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -1,25 +1,30 @@
|
||||
//
|
||||
// FILE: gamma_test.ino
|
||||
// FILE: gammaTest2.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.2.0
|
||||
// PURPOSE: demo setGamma
|
||||
// DATE: 2020-08-08
|
||||
|
||||
// Use Arduino Plotter to see the different curves.
|
||||
|
||||
|
||||
#include "gamma.h"
|
||||
|
||||
GAMMA gt; // uses default 32 size
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("hello");
|
||||
Serial.println("gammaTest2.ino");
|
||||
|
||||
gt.begin();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
for (int gam = 1; gam < 10; gam += 1)
|
||||
for (float gamma = 0.1; gamma < 10; gamma *= 2)
|
||||
{
|
||||
gt.setGamma(gam);
|
||||
gt.setGamma(gamma);
|
||||
Serial.print(gt[i]);
|
||||
Serial.print('\t');
|
||||
}
|
||||
@ -32,4 +37,6 @@ void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,23 +2,21 @@
|
||||
//
|
||||
// FILE: gamma.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2020-08-08
|
||||
// PURPOSE: Arduino Library to efficiently hold a gamma lookup table
|
||||
|
||||
// 0.1.0 2020-08-08 initial release
|
||||
// 0.1.1 2020-12-24 arduino-ci + unit test
|
||||
// 0.2.0 2021-11-02 update build-CI, badges
|
||||
// add begin() - fixes ESP32 crash.
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define GAMMA_LIB_VERSION (F("0.1.1"))
|
||||
#define GAMMA_LIB_VERSION (F("0.2.0"))
|
||||
|
||||
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
#include "types.h"
|
||||
#endif
|
||||
|
||||
class GAMMA
|
||||
{
|
||||
|
||||
@ -39,15 +37,26 @@ public:
|
||||
}
|
||||
_mask = (1 << _shift) - 1;
|
||||
_interval = 256 / _size;
|
||||
_table = (uint8_t *)malloc(_size + 1);
|
||||
setGamma(2.8);
|
||||
// removed malloc from constructor for ESP32
|
||||
}
|
||||
|
||||
|
||||
~GAMMA()
|
||||
{
|
||||
if (_table) free(_table);
|
||||
}
|
||||
|
||||
|
||||
void begin()
|
||||
{
|
||||
if (_table == NULL)
|
||||
{
|
||||
_table = (uint8_t *)malloc(_size + 1);
|
||||
}
|
||||
setGamma(2.8);
|
||||
}
|
||||
|
||||
|
||||
void setGamma(float gamma)
|
||||
{
|
||||
if (_gamma != gamma)
|
||||
@ -62,11 +71,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float getGamma()
|
||||
{
|
||||
return _gamma;
|
||||
};
|
||||
|
||||
|
||||
uint8_t operator[] (uint8_t idx)
|
||||
{
|
||||
if (_interval == 1) return _table[idx];
|
||||
@ -81,11 +92,13 @@ public:
|
||||
return _table[i] + delta;
|
||||
}
|
||||
|
||||
|
||||
uint16_t size()
|
||||
{
|
||||
return _size + 1;
|
||||
};
|
||||
|
||||
|
||||
int distinct()
|
||||
{
|
||||
int last = _table[0];
|
||||
@ -99,6 +112,7 @@ public:
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
void dump()
|
||||
{
|
||||
for (uint16_t i = 0; i < _size; i++)
|
||||
@ -114,8 +128,9 @@ private:
|
||||
uint16_t _size = 0;
|
||||
uint8_t _interval = 0;
|
||||
float _gamma = 0;
|
||||
uint8_t * _table;
|
||||
|
||||
uint8_t * _table = NULL;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/GAMMA.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=GAMMA
|
||||
version=0.1.1
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino Library for the GAMMA function
|
||||
|
@ -37,61 +37,58 @@ unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
unittest(test_new_operator)
|
||||
{
|
||||
assertEqualINF(exp(800));
|
||||
assertEqualINF(0.0/0.0);
|
||||
assertEqualINF(42);
|
||||
|
||||
assertEqualNAN(INFINITY - INFINITY);
|
||||
assertEqualNAN(0.0/0.0);
|
||||
assertEqualNAN(42);
|
||||
}
|
||||
*/
|
||||
|
||||
unittest(test_constructor)
|
||||
{
|
||||
GAMMA gt0; // uses default 32 size
|
||||
gt0.begin();
|
||||
assertEqual(33, gt0.size());
|
||||
assertEqualFloat(2.8, gt0.getGamma(), 0.0001);
|
||||
assertEqual(28, gt0.distinct());
|
||||
|
||||
GAMMA gt1(256);
|
||||
gt1.begin();
|
||||
assertEqual(257, gt1.size());
|
||||
assertEqualFloat(2.8, gt1.getGamma(), 0.0001);
|
||||
assertEqual(163, gt1.distinct());
|
||||
|
||||
GAMMA gt2(128);
|
||||
gt2.begin();
|
||||
assertEqual(129, gt2.size());
|
||||
assertEqualFloat(2.8, gt2.getGamma(), 0.0001);
|
||||
assertEqual(97, gt2.distinct());
|
||||
|
||||
GAMMA gt3(64);
|
||||
gt3.begin();
|
||||
assertEqual(65, gt3.size());
|
||||
assertEqualFloat(2.8, gt3.getGamma(), 0.0001);
|
||||
assertEqual(53, gt3.distinct());
|
||||
|
||||
GAMMA gt4(32); // default
|
||||
gt4.begin();
|
||||
assertEqual(33, gt4.size());
|
||||
assertEqualFloat(2.8, gt4.getGamma(), 0.0001);
|
||||
assertEqual(28, gt4.distinct());
|
||||
|
||||
GAMMA gt5(16);
|
||||
gt5.begin();
|
||||
assertEqual(17, gt5.size());
|
||||
assertEqualFloat(2.8, gt5.getGamma(), 0.0001);
|
||||
assertEqual(15, gt5.distinct());
|
||||
|
||||
GAMMA gt6(8);
|
||||
gt6.begin();
|
||||
assertEqual(9, gt6.size());
|
||||
assertEqualFloat(2.8, gt6.getGamma(), 0.0001);
|
||||
assertEqual(8, gt6.distinct());
|
||||
}
|
||||
|
||||
|
||||
unittest(test_get_set)
|
||||
{
|
||||
GAMMA gt; // uses default 32 size
|
||||
|
||||
gt.begin();
|
||||
for (int i = 1; i < 20; i++)
|
||||
{
|
||||
gt.setGamma(i * 0.1);
|
||||
@ -99,6 +96,7 @@ unittest(test_get_set)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
|
Loading…
x
Reference in New Issue
Block a user