diff --git a/hachi-ni-firmware/build/.DS_Store b/hachi-ni-firmware/build/.DS_Store index aad8199..d549669 100644 Binary files a/hachi-ni-firmware/build/.DS_Store and b/hachi-ni-firmware/build/.DS_Store differ diff --git a/hachi-ni-firmware/build/hachi-ni-firmware_0.7.2b1.uf2 b/hachi-ni-firmware/build/hachi-ni-firmware_0.7.2b1.uf2 new file mode 100644 index 0000000..b6cbb8e Binary files /dev/null and b/hachi-ni-firmware/build/hachi-ni-firmware_0.7.2b1.uf2 differ diff --git a/hachi-ni-firmware/colors.h b/hachi-ni-firmware/colors.h new file mode 100644 index 0000000..f33a704 --- /dev/null +++ b/hachi-ni-firmware/colors.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +// COLOR PRESETS +// https://www.rapidtables.com/web/color/color-wheel.html +// hsl(xxx, 100%, 50%) +const auto RED = 0xFF0000; +const auto ORANGE = 0xFF8000; +const auto YELLOW = 0xFFFF00; +const auto LIME = 0x80FF00; +const auto GREEN = 0x00FF00; +const auto MINT = 0x00FF80; +const auto CYAN = 0x00FFFF; +const auto RBLUE = 0x007FFF; +const auto BLUE = 0x0000FF; +const auto PURPLE = 0x7F00FF; +const auto MAGENTA = 0xFF00FF; +const auto ROSE = 0xFF0080; + +// hsl(xxx, 50%, 50%) +const auto MEDRED = 0xBF4040; +const auto MEDBLUE = 0x4040BF; +const auto MEDYELLOW = 0xBFBF40; + +// hsl(xxx, 100%, 75%) +const auto LTCYAN = 0x80FFFF; +const auto LTPURPLE = 0xBF80FF; +const auto SALMON = 0xFF8080; +const auto PINK = 0xFF80D4; +const auto LTYELLOW = 0xFFFF80; + +// hsl(xxx, 100%, 15%) +const auto DKRED = 0x800000; +const auto DKORANGE = 0x4D2600; +const auto DKYELLOW = 0x4C4D00; +const auto DKLIME = 0x408000; +const auto DKGREEN = 0x264D00; +const auto DKCYAN = 0x004C4D; +const auto DKBLUE = 0x00001A; +const auto DKPURPLE = 0x26004D; +const auto DKMAGENTA = 0x4D004C; +const auto INDIGO = 0x4B0082; + +// hsl(xxx, 100%, 5%) +const auto VDKRED = 0x0B0404; +const auto VDKORANGE = 0x0B0804; +const auto VDKYELLOW = 0x0B0B04; +const auto VDKGREEN = 0x080B04; +const auto VDKCYAN = 0x040B0B; +const auto VDKBLUE = 0x04040B; +const auto VDKPURPLE = 0x08040B; +const auto VDKMAGENTA = 0x0B040B; + + +// hsl(xxx, 50%, 75%) +const auto LBLUE = 0x9FCFDF; +const auto VIOLET = 0xDF9FDF; + +// hsl(xxx, 25%, 50%) +const auto DIMRED = 0x9F6060; +const auto DIMORANGE = 0x9F8060; +const auto DIMYELLOW = 0x9F9F60; +const auto DIMLIME = 0x809F60; +const auto DIMGREEN = 0x609F60; +const auto DIMMAGENTA = 0x9F609F; +const auto DIMCYAN = 0x609F9F; +const auto DIMBLUE = 0x60609F; +const auto DIMPURPLE = 0x7F609F; + + +// other +const auto AMBER = 0x999900; +const auto BEIGE = 0xFFCC33; + +// no color + +const auto WHITE = 0xFFFFFF; +const auto HALFWHITE = 0x808080; +const auto LOWWHITE = 0x202020; +const auto VLOWWHITE = 0x101010; +const auto LEDOFF = 0x000000; + +const uint32_t bankColors[] = {ORANGE,YELLOW,GREEN,MAGENTA,CYAN,BLUE,PURPLE,RED}; +// const uint32_t bankColors2[] = {DIMORANGE,DIMYELLOW,DIMGREEN,DIMMAGENTA,DIMCYAN,DIMBLUE,DIMPURPLE,DIMRED}; +const uint32_t bankColors2[] = {VDKORANGE,VDKYELLOW,VDKGREEN,VDKMAGENTA,VDKCYAN,VDKBLUE,VDKPURPLE,VDKRED}; + diff --git a/hachi-ni-firmware/config.h b/hachi-ni-firmware/config.h index c5a9c63..9a43360 100644 --- a/hachi-ni-firmware/config.h +++ b/hachi-ni-firmware/config.h @@ -9,7 +9,7 @@ /* * firmware metadata */ const int MAJOR_VERSION = 0; const int MINOR_VERSION = 7; -const int POINT_VERSION = 0; +const int POINT_VERSION = 3; const int DEVICE_ID = 5; @@ -36,6 +36,8 @@ const int REDLED = 14; const int NEOPIXPIN = 16; const int NEOPWRPIN = 17; const int numLEDS = 9; +const int FIVEVEN = 21; +const int VBATPIN = 28; // 8x2 globals const int channelCount = 16; @@ -43,11 +45,14 @@ const int numKnobs = 16; const int numBanks = 8; const int buttons[2] = {25,24}; int buttonState[2] = {0,0}; +bool forceRead = false; int faderMin = 0; int faderMax = 1019; int shiftyTemp; bool activity = true; +int tempFaderValues[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const char* save_file = "/saved_configs.json"; diff --git a/hachi-ni-firmware/hachi-ni-firmware.ino b/hachi-ni-firmware/hachi-ni-firmware.ino index 671afee..9f4a317 100644 --- a/hachi-ni-firmware/hachi-ni-firmware.ino +++ b/hachi-ni-firmware/hachi-ni-firmware.ino @@ -1,6 +1,6 @@ /* // Hachi x Ni (8x2) MIDI Controller -// v0.7.0 +// v0.7.3 // by Steven Noreyko // @@ -24,19 +24,25 @@ #include #include "config.h" +#include "colors.h" //Switch(byte _pin, byte PinMode=INPUT_PULLUP, bool polarity=LOW, int debouncePeriod=50, int longPressPeriod=300, int doubleClickPeriod=250, int deglitchPeriod=10); Switch leftButton = Switch(buttons[0], INPUT_PULLUP, LOW, 1, 450, 350); Switch rightButton = Switch(buttons[1], INPUT_PULLUP, LOW, 1, 450, 350); - // USB MIDI object Adafruit_USBD_MIDI usb_midi; // Create USB and Hardware MIDI interfaces MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, USBMIDI); MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, HWMIDI); +// USB WebUSB object +// Landing Page: scheme (0: http, 1: https), url +// Page source can be found at https://github.com/hathach/tinyusb-webusb-page/tree/main/webusb-rgb +Adafruit_USBD_WebUSB usb_web; +WEBUSB_URL_DEF(landingPage, 1 /*https*/, "okyeron.github.io/8x2/index.html"); + // NEOPIXELs Adafruit_NeoPixel pixels = Adafruit_NeoPixel(9, NEOPIXPIN, NEO_GRB + NEO_KHZ800); @@ -90,25 +96,42 @@ int activeBank = 0; void leftButtonCallback(void* s) { // Serial.print("Left: "); // Serial.println((char*)s); +// activeBank--; +// activeBank = constrain(activeBank, 0, numBanks-1); +// USBMIDI.sendProgramChange(activeBank, 1); +// pixelsOff(); +// pixels.setPixelColor(activeBank+1, 128, 0, 0); // bank pixels are 1-8 not 0-7 +// pixels.show(); + // Serial.println(activeBank); activeBank--; - activeBank = constrain(activeBank, 0, numBanks-1); + activeBank = constrain(activeBank, 0, numBanks-1); + bankLeds(); USBMIDI.sendProgramChange(activeBank, 1); - pixelsOff(); - pixels.setPixelColor(activeBank+1, 128, 0, 0); // bank pixels are 1-8 not 0-7 - pixels.show(); - // Serial.println(activeBank); } void rightButtonCallback(void* s) { // Serial.print("Right: "); // Serial.println((char*)s); +// activeBank++; +// activeBank = constrain(activeBank, 0, numBanks-1); +// USBMIDI.sendProgramChange(activeBank, 1); +// pixelsOff(); +// pixels.setPixelColor(activeBank+1, 128, 0, 0); +// pixels.show(); + // Serial.println(activeBank); activeBank++; - activeBank = constrain(activeBank, 0, numBanks-1); + activeBank = constrain(activeBank, 0, numBanks-1); + bankLeds(); + // send program change USBMIDI.sendProgramChange(activeBank, 1); - pixelsOff(); - pixels.setPixelColor(activeBank+1, 128, 0, 0); +} + +void bankLeds(){ + for( int i=1; i< numLEDS; i++) { + pixels.setPixelColor(i, bankColors2[i-1]); + } + pixels.setPixelColor(activeBank+1, bankColors[activeBank]); // bank pixels are 1-8 not 0-7 pixels.show(); - // Serial.println(activeBank); } @@ -126,15 +149,21 @@ void setup() { pinMode(mux_common_pin, INPUT); pinMode(TXLED, OUTPUT); // TX pinMode(REDLED, OUTPUT); // RED LED + digitalWrite(REDLED, LOW); pinMode(NEOPWRPIN, OUTPUT); // NEOPWR Pin digitalWrite(NEOPWRPIN, HIGH); // Turn NEOPWR ON - + pinMode(FIVEVEN, OUTPUT); // fiveVen Pin + digitalWrite(FIVEVEN, HIGH); // Turn 5v enable ON LittleFS.begin(); // Serial1.setRX(midi_rx_pin); // Serial1.setTX(midi_tx_pin); - + + // Initialize WebUSB for connection notification, etc + usb_web.setLandingPage(&landingPage); + usb_web.begin(); + // Initialize MIDI, and listen to all MIDI channels USBMIDI.begin(MIDI_CHANNEL_OMNI); HWMIDI.begin(MIDI_CHANNEL_OMNI); @@ -166,7 +195,7 @@ void setup() { delay(1000); } - Serial.println("MIDI Test"); +// Serial.println("MIDI Test"); // Button setup // leftButton.setPushedCallback(&leftButtonCallback, (void*)"turned on"); @@ -177,6 +206,8 @@ void setup() { // rightButton.setDoubleClickCallback(&rightButtonCallback, (void*)"double click"); rightButton.setSingleClickCallback(&rightButtonCallback, (void*)"right single click"); + // force pots to read + forceRead = true; if (!config_read()){ initCCbanks(); @@ -187,12 +218,16 @@ void setup() { pixels.begin(); // Start the NeoPixel object pixels.clear(); // Set NeoPixel color to black (0,0,0) - pixels.setBrightness(50); // Affects all subsequent settings + pixels.setBrightness(100); // Affects all subsequent settings rainbow(2); pixels.setPixelColor(0, 0, 20, 20); - pixels.show(); + for( int i=1; i< numLEDS; i++) { + pixels.setPixelColor(i, bankColors2[i-1]); + } + pixels.setPixelColor(activeBank+1, bankColors[activeBank]); + pixels.show(); } // END SETUP @@ -204,6 +239,17 @@ void loop() // bool button1Temp = digitalRead(buttons[1]); leftButton.poll(); rightButton.poll(); + + float measuredvbat = analogRead(VBATPIN); + measuredvbat *= 2; // we divided by 2, so multiply back + measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage + measuredvbat /= 1024; // convert to voltage + if (measuredvbat > 4){ + digitalWrite(REDLED, HIGH); + // Serial.print("VBat: " ); Serial.println(measuredvbat); + }else{ + digitalWrite(REDLED, LOW); + } for (int i = 0; i < 16; i++) { @@ -212,7 +258,7 @@ void loop() temp = analogRead(mux_common_pin); // mux goes into g_common_pin // sensorValue = analogRead(g_common_pin); analog[i]->update(temp); - if(analog[i]->hasChanged()) { + if(analog[i]->hasChanged() || forceRead == true) { temp = analog[i]->getValue(); temp = constrain(temp, faderMin, faderMax); temp = map(temp, faderMin, faderMax, 1024, 0); // flip the value for backwards pots @@ -230,18 +276,27 @@ void loop() pixels.setPixelColor(i-7, tempR, tempG, tempB); } - + tempFaderValues[i] = shiftyTemp; // send the message over USB and physical MIDI USBMIDI.sendControlChange(ccBanks[activeBank].usbCC[i], shiftyTemp, ccBanks[activeBank].usbChannel[i]+1); HWMIDI.sendControlChange(ccBanks[activeBank].trsCC[i], shiftyTemp, ccBanks[activeBank].trsChannel[i]+1); - - // Serial.print(i); + + } + // pixels.show(); + } + + if (forceRead){ + // Serial.println("forceRead"); + delay(100); + for (int x=0; x < 16; x++ ){ + USBMIDI.sendControlChange(ccBanks[activeBank].usbCC[x], tempFaderValues[x], ccBanks[activeBank].usbChannel[x]+1); + // Serial.print(x); // Serial.print(": "); - // Serial.print(ccBanks[activeBank].usbCC[i]); + // Serial.print(ccBanks[activeBank].usbCC[x]); // Serial.print(": "); - // Serial.println(shiftyTemp); + // Serial.println(tempFaderValues[x]); } - // pixels.show(); + forceRead = false; } // READ HARDWARE MIDI @@ -351,9 +406,10 @@ void onProgramChange(byte channel, byte program) { // Serial.print (":"); // Serial.println (program); activeBank = constrain(program, 0, numBanks-1); - pixelsOff(); - pixels.setPixelColor(activeBank+1, 128, 0, 0); - pixels.show(); + bankLeds(); + // pixelsOff(); + // pixels.setPixelColor(activeBank+1, 128, 0, 0); + // pixels.show(); // USBMIDI.sendProgramChange(program, channel); // HWMIDI.sendProgramChange(program, channel); @@ -568,6 +624,7 @@ void processIncomingSysex(const uint8_t* sysexData, unsigned size) { // 1F = "1nFo" - please send me your current config // Serial.println("Got an 1nFo request"); sendCurrentState(); + forceRead = true; break; case CONFIG_EDIT: // 0E - c0nfig Edit - here is a new config