From 07eb5385042ced6285ce72e5fe93fe133f74a6d8 Mon Sep 17 00:00:00 2001
From: David Huss <dh@atoav.com>
Date: Sun, 16 Jun 2024 14:51:37 +0200
Subject: [PATCH] Fix rev1.1 LED colors

---
 build-environment.md                          |  58 ++
 build.sh                                      |  21 +
 daisyy-looper/daisyy-looper.ino               |   6 +
 deploy.sh                                     |  10 +
 .../lookup-tables-checkpoint.ipynb            | 971 ++++++++++++++++++
 .../default-37a8.jupyterlab-workspace         |   1 +
 scripts/lookup-tables.ipynb                   | 132 ++-
 7 files changed, 1175 insertions(+), 24 deletions(-)
 create mode 100644 build-environment.md
 create mode 100755 build.sh
 create mode 100755 deploy.sh
 create mode 100644 scripts/.ipynb_checkpoints/lookup-tables-checkpoint.ipynb
 create mode 100644 scripts/.jupyter/desktop-workspaces/default-37a8.jupyterlab-workspace

diff --git a/build-environment.md b/build-environment.md
new file mode 100644
index 0000000..5dec368
--- /dev/null
+++ b/build-environment.md
@@ -0,0 +1,58 @@
+# Build Environment Setup
+
+This project uses `arduino-cli` to allow us to build binaries for the daisy seed using a build script.
+
+## Prerequesites
+
+- Install the usual Daisy-Seed build environment
+- install `arduino-cli`
+- hope that was all
+
+## Installing the Dependencies
+
+arduino-cli is a totally separate tool from the Arduino GUI application, that means it manages boards and libraries separately. In order to get this project started follow the steps below:
+
+
+### 1. Install h7 board
+
+```bash
+arduino-cli core install --additional-urls https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json STMicroelectronics:stm32
+```
+
+### 2. Install library dependencies
+
+```bash
+arduino-cli lib install 'DaisyDuino'
+arduino-cli lib install 'Adafruit GFX Library'
+arduino-cli lib install 'Adafruit SH110X'
+arduino-cli lib install 'MIDI Library'
+arduino-cli lib install 'MultiMap'
+```
+
+
+## Building
+
+At this point you should be able to run `./build.sh` which should create new bin files in your build directory.
+
+### More Details
+
+Get board details and the Fully Qualified Board Name (fqbn) using this command:
+
+```bash
+arduino-cli board search --additional-urls https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json H7
+```
+
+You can list all build options using:
+
+```bash
+arduino-cli board details --fqbn STMicroelectronics:stm32:GenH7
+```
+
+These options can be attached to the FQBN used in the build.sh, e.g. like this:
+```bash
+--fqbn 'STMicroelectronics:stm32:GenH7:pnum=DAISY_SEED,xserial=generic,usb=none,xusb=FS,opt=osstd,dbg=none,rtlib=nano,upload_method=dfuMethod'
+```
+
+## defines
+
+Within the build script we also have a `--build-property build.extra_flags=-DSOME_DEFINED_FLAG` which allows us to pass preprocessor definitions to our arduino files, e.g. in our case we pass `BOARD_VERSION_1_1` which allows us to react to pinout changes in different board versions by using preprocessor-if else structures
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..d18749c
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+
+echo "Building daisy-looper for board rev 1.1"
+rm -f build/*
+
+# Build binary for board rev 1.1
+arduino-cli compile --build-property build.extra_flags=-DBOARD_VERSION_1_1 -e --fqbn 'STMicroelectronics:stm32:GenH7:pnum=DAISY_SEED,xserial=generic,usb=none,xusb=FS,opt=osstd,dbg=none,rtlib=nano,upload_method=dfuMethod' --output-dir build/ daisyy-looper/
+
+mv build/daisyy-looper.ino.bin build/daisyy-looper.rev1.1.bin
+rm build/*.elf build/*.hex build/*.map
+
+
+echo "Building daisy-looper for board rev 1.0"
+
+arduino-cli compile --build-property build.extra_flags=-DBOARD_VERSION_1_0 -e --fqbn 'STMicroelectronics:stm32:GenH7:pnum=DAISY_SEED,xserial=generic,usb=none,xusb=FS,opt=osstd,dbg=none,rtlib=nano,upload_method=dfuMethod' --output-dir build/ daisyy-looper/
+
+mv build/daisyy-looper.ino.bin build/daisyy-looper.rev1.0.bin
+rm build/*.elf build/*.hex build/*.map
+
+echo "done"
diff --git a/daisyy-looper/daisyy-looper.ino b/daisyy-looper/daisyy-looper.ino
index 5914716..f9f6466 100644
--- a/daisyy-looper/daisyy-looper.ino
+++ b/daisyy-looper/daisyy-looper.ino
@@ -51,8 +51,14 @@ Potentiometer pot_5 = Potentiometer(A4);
 Potentiometer pot_6 = Potentiometer(A5);
 Potentiometer pot_7 = Potentiometer(A6);
 
+
+#ifdef BOARD_VERSION_1_1
+// RGB LED               R    G    B
+RGBLed rgb_led = RGBLed(A10, A9, A11);
+#else
 // RGB LED               R    G    B
 RGBLed rgb_led = RGBLed(A10, A11, A9);
+#endif
 
 
 // OLED Display
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..9beb655
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+VERSION=$(git describe --tags --abbrev=0)
+
+echo "Uploading binary packages for Version $VERSION"
+
+glab upload-package daisyy-looper/$VERSION/daisyy-looper.bin build/daisyy-looper.rev1.0.bin
+glab upload-package daisyy-looper/$VERSION/daisyy-looper.bin build/daisyy-looper.rev1.1.bin
+
+echo "done"
diff --git a/scripts/.ipynb_checkpoints/lookup-tables-checkpoint.ipynb b/scripts/.ipynb_checkpoints/lookup-tables-checkpoint.ipynb
new file mode 100644
index 0000000..e266163
--- /dev/null
+++ b/scripts/.ipynb_checkpoints/lookup-tables-checkpoint.ipynb
@@ -0,0 +1,971 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "52c8bec3-db2d-4522-b692-b035a71410de",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "zsh:1: parse error near `-m'\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "ffe8405ccce2405c84171b7c83e66e65",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 800x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from matplotlib import pyplot as plt\n",
+    "%matplotlib inline\n",
+    "import math\n",
+    "!{sys.executable} -m pip install clipboard\n",
+    "%matplotlib inline\n",
+    "import clipboard\n",
+    "\n",
+    "\n",
+    "def draw(r, g, b):\n",
+    "    x = [x for x in range(256)]\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.axhline(y=0.5, color='black', linestyle='--')\n",
+    "    ax.set_xticks(range(0, 256, 64))\n",
+    "    ax.set_yticks(range(-256*2, 256*2+1, 128))\n",
+    "    ax.grid()\n",
+    "    ax.plot(x, r, 'r')\n",
+    "    ax.plot(x, g, 'g')\n",
+    "    ax.plot(x, b, 'b')\n",
+    "\n",
+    "def r():\n",
+    "    start = 100\n",
+    "    start2 = 220\n",
+    "    last_a = 0\n",
+    "    for i in range(256):\n",
+    "        if i < start:\n",
+    "            yield 0\n",
+    "        elif i < start2:\n",
+    "            span = 255-start\n",
+    "            d = (i-start)/span\n",
+    "            last_a = int(d*30.0)\n",
+    "            yield min(255, last_a)\n",
+    "        else:\n",
+    "            span = 255-start2\n",
+    "            d = (i-start2)/span\n",
+    "            d = d*d*d\n",
+    "            yield min(255, last_a + int(d*350.0))\n",
+    "\n",
+    "def g():\n",
+    "    start = 0\n",
+    "    end = 180-80\n",
+    "    scale = 0.25\n",
+    "    for i in range(256):\n",
+    "        if i < start:\n",
+    "            yield 0\n",
+    "        elif i > end:\n",
+    "            d = 1.0 - ((i-end)/(295-end))\n",
+    "            # d = (d*d)/4 + d/2\n",
+    "            yield max(0, min(255, int(d*175*scale)))\n",
+    "        else:\n",
+    "            d = ((i-start)/(255-start))\n",
+    "            d = (d*d*d)\n",
+    "            yield min(255, int(d*2800*scale))\n",
+    "            \n",
+    "def b():\n",
+    "    start = 4\n",
+    "    end = 40\n",
+    "    scale = 0.2\n",
+    "    for i in range(256):\n",
+    "        if i < start:\n",
+    "            yield 0\n",
+    "        elif i > end:\n",
+    "            d = (i-end)/(60)\n",
+    "            d = d*d\n",
+    "            d = 1.0 - d\n",
+    "            # d = math.sqrt(d)\n",
+    "            yield max(0, min(255, int(d*32*scale)))\n",
+    "        else:\n",
+    "            d = (i-start)/(255-start)\n",
+    "            d = math.sqrt(d)/2 + d/2\n",
+    "            yield max(0, min(255, int(d*107*scale)))\n",
+    "r, g, b = list(r()), list(g()), list(b())\n",
+    "draw(r, g, b)\n",
+    "\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Table for Red LED Channel\\n\"\n",
+    "text += f\"int red_lookup[] = {{{', '.join(str(v) for v in r)}}};\\n\\n\"\n",
+    "text += \"// Lookup Table for Green LED Channel\\n\"\n",
+    "text += f\"int green_lookup[] = {{{', '.join(str(v) for v in g)}}};\\n\\n\"\n",
+    "text += \"// Lookup Table for Blue LED Channel\\n\"\n",
+    "text += f\"int blue_lookup[] = {{{', '.join(str(v) for v in b)}}};\\n\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "41562cc6-9911-4fb1-87ec-f2b3c8bfb3c2",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "f634b493129d44ee861620bc2c52f2df",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "16"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 800x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from matplotlib import pyplot as plt\n",
+    "%matplotlib inline\n",
+    "import math\n",
+    "\n",
+    "\n",
+    "def draw(r):\n",
+    "    l = len(r)\n",
+    "    x = [x for x in range(l)]\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.axhline(y=0.5, color='black', linestyle='--')\n",
+    "    ax.axvline(x=l/2, color='black', linestyle='--')\n",
+    "    ax.set_xticks(range(0, l, 64))\n",
+    "    ax.set_yticks(range(-l*2, l*2+1, 128))\n",
+    "    ax.grid()\n",
+    "    ax.plot(x, r)\n",
+    "\n",
+    "    \n",
+    "    \n",
+    "def deadband(length, deadband=0.04):\n",
+    "    readings = []\n",
+    "\n",
+    "    for i in range(length):\n",
+    "        current_reading = i/(length-1)\n",
+    "        scaler = (1.0) / (1.0 - deadband)\n",
+    "        scaler += 0.1\n",
+    "\n",
+    "        if current_reading < 0.5:\n",
+    "            current_reading += deadband\n",
+    "            current_reading = min(0.5, current_reading)\n",
+    "            current_reading = 0.5 - current_reading\n",
+    "            current_reading *= scaler\n",
+    "            current_reading = 0.5 - current_reading\n",
+    "            # current_reading =\n",
+    "        else:\n",
+    "            current_reading -= deadband\n",
+    "            current_reading = max(0.5, current_reading)\n",
+    "            current_reading = 0.5 - current_reading\n",
+    "            current_reading *= scaler\n",
+    "            current_reading = 0.5 - current_reading\n",
+    "        \n",
+    "        val = min(length, max(0, current_reading))\n",
+    "        readings.append(val)\n",
+    "    return readings\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "bip = deadband(16, deadband = 0.08)\n",
+    "draw(bip)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Table for Bipolar Curve with deadband\\n\"\n",
+    "text += f\"float bip_lookup[] = {{{', '.join(str(v) for v in bip)}}};\\n\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)\n",
+    "len(bip)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "ecc666b0-8195-4276-a576-39d41753b540",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "c0275989ec7240269d115c3bda12a1ea",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "0.0"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 800x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from matplotlib import pyplot as plt\n",
+    "%matplotlib inline\n",
+    "import math\n",
+    "import sys\n",
+    "\n",
+    "\n",
+    "\n",
+    "def draw(r):\n",
+    "    l = len(r)\n",
+    "    x = [x for x in range(l)]\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.axhline(y=0.5, color='black', linestyle='--')\n",
+    "    ax.set_xticks(range(0, l, 64))\n",
+    "    ax.set_yticks(range(-l*2, l*2+1, 128))\n",
+    "    ax.grid()\n",
+    "    ax.plot(x, r)\n",
+    "\n",
+    "    \n",
+    "    \n",
+    "def lin_to_log(length, strength=1.0):\n",
+    "    # Limit to range 0.0 and 1.0\n",
+    "    strength = min(1.0, max(0.0, strength))\n",
+    "    readings = []\n",
+    "    linear_readings = []\n",
+    "    for i in range(length):\n",
+    "        current_reading = i/length\n",
+    "        linear_readings.append(current_reading)\n",
+    "        # Log of 0 is error, so handle it explicitly\n",
+    "        if i == 0:\n",
+    "            current_reading = 0.0\n",
+    "        else:\n",
+    "            current_reading = math.log10(i)\n",
+    "        readings.append(current_reading)\n",
+    "    \n",
+    "    # Normalize to scale 0.1 to one\n",
+    "    maxima = max(readings)\n",
+    "    scaler = 1.0 / maxima\n",
+    "    readings = [r*scaler for r in readings]\n",
+    "    \n",
+    "    output = []\n",
+    "    for i, r in enumerate(readings):\n",
+    "        val = r*strength + linear_readings[i] * (1.0 - strength)\n",
+    "        output.append(val)\n",
+    "    \n",
+    "    # Convert to integer value range\n",
+    "    output = [o for o in output]\n",
+    "    return output\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# lilo = lin_to_log(4096, strength=1.0)\n",
+    "lilo = lin_to_log(32, strength=1.0)\n",
+    "# lilo = [l/256.0 for l in lilo]\n",
+    "draw(lilo)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Table for Logarithmic Curve\\n\"\n",
+    "text += f\"float log_lookup[] = {{{', '.join(str(v) for v in lilo)}}};\\n\\n\"\n",
+    "# print(text)\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)\n",
+    "min(lilo)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "2ecfda42-4a3c-489a-bc90-8576648c339c",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "b80d3161dda442aca4fd56a9650f76e5",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "0.9999999999999999"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 800x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from matplotlib import pyplot as plt\n",
+    "%matplotlib inline\n",
+    "import math\n",
+    "import sys\n",
+    "\n",
+    "\n",
+    "\n",
+    "def draw(r):\n",
+    "    l = len(r)\n",
+    "    x = [x for x in range(l)]\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.axhline(y=0.5, color='black', linestyle='--')\n",
+    "    ax.set_xticks(range(0, l, 64))\n",
+    "    ax.set_yticks(range(-l*2, l*2+1, 128))\n",
+    "    ax.grid()\n",
+    "    ax.plot(x, r)\n",
+    "\n",
+    "    \n",
+    "    \n",
+    "def exp_lookup(length, strength=1.0):\n",
+    "    # Limit to range 0.0 and 1.0\n",
+    "    strength = min(1.0, max(0.0, strength))\n",
+    "    readings = []\n",
+    "    linear_readings = []\n",
+    "    for i in range(length):\n",
+    "        current_reading = i/length\n",
+    "        linear_readings.append(current_reading)\n",
+    "        # Log of 0 is error, so handle it explicitly\n",
+    "        if i == 0:\n",
+    "            current_reading = 0.0\n",
+    "        else:\n",
+    "            current_reading = i*i\n",
+    "        readings.append(current_reading)\n",
+    "    \n",
+    "    # Normalize to scale 0.1 to one\n",
+    "    maxima = max(readings)\n",
+    "    scaler = 1.0 / maxima\n",
+    "    readings = [r*scaler for r in readings]\n",
+    "    \n",
+    "    output = []\n",
+    "    for i, r in enumerate(readings):\n",
+    "        val = r*strength + linear_readings[i] * (1.0 - strength)\n",
+    "        output.append(val)\n",
+    "    \n",
+    "    # Convert to integer value range\n",
+    "    output = [o for o in output]\n",
+    "    return output\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# lilo = lin_to_log(4096, strength=1.0)\n",
+    "lilo = exp_lookup(8, strength=1.0)\n",
+    "draw(lilo)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Table for Exponential Curve\\n\"\n",
+    "text += f\"float exp_lookup[] = {{{', '.join(str(v) for v in lilo)}}};\\n\\n\"\n",
+    "# print(text)\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)\n",
+    "\n",
+    "max(lilo)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "e51416f3-f34d-4513-9f0c-fa52c468274e",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "20aa9b4615984d5e9c1c6af071018e61",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(FloatSlider(value=0.2, description='f', max=1.0, step=0.001), Output()), _dom_classes=('…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "dab51951087c4eaea31ddefaaafa0ce6",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from matplotlib import pyplot as plt\n",
+    "%matplotlib inline\n",
+    "from ipywidgets import interact, FloatSlider\n",
+    "import matplotlib.transforms as transforms\n",
+    "import math\n",
+    "import clipboard\n",
+    "\n",
+    "def draw(f):\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    b = scan2d(x, y, f)\n",
+    "    ax.axhline(y=b, color='red', linestyle='--')\n",
+    "    ax.axvline(x=f, color='red', linestyle='--')\n",
+    "    trans = transforms.blended_transform_factory(\n",
+    "    ax.get_yticklabels()[0].get_transform(), ax.transData)\n",
+    "    ax.text(0.95, b, \"{:.02f}\".format(b), color=\"red\", transform=trans, ha=\"right\", va=\"bottom\")\n",
+    "    ax.grid()\n",
+    "    ax.plot(x, y)\n",
+    "\n",
+    "def lerp(a, b, f=0.5) -> float:\n",
+    "    f = min(1.0, max(0.0, f))\n",
+    "    if f == 0.0:\n",
+    "        return a\n",
+    "    elif f == 1.0:\n",
+    "        return b\n",
+    "    else:\n",
+    "        return a * (1.0-f) + b * f\n",
+    "\n",
+    "def lerp2d(x1, y1, x2, y2, f=0.5):\n",
+    "    if f == 0.0:\n",
+    "        return [x1, x2]\n",
+    "    elif f == 1.0:\n",
+    "        return [x1, x2]\n",
+    "    else:\n",
+    "        x = lerp(x1, x2, f)\n",
+    "        y = lerp(y1, y2, f)\n",
+    "        return [x, y]\n",
+    "\n",
+    "\n",
+    "# A function that scans through two lists representing x/y values using a\n",
+    "# third value called f and returns the linear interpolation between those points\n",
+    "def scan2d(x, y, f):\n",
+    "        # f = min(1.0, max(0.0, f))\n",
+    "        assert len(x) == len(y)\n",
+    "        # Find ax and bx for given factor\n",
+    "        xa = None\n",
+    "        last_value = None\n",
+    "        idx = None\n",
+    "        for i, v in enumerate(x):\n",
+    "            # this = abs(f-v)\n",
+    "            this = f-v\n",
+    "            if xa is None or this > 0:\n",
+    "                xa = this\n",
+    "                idx = i\n",
+    "        idx2 = min(idx+1, len(x)-1)\n",
+    "        if idx == idx2:\n",
+    "            return y[idx]\n",
+    "        xa = x[idx]\n",
+    "        xb = x[idx2]\n",
+    "        ya = y[idx]\n",
+    "        yb = y[idx2]\n",
+    "        xspan = xb-xa\n",
+    "        xscaler = 1/xspan\n",
+    "        new_f = (f-xa)*xscaler\n",
+    "        return lerp(ya, yb, new_f)\n",
+    "        \n",
+    "    \n",
+    "# lines_orig = [\n",
+    "#     [0.0, 0.0, -0.5],\n",
+    "#     [0.45, 0.5, 0.0],\n",
+    "#     [0.55, 0.5, 1.0],\n",
+    "#     [1.0, 1.0, 0.0],\n",
+    "# ]\n",
+    "\n",
+    "# half_deadband = 0.005\n",
+    "\n",
+    "# lines_orig = [\n",
+    "#     [0.0, -1.0, 0.0],\n",
+    "#     [0.0+half_deadband, -1.0, 0.0],\n",
+    "# ] \n",
+    "\n",
+    "# steps = list(range(-9, 11))\n",
+    "# for i in steps:\n",
+    "#     f = float(i)\n",
+    "#     print(f/10)\n",
+    "#     lines_orig.append([0.5+f/20-half_deadband, f/10, 0.0])\n",
+    "#     lines_orig.append([0.5+f/20+half_deadband, f/10, 0.0])\n",
+    "\n",
+    "db = 0.005\n",
+    "hb = db/2.0\n",
+    "\n",
+    "lines_orig = [\n",
+    "    [0.0, -1.0, 0.0],    # -1000%\n",
+    "    [0.0+hb, -1.0, 0.0], # -1000%\n",
+    "    [0.02-hb, -0.9, 0.0], # -900%\n",
+    "    [0.02+hb, -0.9, 0.0], # -900%\n",
+    "    [0.04-hb, -0.8, 0.0], # -800%\n",
+    "    [0.04+hb, -0.8, 0.0], # -800%\n",
+    "    [0.06-hb, -0.7, 0.0], # -700%\n",
+    "    [0.06+hb, -0.7, 0.0], # -700%\n",
+    "    [0.08-hb, -0.6, 0.0], # -600%\n",
+    "    [0.08+hb, -0.6, 0.0], # -600%\n",
+    "    [0.1-hb, -0.5, 0.0], # -500%\n",
+    "    [0.1+hb, -0.5, 0.0], # -500%\n",
+    "    [0.12-hb, -0.4, 0.0], # -400%\n",
+    "    [0.12+hb, -0.4, 0.0], # -400%\n",
+    "    [0.14-hb, -0.3, 0.0], # -300%\n",
+    "    [0.14+hb, -0.3, 0.0], # -300%\n",
+    "    [0.16-hb, -0.2, 0.0], # -200%\n",
+    "    [0.16+hb, -0.2, 0.0], # -200%\n",
+    "    [0.2-hb, -0.1, 0.0], # -100%\n",
+    "    [0.2+hb, -0.1, 0.0], # -100%\n",
+    "    [0.25-hb, -0.05, 0.0], # -50%\n",
+    "    [0.25+hb, -0.05, 0.0], # -50%\n",
+    "    [0.3-hb, -0.025, 0.0], # -25%\n",
+    "    [0.3+hb, -0.025, 0.0], # -25%\n",
+    "    [0.38-hb, -0.0125, 0.0], # -12.5%\n",
+    "    [0.38+hb, -0.0125, 0.0], # -12.5%\n",
+    "    [0.42-hb, -0.00625, 0.0], # -6.25%\n",
+    "    [0.42+hb, -0.00625, 0.0], # -6.25%\n",
+    "    [0.46-hb, -0.003125, 0.0], # -3.125%\n",
+    "    [0.46+hb, -0.003125, 0.0], # -3.125%\n",
+    "    [0.5-hb, 0.0, 0.0], # 0%\n",
+    "    [0.5+hb, 0.0, 0.0], # 0%\n",
+    "    [1.0-0.46-hb, 0.003125, 0.0], # 3.125%\n",
+    "    [1.0-0.46+hb, 0.003125, 0.0], # 3.125%\n",
+    "    [1.0-0.42-hb, 0.00625, 0.0], # 6.25%\n",
+    "    [1.0-0.42+hb, 0.00625, 0.0], # 6.25%\n",
+    "    [1.0-0.38-hb, 0.0125, 0.0], # 12.5%\n",
+    "    [1.0-0.38+hb, 0.0125, 0.0], # 12.5%\n",
+    "    [1.0-0.3-hb, 0.025, 0.0], # 25%\n",
+    "    [1.0-0.3+hb, 0.025, 0.0], # 25%\n",
+    "    [1.0-0.25-hb, 0.05, 0.0], # 50%\n",
+    "    [1.0-0.25+hb, 0.05, 0.0], # 50%\n",
+    "    [1.0-0.2-hb, 0.1, 0.0], # 100%\n",
+    "    [1.0-0.2+hb, 0.1, 0.0], # 100%\n",
+    "    [1.0-0.16-hb, 0.2, 0.0], # 200%\n",
+    "    [1.0-0.16+hb, 0.2, 0.0], # 200%\n",
+    "    [1.0-0.14-hb, 0.3, 0.0], # 300%\n",
+    "    [1.0-0.14+hb, 0.3, 0.0], # 300%\n",
+    "    [1.0-0.12-hb, 0.4, 0.0], # 400%\n",
+    "    [1.0-0.12+hb, 0.4, 0.0], # 400%\n",
+    "    [1.0-0.1-hb, 0.5, 0.0], # 500%\n",
+    "    [1.0-0.1+hb, 0.5, 0.0], # 500%\n",
+    "    [1.0-0.08-hb, 0.6, 0.0], # 600%\n",
+    "    [1.0-0.08+hb, 0.6, 0.0], # 600%\n",
+    "    [1.0-0.06-hb, 0.7, 0.0], # 700%\n",
+    "    [1.0-0.06+hb, 0.7, 0.0], # 700%\n",
+    "    [1.0-0.04-hb, 0.8, 0.0], # 800%\n",
+    "    [1.0-0.04+hb, 0.8, 0.0], # 800%\n",
+    "    [1.0-0.02-hb, 0.9, 0.0], # 900%\n",
+    "    [1.0-0.02+hb, 0.9, 0.0], # 900%\n",
+    "    [1.0-0.0-hb, 1.0, 0.0], # 1000%\n",
+    "    [1.0-0.0, 1.0, 0.0],    # 1000%\n",
+    "]\n",
+    "\n",
+    "# Calculate curves for points of curvature\n",
+    "def make_lines(lines_orig, resolution=20):\n",
+    "    lines = []\n",
+    "    for i, l in enumerate(lines_orig):\n",
+    "        i2 = min(len(lines_orig)-1, i+1)\n",
+    "        if l[2] == 0.0:\n",
+    "            lines.append(l)\n",
+    "        else:\n",
+    "            xa = lines_orig[i][0]\n",
+    "            xb = lines_orig[i2][0]\n",
+    "            ya = lines_orig[i][1]\n",
+    "            yb = lines_orig[i2][1]\n",
+    "            x_span = xb-xa\n",
+    "            y_span = yb-ya\n",
+    "            x_step = 1/20\n",
+    "            y_step = 1/20\n",
+    "            for j in range(resolution):\n",
+    "                x = x_step * j\n",
+    "                y = y_step * j\n",
+    "                y_curve = 0\n",
+    "                if l[2] > 0.0:\n",
+    "                    y_curve = y*y*y\n",
+    "                else:\n",
+    "                    y_curve = y*y\n",
+    "                y = (1.0-l[2]) * y + l[2] * y_curve\n",
+    "                lines.append([xa+x*x_span, ya+y*y_span, 0.0])\n",
+    "    return lines\n",
+    "\n",
+    "lines = make_lines(lines_orig, 20)\n",
+    "\n",
+    "x = [a[0] for a in lines]\n",
+    "y = [a[1] for a in lines]\n",
+    "c = [a[2] for a in lines]\n",
+    "# draw(x, y, 0.45/2)\n",
+    "\n",
+    "interact(draw, f=FloatSlider(min=min(x), max=max(x), step=0.001, value=0.2))\n",
+    "\n",
+    "length = len(x)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Table for Pitch Knob\\n\"\n",
+    "text += f\"float pitch_knob_lookup_x[] = {{{', '.join(str(xv) for xv in x)}}};\\n\"\n",
+    "text += f\"float pitch_knob_lookup_y[] = {{{', '.join(str(yv) for yv in y)}}};\\n\"\n",
+    "text += f\"size_t pitch_knob_lookup_length = {length};\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "f35f1609-3a10-4dce-b7dd-201d79f2c39c",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "1722650a6b67420b828b4257209c0c20",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(FloatSlider(value=0.2, description='f', max=1.5, min=-1.5, step=0.001), Output()), _dom_…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "8cb6ac47adeb428cb272883eda5c34fb",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "19\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Saturation curve\n",
+    "\n",
+    "# X / Y / Curvature\n",
+    "lines_orig = [\n",
+    "    [-1.5, -1.0, 1.0],\n",
+    "    [-0.9, -0.8, 0.0],\n",
+    "    [0.0, 0.0, 0.0],\n",
+    "    [0.9, 0.8, -1.1],\n",
+    "    [1.5, 1.0, 0.0],\n",
+    "]\n",
+    "\n",
+    "lines = make_lines(lines_orig, 8)\n",
+    "\n",
+    "\n",
+    "x = [a[0] for a in lines]\n",
+    "y = [min(1.0, a[1]) for a in lines]\n",
+    "c = [a[2] for a in lines]\n",
+    "# draw(x, y, 0.45/2)\n",
+    "\n",
+    "interact(draw, f=FloatSlider(min=min(x), max=max(x), step=0.001, value=0.2))\n",
+    "\n",
+    "length = len(x)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Curves for Saturation b\\n\"\n",
+    "text += f\"float saturation_lookup_x[] = {{{', '.join(str(xv) for xv in x)}}};\\n\"\n",
+    "text += f\"float saturation_lookup_y[] = {{{', '.join(str(yv) for yv in y)}}};\\n\"\n",
+    "text += f\"size_t saturation_lookup_length = {length};\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)\n",
+    "print(len(x))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "f0cd9d06-a15a-46b4-a3ef-4aee3d4f7cd0",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "5d93604ad4424d3e9fe43ad3bf55aa35",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 800x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# X / Y / Curvature\n",
+    "\n",
+    "def draw_rgb(xr, yr, xg, yg, xb, yb):\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.grid()\n",
+    "    ax.plot(xr, yr, 'r')\n",
+    "    ax.plot(xg, yg, 'g')\n",
+    "    ax.plot(xb, yb, 'b')\n",
+    "\n",
+    "\n",
+    "# BLUE\n",
+    "lines_b = [\n",
+    "    [0, 0, 0.8],\n",
+    "    [40, 10, -1.0],\n",
+    "    [170, 0, 1.0],\n",
+    "]\n",
+    "lines_b = make_lines(lines_b, 20)\n",
+    "xb = [a[0] for a in lines_b]\n",
+    "yb = [a[1] for a in lines_b]\n",
+    "\n",
+    "# Green\n",
+    "lines_g = [\n",
+    "    [10, 0, 1.0],\n",
+    "    [180, 60, -0.2],\n",
+    "    [250, 0, 0.0],\n",
+    "]\n",
+    "lines_g = make_lines(lines_g, 20)\n",
+    "xg = [a[0] for a in lines_g]\n",
+    "yg = [a[1] for a in lines_g]\n",
+    "\n",
+    "# RED\n",
+    "lines_r = [\n",
+    "    [170, 0, 1.0],\n",
+    "    [240, 30, 0.9],\n",
+    "    [255, 255, 0.0],\n",
+    "]\n",
+    "lines_r = make_lines(lines_r, 20)\n",
+    "xr = [a[0] for a in lines_r]\n",
+    "yr = [a[1] for a in lines_r]\n",
+    "\n",
+    "draw_rgb(xr, yr, xg, yg, xb, yb)\n",
+    "\n",
+    "length = len(xr)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Curves LED Red b\\n\"\n",
+    "text += f\"float red_lut_x[] = {{{', '.join(str(xv) for xv in xr)}}};\\n\"\n",
+    "text += f\"float red_lut_y[] = {{{', '.join(str(yv) for yv in yr)}}};\\n\"\n",
+    "text += f\"size_t red_lut_len = {length};\\n\\n\"\n",
+    "length = len(xg)\n",
+    "text += \"// Lookup Curves LED Green b\\n\"\n",
+    "text += f\"float green_lut_x[] = {{{', '.join(str(xv) for xv in xg)}}};\\n\"\n",
+    "text += f\"float green_lut_y[] = {{{', '.join(str(yv) for yv in yg)}}};\\n\"\n",
+    "text += f\"size_t green_lut_len = {length};\\n\\n\"\n",
+    "length = len(xb)\n",
+    "text += \"// Lookup Curves LED Blue b\\n\"\n",
+    "text += f\"float blue_lut_x[] = {{{', '.join(str(xv) for xv in xb)}}};\\n\"\n",
+    "text += f\"float blue_lut_y[] = {{{', '.join(str(yv) for yv in yb)}}};\\n\"\n",
+    "text += f\"size_t blue_lut_len = {length};\\n\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "59b56dbc-6852-4989-bc19-3525ee7caf8b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.0"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5a511d24-cc91-450f-83e4-8295647d9391",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.15"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/scripts/.jupyter/desktop-workspaces/default-37a8.jupyterlab-workspace b/scripts/.jupyter/desktop-workspaces/default-37a8.jupyterlab-workspace
new file mode 100644
index 0000000..a074411
--- /dev/null
+++ b/scripts/.jupyter/desktop-workspaces/default-37a8.jupyterlab-workspace
@@ -0,0 +1 @@
+{"data":{"layout-restorer:data":{"main":{"dock":{"type":"tab-area","currentIndex":0,"widgets":["notebook:lookup-tables.ipynb"]},"current":"notebook:lookup-tables.ipynb"},"down":{"size":0,"widgets":[]},"left":{"collapsed":false,"current":"filebrowser","widgets":["filebrowser","running-sessions","@jupyterlab/toc:plugin","extensionmanager.main-view"]},"right":{"collapsed":true,"widgets":["jp-property-inspector","debugger-sidebar"]},"relativeSizes":[0.26227795193312436,0.7377220480668757,0]},"notebook:lookup-tables.ipynb":{"data":{"path":"lookup-tables.ipynb","factory":"Notebook"}}},"metadata":{"id":"default"}}
\ No newline at end of file
diff --git a/scripts/lookup-tables.ipynb b/scripts/lookup-tables.ipynb
index e266163..124a7c5 100644
--- a/scripts/lookup-tables.ipynb
+++ b/scripts/lookup-tables.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 3,
    "id": "52c8bec3-db2d-4522-b692-b035a71410de",
    "metadata": {},
    "outputs": [
@@ -16,7 +16,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "ffe8405ccce2405c84171b7c83e66e65",
+       "model_id": "66b5440ce99d43a3af5bd4619a347e74",
        "version_major": 2,
        "version_minor": 0
       },
@@ -136,14 +136,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 4,
    "id": "41562cc6-9911-4fb1-87ec-f2b3c8bfb3c2",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "f634b493129d44ee861620bc2c52f2df",
+       "model_id": "32adb47b84dd4f58858c49bea359063f",
        "version_major": 2,
        "version_minor": 0
       },
@@ -160,7 +160,7 @@
        "16"
       ]
      },
-     "execution_count": 1,
+     "execution_count": 4,
      "metadata": {},
      "output_type": "execute_result"
     },
@@ -246,14 +246,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 5,
    "id": "ecc666b0-8195-4276-a576-39d41753b540",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "c0275989ec7240269d115c3bda12a1ea",
+       "model_id": "ecad8d4a664440588b5c4b162cf59f6f",
        "version_major": 2,
        "version_minor": 0
       },
@@ -270,7 +270,7 @@
        "0.0"
       ]
      },
-     "execution_count": 1,
+     "execution_count": 5,
      "metadata": {},
      "output_type": "execute_result"
     },
@@ -363,14 +363,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 6,
    "id": "2ecfda42-4a3c-489a-bc90-8576648c339c",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "b80d3161dda442aca4fd56a9650f76e5",
+       "model_id": "0e8ee669f5134fbab284cd4f35329938",
        "version_major": 2,
        "version_minor": 0
       },
@@ -387,7 +387,7 @@
        "0.9999999999999999"
       ]
      },
-     "execution_count": 2,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     },
@@ -480,14 +480,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 7,
    "id": "e51416f3-f34d-4513-9f0c-fa52c468274e",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "20aa9b4615984d5e9c1c6af071018e61",
+       "model_id": "708a3ca63dda4a76bd0ca1816f67720d",
        "version_major": 2,
        "version_minor": 0
       },
@@ -501,7 +501,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "dab51951087c4eaea31ddefaaafa0ce6",
+       "model_id": "feea2cde9b3c451b88cbd02068b5c26c",
        "version_major": 2,
        "version_minor": 0
       },
@@ -730,14 +730,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 8,
    "id": "f35f1609-3a10-4dce-b7dd-201d79f2c39c",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "1722650a6b67420b828b4257209c0c20",
+       "model_id": "9d6fe4e2863c48ada7c5c22213eb4c0e",
        "version_major": 2,
        "version_minor": 0
       },
@@ -751,7 +751,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "8cb6ac47adeb428cb272883eda5c34fb",
+       "model_id": "5574a08a54ee41db85a2eb7f048114ac",
        "version_major": 2,
        "version_minor": 0
       },
@@ -816,14 +816,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 9,
    "id": "f0cd9d06-a15a-46b4-a3ef-4aee3d4f7cd0",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "5d93604ad4424d3e9fe43ad3bf55aa35",
+       "model_id": "52f6bbe3110d4e559101337fb3fd17be",
        "version_major": 2,
        "version_minor": 0
       },
@@ -921,22 +921,106 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 15,
    "id": "59b56dbc-6852-4989-bc19-3525ee7caf8b",
    "metadata": {},
    "outputs": [
     {
      "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "3ac51e977247409991d27f6285b55164",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(button_style='success', description='copy C++ to clipboard', style=ButtonStyle())"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
       "text/plain": [
-       "1.0"
+       "<Figure size 800x400 with 1 Axes>"
       ]
      },
-     "execution_count": 19,
      "metadata": {},
-     "output_type": "execute_result"
+     "output_type": "display_data"
     }
    ],
-   "source": []
+   "source": [
+    "# X / Y / Curvature\n",
+    "\n",
+    "def draw_rgb(xr, yr, xg, yg, xb, yb):\n",
+    "    fig = plt.figure(figsize=(8, 4))\n",
+    "    ax = fig.add_axes([0, 0, 1, 1])\n",
+    "    ax.grid()\n",
+    "    ax.plot(xr, yr, 'r')\n",
+    "    ax.plot(xg, yg, 'g')\n",
+    "    ax.plot(xb, yb, 'b')\n",
+    "\n",
+    "\n",
+    "# BLUE\n",
+    "lines_b = [\n",
+    "    [0, 0, 0.0],\n",
+    "]\n",
+    "lines_b = make_lines(lines_b, 20)\n",
+    "xb = [a[0] for a in lines_b]\n",
+    "yb = [a[1] for a in lines_b]\n",
+    "\n",
+    "# Green\n",
+    "lines_g = [\n",
+    "    [3.2, 0, 0.0],\n",
+    "    [4.2, 255, 0.],\n",
+    "    [5.0, 255, 0.0],\n",
+    "]\n",
+    "lines_g = make_lines(lines_g, 20)\n",
+    "xg = [a[0] for a in lines_g]\n",
+    "yg = [a[1] for a in lines_g]\n",
+    "\n",
+    "# RED\n",
+    "lines_r = [\n",
+    "    [0, 255, 0.0],\n",
+    "    [3.2, 255, 0.0],\n",
+    "    [4.2, 0, 0.0],\n",
+    "]\n",
+    "lines_r = make_lines(lines_r, 20)\n",
+    "xr = [a[0] for a in lines_r]\n",
+    "yr = [a[1] for a in lines_r]\n",
+    "\n",
+    "draw_rgb(xr, yr, xg, yg, xb, yb)\n",
+    "\n",
+    "length = len(xr)\n",
+    "text = \"\"\n",
+    "text += \"// Lookup Curves LED Red b\\n\"\n",
+    "text += f\"float red_lut_x[] = {{{', '.join(str(xv) for xv in xr)}}};\\n\"\n",
+    "text += f\"float red_lut_y[] = {{{', '.join(str(yv) for yv in yr)}}};\\n\"\n",
+    "text += f\"size_t red_lut_len = {length};\\n\\n\"\n",
+    "length = len(xg)\n",
+    "text += \"// Lookup Curves LED Green b\\n\"\n",
+    "text += f\"float green_lut_x[] = {{{', '.join(str(xv) for xv in xg)}}};\\n\"\n",
+    "text += f\"float green_lut_y[] = {{{', '.join(str(yv) for yv in yg)}}};\\n\"\n",
+    "text += f\"size_t green_lut_len = {length};\\n\\n\"\n",
+    "length = len(xb)\n",
+    "text += \"// Lookup Curves LED Blue b\\n\"\n",
+    "text += f\"float blue_lut_x[] = {{{', '.join(str(xv) for xv in xb)}}};\\n\"\n",
+    "text += f\"float blue_lut_y[] = {{{', '.join(str(yv) for yv in yb)}}};\\n\"\n",
+    "text += f\"size_t blue_lut_len = {length};\\n\\n\"\n",
+    "\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display, HTML, Javascript\n",
+    "mybtn = widgets.Button(description='copy C++ to clipboard', button_style='success')\n",
+    "\n",
+    "def mybtn_event_handler(b):\n",
+    "    print(\"copied\")\n",
+    "    clipboard.copy(text)\n",
+    "\n",
+    "mybtn.on_click(mybtn_event_handler)\n",
+    "\n",
+    "display(mybtn)"
+   ]
   },
   {
    "cell_type": "code",
-- 
GitLab