1
+ // SPDX-FileCopyrightText: 2025 John Park and Tod Kurt
2
+ //
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ // Use a DMX controller to drive NeoPixel strips
6
+ // Arduino Uno or Metro 328 + Conceptinetics DMX Shield
7
+ // Recieves incoming DMX messages from controller, translates to NeoPixel
8
+
9
+ // MIDIHost2Host -- Connect two USB-MIDI host devices together
10
+ // 2019 @todbot / Tod E. Kurt
11
+ // 2025 @johnedgarpark / John E. Park
12
+ // This sketch is meant to be installed on two Adafruit QT Py RP2040s.
13
+ // The connections between the two QT Py RP2040s are
14
+ // QTPyA Gnd ----- QTPyB Gnd
15
+ // QTPyA TX ----- QTPyB RX
16
+ // QTPyA RX ----- QTPyB TX
17
+ // except it's done w PIO over the stemma qt cable (remove red wire first)
18
+
19
+
20
+ // When compiling:
21
+ // Install libraries: Adafruit_TinyUSB & MIDI
22
+ // Be sure to have updated all boards and libraries
23
+ // Select "Tools" -> "USB Stack" -> "TinyUSB"
24
+
25
+ // The following libraries are required:
26
+ // Adafruit_TinyUSB library by Adafruit
27
+ // https://github.com/adafruit/Adafruit_TinyUSB_Arduino
28
+ // MIDI Library by Forty Seven Effects
29
+ // https://github.com/FortySevenEffects/arduino_midi_library
30
+
31
+
32
+ #include < Arduino.h>
33
+ #include < Adafruit_TinyUSB.h>
34
+ #include < MIDI.h>
35
+ #include < Adafruit_NeoPixel.h>
36
+
37
+ // Adjust these for flashing the two different boards either "red" or "blue"
38
+ #define RED_BOARD
39
+ // #define BLUE_BOARD
40
+
41
+
42
+
43
+ // Color definitions
44
+ uint32_t RED = 0xCC0000 ;
45
+ uint32_t DIM_RED = 0x3F0000 ; // 25% brightness red
46
+ uint32_t GREEN = 0x00DD00 ;
47
+ uint32_t BLUE = 0x0000CC ;
48
+ uint32_t DIM_BLUE = 0x00003F ; // 25% brightness blue
49
+ uint32_t YELLOW = 0xAAAA00 ;
50
+ char mfgstr[32 ] = " Lars Productions" ;
51
+ #ifdef RED_BOARD
52
+ char prodstr[32 ] = " QTHost2 Red" ;
53
+ uint32_t LED_COLOR = RED;
54
+ uint32_t LED_DIM_COLOR = DIM_RED;
55
+ SerialPIO pioserial (23 , 22 );
56
+ #else
57
+ char prodstr[32 ] = " QTHost2 Blue" ;
58
+ uint32_t LED_COLOR = BLUE;
59
+ uint32_t LED_DIM_COLOR = DIM_BLUE;
60
+ SerialPIO pioserial (22 , 23 );
61
+ #endif
62
+
63
+
64
+ // NeoPixel settings
65
+ #define NUM_PIXELS 1
66
+
67
+ // NeoPixel RGB LED
68
+ Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
69
+
70
+ bool led_on = false ;
71
+ uint32_t led_time;
72
+ uint32_t led_on_time = 50 ; // how long LED should blink
73
+ uint32_t last_color = LED_DIM_COLOR; // Track last active color
74
+
75
+ // USB MIDI object
76
+ Adafruit_USBD_MIDI usb_midi;
77
+
78
+ // Create instance of Arduino MIDI library,
79
+ // and attach usb_midi as the transport.
80
+ // MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, midiA);
81
+ MIDI_CREATE_INSTANCE (Adafruit_USBD_MIDI, usb_midi, midiA);
82
+
83
+ // Create instance of Arduino MIDI library,
84
+ // and attach HardwareSerial Serial1 (TrinketM0 pins 3 & 4 or TX/RX on a QT Py, this is automatic)
85
+ MIDI_CREATE_INSTANCE (HardwareSerial, pioserial, midiB);
86
+
87
+
88
+ void setup ()
89
+ {
90
+
91
+
92
+ #if defined(NEOPIXEL_POWER)
93
+ // If this board has a power control pin, we must set it to output and high
94
+ // in order to enable the NeoPixels. We put this in an #if defined so it can
95
+ // be reused for other boards without compilation errors
96
+ pinMode (NEOPIXEL_POWER, OUTPUT);
97
+ digitalWrite (NEOPIXEL_POWER, HIGH);
98
+ #endif
99
+ pixels.begin ();
100
+ pixels.setBrightness (60 );
101
+ set_pixel (YELLOW);
102
+
103
+ USBDevice.setManufacturerDescriptor (mfgstr);
104
+ USBDevice.setProductDescriptor (prodstr);
105
+
106
+ // Initialize MIDI, and listen to all MIDI channels
107
+ // This will also call usb_midi's and Serial1's begin()
108
+ midiA.begin (MIDI_CHANNEL_OMNI);
109
+ midiB.begin (MIDI_CHANNEL_OMNI);
110
+
111
+ midiA.turnThruOff ();
112
+ midiB.turnThruOff ();
113
+
114
+ // Serial.begin(115200);
115
+
116
+ // wait until device mounted
117
+ while ( !USBDevice.mounted () ) delay (1 );
118
+ set_pixel (LED_COLOR);
119
+ }
120
+
121
+ void loop ()
122
+ {
123
+ // read any new MIDI messages
124
+ if ( midiA.read () ) {
125
+ midiB.send (midiA.getType (),
126
+ midiA.getData1 (),
127
+ midiA.getData2 (),
128
+ midiA.getChannel ());
129
+ last_color = LED_DIM_COLOR; // Update last color to red
130
+ pixel_on (LED_COLOR);
131
+ // Serial.println("midiA");
132
+ }
133
+
134
+ if ( midiB.read () ) {
135
+ midiA.send (midiB.getType (),
136
+ midiB.getData1 (),
137
+ midiB.getData2 (),
138
+ midiB.getChannel ());
139
+ last_color = LED_DIM_COLOR; // Update last color to blue
140
+ pixel_on (LED_COLOR);
141
+ // Serial.println("midiB");
142
+ }
143
+
144
+ pixel_check ();
145
+ }
146
+
147
+ void pixel_check () {
148
+ if ( led_on && (millis () - led_time) > led_on_time ) {
149
+ led_on = false ;
150
+ set_pixel (last_color); // Return to dimmed version of last active color
151
+ }
152
+ }
153
+
154
+ void pixel_on (uint32_t color) {
155
+ set_pixel (color);
156
+ led_on = true ;
157
+ led_time = millis ();
158
+ }
159
+
160
+ void set_pixel (uint32_t color) {
161
+ pixels.setPixelColor (0 , color);
162
+ pixels.show ();
163
+ }
0 commit comments