Skip to content

Commit f521981

Browse files
committed
first commit USB MIDI Host2Host
1 parent 547a331 commit f521981

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

USB_MIDI_Host2Host/.qt_py_rp2040.test.only

Whitespace-only changes.
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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

Comments
 (0)