Components and supplies
36-pin 0.1" Female header - pack of 5!
Monochrome 128x32 I2C OLED graphic display
4x4 Matrix Keypad
Arduino Micro
Tools and machines
Soldering iron (generic)
Apps and platforms
Arduino IDE
Project description
Code
Keypad Midi code
This repository contains the arduino code, and svg schematics.
Keypad Midi
arduino
This is the code, at the moment I made this tutorial. Please check the repository for the last version.
1#include "MIDIUSB.h" 2 3/* Settings for MIDI preset */ 4const byte ROWS = 4; //four rows 5const byte COLS = 4; //four columns 6const int NB_BUTTONS = ROWS * COLS; 7 8const int PRESET = 8; 9String preset_name[PRESET] = {"Du Riechst So Gut", "FF - Replica", "DrumKit", "A", "4", "5", "6", "B"}; 10int notes[PRESET][NB_BUTTONS] = { 11 {38, 38, 39, 39, 43, 46, 38, 38, 48, 46, 45, 45, 57, 60, 60, 57}, //Preset 1 12 {37, 40, 42, 39, 40, 38, 41, 40, 48, 46, 45, 45, 57, 60, 60, 57}, // Preset 2 13 {35, 35, 38, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 57}, // Preset 3 14 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset A 15 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 4 16 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 5 17 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 6 18 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //Preset B 19}; 20 21int velocity[PRESET][NB_BUTTONS] = { 22 {70, 70, 70, 70, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}, //Preset 1 23 {70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70}, //Preset 2 24 {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}, //Preset 3 25 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset A 26 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 4 27 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 5 28 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset 6 29 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Preset B 30}; 31 32const int velocity_button = 15; // The D key is used to change velocity if velocity changer is true 33const int VELOCITY_CHANGE = 100; //Velocity when D is pressed (should probably be changeable) 34bool velocity_changer[PRESET] = {false, true, false, false, false, false, false, false}; 35 36/* Keypad Init */ 37//https://github.com/Nullkraft/Keypad 38#include <Keypad.h> 39char keys[ROWS][COLS] = { 40 {'1', '2', '3', 'A'}, 41 {'4', '5', '6', 'B'}, 42 {'7', '8', '9', 'C'}, 43 {'*', '0', '#', 'D'} 44}; 45 46//Keypad pins 47byte rowPins[ROWS] = {8, 9, 10, 11}; //connect to the row pinouts of the kpd 48byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the kpd 49Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 50 51//Keypad state : 1 = DOWN 3 = UP (there are other state which are unused here) 52unsigned int buttons_state[NB_BUTTONS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 53bool preset_selector = false; 54 55//Oled Display 56#include <Wire.h> //I2C 57#include <U8g2lib.h> 58U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); 59String oled_line1; 60String oled_line2; 61 62//Preset 63int selected_preset = 0; 64 65void setup() { 66 Serial.begin(115200); 67 u8g2.begin(); 68 change_preset(selected_preset); 69} 70 71//Change preset and display it on screen 72//You need to press "*" again to validate the preset 73void change_preset(int preset) { 74 if (preset < PRESET) { 75 selected_preset = preset; 76 oled_line1 = "-----Preset------"; 77 oled_line2 = preset_name[preset]; 78 printScreen(); 79 Serial.println(oled_line1); 80 Serial.println(oled_line2); 81 } 82} 83 84//Change what is written on the Oled screen using global variable 85//oled_line1 and oled_line2 86void printScreen() { 87 //https://github.com/olikraus/u8g2/wiki/fntlist8x8 88 u8g2.setFont(u8g2_font_7x14_mr); 89 u8g2.firstPage(); 90 do { 91 u8g2.setCursor(0, 14); 92 u8g2.println(oled_line1); // write something to the internal memory 93 u8g2.setCursor(0, 30); 94 u8g2.println(oled_line2); // write something to the internal memory 95 } 96 while ( u8g2.nextPage() ); 97} 98 99void loop() { 100 if (kpd.getKeys()) { 101 for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list. 102 { 103 if ( kpd.key[i].stateChanged ) // Only find keys that have changed state. 104 { 105 buttons_state[kpd.key[i].kcode] = kpd.key[i].kstate; 106 107 if (kpd.key[i].kstate == 1) { //DOWN 108 Serial.print(kpd.key[i].kcode); 109 Serial.print(":"); 110 Serial.println("1"); 111 112 //If key "#" is pressed 113 if (kpd.key[i].kcode == 12) { 114 //If preset selection is not active, we go to selection mode 115 if (!preset_selector) { 116 Serial.println("Selector"); 117 preset_selector = true; 118 oled_line1 = "Selector"; 119 oled_line2 = "--------"; 120 printScreen(); 121 } else { 122 //If preset selection is active, we return to midi mode 123 Serial.println("Deselect"); 124 oled_line1 = preset_name[selected_preset]; 125 oled_line2 = ""; 126 printScreen(); 127 preset_selector = false; 128 } 129 } else { 130 //If in selection mode we change preset 131 if (preset_selector) { 132 Serial.println("Change preset"); 133 change_preset(kpd.key[i].kcode); 134 } else { 135 //If in midi mode we play midi note 136 key_down(kpd.key[i].kcode); 137 } 138 } 139 } 140 if (kpd.key[i].kstate == 3) { //UP 141 Serial.print(kpd.key[i].kcode); 142 Serial.print(":"); 143 Serial.println("0"); 144 // If key is up we send a midi note off 145 key_up(kpd.key[i].kcode); 146 } 147 } 148 } 149 } 150} 151 152//Key down (pressed) 153void key_down(int key) { 154 int current_velocity = 100; 155 //Serial.print(buttons_state[velocity_button]); 156 157 //If velocity_changer (D) active 158 if (velocity_changer[selected_preset]) { 159 //If velocity changer pressed check for state 1 (down) or 2 (long down) 160 if ((buttons_state[velocity_button] == 1) || (buttons_state[velocity_button] == 2)) { 161 current_velocity = VELOCITY_CHANGE; 162 } else { 163 //If not pressed use velocity from preset 164 current_velocity = velocity[selected_preset][key]; 165 } 166 } else { 167 //If velocity_changer not active, use velocity from preset 168 current_velocity = velocity[selected_preset][key]; 169 } 170 171 172 if (!velocity_changer[selected_preset]) { 173 //Play note if velocity changer not set 174 noteOn(0, notes[selected_preset][key], current_velocity); 175 } else { 176 //Else do not play note on velocity changer button (D) 177 if (key != velocity_button) { 178 noteOn(0, notes[selected_preset][key], current_velocity); 179 } 180 } 181 182 //Display note and velocity on screen 183 oled_line1 = preset_name[selected_preset]; 184 oled_line2 = "Note:" + String(notes[selected_preset][key]) + " " "V:" + String(current_velocity); 185 printScreen(); 186 MidiUSB.flush(); 187} 188 189//Key up (unpressed) 190void key_up(int key) { 191 //If velocity_changer 192 if (!velocity_changer[selected_preset]) { 193 noteOff(0, notes[selected_preset][key], 127); 194 } else { 195 if (key != velocity_button) { 196 noteOff(0, notes[selected_preset][key], 127); 197 } 198 } 199 MidiUSB.flush(); 200} 201 202void noteOn(byte channel, byte pitch, byte velocity) { 203 midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity}; 204 MidiUSB.sendMIDI(noteOn); 205} 206 207void noteOff(byte channel, byte pitch, byte velocity) { 208 midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity}; 209 MidiUSB.sendMIDI(noteOff); 210} 211 212void controlChange(byte channel, byte control, byte value) { 213 midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value}; 214 MidiUSB.sendMIDI(event); 215}
Keypad Midi code
This repository contains the arduino code, and svg schematics.
Downloadable files
Keypad Schematic
Keypad Schematic
OLED Schematic
OLED Schematic
Keypad Schematic
Keypad Schematic
OLED Schematic
OLED Schematic
Comments
Only logged in users can leave comments
usini
0 Followers
•0 Projects
Table of contents
Intro
6
0