-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implemented sketch for Teensy with 4x neopixel, 2x DAC (control volta…
…ge), and 2x digital output (gate)
- Loading branch information
1 parent
c769c41
commit 83e2c30
Showing
2 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* | ||
* This is the "turbo" colormap, which resembles the MATLAB "jet" colormap | ||
* See https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html | ||
* | ||
* It consists of 256 RGB triplets with values between 0 and 1. | ||
*/ | ||
|
||
float R[] = {0.18995,0.19483,0.19956,0.20415,0.20860,0.21291,0.21708,0.22111,0.22500,0.22875,0.23236,0.23582,0.23915,0.24234,0.24539,0.24830,0.25107,0.25369,0.25618,0.25853,0.26074,0.26280,0.26473,0.26652,0.26816,0.26967,0.27103,0.27226,0.27334,0.27429,0.27509,0.27576,0.27628,0.27667,0.27691,0.27701,0.27698,0.27680,0.27648,0.27603,0.27543,0.27469,0.27381,0.27273,0.27106,0.26878,0.26592,0.26252,0.25862,0.25425,0.24946,0.24427,0.23874,0.23288,0.22676,0.22039,0.21382,0.20708,0.20021,0.19326,0.18625,0.17923,0.17223,0.16529,0.15844,0.15173,0.14519,0.13886,0.13278,0.12698,0.12151,0.11639,0.11167,0.10738,0.10357,0.10026,0.09750,0.09532,0.09377,0.09287,0.09267,0.09320,0.09451,0.09662,0.09958,0.10342,0.10815,0.11374,0.12014,0.12733,0.13526,0.14391,0.15323,0.16319,0.17377,0.18491,0.19659,0.20877,0.22142,0.23449,0.24797,0.26180,0.27597,0.29042,0.30513,0.32006,0.33517,0.35043,0.36581,0.38127,0.39678,0.41229,0.42778,0.44321,0.45854,0.47375,0.48879,0.50362,0.51822,0.53255,0.54658,0.56026,0.57357,0.58646,0.59891,0.61088,0.62233,0.63323,0.64362,0.65394,0.66428,0.67462,0.68494,0.69525,0.70553,0.71577,0.72596,0.73610,0.74617,0.75617,0.76608,0.77591,0.78563,0.79524,0.80473,0.81410,0.82333,0.83241,0.84133,0.85010,0.85868,0.86709,0.87530,0.88331,0.89112,0.89870,0.90605,0.91317,0.92004,0.92666,0.93301,0.93909,0.94489,0.95039,0.95560,0.96049,0.96507,0.96931,0.97323,0.97679,0.98000,0.98289,0.98549,0.98781,0.98986,0.99163,0.99314,0.99438,0.99535,0.99607,0.99654,0.99675,0.99672,0.99644,0.99593,0.99517,0.99419,0.99297,0.99153,0.98987,0.98799,0.98590,0.98360,0.98108,0.97837,0.97545,0.97234,0.96904,0.96555,0.96187,0.95801,0.95398,0.94977,0.94538,0.94084,0.93612,0.93125,0.92623,0.92105,0.91572,0.91024,0.90463,0.89888,0.89298,0.88691,0.88066,0.87422,0.86760,0.86079,0.85380,0.84662,0.83926,0.83172,0.82399,0.81608,0.80799,0.79971,0.79125,0.78260,0.77377,0.76476,0.75556,0.74617,0.73661,0.72686,0.71692,0.70680,0.69650,0.68602,0.67535,0.66449,0.65345,0.64223,0.63082,0.61923,0.60746,0.59550,0.58336,0.57103,0.55852,0.54583,0.53295,0.51989,0.50664,0.49321,0.47960}; | ||
float G[] = {0.07176,0.08339,0.09498,0.10652,0.11802,0.12947,0.14087,0.15223,0.16354,0.17481,0.18603,0.19720,0.20833,0.21941,0.23044,0.24143,0.25237,0.26327,0.27412,0.28492,0.29568,0.30639,0.31706,0.32768,0.33825,0.34878,0.35926,0.36970,0.38008,0.39043,0.40072,0.41097,0.42118,0.43134,0.44145,0.45152,0.46153,0.47151,0.48144,0.49132,0.50115,0.51094,0.52069,0.53040,0.54015,0.54995,0.55979,0.56967,0.57958,0.58950,0.59943,0.60937,0.61931,0.62923,0.63913,0.64901,0.65886,0.66866,0.67842,0.68812,0.69775,0.70732,0.71680,0.72620,0.73551,0.74472,0.75381,0.76279,0.77165,0.78037,0.78896,0.79740,0.80569,0.81381,0.82177,0.82955,0.83714,0.84455,0.85175,0.85875,0.86554,0.87211,0.87844,0.88454,0.89040,0.89600,0.90142,0.90673,0.91193,0.91701,0.92197,0.92680,0.93151,0.93609,0.94053,0.94484,0.94901,0.95304,0.95692,0.96065,0.96423,0.96765,0.97092,0.97403,0.97697,0.97974,0.98234,0.98477,0.98702,0.98909,0.99098,0.99268,0.99419,0.99551,0.99663,0.99755,0.99828,0.99879,0.99910,0.99919,0.99907,0.99873,0.99817,0.99739,0.99638,0.99514,0.99366,0.99195,0.98999,0.98775,0.98524,0.98246,0.97941,0.97610,0.97255,0.96875,0.96470,0.96043,0.95593,0.95121,0.94627,0.94113,0.93579,0.93025,0.92452,0.91861,0.91253,0.90627,0.89986,0.89328,0.88655,0.87968,0.87267,0.86553,0.85826,0.85087,0.84337,0.83576,0.82806,0.82025,0.81236,0.80439,0.79634,0.78823,0.78005,0.77181,0.76352,0.75519,0.74682,0.73842,0.73000,0.72140,0.71250,0.70330,0.69382,0.68408,0.67408,0.66386,0.65341,0.64277,0.63193,0.62093,0.60977,0.59846,0.58703,0.57549,0.56386,0.55214,0.54036,0.52854,0.51667,0.50479,0.49291,0.48104,0.46920,0.45740,0.44565,0.43399,0.42241,0.41093,0.39958,0.38836,0.37729,0.36638,0.35566,0.34513,0.33482,0.32473,0.31489,0.30530,0.29599,0.28696,0.27824,0.26981,0.26152,0.25334,0.24526,0.23730,0.22945,0.22170,0.21407,0.20654,0.19912,0.19182,0.18462,0.17753,0.17055,0.16368,0.15693,0.15028,0.14374,0.13731,0.13098,0.12477,0.11867,0.11268,0.10680,0.10102,0.09536,0.08980,0.08436,0.07902,0.07380,0.06868,0.06367,0.05878,0.05399,0.04931,0.04474,0.04028,0.03593,0.03169,0.02756,0.02354,0.01963,0.01583}; | ||
float B[] = {0.23217,0.26149,0.29024,0.31844,0.34607,0.37314,0.39964,0.42558,0.45096,0.47578,0.50004,0.52373,0.54686,0.56942,0.59142,0.61286,0.63374,0.65406,0.67381,0.69300,0.71162,0.72968,0.74718,0.76412,0.78050,0.79631,0.81156,0.82624,0.84037,0.85393,0.86692,0.87936,0.89123,0.90254,0.91328,0.92347,0.93309,0.94214,0.95064,0.95857,0.96594,0.97275,0.97899,0.98461,0.98930,0.99303,0.99583,0.99773,0.99876,0.99896,0.99835,0.99697,0.99485,0.99202,0.98851,0.98436,0.97959,0.97423,0.96833,0.96190,0.95498,0.94761,0.93981,0.93161,0.92305,0.91416,0.90496,0.89550,0.88580,0.87590,0.86581,0.85559,0.84525,0.83484,0.82437,0.81389,0.80342,0.79299,0.78264,0.77240,0.76230,0.75237,0.74265,0.73316,0.72393,0.71500,0.70599,0.69651,0.68660,0.67627,0.66556,0.65448,0.64308,0.63137,0.61938,0.60713,0.59466,0.58199,0.56914,0.55614,0.54303,0.52981,0.51653,0.50321,0.48987,0.47654,0.46325,0.45002,0.43688,0.42386,0.41098,0.39826,0.38575,0.37345,0.36140,0.34963,0.33816,0.32701,0.31622,0.30581,0.29581,0.28623,0.27712,0.26849,0.26038,0.25280,0.24579,0.23937,0.23356,0.22835,0.22370,0.21960,0.21602,0.21294,0.21032,0.20815,0.20640,0.20504,0.20406,0.20343,0.20311,0.20310,0.20336,0.20386,0.20459,0.20552,0.20663,0.20788,0.20926,0.21074,0.21230,0.21391,0.21555,0.21719,0.21880,0.22038,0.22188,0.22328,0.22456,0.22570,0.22667,0.22744,0.22800,0.22831,0.22836,0.22811,0.22754,0.22663,0.22536,0.22369,0.22161,0.21918,0.21650,0.21358,0.21043,0.20706,0.20348,0.19971,0.19577,0.19165,0.18738,0.18297,0.17842,0.17376,0.16899,0.16412,0.15918,0.15417,0.14910,0.14398,0.13883,0.13367,0.12849,0.12332,0.11817,0.11305,0.10797,0.10294,0.09798,0.09310,0.08831,0.08362,0.07905,0.07461,0.07031,0.06616,0.06218,0.05837,0.05475,0.05134,0.04814,0.04516,0.04243,0.03993,0.03753,0.03521,0.03297,0.03082,0.02875,0.02677,0.02487,0.02305,0.02131,0.01966,0.01809,0.01660,0.01520,0.01387,0.01264,0.01148,0.01041,0.00942,0.00851,0.00769,0.00695,0.00629,0.00571,0.00522,0.00481,0.00449,0.00424,0.00408,0.00401,0.00401,0.00410,0.00427,0.00453,0.00486,0.00529,0.00579,0.00638,0.00705,0.00780,0.00863,0.00955,0.01055}; |
202 changes: 202 additions & 0 deletions
202
teensy_cvgate_mcp4725_neopixel/teensy_cvgate_mcp4725_neopixel.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/* | ||
* EEGSynth Teensy based CV/Gate controller. This sketch allows | ||
* one to use control voltages and gates to interface a computer | ||
* with an analog synthesizer. The hardware comprises a Teensy | ||
* with two MCP4725 12-bit DAC breakout boards. | ||
* | ||
* Some example sequences of characters are | ||
* *c1v1024# control 1 voltage 5*1024/4095 = 1.25 V | ||
* *g1v1# gate 1 value ON | ||
* | ||
* This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. | ||
* See http://creativecommons.org/licenses/by-sa/4.0/ | ||
* | ||
* Copyright (C) 2020, Robert Oostenveld, http://www.eegsynth.org/ | ||
*/ | ||
|
||
#include <Wire.h>//Include the Wire library to talk I2C | ||
#include <Adafruit_NeoPixel.h> | ||
|
||
#include "colormap.h" | ||
|
||
#define enable1 true | ||
#define enable2 true | ||
|
||
// 0x60 is the I2C Address of the MCP4725, by default (A0 pulled to GND). | ||
// Please note that this breakout is for the MCP4725A0. | ||
// For devices with A0 pulled HIGH, use 0x61 | ||
#define address1 0x60 | ||
#define address2 0x61 | ||
|
||
#define gate1pin A0 // the pin controlling the digital gate | ||
#define gate2pin A1 // the pin controlling the digital gate | ||
|
||
#define MCP4726_CMD_WRITEDAC (0x40) // Writes data to the DAC | ||
#define MCP4726_CMD_WRITEDACEEPROM (0x60) // Writes data to the DAC and the EEPROM (persisting the assigned value after reset) | ||
|
||
// the values of the DAC range from 0 to 4095 (12 bits) | ||
#define MAXVALUE 4095. | ||
|
||
// these are the commands over the serial interface | ||
#define NONE 0 | ||
#define VOLTAGE 1 | ||
#define GATE 2 | ||
|
||
// status after parsing the commands | ||
#define OK 0 | ||
#define ERROR -1 | ||
|
||
#define PIXELPIN 20 | ||
#define NUMPIXELS 4 | ||
#define BRIGHTNESS 0.3 | ||
|
||
Adafruit_NeoPixel pixels(NUMPIXELS, PIXELPIN, NEO_GRB + NEO_KHZ800); | ||
|
||
// the initial values of the output control voltages and gates | ||
int voltage1 = 0, voltage2 = 0; | ||
int gate1 = 0, gate2 = 0; | ||
|
||
void setColor(int led, float value) { | ||
byte r, g, b; | ||
int index = value*255.; | ||
index = (index > 255 ? 255 : index); // must be between 0 and 255 | ||
r = 255*R[index]*BRIGHTNESS; | ||
g = 255*G[index]*BRIGHTNESS; | ||
b = 255*B[index]*BRIGHTNESS; | ||
pixels.setPixelColor(led, pixels.Color(r, g, b)); | ||
pixels.show(); | ||
return; | ||
} | ||
|
||
void setValue(uint16_t address, uint16_t value) { | ||
uint8_t msb, lsb; | ||
msb = (value / 16); | ||
lsb = (value % 16) << 4; | ||
Wire.beginTransmission(address); | ||
Wire.write(MCP4726_CMD_WRITEDAC); // cmd to update the DAC | ||
Wire.write(msb); // the 8 most significant bits... | ||
Wire.write(lsb); // the 4 least significant bits... | ||
Wire.endTransmission(); | ||
return; | ||
} | ||
|
||
void setup() { | ||
// initialize the serial communication: | ||
while (!Serial) {;} | ||
Serial.begin(115200); | ||
Serial.print("\n[teensy_cvgate_mcp4725_neopixel/ "); | ||
Serial.print(__DATE__); | ||
Serial.print(" / "); | ||
Serial.print(__TIME__); | ||
Serial.println("]"); | ||
Serial.setTimeout(1000); | ||
|
||
Wire.begin(); | ||
|
||
// initialize the gate pins as output: | ||
pinMode(gate1pin, OUTPUT); | ||
pinMode(gate2pin, OUTPUT); | ||
|
||
// INITIALIZE NeoPixel strip object | ||
pixels.begin(); | ||
|
||
// Set all pixel colors to 'off' | ||
pixels.clear(); | ||
|
||
return; | ||
} | ||
|
||
void loop() { | ||
byte b, channel = 0, command = NONE, status = OK; | ||
int value = 0; | ||
|
||
if (Serial.available()) { | ||
|
||
// parse the input over the serial connection | ||
b = Serial.read(); | ||
if (b == '*') { | ||
Serial.readBytes(&b, 1); | ||
if (b == 'c') { | ||
command = VOLTAGE; | ||
value = 0; | ||
Serial.readBytes(&b, 1); channel = b - 48; // character '1' is ascii value 49 | ||
Serial.readBytes(&b, 1); // 'v' | ||
Serial.readBytes(&b, 1); value = (b - 48) * 1000; | ||
Serial.readBytes(&b, 1); value += (b - 48) * 100; | ||
Serial.readBytes(&b, 1); value += (b - 48) * 10; | ||
Serial.readBytes(&b, 1); value += (b - 48) * 1; | ||
Serial.readBytes(&b, 1); command = (b == '#' ? command : NONE); | ||
} | ||
else if (b == 'g') { | ||
command = GATE; | ||
Serial.readBytes(&b, 1); channel = b - 48; // character '1' is ascii value 49 | ||
Serial.readBytes(&b, 1); // 'v' | ||
Serial.readBytes(&b, 1); value = (b == '1'); | ||
Serial.readBytes(&b, 1); command = (b == '#' ? command : NONE); | ||
} | ||
else { | ||
command = NONE; | ||
} | ||
} | ||
else { | ||
command = NONE; | ||
} | ||
|
||
// update the internal state of all output channels | ||
if (command == VOLTAGE) { | ||
switch (channel) { | ||
case 1: | ||
voltage1 = (value > MAXVALUE ? MAXVALUE : value); | ||
status = (enable1 ? OK : ERROR); | ||
break; | ||
case 2: | ||
voltage2 = (value > MAXVALUE ? MAXVALUE : value); | ||
status = (enable2 ? OK : ERROR); | ||
break; | ||
default: | ||
status = ERROR; | ||
} | ||
|
||
} | ||
else if (command == GATE) { | ||
switch (channel) { | ||
case 1: | ||
gate1 = (value != 0); | ||
status = OK; | ||
break; | ||
case 2: | ||
gate2 = (value != 0); | ||
status = OK; | ||
break; | ||
default: | ||
status = ERROR; | ||
} | ||
} | ||
else { | ||
status = ERROR; | ||
} | ||
if (status == OK) | ||
Serial.println("ok"); | ||
else if (status == ERROR) | ||
Serial.println("error"); | ||
} | ||
else { | ||
// refresh the output voltages and gates | ||
if (enable1) { | ||
setValue(address1, voltage1); | ||
digitalWrite(gate1pin, gate1); | ||
} | ||
if (enable2) { | ||
setValue(address2, voltage2); | ||
digitalWrite(gate2pin, gate2); | ||
} | ||
|
||
// update the color of the Neopixels | ||
// the integer representation of the control voltage is represented between 0 and 4095 | ||
setColor(0, voltage1/MAXVALUE); | ||
setColor(1, voltage2/MAXVALUE); | ||
// the integer representation of the gate voltage is either 0 or 1 | ||
setColor(2, gate1); | ||
setColor(3, gate2); | ||
} | ||
} //main |