|
arduino IDEArduino
|
Stylophone Midi Complete controller
This project have the aim to make a stylophone with a midi usb interface that can be easily connected to a computer or a phone and you can also play in your headphone in a train with a full featured midi controller that you can put in your pocket.
#include <USB-MIDI.h>
USBMIDI_CREATE_DEFAULT_INSTANCE();
//#define DEBUG
#define LED_PLUS 14
#define LED_LESS 16
#define LED_FN 10
#define BUTTONS_LEN 9
const int buttons[BUTTONS_LEN] = {9, 8, 7, 5, 3, 2, 6, 4, 15};
const String btns_actions[BUTTONS_LEN * BUTTONS_LEN] = { "FN", "", "", "OCT_PLUS", "", "", "OCT_LESS", "", "",
"FN", "", "", "", "", "", "", "", "" };
bool btns[BUTTONS_LEN * BUTTONS_LEN] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
bool btns_mid_state[BUTTONS_LEN * BUTTONS_LEN] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
bool fn_enabled = false;
#define KNOB_TOLERANCE 3
#define KNOBS_LEN 3
const int KNOBS[KNOBS_LEN] = {0, 1, 2};
int knobvalold[KNOBS_LEN] = {0, 0, 0};
int controlknobs[KNOBS_LEN] = {14, 15, 16};
#define KEYBOARD_TOLERANCE 3
#define KEYBOARD 3
#define BASE_MIDI 60
int octave = 0;
#define KEYMAX 1021
#define KEY_LEN 15
const int KEYS[KEY_LEN] = {959,954,950,944,937,929,920,909,894,876,852,818,768,681,511 };
bool key1 = false;
int keyvalold = KEYMAX;
int note = -1;
int noteold = -1;
int velocity = 127;
void setup() {
#ifdef DEBUG
Serial.begin(9600);
#endif
MIDI.begin(1);
pinMode(LED_PLUS, OUTPUT);
// digitalWrite(LED_PLUS, HIGH);
pinMode(LED_LESS, OUTPUT);
// digitalWrite(LED_LESS, HIGH);
pinMode(LED_FN, OUTPUT);
// digitalWrite(LED_FN, HIGH);
for (int i=0; i < BUTTONS_LEN; i++){
pinMode(buttons[i], INPUT);
}
}
void loop() {
// Octave LED
if (octave > 0){
digitalWrite(LED_PLUS, HIGH);
digitalWrite(LED_LESS, LOW);
}
else if (octave < 0){
digitalWrite(LED_PLUS, LOW);
digitalWrite(LED_LESS, HIGH);
}
else {
digitalWrite(LED_PLUS, LOW);
digitalWrite(LED_LESS, LOW);
}
//Manage Generic Buttons
for (int i_orig=0; i_orig < BUTTONS_LEN; i_orig++){
int btn_read = digitalRead(buttons[i_orig]);
int i = i_orig;
if (fn_enabled){
i = i + BUTTONS_LEN;
}
// Serial.println("Button " + String(btn_read));
if (btn_read == HIGH && !btns[i]) {
btns[i] = true;
Serial.println("Button " + String(i) + " Pressed");
if (btns_actions[i] == "OCT_LESS") {
#ifdef DEBUG
Serial.println("Octave less");
#endif
octave--;
}
else if (btns_actions[i] == "OCT_PLUS") {
#ifdef DEBUG
Serial.println("Octave plus");
#endif
octave++;
}
else if (btns_actions[i] == "FN") {
#ifdef DEBUG
Serial.println("FN");
#endif
btns_mid_state[i] = ! btns_mid_state[i];
if (btns_mid_state[i]){
digitalWrite(LED_FN, HIGH);
}
else{
digitalWrite(LED_FN, LOW);
}
fn_enabled = btns_mid_state[i];
}
else {
btns_mid_state[i] = ! btns_mid_state[i];
#ifdef DEBUG
Serial.println("Midi " + String(i) + " send state " + String(btns_mid_state[i]));
#endif
btns_mid_state[i] ? MIDI.sendControlChange(i, 127, 1) : MIDI.sendControlChange(i, 0, 1);
}
} else if (btn_read == LOW && btns[i]) {
btns[i] = false;
#ifdef DEBUG
Serial.println("Button " + String(i) + " Released");
#endif
}
}
// Manage Knobs
for (int i=0; i < KNOBS_LEN; i++){
int knobval = map(analogRead(KNOBS[i]), 0, 1023, 0, 127);
if (knobval > (knobvalold[i] + KNOB_TOLERANCE) || knobval < (knobvalold[i] - KNOB_TOLERANCE)) {
knobvalold[i] = knobval;
#ifdef DEBUG
Serial.println(String(i) + " Knob " + String(controlknobs[i]) + ": " + String(knobval));
#endif
if (i!= 0){
MIDI.sendControlChange(controlknobs[i], knobval, 1);
} else {
velocity = knobval;
}
}
}
// Manage Keyboard
int keyval = analogRead(KEYBOARD);
if (keyval < (KEYMAX - KEYBOARD_TOLERANCE)) { // key pressed
// Serial.println(keyval);
if (keyval < (keyvalold - KEYBOARD_TOLERANCE) || keyval > (keyvalold + KEYBOARD_TOLERANCE)) { // key changed
// Serial.println(keyval);
for (int i=0; i < KEY_LEN; i++){
if (keyval < (KEYS[i] + KEYBOARD_TOLERANCE) && keyval > (KEYS[i] - KEYBOARD_TOLERANCE)) { //the key i is pressed
note = BASE_MIDI + (12 * octave) + i;
#ifdef DEBUG
Serial.println("Press Key: " + String(note) + " " + String(keyval));
#endif
if (key1){
MIDI.sendNoteOff(noteold, 0, 1);
}
key1 = true;
MIDI.sendNoteOn(note, velocity, 1);
noteold = note;
}
}
}
} else { // Key released
if (key1) {
#ifdef DEBUG
Serial.println("Release Key: " + String(keyval));
#endif
MIDI.sendNoteOff(noteold, 0, 1);
key1 = false;
}
}
keyvalold = keyval;
}
Stylophone Midi Complete controller
Project images are for reference only. Actual production is based on the manufacturing files on the project page.
Please review the designer's notes (e.g., PCB thickness) and select the appropriate options.
PCBWay is not responsible
for issues caused by unsuitable parameter selections.
For more important ordering information, please refer to
Read More
Raspberry Pi 5 7 Inch Touch Screen IPS 1024x600 HD LCD HDMI-compatible Display for RPI 4B 3B+ OPI 5 AIDA64 PC Secondary Screen(Without Speaker)
BUY NOW- Comments(0)
- Likes(4)
-
Engineer
Mar 01,2024
-
Engineer
Dec 12,2023
-
kadu
Nov 08,2023
-
Nicola Landro
Nov 05,2023
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Nicola Landro
-
Programmable Mist Maker - XIAO / QT PY Extension
1150 2 1 -
RadioHAT - Raspberry Pi radio development platform
960 0 2 -
QWIIC-VL53L4CD Time-of-Flight Distance Sensor Module
1170 0 1 -
-
-
-
ARPS-2 – Arduino-Compatible Robot Project Shield for Arduino UNO
3382 0 6 -
-
A Compact Charging Breakout Board For Waveshare ESP32-C3
4001 3 8 -
AI-driven LoRa & LLM-enabled Kiosk & Food Delivery System
4389 2 2







