├── .gitattributes ├── .gitignore ├── Firmware ├── MIDI-CV │ ├── MIDI-CV.ino │ ├── dac-integration-test │ │ └── dac-integration-test.ino │ ├── notemap.cpp │ └── notemap.h ├── MIDI-sniffer │ └── MIDI-sniffer.ino ├── buttons-N-pots │ └── buttons-N-pots.ino ├── clock-gen │ ├── clock-gen.ino │ └── msec-to-bpm.ods └── clock-recv │ └── clock-recv.ino ├── Hardware ├── SparkFun_MIDI_Shield.brd └── SparkFun_MIDI_Shield.sch ├── LICENSE.md ├── Production └── SparkFun_MIDI_Shield_Panel_v15.brd └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## SparkFun Useful stuff 3 | ################# 4 | 5 | ## AVR Development 6 | *.eep 7 | *.elf 8 | *.lst 9 | *.lss 10 | *.sym 11 | *.d 12 | *.o 13 | *.srec 14 | *.map 15 | 16 | ## Notepad++ backup files 17 | *.bak 18 | 19 | ## BOM files 20 | *bom* 21 | 22 | ################# 23 | ## Eclipse 24 | ################# 25 | 26 | *.pydevproject 27 | .project 28 | .metadata 29 | bin/ 30 | tmp/ 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | 40 | # External tool builders 41 | .externalToolBuilders/ 42 | 43 | # Locally stored "Eclipse launch configurations" 44 | *.launch 45 | 46 | # CDT-specific 47 | .cproject 48 | 49 | # PDT-specific 50 | .buildpath 51 | 52 | 53 | ############# 54 | ## Eagle 55 | ############# 56 | 57 | # Ignore the board and schematic backup files 58 | *.b#? 59 | *.s#? 60 | 61 | 62 | ################# 63 | ## Visual Studio 64 | ################# 65 | 66 | ## Ignore Visual Studio temporary files, build results, and 67 | ## files generated by popular Visual Studio add-ons. 68 | 69 | # User-specific files 70 | *.suo 71 | *.user 72 | *.sln.docstates 73 | 74 | # Build results 75 | [Dd]ebug/ 76 | [Rr]elease/ 77 | *_i.c 78 | *_p.c 79 | *.ilk 80 | *.meta 81 | *.obj 82 | *.pch 83 | *.pdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.vspscc 93 | .builds 94 | *.dotCover 95 | 96 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 97 | #packages/ 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opensdf 104 | *.sdf 105 | 106 | # Visual Studio profiler 107 | *.psess 108 | *.vsp 109 | 110 | # ReSharper is a .NET coding add-in 111 | _ReSharper* 112 | 113 | # Installshield output folder 114 | [Ee]xpress 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish 128 | 129 | # Others 130 | [Bb]in 131 | [Oo]bj 132 | sql 133 | TestResults 134 | *.Cache 135 | ClientBin 136 | stylecop.* 137 | ~$* 138 | *.dbmdl 139 | Generated_Code #added for RIA/Silverlight projects 140 | 141 | # Backup & report files from converting an old project file to a newer 142 | # Visual Studio version. Backup files are not needed, because we have git ;-) 143 | _UpgradeReport_Files/ 144 | Backup*/ 145 | UpgradeLog*.XML 146 | 147 | 148 | ############ 149 | ## Windows 150 | ############ 151 | 152 | # Windows image file caches 153 | Thumbs.db 154 | 155 | # Folder config file 156 | Desktop.ini 157 | 158 | 159 | ############# 160 | ## Python 161 | ############# 162 | 163 | *.py[co] 164 | 165 | # Packages 166 | *.egg 167 | *.egg-info 168 | dist 169 | build 170 | eggs 171 | parts 172 | bin 173 | var 174 | sdist 175 | develop-eggs 176 | .installed.cfg 177 | 178 | # Installer logs 179 | pip-log.txt 180 | 181 | # Unit test / coverage reports 182 | .coverage 183 | .tox 184 | 185 | #Translations 186 | *.mo 187 | 188 | #Mr Developer 189 | .mr.developer.cfg 190 | 191 | # Mac crap 192 | .DS_Store 193 | -------------------------------------------------------------------------------- /Firmware/MIDI-CV/MIDI-CV.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | MIDI-CV.ino 3 | MIDI to Control Voltage converter for synthesizers. 4 | Byron Jacquot, SparkFun Electronics 5 | October 2, 2015 6 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/MIDI-CV 7 | 8 | This functions as a MIDI-to-control voltage interface for analog synthesizers. 9 | It was developed for the Moog Werkstatt WS-01, but should work with any volt-per-octave 10 | synthesizer. 11 | 12 | Resources: 13 | This code is dependent on the FortySevenEffects MIDI library for Arduino. 14 | https://github.com/FortySevenEffects/arduino_midi_library 15 | This was done using version 4.2, hash fb693e724508cb8a473fa0bf1915101134206c34 16 | This library is now under the MIT license, as well. 17 | You'll need to install that library into the Arduino IDE before compiling. 18 | 19 | It is also dependent on the notemap class, stored in the same repository (notemap.cpp/h). 20 | 21 | Development environment specifics: 22 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 23 | MIDI Shield and a pair of Microchip MCP4725 DACs to generate the control voltages. 24 | 25 | Written, compiled and loaded with Arduino 1.6.5 26 | 27 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 28 | 29 | Please review the LICENSE.md file included with this example. If you have any questions 30 | or concerns with licensing, please contact techsupport@sparkfun.com. 31 | 32 | Distributed as-is; no warranty is given. 33 | ******************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "notemap.h" 41 | 42 | // VERBOSE mode switches MIDI to use soft serial on pins 8 & 9, 43 | // and enables a bunch of debug print messages. 44 | #define VERBOSE 0 45 | 46 | // Instantiate the MIDI interface using the macro 47 | // - HardwareSerial is the type of serial port to be used underneath 48 | // the MIDI routines. 49 | // - Serial1 is the name of that portto be used. On a pro-micro, "Serial" 50 | // is the USB serial port, and "Serial1" is the hardware UART. 51 | // - "MIDI" parameter is the resulting object name. 52 | #if VERBOSE 53 | SoftwareSerial SoftSerial(8, 9); 54 | MIDI_CREATE_INSTANCE(SoftwareSerial, SoftSerial, MIDI); 55 | #else 56 | MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI); 57 | #endif 58 | 59 | // Functional assignments to Arduino pin numbers. 60 | // Digital outputs 61 | static const int GATEPIN = 10; 62 | static const int REDLEDPIN = 7; 63 | static const int GREENLEDPIN = 6; 64 | 65 | // Analog input 66 | static const int PIN_TEMPO_POT = 1; 67 | 68 | // Digital inputs 69 | static const int UPBTNPIN = 2; 70 | static const int DNBTNPIN = 3; 71 | static const int SHORTBTNPIN= 4; 72 | static const int BTN_DEBOUNCE = 50; 73 | 74 | // global variables 75 | // 76 | // notetracker knows which note ons & offs we have seen. 77 | // We refer to it when it's time to generate CV and gate signals, 78 | static notetracker themap; 79 | 80 | // Variables for arpeggiator clock. 81 | static uint32_t tempo_delay = 10; 82 | static bool send_tick = false; 83 | 84 | // The last bend records the most recently seen bend message. 85 | // We need to keep track so we can update note CV when we get new notes, 86 | // or new bend messages - we need the other half in order to put them together. 87 | // bend is signed, 14-bit 88 | static int16_t last_bend = 0; 89 | 90 | // constants to describe the MIDI input. 91 | // NUM_KEYS is the number of keys we're interpreting 92 | // BASE_KEY is the offset of the lowest key number 93 | static const int8_t NUM_KEYS = 49; 94 | static const int8_t BASE_KEY = 36; 95 | 96 | // The tuning constant - representing the DAC conts per semitone 97 | // 98 | // Arrived at using: (((2^)/5)/12) * 100 99 | // 100 | // 2^12 = 4096 total DAC counts. 101 | // 4096/5 = 819.2 DAC counts per volt on a 5V supply 102 | // 819.2/12 = dac counts per semitone = 68.26 103 | // times 100 for some extra calculation precision = 6826 104 | static const uint32_t DAC_CAL = 6826; 105 | 106 | /* 107 | * void updateCV(uint8_t key) 108 | * 109 | *Converts key number to DAC count value, 110 | *and sends the value tio the DAC 111 | */ 112 | void updateCV(uint8_t key) 113 | { 114 | #if 0 115 | Serial.print("KEY: "); 116 | Serial.print(key); 117 | #endif 118 | uint32_t val = 400ul + ((key * DAC_CAL)/100ul); 119 | 120 | #if 0 121 | val = last_key * 6826ul; 122 | Serial.print(" VALa: "); 123 | Serial.print(val, HEX); 124 | 125 | val /= 100; 126 | Serial.print(" VALb: "); 127 | Serial.print(val, HEX); 128 | 129 | val += 400 ; 130 | Serial.print(" VALc: "); 131 | Serial.print(val, HEX); 132 | #endif 133 | val += last_bend; 134 | 135 | // Serial.print(" VAL2: "); 136 | // Serial.println(val, HEX); 137 | 138 | 139 | Wire.beginTransmission(0x60); 140 | Wire.write(byte((val & 0x0f00) >> 8)); 141 | Wire.write(byte(val & 0xff)); 142 | Wire.endTransmission(); 143 | 144 | } 145 | 146 | /* 147 | * void updateOutputs() 148 | * 149 | * Update otputs sets the outputs to the current conditions. 150 | * Called from note on, note off, arp tick. 151 | */ 152 | void updateOutputs() 153 | { 154 | uint8_t key; 155 | 156 | key = themap.whichKey(); 157 | 158 | #if VERBOSE 159 | Serial.print("key: "); 160 | Serial.println(key, HEX); 161 | #endif 162 | 163 | // key is in terms of MIDI note number. 164 | // Constraining the key number to 4 octave range 165 | // Soc we can do 4 Volts +/- ~0.5V bend range. 166 | if (key < BASE_KEY) 167 | { 168 | key = 0; 169 | } 170 | else if ( key > BASE_KEY + NUM_KEYS) 171 | { 172 | key = NUM_KEYS; 173 | } 174 | else 175 | { 176 | key -= BASE_KEY; 177 | } 178 | 179 | updateCV(key); 180 | 181 | digitalWrite(GATEPIN, themap.getGate()); 182 | } 183 | 184 | ///////////////////////////////////////////////////////////////////////// 185 | // Callbacks for the MIDI parser 186 | ///////////////////////////////////////////////////////////////////////// 187 | 188 | /* void handleNoteOn(byte channel, byte pitch, byte velocity) 189 | * 190 | * Called by MIDI parser when note on messages arrive. 191 | */ 192 | void handleNoteOn(byte channel, byte pitch, byte velocity) 193 | { 194 | // Do whatever you want when a note is pressed. 195 | // Try to keep your callbacks short (no delays ect) 196 | // otherwise it would slow down the loop() and have a bad impact 197 | // on real-time performance. 198 | 199 | Serial.print("on: "); 200 | Serial.println(pitch , HEX); 201 | 202 | themap.noteOn(pitch); 203 | 204 | updateOutputs(); 205 | 206 | } 207 | 208 | /* void handleNoteOff(byte channel, byte pitch, byte velocity) 209 | * 210 | * Called by MIDI parser when note off messages arrive. 211 | */ 212 | void handleNoteOff(byte channel, byte pitch, byte velocity) 213 | { 214 | // Do something when the note is released. 215 | // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs. 216 | Serial.print("off: "); 217 | Serial.println(pitch , HEX); 218 | 219 | themap.noteOff(pitch); 220 | 221 | updateOutputs(); 222 | } 223 | 224 | /*void handlePitchBend(byte channel, int bend) 225 | * 226 | * Called by parser when bend messages arrive. 227 | */ 228 | void handlePitchBend(byte channel, int bend) 229 | { 230 | #if VERBOSE 231 | Serial.print("bend: "); 232 | Serial.println(bend , HEX); 233 | #endif 234 | // Bend data from the parser is 14 bits, signed, centered 235 | // on 0. 236 | // unsigned conversion & dual-7-bit thwacking 237 | // already handled by midi parser 238 | 239 | last_bend = bend >> 5; 240 | 241 | #if VERBOSE 242 | Serial.print("newbend: "); 243 | Serial.println(last_bend, HEX); 244 | #endif 245 | 246 | updateOutputs(); 247 | } 248 | 249 | /* void handleCC(byte channel, byte number, byte value) 250 | * 251 | * Called by parser when continuous controller message arrive 252 | */ 253 | void handleCC(byte channel, byte number, byte value) 254 | { 255 | #if VERBOSE 256 | Serial.print("cc: "); 257 | Serial.print(number); 258 | Serial.print(" chan: "); 259 | Serial.print(channel, HEX); 260 | Serial.print("val: "); 261 | Serial.println(value, HEX); 262 | #endif 263 | 264 | switch (number) 265 | { 266 | case 1: 267 | { // Mod wheel 268 | 269 | Wire.beginTransmission(0x61); 270 | // Turn 7 bits into 12 271 | Wire.write(byte((value & 0x70) >> 3)); 272 | Wire.write(byte((value & 0x0f) << 4)); 273 | Wire.endTransmission(); 274 | }; 275 | break; 276 | case 64: 277 | { // sustain pedal 278 | themap.setSustain( (value != 0) ); 279 | } 280 | 281 | // Other CC's would line up here... 282 | 283 | default: 284 | break; 285 | } 286 | 287 | } 288 | 289 | ///////////////////////////////////////////////////////////////////////// 290 | // millisecond timer related 291 | // 292 | // See documentation for MStimer2 (http://playground.arduino.cc/Main/MsTimer2). 293 | //////////////////////////////////////////////////////////////////////// 294 | 295 | void timer_callback() 296 | { 297 | // Tell the mainline loop that time has elapsed 298 | send_tick = true; 299 | } 300 | 301 | /* void tick_func() 302 | * 303 | * Called by mainline loop when send_tick is true. 304 | * Keeps track of rising/falling edges, and notifies notetracker 305 | * of clock status. 306 | */ 307 | void tick_func() 308 | { 309 | static uint8_t counter = 0; 310 | 311 | counter++; 312 | 313 | if(counter & 0x01) 314 | { 315 | digitalWrite(REDLEDPIN, HIGH); 316 | 317 | themap.tickArp(false); 318 | updateOutputs(); 319 | } 320 | else 321 | { 322 | digitalWrite(REDLEDPIN, LOW); 323 | 324 | themap.tickArp(true); 325 | updateOutputs(); 326 | } 327 | } 328 | 329 | ///////////////////////////////////////////////////////////////////////// 330 | // Panel interface control routines 331 | ///////////////////////////////////////////////////////////////////////// 332 | 333 | /*void check_pots() 334 | * 335 | * Read the analog input (tempo control) 336 | */ 337 | void check_pots() 338 | { 339 | uint32_t pot_val; 340 | uint32_t calc; 341 | 342 | pot_val = analogRead(PIN_TEMPO_POT); 343 | 344 | // Result is 10 bits 345 | //calc = (((0x3ff - pot_val) * 75)/1023) + 8; 346 | calc = (((0x3ff - pot_val) * 1800)/1023) + 25; 347 | 348 | tempo_delay = calc ; 349 | 350 | } 351 | 352 | /* void up_btn_func() 353 | * 354 | * Called when button reader detects arpeggio up button has been pressed. 355 | * 356 | * If not in up mode, turn on up mode. 357 | * If in up mode, stops arpeggiator. 358 | */ 359 | void up_btn_func() 360 | { 361 | #if VERBOSE 362 | Serial.println("Up!"); 363 | #endif 364 | 365 | if(themap.getMode() == notetracker::ARP_UP) 366 | { 367 | digitalWrite(GREENLEDPIN, HIGH); 368 | themap.setMode(notetracker::NORMAL); 369 | } 370 | else 371 | { 372 | digitalWrite(GREENLEDPIN, LOW); 373 | themap.setMode(notetracker::ARP_UP); 374 | } 375 | } 376 | 377 | /* void dn_btn_func() 378 | * 379 | * Called when button reader detects arpeggio up button has been pressed. 380 | * 381 | * If not in dn mode, turn on up mode. 382 | * If in dn mode, stops arpeggiator. 383 | */ 384 | void dn_btn_func() 385 | { 386 | #if VERBOSE 387 | Serial.println("Dn!"); 388 | #endif 389 | 390 | if(themap.getMode() == notetracker::ARP_DN) 391 | { 392 | digitalWrite(GREENLEDPIN, HIGH); 393 | themap.setMode(notetracker::NORMAL); 394 | } 395 | else 396 | { 397 | digitalWrite(GREENLEDPIN, LOW); 398 | themap.setMode(notetracker::ARP_DN); 399 | } 400 | } 401 | 402 | /* void short_btn_func() 403 | * 404 | * Toggles staccato articulations 405 | * Works independently of arpeggiator enablement. 406 | */ 407 | void short_btn_func() 408 | { 409 | #if VERBOSE 410 | Serial.print("Short!"); 411 | #endif 412 | 413 | if(themap.getShort()) 414 | { 415 | themap.setShort(false); 416 | } 417 | else 418 | { 419 | themap.setShort(true); 420 | } 421 | } 422 | 423 | /* Button behavior function array for ease of referencing using index 424 | * 425 | */ 426 | void(*func_array[3])(void) = 427 | { 428 | up_btn_func, 429 | dn_btn_func, 430 | short_btn_func 431 | }; 432 | 433 | /* void check_buttons() 434 | * 435 | * Implements debounced button polling for the 3 buttons on then MIDI shield. 436 | * 437 | * Buttons are active low, pulled up. 438 | * On a poll cycle, reads each button. 439 | * If button is pressed (LOW), it counts up. 440 | * If button is held for enough cycles, it calls the indirect routine for the button. 441 | * When button is released, debounce counter clears. 442 | */ 443 | void check_buttons() 444 | { 445 | static uint8_t deb_array[3]; 446 | uint8_t val; 447 | 448 | for(uint8_t i = 0; i < 3; i++) 449 | { 450 | // active low, pulled high 451 | val = digitalRead(i + UPBTNPIN); 452 | 453 | if(val == LOW) 454 | { 455 | if(deb_array[i] < BTN_DEBOUNCE+1) 456 | { 457 | deb_array[i]++; 458 | 459 | if(deb_array[i] == BTN_DEBOUNCE) 460 | { 461 | (*func_array[i])(); 462 | } 463 | } 464 | } 465 | else 466 | { 467 | deb_array[i] = 0; 468 | } 469 | } 470 | } 471 | 472 | ///////////////////////////////////////////////////////////////////////// 473 | // Arduino boilerplate - setup() & loop() 474 | ///////////////////////////////////////////////////////////////////////// 475 | 476 | void setup() 477 | { 478 | // Output pins 479 | pinMode(GATEPIN, OUTPUT); 480 | pinMode(REDLEDPIN, OUTPUT); 481 | pinMode(GREENLEDPIN, OUTPUT); 482 | 483 | digitalWrite(REDLEDPIN, HIGH); 484 | digitalWrite(GREENLEDPIN, HIGH); 485 | 486 | // Button pins 487 | pinMode(UPBTNPIN, INPUT_PULLUP); 488 | pinMode(DNBTNPIN, INPUT_PULLUP); 489 | pinMode(SHORTBTNPIN, INPUT_PULLUP); 490 | 491 | Serial.begin(115200); //This pipes to the serial monitor 492 | 493 | Wire.begin(); 494 | 495 | // Initiate MIDI communications, listen to all channels 496 | // .begin sets the thru mode to on, so we'll have to turn it off if we don't want echo 497 | MIDI.begin(MIDI_CHANNEL_OMNI); 498 | 499 | MIDI.turnThruOff(); 500 | 501 | // so it is called upon reception of a NoteOn. 502 | MIDI.setHandleNoteOn(handleNoteOn); // Put only the name of the function 503 | // Do the same for NoteOffs 504 | MIDI.setHandleNoteOff(handleNoteOff); 505 | MIDI.setHandleControlChange(handleCC); 506 | MIDI.setHandlePitchBend(handlePitchBend); 507 | 508 | MsTimer2::set(tempo_delay, timer_callback); 509 | MsTimer2::start(); 510 | 511 | Serial.println("setup complete"); 512 | } 513 | 514 | void loop() 515 | { 516 | // Pump the MIDI parser as quickly as we can. 517 | // This will invoke the callbacks when messages are parsed. 518 | MIDI.read(); 519 | 520 | // check the tempo pot. 521 | check_pots(); 522 | 523 | // check panel buttons 524 | check_buttons(); 525 | 526 | if(send_tick) 527 | { 528 | send_tick = false; 529 | 530 | tick_func(); 531 | 532 | MsTimer2::stop(); 533 | MsTimer2::set(tempo_delay, timer_callback); 534 | MsTimer2::start(); 535 | } 536 | 537 | } 538 | 539 | -------------------------------------------------------------------------------- /Firmware/MIDI-CV/dac-integration-test/dac-integration-test.ino: -------------------------------------------------------------------------------- 1 | /* Werkstatt MIDI-CV interface DAC integration test 2 | by: Byron Jacquot 3 | SparkFun Electronics 4 | date: October 9, 2014 5 | license: Public Domain - please use this code however you'd like. 6 | It's provided as a learning tool. 7 | 8 | Generates opposing sawtooth waves on two I2C DACs so we can verify that 9 | they've got the proper address configuration. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | void setup() 18 | { 19 | Serial.begin(9600); 20 | 21 | Wire.begin(); 22 | 23 | analogReference(INTERNAL); 24 | 25 | // Scope loop 26 | pinMode(8, OUTPUT); 27 | 28 | #define TWI_FREQ_NUNCHUCK 800000L 29 | TWBR = ((F_CPU / TWI_FREQ_NUNCHUCK) - 16) / 2; 30 | } 31 | 32 | uint16_t val = 0; 33 | 34 | void loop() 35 | { 36 | 37 | digitalWrite(8, HIGH); 38 | #if 1 39 | Wire.beginTransmission(0x60); 40 | Wire.write(byte(val >> 8)); 41 | Wire.write(byte(val & 0xff)); 42 | Wire.endTransmission(); 43 | #endif 44 | #if 1 45 | uint16_t val2 = 0xfff - val; 46 | Wire.beginTransmission(0x61); 47 | Wire.write(byte(val2 >> 8)); 48 | Wire.write(byte(val2 & 0xff)); 49 | Wire.endTransmission(); 50 | #endif 51 | val++; 52 | val &= 0x0fff; 53 | 54 | digitalWrite(8, LOW); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Firmware/MIDI-CV/notemap.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | notemap.cpp 3 | 4 | Ancillary classes to MIDI-CV intervase (MIDI-CV.ino) 5 | Byron Jacquot, SparkFun Electronics 6 | October 5, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/MIDI-CV 8 | 9 | This file contains two classes. 10 | 11 | The first (notemap) is a simple bitmap that's used to track note on and off events. It's an 12 | array of 128 bits, corresponding the the 128 possible key numbers in MIDI. Note ons 13 | set bits in the map, note offs remove them. Other routines can check bits, or find the lowest bit set. 14 | Outside code probably won't interface with this class directly. 15 | 16 | The second class (notetracker) manages a couple instances of notemap. The main sketch 17 | passes note on/off, sustain pedal, arpeggiator clock ticks, etc to it. 18 | It keeps track of which note CV should be generated, and whether the gate should be on. 19 | 20 | Resources: 21 | 22 | Development environment specifics: 23 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 24 | MIDI Shield and a pair of Microchip MCP4725 DACs to generate the control voltages. 25 | 26 | Written, compiled and loaded with Arduino 1.6.5 27 | 28 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 29 | 30 | Please review the LICENSE.md file included with this example. If you have any questions 31 | or concerns with licensing, please contact techsupport@sparkfun.com. 32 | 33 | Distributed as-is; no warranty is given. 34 | ******************************************************************************/ 35 | 36 | #include "notemap.h" 37 | 38 | /* notemap::notemap() 39 | * 40 | * Construct an empty notemap. 41 | */ 42 | notemap::notemap() 43 | { 44 | for(uint8_t i = 0; i < 16; i++) 45 | { 46 | keys[i] = 0; 47 | } 48 | numKeys = 0; 49 | } 50 | 51 | /* void notemap::debug() 52 | * 53 | * Display the contents of a notemap 54 | */ 55 | void notemap::debug() 56 | { 57 | Serial.print("Notemap: numKeys: "); 58 | Serial.print(numKeys); 59 | Serial.print(" Array: "); 60 | for (uint8_t i = 0; i < 16; i++) 61 | { 62 | Serial.print(keys[i], HEX); 63 | Serial.print(' '); 64 | } 65 | Serial.println(); 66 | } 67 | 68 | /* void notemap::setBit(uint8_t note) 69 | * 70 | * Set a bit in a notemap. 71 | * Usually corresponds to note-on commands 72 | */ 73 | void notemap::setBit(uint8_t note) 74 | { 75 | uint8_t idx = note / 8; 76 | uint8_t pos = (note % 8) ; 77 | 78 | keys[idx] |= (0x01 << pos); 79 | 80 | numKeys ++; 81 | } 82 | 83 | /* void notemap::clearBit(uint8_t note) 84 | * 85 | * Clear a bit in a notemap. 86 | * Usually corresponds to note-off commands 87 | */ 88 | void notemap::clearBit(uint8_t note) 89 | { 90 | uint8_t idx = note / 8; 91 | uint8_t pos = (note % 8) ; 92 | 93 | keys[idx] &= ~(0x01 << pos); 94 | 95 | numKeys --; 96 | } 97 | 98 | /* void notemap::clearAll(uint8_t note) 99 | * 100 | * Empty out a notemap. 101 | * Mainly used when sustain pedal is released. 102 | */ 103 | void notemap::clearAll() 104 | { 105 | for(uint8_t i = 0; i < 16; i++) 106 | { 107 | keys[i] = 0; 108 | } 109 | numKeys = 0; 110 | } 111 | 112 | /* void notemap::isBitSet(uint8_t note) 113 | * 114 | * Check a bit in a notemap, return it's status. 115 | */ 116 | bool notemap::isBitSet(uint8_t note) 117 | { 118 | uint8_t idx = note / 8; 119 | uint8_t pos = (note % 8) ; 120 | 121 | return( keys[idx] & (0x01 << pos)); 122 | } 123 | 124 | /* void notemap::getLowest(uint8_t note) 125 | * 126 | * Find the lowest bit set in the bitmap and return it's index. 127 | * Used when we want to determine which not to play. 128 | * 129 | * Implements low-note priority. 130 | * TBD: Could reverse the search for high-note priority. 131 | */ 132 | uint8_t notemap::getLowest() 133 | { 134 | //Serial.print("Checkmap:"); 135 | //mapDebug(); 136 | 137 | uint8_t keynum; 138 | 139 | // starting at bottom gives us low note priority. 140 | // could alternately start from the top... 141 | for (uint8_t i = 0; i < 16; i++) 142 | { 143 | if (keys[i] != 0x0) 144 | { 145 | // find the lowest bit set 146 | uint8_t j, k; 147 | for (j = 0x1, k = 0; k < 8; j <<= 1, k++) 148 | { 149 | #if 0 150 | Serial.print("j: "); 151 | Serial.print(j); 152 | Serial.print("k: "); 153 | Serial.println(k); 154 | #endif 155 | if (keys[i] & j) 156 | { 157 | keynum = (i * 8) + k ; 158 | 159 | return keynum; 160 | } 161 | } 162 | } 163 | } 164 | 165 | return 0; 166 | } 167 | 168 | /* void notemap::getNumBits() 169 | * 170 | * Tell te caller how many bits have been set in the map. 171 | */ 172 | uint8_t notemap::getNumBits() 173 | { 174 | return numKeys; 175 | } 176 | 177 | 178 | ///////////////////////////////////////////////////////////////////////////////////////////// 179 | 180 | /* notetracker::notetracker() 181 | * 182 | * Notetracker class constructor. 183 | * Build an empty notrtracker. 184 | */ 185 | notetracker::notetracker() 186 | { 187 | mode = NORMAL; 188 | 189 | staccato = false; 190 | sustaining = false; 191 | clk_hi = false; 192 | 193 | active_map_p = &voice_map; 194 | 195 | last_key = 0; 196 | } 197 | 198 | /* void notetracker::noteOn(uint8_t key) 199 | * 200 | * Accept a note on event. 201 | * Always set bits in the main bitmap. 202 | * If we're sustaining, add the bits to the sustain bitmap, too. 203 | */ 204 | void notetracker::noteOn(uint8_t key) 205 | { 206 | voice_map.setBit(key); 207 | 208 | if(sustaining) 209 | { 210 | sustain_map.setBit(key); 211 | } 212 | } 213 | 214 | /* void notetracker::noteOff(uint8_t key) 215 | * 216 | * Accept a note off event. 217 | * Remove bits from the main bitmap. 218 | * Don't touch the suystain bitmap. 219 | * If we're sustaining, note ons get held until pedal is released, 220 | * even if the keys are released. 221 | */ 222 | void notetracker::noteOff(uint8_t key) 223 | { 224 | voice_map.clearBit(key); 225 | } 226 | 227 | /*void notetracker::setMode(notetracker::tracker_mode m) 228 | * 229 | * Set an arpeggiator mode - normal, up or down 230 | */ 231 | void notetracker::setMode(notetracker::tracker_mode m) 232 | { 233 | mode = m; 234 | } 235 | 236 | /* notetracker::tracker_mode notetracker::getMode() 237 | * 238 | * Return present arpeggiator mode - normal, up or down 239 | */ 240 | notetracker::tracker_mode notetracker::getMode() 241 | { 242 | return mode; 243 | } 244 | 245 | /* void notetracker::setShort(bool short_on) 246 | * 247 | * Change present staccato setting. 248 | */ 249 | void notetracker::setShort(bool short_on) 250 | { 251 | staccato = short_on; 252 | } 253 | 254 | /* bool notetracker::getShort() 255 | * 256 | * return present staccato setting 257 | */ 258 | bool notetracker::getShort() 259 | { 260 | return staccato; 261 | } 262 | 263 | /* void notetracker::setSustain(bool on) 264 | * 265 | * Turn sustain on/off. 266 | * 267 | * Sustain is the trickiest piece of this. 268 | * When sustain pedal is pressed, we make a copy of the notemap, and use it 269 | * instead of the regular one. 270 | * The sustaining bitmap accumulates all new note ons, but is only pueged when the pedal 271 | * is let up. 272 | * 273 | * The regular bitmap continues to update with both note on and offs. 274 | * 275 | * When the pedal is released, the sustain bitmap is purged, and the 276 | * regular bitmap takes over, knowing which 277 | * keys are presently being held. 278 | */ 279 | void notetracker::setSustain(bool on) 280 | { 281 | #if 0 282 | Serial.print("Sustain: "); 283 | Serial.println(sustaining); 284 | #endif 285 | 286 | if(on) 287 | { 288 | sustaining = true; 289 | 290 | //This gives us a member-by-member copy of bitmap object 291 | sustain_map = voice_map; 292 | 293 | active_map_p = &sustain_map; 294 | 295 | } 296 | else 297 | { 298 | sustaining = false; 299 | 300 | sustain_map.clearAll(); 301 | 302 | active_map_p = &voice_map; 303 | } 304 | 305 | } 306 | 307 | /* uint8_t notetracker::getNext(uint8_t start) 308 | * 309 | * Called when the arpeggiator is active and the clock advances. 310 | * It hunts the active bitmap in the approptiate direction (up/dn), 311 | * and finds the next note. 312 | * 313 | * While it's similar to getLowest, it makes more sense as part of the 314 | * notetracker (rather than notemap), because the arpeggiator info is all in the 315 | * notetracker - notemap has no knowledge of arpeggiation. 316 | */ 317 | uint8_t notetracker::getNext(uint8_t start) 318 | { 319 | int8_t step; 320 | 321 | if(mode == ARP_UP) 322 | { 323 | step = 1; 324 | } 325 | else if(mode == ARP_DN) 326 | { 327 | step = -1; 328 | } 329 | 330 | for(uint8_t key = start+step; key != start; key = (key+step)%128) 331 | { 332 | if(active_map_p->isBitSet(key)) 333 | { 334 | return key; 335 | } 336 | } 337 | return start; 338 | } 339 | 340 | /* void notetracker::tickArp(bool rising) 341 | * 342 | * Called when the apreggiator clock sees a rising or falling event. 343 | * 344 | * The arp clock runs at twice the desired frequency, so we can have 345 | * 50% duty cycle for LED blinking, and staccato mode. The clock notifies 346 | * us of both rising and falling edges. 347 | * 348 | * Rising edges cause us to hunt for the next note in the active map. 349 | * Falling edges simply set the clk_hi to false, which interrupts the gate output 350 | * in staccato mode. 351 | */ 352 | void notetracker::tickArp(bool rising) 353 | { 354 | if(rising) 355 | { 356 | clk_hi = true; 357 | 358 | if(active_map_p->getNumBits() > 1) 359 | { 360 | last_key = getNext(last_key); 361 | } 362 | } 363 | else // falling 364 | { 365 | clk_hi = false; 366 | } 367 | } 368 | 369 | /* uint8_t notetracker::whichKey() 370 | * 371 | * Which key should be used to generate the current CV? 372 | * 373 | * If no keys are held, return the last value we sent. 374 | * If apreggiator is off, just return the lowest bit in the active map. 375 | * 376 | * If arpeggiator is on: 377 | * If only one key is held, return that key. 378 | * If multiple keys are held, return last_key. 379 | * Last_key will be updated by arpeggiator clock 380 | * 381 | */ 382 | uint8_t notetracker::whichKey() 383 | { 384 | uint8_t num_keys = active_map_p->getNumBits(); 385 | 386 | if(num_keys == 0) 387 | { 388 | return last_key; 389 | } 390 | 391 | switch(mode) 392 | { 393 | case ARP_UP: 394 | { 395 | // When there's only one key held, we need to respond to it 396 | // immediately. 397 | // If multiple keys are held, advanceArp() sets last_key 398 | // based on timer. 399 | if(num_keys == 1) 400 | { 401 | last_key = active_map_p->getLowest(); 402 | } 403 | } 404 | break; 405 | case ARP_DN: 406 | { 407 | if(num_keys == 1) 408 | { 409 | last_key = active_map_p->getLowest(); 410 | } 411 | } 412 | break; 413 | case NORMAL: 414 | default: 415 | { 416 | last_key = active_map_p->getLowest(); 417 | } 418 | break; 419 | } 420 | 421 | return last_key; 422 | 423 | } 424 | 425 | /* bool notetracker::getGate() 426 | * 427 | * Return whether we should be driving the gatr signal or not. 428 | * 429 | * In legato mode, we drive the gate is any keys are presently held/sustained. 430 | * 431 | * In staccato mode, the gate is the combination of keys held and the 432 | * arpeggiator clock. It seemed more fun to have staccato mode 433 | * independent of the arpeggio mode...if you don't like that, 434 | * then change it here. 435 | */ 436 | bool notetracker::getGate() 437 | { 438 | if(staccato) 439 | { 440 | return clk_hi & ((active_map_p->getNumBits())> 0); 441 | } 442 | else 443 | { 444 | return ((active_map_p->getNumBits()) > 0); 445 | } 446 | } 447 | 448 | 449 | -------------------------------------------------------------------------------- /Firmware/MIDI-CV/notemap.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | notemap.h 3 | 4 | Ancillary classes to MIDI-CV intervase (MIDI-CV.ino) 5 | Byron Jacquot, SparkFun Electronics 6 | October 5, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/MIDI-CV 8 | 9 | This file contains two classes. 10 | 11 | The first (notemap) is a simple bitmap that's used to track note on and off events. It's an 12 | array of 128 bits, corresponding the the 128 possible key numbers in MIDI. Note ons 13 | set bits in the map, note offs remove them. Other routines can check bits, or find the lowest bit set. 14 | Outside code probably won't interface with this class directly. 15 | 16 | The second class (notetracker) manages a couple instances of notemap. The main sketch 17 | passes note on/off, sustain pedal, arpeggiator clock ticks, etc to it. 18 | It keeps track of which note CV should be generated, and whether the gate should be on. 19 | 20 | Resources: 21 | 22 | Development environment specifics: 23 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 24 | MIDI Shield and a pair of Microchip MCP4725 DACs to generate the control voltages. 25 | 26 | Written, compiled and loaded with Arduino 1.6.5 27 | 28 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 29 | 30 | Please review the LICENSE.md file included with this example. If you have any questions 31 | or concerns with licensing, please contact techsupport@sparkfun.com. 32 | 33 | Distributed as-is; no warranty is given. 34 | ******************************************************************************/ 35 | 36 | #pragma once 37 | 38 | #include 39 | #include 40 | 41 | 42 | /* 43 | * class notemap 44 | * 45 | * Keeps track of which keys are being held. 46 | * 47 | * Represents the full set of 128 MIDI keys. If you want to constrain that, 48 | * you can do it by limiting input to the class, or filtering it's output. 49 | */ 50 | class notemap 51 | { 52 | public: 53 | 54 | notemap(); 55 | 56 | void debug(); 57 | 58 | void setBit(uint8_t note); 59 | void clearBit(uint8_t note); 60 | void clearAll(); 61 | 62 | bool isBitSet(uint8_t note); 63 | 64 | uint8_t getNumBits(); 65 | uint8_t getLowest(); 66 | 67 | private: 68 | 69 | uint8_t keys[16]; 70 | uint8_t numKeys; 71 | }; 72 | 73 | /* 74 | * Class notetracker 75 | * 76 | * Answers the question: what CV should we be producing. 77 | * 78 | * Inputs are note on/off, sustain pedal events, key presses, apreggiator clocks. 79 | * Outputs are note CV value and gate. 80 | * Uses two instances of notemap to track keys (second instance is used when 81 | * sustain pedal is held.), plus some logic to implement low-voice priority 82 | * and an arpeggiator. 83 | * 84 | * Represents the full set of 128 MIDI keys. If you want to constrain that, 85 | * you can do it by limiting input to the class, or filtering it's output. 86 | * 87 | * Read the annotations on the indivudual functions for a better understanding 88 | * of their uses and interactions. 89 | */ 90 | class notetracker 91 | { 92 | public: 93 | notetracker(); 94 | 95 | enum tracker_mode {NORMAL, ARP_UP, ARP_DN}; 96 | 97 | void noteOn (uint8_t key); 98 | void noteOff(uint8_t key); 99 | 100 | void setMode (notetracker::tracker_mode m); 101 | notetracker::tracker_mode getMode(); 102 | 103 | void setShort(bool short_on); 104 | bool getShort(); 105 | 106 | uint8_t getNext(uint8_t start); 107 | 108 | void setSustain(bool); 109 | 110 | void tickArp(bool); 111 | 112 | uint8_t whichKey(); 113 | 114 | bool getGate(); 115 | 116 | private: 117 | 118 | tracker_mode mode; 119 | 120 | bool staccato; 121 | bool sustaining; 122 | bool clk_hi; 123 | 124 | notemap voice_map; 125 | notemap sustain_map; 126 | notemap * active_map_p; 127 | 128 | uint8_t last_key; 129 | }; 130 | 131 | 132 | -------------------------------------------------------------------------------- /Firmware/MIDI-sniffer/MIDI-sniffer.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | MIDI-sniffer.ino 3 | Use SparkFun MIDI Shield as a MIDI data analyzer. 4 | 5 | Byron Jacquot, SparkFun Electronics 6 | October 8, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/MIDI-sniffer 8 | 9 | Reads all events arriving over MIDI, and turns them into descriptive text. 10 | If you hold the button on D2, it will switch to display the raw hex values arriving, 11 | which can be useful for viewing incomplete messages and running status. 12 | 13 | Resources: 14 | 15 | Requires that the MIDI Sheild be configured to use soft serial on pins 8 & 9, 16 | so that debug text can be printed to the hardware serial port. 17 | 18 | This code is dependent on the FortySevenEffects MIDI library for Arduino. 19 | https://github.com/FortySevenEffects/arduino_midi_library 20 | This was done using version 4.2, hash fb693e724508cb8a473fa0bf1915101134206c34 21 | This library is now under the MIT license, as well. 22 | You'll need to install that library into the Arduino IDE before compiling. 23 | 24 | 25 | Development environment specifics: 26 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 27 | MIDI Shield. 28 | 29 | Written, compiled and loaded with Arduino 1.6.5 30 | 31 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 32 | 33 | Please review the LICENSE.md file included with this example. If you have any questions 34 | or concerns with licensing, please contact techsupport@sparkfun.com. 35 | 36 | Distributed as-is; no warranty is given. 37 | ******************************************************************************/ 38 | 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #define PIN_RAW_INPUT 2 45 | 46 | #define PIN_POT_A0 0 47 | #define PIN_POT_A1 1 48 | 49 | static const uint16_t DEBOUNCE_COUNT = 50; 50 | 51 | // Need to use soft serial, so we can report what's happening 52 | // via messages on hard serial. 53 | SoftwareSerial SoftSerial(8, 9); 54 | 55 | /* Args: 56 | - type of port to use (hard/soft) 57 | - port object name 58 | - name for this midi instance 59 | */ 60 | MIDI_CREATE_INSTANCE(SoftwareSerial, SoftSerial, MIDI); 61 | // This doesn't make much sense to use with hardware serial, as it needs 62 | // hard serial to report what it's seeing... 63 | 64 | void setup() 65 | { 66 | // put your setup code here, to run 67 | once: 68 | 69 | // LED outputs 70 | Serial.begin(19200); 71 | Serial.println("Setting up"); 72 | 73 | // do I need to init the soft serial port? 74 | // No - MIDI Lib will do it. 75 | 76 | // We want to receive messages on all channels 77 | MIDI.begin(MIDI_CHANNEL_OMNI); 78 | 79 | // We also want to echo the input to the output, 80 | // so the sniffer can be dropped inline when things misbehave. 81 | MIDI.turnThruOn(); 82 | 83 | pinMode(PIN_RAW_INPUT, INPUT_PULLUP); 84 | 85 | } 86 | 87 | void loop() 88 | { 89 | static uint8_t ticks = 0; 90 | static uint8_t old_ticks = 0; 91 | 92 | 93 | // put your main code here, to run repeatedly: 94 | 95 | if(digitalRead(PIN_RAW_INPUT) == LOW) 96 | { 97 | // If you hold button D2 on the shield, we'll print 98 | // the raw hex values from the MIDI input. 99 | // 100 | // This can be useful if you need to troubleshoot issues with 101 | // running status 102 | 103 | byte input; 104 | if(SoftSerial.available() != 0) 105 | { 106 | input = SoftSerial.read(); 107 | 108 | if(input & 0x80) 109 | { 110 | Serial.println(); 111 | } 112 | Serial.print(input, HEX); 113 | Serial.print(' '); 114 | } 115 | } 116 | else 117 | { 118 | // turn the crank... 119 | if ( MIDI.read()) 120 | { 121 | switch (MIDI.getType()) 122 | { 123 | case midi::NoteOff : 124 | { 125 | Serial.print("NoteOff, chan: "); 126 | Serial.print(MIDI.getChannel()); 127 | Serial.print(" Note#: "); 128 | Serial.print(MIDI.getData1()); 129 | Serial.print(" Vel#: "); 130 | Serial.println(MIDI.getData2()); 131 | } 132 | break; 133 | case midi::NoteOn : 134 | { 135 | uint8_t vel; 136 | 137 | Serial.print("NoteOn, chan: "); 138 | Serial.print(MIDI.getChannel()); 139 | Serial.print(" Note#: "); 140 | Serial.print(MIDI.getData1()); 141 | Serial.print(" Vel#: "); 142 | vel = MIDI.getData2(); 143 | Serial.print(vel); 144 | if (vel == 0) 145 | { 146 | Serial.print(" *Implied off*"); 147 | } 148 | Serial.println(); 149 | } 150 | break; 151 | case midi::AfterTouchPoly : 152 | { 153 | Serial.print("PolyAT, chan: "); 154 | Serial.print(MIDI.getChannel()); 155 | Serial.print(" Note#: "); 156 | Serial.print(MIDI.getData1()); 157 | Serial.print(" AT: "); 158 | Serial.println(MIDI.getData2()); 159 | } 160 | break; 161 | case midi::ControlChange : 162 | { 163 | Serial.print("Controller, chan: "); 164 | Serial.print(MIDI.getChannel()); 165 | Serial.print(" Controller#: "); 166 | Serial.print(MIDI.getData1()); 167 | Serial.print(" Value: "); 168 | Serial.println(MIDI.getData2()); 169 | } 170 | break; 171 | case midi::ProgramChange : 172 | { 173 | Serial.print("PropChange, chan: "); 174 | Serial.print(MIDI.getChannel()); 175 | Serial.print(" program: "); 176 | Serial.println(MIDI.getData1()); 177 | } 178 | break; 179 | case midi::AfterTouchChannel : 180 | { 181 | Serial.print("ChanAT, chan: "); 182 | Serial.print(MIDI.getChannel()); 183 | Serial.print(" program: "); 184 | Serial.println(MIDI.getData1()); 185 | 186 | } 187 | break; 188 | case midi::PitchBend : 189 | { 190 | uint16_t val; 191 | 192 | Serial.print("Bend, chan: "); 193 | Serial.print(MIDI.getChannel()); 194 | 195 | // concatenate MSB,LSB 196 | // LSB is Data1 197 | val = MIDI.getData2() << 7 | MIDI.getData1(); 198 | 199 | Serial.print(" value: 0x"); 200 | Serial.println(val, HEX); 201 | 202 | 203 | } 204 | break; 205 | case midi::SystemExclusive : 206 | { 207 | // Sysex is special. 208 | // could contain very long data... 209 | // the data bytes form the length of the message, 210 | // with data contained in array member 211 | uint16_t length; 212 | const uint8_t * data_p; 213 | 214 | Serial.print("SysEx, chan: "); 215 | Serial.print(MIDI.getChannel()); 216 | length = MIDI.getSysExArrayLength(); 217 | 218 | Serial.print(" Data: 0x"); 219 | data_p = MIDI.getSysExArray(); 220 | for (uint16_t idx = 0; idx < length; idx++) 221 | { 222 | Serial.print(data_p[idx], HEX); 223 | Serial.print(" 0x"); 224 | } 225 | Serial.println(); 226 | } 227 | break; 228 | case midi::TimeCodeQuarterFrame : 229 | { 230 | // MTC is also special... 231 | // 1 byte of data carries 3 bits of field info 232 | // and 4 bits of data (sent as MS and LS nybbles) 233 | // It takes 2 messages to send each TC field, 234 | 235 | Serial.print("TC 1/4Frame, type: "); 236 | Serial.print(MIDI.getData1() >> 4); 237 | Serial.print("Data nybble: "); 238 | Serial.println(MIDI.getData1() & 0x0f); 239 | } 240 | break; 241 | case midi::SongPosition : 242 | { 243 | // Data is the number of elapsed sixteenth notes into the song, set as 244 | // 7 seven-bit values, LSB, then MSB. 245 | 246 | Serial.print("SongPosition "); 247 | Serial.println(MIDI.getData2() << 7 | MIDI.getData1()); 248 | } 249 | break; 250 | case midi::SongSelect : 251 | { 252 | Serial.print("SongSelect "); 253 | Serial.println(MIDI.getData1()); 254 | } 255 | break; 256 | case midi::TuneRequest : 257 | { 258 | Serial.println("Tune Request"); 259 | } 260 | break; 261 | case midi::Clock : 262 | { 263 | ticks++; 264 | 265 | Serial.print("Clock "); 266 | Serial.println(ticks); 267 | } 268 | break; 269 | case midi::Start : 270 | { 271 | ticks = 0; 272 | Serial.println("Starting"); 273 | } 274 | break; 275 | case midi::Continue : 276 | { 277 | ticks = old_ticks; 278 | Serial.println("continuing"); 279 | } 280 | break; 281 | case midi::Stop : 282 | { 283 | old_ticks = ticks; 284 | Serial.println("Stopping"); 285 | } 286 | break; 287 | case midi::ActiveSensing : 288 | { 289 | Serial.println("ActiveSense"); 290 | } 291 | break; 292 | case midi::SystemReset : 293 | { 294 | Serial.println("Stopping"); 295 | } 296 | break; 297 | case midi::InvalidType : 298 | { 299 | Serial.println("Invalid Type"); 300 | } 301 | break; 302 | default: 303 | { 304 | Serial.println(); 305 | } 306 | break; 307 | } 308 | } 309 | } 310 | } 311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /Firmware/buttons-N-pots/buttons-N-pots.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | buttons-N-pots.ino 3 | Test the physical controls on SparkFun MIDI Shield. 4 | 5 | Byron Jacquot, SparkFun Electronics 6 | October 8, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/buttons-N-pots 8 | 9 | A quick test to show that the bottons and pots on the MIDI Shield are functional. 10 | Reads their values, and prints out reports when they change. 11 | 12 | It doesn't exercise any of the MIDI functionality. See the other 13 | sketches for MIDI examples: 14 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware 15 | 16 | Development environment specifics: 17 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 18 | MIDI Shield. 19 | 20 | Written, compiled and loaded with Arduino 1.6.5 21 | 22 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 23 | 24 | Please review the LICENSE.md file included with this example. If you have any questions 25 | or concerns with licensing, please contact techsupport@sparkfun.com. 26 | 27 | Distributed as-is; no warranty is given. 28 | ******************************************************************************/ 29 | 30 | 31 | static const uint8_t PIN_BTN0 = 2; 32 | static const uint8_t PIN_BTN1 = 3; 33 | static const uint8_t PIN_BTN2 = 4; 34 | 35 | static const uint8_t PIN_POT0 = 0; 36 | static const uint8_t PIN_POT1 = 1; 37 | 38 | static const uint8_t PIN_LED_GRN = 6; 39 | static const uint8_t PIN_LED_RED = 7; 40 | 41 | typedef struct inputStates 42 | { 43 | uint8_t button[3]; 44 | uint8_t pot[2]; 45 | }inputStates; 46 | 47 | inputStates lastdata; 48 | inputStates newdata; 49 | 50 | void readinputs(struct inputStates * data) 51 | { 52 | // A bit of a funny statement below. 53 | // digitalRead return HIGH or LOW. 54 | // We want boolean (true/false) indicators of whether the button are 55 | // pushed. 56 | // And button inputs are active low - when a button is pushed, it'll read "LOW" 57 | // The right side of the expression checks if the input is equal to LOW, converting 58 | // that into a boolean indicator, stored in the array. 59 | data->button[0] = (digitalRead(PIN_BTN0) == LOW); 60 | data->button[1] = (digitalRead(PIN_BTN1) == LOW); 61 | data->button[2] = (digitalRead(PIN_BTN2) == LOW); 62 | 63 | // Analog inputs have an LSB (out of 10 bits) or so noise, 64 | // leading to "chatter" in the change detector logic. 65 | // Shifting off the 2 LSBs to remove it 66 | data->pot[0] = analogRead(PIN_POT0) >> 2; 67 | data->pot[1] = analogRead(PIN_POT1) >> 2; 68 | } 69 | 70 | void compareinputs(inputStates * old_p, inputStates * new_p) 71 | { 72 | uint8_t idx; 73 | 74 | for(idx = 0; idx < 3; idx++) 75 | { 76 | if(old_p->button[idx] != new_p->button[idx]) 77 | { 78 | old_p->button[idx] = new_p->button[idx]; 79 | Serial.print("Button #"); 80 | Serial.print(idx); 81 | Serial.print(" changed to "); 82 | Serial.println(old_p->button[idx]); 83 | } 84 | } 85 | 86 | for(idx = 0; idx < 2; idx++) 87 | { 88 | if(old_p->pot[idx] != new_p->pot[idx]) 89 | { 90 | old_p->pot[idx] = new_p->pot[idx]; 91 | Serial.print("Pot #"); 92 | Serial.print(idx); 93 | Serial.print(" changed to "); 94 | Serial.println(old_p->pot[idx]); 95 | } 96 | } 97 | } 98 | 99 | void updateLEDs(inputStates * data) 100 | { 101 | digitalWrite(PIN_LED_GRN, !data->button[0]); 102 | digitalWrite(PIN_LED_RED, !data->button[1]); 103 | } 104 | 105 | void setup() { 106 | // put your setup code here, to run once: 107 | 108 | Serial.begin(19200); 109 | Serial.println("Setting up."); 110 | 111 | pinMode(PIN_BTN0, INPUT_PULLUP); 112 | pinMode(PIN_BTN1, INPUT_PULLUP); 113 | pinMode(PIN_BTN2, INPUT_PULLUP); 114 | 115 | pinMode(PIN_LED_GRN, OUTPUT); 116 | pinMode(PIN_LED_RED, OUTPUT); 117 | 118 | readinputs(&lastdata); 119 | } 120 | 121 | void loop() { 122 | // put your main code here, to run repeatedly: 123 | 124 | readinputs(& newdata); 125 | compareinputs(& lastdata, & newdata); 126 | updateLEDs(&newdata); 127 | } 128 | -------------------------------------------------------------------------------- /Firmware/clock-gen/clock-gen.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | clock-gen.ino 3 | Use SparkFun MIDI Shield as a MIDI clock generator. 4 | 5 | Byron Jacquot, SparkFun Electronics 6 | October 8, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/clock-gen 8 | 9 | Generate MIDI clock messages at the tempo indicated by A1. 10 | Send start/stop messages when D2 is pressed, and continue when D3 is pressed. 11 | 12 | Resources: 13 | 14 | This sketch has a clock receiving counterpart in clock-recv.ino 15 | 16 | This code is dependent on the FortySevenEffects MIDI library for Arduino. 17 | https://github.com/FortySevenEffects/arduino_midi_library 18 | This was done using version 4.2, hash fb693e724508cb8a473fa0bf1915101134206c34 19 | This library is now under the MIT license, as well. 20 | You'll need to install that library into the Arduino IDE before compiling. 21 | 22 | 23 | Development environment specifics: 24 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 25 | MIDI Shield. 26 | 27 | Written, compiled and loaded with Arduino 1.6.5 28 | 29 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 30 | 31 | Please review the LICENSE.md file included with this example. If you have any questions 32 | or concerns with licensing, please contact techsupport@sparkfun.com. 33 | 34 | Distributed as-is; no warranty is given. 35 | ******************************************************************************/ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #define PIN_LED_PLAYING 6 42 | #define PIN_LED_TEMPO 7 43 | #define PIN_PLAY_INPUT 2 44 | #define PIN_CONTINUE_INPUT 3 45 | 46 | #define PIN_TEMPO_POT 1 47 | 48 | static const uint16_t DEBOUNCE_COUNT = 50; 49 | 50 | //SoftwareSerial SoftSerial(8,9); 51 | 52 | /* Args: 53 | - type of port to use (hard/soft) 54 | - port object name 55 | - name for this midi instance 56 | */ 57 | MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI); 58 | //MIDI_CREATE_INSTANCE(SoftwareSerial, SoftSerial, MIDI); 59 | 60 | bool running; 61 | bool send_start; 62 | bool send_stop; 63 | bool send_continue; 64 | bool send_tick; 65 | uint32_t tempo_delay; 66 | 67 | 68 | void play_button_event() 69 | { 70 | // toggle running state, 71 | // send corresponding responses 72 | running = !running; 73 | 74 | if(running) 75 | { 76 | send_start = true; 77 | digitalWrite(PIN_LED_PLAYING, LOW); 78 | } 79 | else 80 | { 81 | send_stop = true; 82 | digitalWrite(PIN_LED_PLAYING, HIGH); 83 | } 84 | } 85 | 86 | void cont_button_event() 87 | { 88 | // ignore continue if running 89 | if(!running) 90 | { 91 | send_continue = true; 92 | running = true; 93 | digitalWrite(PIN_LED_PLAYING, LOW); 94 | } 95 | } 96 | 97 | void timer_callback() 98 | { 99 | send_tick = true; 100 | } 101 | 102 | void check_pots() 103 | { 104 | uint32_t pot_val; 105 | uint32_t calc; 106 | 107 | pot_val = analogRead(PIN_TEMPO_POT); 108 | 109 | // Result is 10 bits 110 | calc = (((0x3ff - pot_val) * 75)/1023) + 8; 111 | 112 | tempo_delay = calc ;//* 5; 113 | } 114 | 115 | void check_buttons() 116 | { 117 | uint8_t val; 118 | static uint16_t play_debounce = 0; 119 | static uint16_t cont_debounce = 0; 120 | 121 | // First the PLAY/STOP button 122 | val = digitalRead(PIN_PLAY_INPUT); 123 | 124 | if(val == LOW) 125 | { 126 | play_debounce++; 127 | 128 | if(play_debounce == DEBOUNCE_COUNT) 129 | { 130 | play_button_event(); 131 | } 132 | } 133 | else 134 | { 135 | play_debounce = 0; 136 | } 137 | 138 | // Then the continue button 139 | val = digitalRead(PIN_CONTINUE_INPUT); 140 | 141 | if(val == LOW) 142 | { 143 | cont_debounce++; 144 | 145 | if(cont_debounce == DEBOUNCE_COUNT) 146 | { 147 | cont_button_event(); 148 | } 149 | } 150 | else 151 | { 152 | cont_debounce = 0; 153 | } 154 | 155 | 156 | 157 | } 158 | 159 | 160 | void setup() 161 | { 162 | // put your setup code here, to run once: 163 | 164 | // LED outputs 165 | pinMode(PIN_LED_PLAYING, OUTPUT); 166 | pinMode(PIN_LED_TEMPO, OUTPUT); 167 | digitalWrite(PIN_LED_PLAYING, HIGH); 168 | digitalWrite(PIN_LED_TEMPO, HIGH); 169 | 170 | // button inputs 171 | pinMode(PIN_PLAY_INPUT, INPUT_PULLUP); 172 | pinMode(PIN_CONTINUE_INPUT, INPUT_PULLUP); 173 | 174 | // Serial.begin(9600); 175 | // Serial.println("Setting up"); 176 | 177 | // SoftSerial.begin(31250); 178 | 179 | // do I need to init the soft serial port? 180 | 181 | #if 1 182 | MIDI.begin(MIDI_CHANNEL_OMNI); 183 | MIDI.turnThruOff(); 184 | #endif 185 | 186 | running = false; 187 | send_start = false; 188 | send_stop = false; 189 | send_tick = false; 190 | 191 | // prime the tempo pump 192 | check_pots(); 193 | 194 | // check_timing(); 195 | 196 | MsTimer2::set(tempo_delay, timer_callback); 197 | MsTimer2::start(); 198 | 199 | } 200 | 201 | void loop() 202 | { 203 | static uint32_t loops = 0; 204 | static uint8_t ticks = 0; 205 | static uint8_t prev_ticks = 0; 206 | bool reset_timer = false; 207 | 208 | // put your main code here, to run repeatedly: 209 | 210 | // turn the crank... 211 | MIDI.read(); 212 | 213 | // Check buttons 214 | check_buttons(); 215 | 216 | // process inputs 217 | if(send_start) 218 | { 219 | MIDI.sendRealTime(MIDI_NAMESPACE::Start); 220 | send_start = false; 221 | // Serial.println("Starting"); 222 | 223 | ticks = 0; 224 | 225 | // Next tick comes immediately... 226 | // it also resets the timer 227 | send_tick = true; 228 | 229 | } 230 | if(send_continue) 231 | { 232 | MIDI.sendRealTime(MIDI_NAMESPACE::Continue); 233 | send_continue = false; 234 | // Serial.println("continuing"); 235 | 236 | // Restore the LED blink counter 237 | ticks = prev_ticks; 238 | 239 | // Next tick comes immediately... 240 | // it also resets the timer 241 | send_tick = true; 242 | } 243 | 244 | if(send_stop) 245 | { 246 | MIDI.sendRealTime(MIDI_NAMESPACE::Stop); 247 | send_stop = false; 248 | prev_ticks = ticks ; 249 | // Serial.println("Stopping"); 250 | } 251 | 252 | if(send_tick) 253 | { 254 | MIDI.sendRealTime(MIDI_NAMESPACE::Clock); 255 | send_tick = false; 256 | 257 | ticks++; 258 | if(ticks < 6) 259 | { 260 | digitalWrite(PIN_LED_TEMPO, LOW); 261 | } 262 | else if(ticks == 6) 263 | { 264 | digitalWrite(PIN_LED_TEMPO, HIGH); 265 | } 266 | else if(ticks >= 24) 267 | { 268 | ticks = 0; 269 | } 270 | 271 | check_pots(); 272 | 273 | reset_timer = true; 274 | } 275 | 276 | if(reset_timer) 277 | { 278 | MsTimer2::stop(); 279 | MsTimer2::set(tempo_delay, timer_callback); 280 | MsTimer2::start(); 281 | 282 | reset_timer = false; 283 | } 284 | 285 | loops++; 286 | } 287 | -------------------------------------------------------------------------------- /Firmware/clock-gen/msec-to-bpm.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/MIDI_Shield/66a5664d53bd1324653deffb7326d3812cee663b/Firmware/clock-gen/msec-to-bpm.ods -------------------------------------------------------------------------------- /Firmware/clock-recv/clock-recv.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | clock-recv.ino 3 | Use SparkFun MIDI Shield as a MIDI clock receiver. 4 | 5 | Byron Jacquot, SparkFun Electronics 6 | October 8, 2015 7 | https://github.com/sparkfun/MIDI_Shield/tree/V_1.5/Firmware/clock-recv 8 | 9 | Listenn for clock/start/stop/continue messages on the MIDI input 10 | 11 | Resources: 12 | 13 | This sketch has a clock generating counterpart in clock-gen.ino 14 | 15 | This code is dependent on the FortySevenEffects MIDI library for Arduino. 16 | https://github.com/FortySevenEffects/arduino_midi_library 17 | This was done using version 4.2, hash fb693e724508cb8a473fa0bf1915101134206c34 18 | This library is now under the MIT license, as well. 19 | You'll need to install that library into the Arduino IDE before compiling. 20 | 21 | 22 | Development environment specifics: 23 | It was developed for the Arduino Uno compatible SparkFun RedBoard, with a SparkFun 24 | MIDI Shield. 25 | 26 | Written, compiled and loaded with Arduino 1.6.5 27 | 28 | This code is released under the [MIT License](http://opensource.org/licenses/MIT). 29 | 30 | Please review the LICENSE.md file included with this example. If you have any questions 31 | or concerns with licensing, please contact techsupport@sparkfun.com. 32 | 33 | Distributed as-is; no warranty is given. 34 | ******************************************************************************/ 35 | #include 36 | #include 37 | #include 38 | 39 | #define PIN_LED_PLAYING 6 40 | #define PIN_LED_TEMPO 7 41 | #define PIN_PLAY_INPUT 2 42 | #define PIN_CONTINUE_INPUT 3 43 | 44 | #define PIN_TEMPO_POT 1 45 | 46 | static const uint16_t DEBOUNCE_COUNT = 50; 47 | 48 | //SoftwareSerial SoftSerial(8,9); 49 | 50 | /* Args: 51 | - type of port to use (hard/soft) 52 | - port object name 53 | - name for this midi instance 54 | */ 55 | //MIDI_CREATE_INSTANCE(SoftwareSerial, SoftSerial, MIDI); 56 | MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI); 57 | 58 | void setup() 59 | { 60 | // put your setup code here, to run once: 61 | 62 | // LED outputs 63 | pinMode(PIN_LED_PLAYING, OUTPUT); 64 | pinMode(PIN_LED_TEMPO, OUTPUT); 65 | digitalWrite(PIN_LED_PLAYING, HIGH); 66 | digitalWrite(PIN_LED_TEMPO, HIGH); 67 | 68 | // button inputs 69 | // Serial.begin(9600); 70 | // Serial.println("Setting up"); 71 | 72 | // SoftSerial.begin(31250); 73 | // do I need to init the soft serial port? 74 | // No - MIDI will do it. 75 | 76 | #if 1 77 | MIDI.begin(MIDI_CHANNEL_OMNI); 78 | MIDI.turnThruOff(); 79 | #endif 80 | 81 | } 82 | 83 | void loop() 84 | { 85 | static uint32_t loops = 0; 86 | static uint8_t ticks = 0; 87 | static uint8_t prev_ticks = 0; 88 | 89 | // put your main code here, to run repeatedly: 90 | 91 | // turn the crank... 92 | if( MIDI.read()) 93 | { 94 | switch(MIDI.getType()) 95 | { 96 | case midi::Clock : 97 | { 98 | ticks++; 99 | 100 | //Serial.print('.'); 101 | // Serial.println(ticks); 102 | 103 | if(ticks < 6) 104 | { 105 | digitalWrite(PIN_LED_TEMPO, LOW); 106 | //Serial.print('#'); 107 | } 108 | else if(ticks == 6) 109 | { 110 | digitalWrite(PIN_LED_TEMPO, HIGH); 111 | } 112 | else if(ticks >= 24) 113 | { 114 | ticks = 0; 115 | // Serial.print('\n'); 116 | } 117 | } 118 | break; 119 | 120 | case midi::Start : 121 | { 122 | digitalWrite(PIN_LED_PLAYING, LOW); 123 | ticks = 0; 124 | // Serial.println("Starting"); 125 | } 126 | break; 127 | 128 | case midi::Stop : 129 | { 130 | digitalWrite(PIN_LED_PLAYING, HIGH); 131 | prev_ticks = ticks; 132 | // Serial.println("Stopping"); 133 | } 134 | break; 135 | case midi::Continue : 136 | { 137 | 138 | digitalWrite(PIN_LED_PLAYING, LOW); 139 | 140 | // Restore the LED blink counter 141 | ticks = prev_ticks; 142 | // Serial.println("continuing"); 143 | } 144 | break; 145 | 146 | default: 147 | break; 148 | } 149 | } 150 | 151 | loops++; 152 | } 153 | 154 | 155 | -------------------------------------------------------------------------------- /Hardware/SparkFun_MIDI_Shield.brd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | RESET 167 | D2 168 | D3 169 | D4 170 | A1 171 | A0 172 | MIDI IN 173 | MIDI OUT 174 | MIDI 175 | Shield 176 | STAT1 (D7) 177 | STAT2 (D6) 178 | PROG 179 | RUN 180 | Byron Jacquot 181 | SJ4 182 | SJ5 183 | SJ6 184 | SJ7 185 | V15 186 | SJ1 187 | SJ2 188 | 189 | Hardware (0,1) 190 | Software (8,9) 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | SJ1&2 select UART 201 | SJ4 & 5 Power 202 | To MIDI Input 203 | SJ6 & 7 Power 204 | To MIDI Output 205 | SJ3 206 | 207 | MIDI Thru 208 | MIDI Out 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | SJ3 selects out type 219 | Chris Taylor 220 | 221 | 222 | 223 | All units in Inches 224 | 225 | 226 | 227 | 228 | 229 | Pot shafts are 0.24" (6mm) diameter 230 | 231 | 5-pin DIN connectors need approx 232 | 0.53" (13.5mm) diam holes 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | Updated 5-pin DIN commector (AKA MIDI). 242 | <br><br> 243 | Updated to match parts as of May 2015. 244 | PROD_ID CONN=09481 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | DIN-5 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | BOARD EDGE 279 | 280 | 281 | 282 | 283 | <h3>SparkFun Electronics' preferred foot prints</h3> 284 | In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> 285 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 286 | <br><br> 287 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 288 | <br><br> 289 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 290 | 291 | 292 | Released under the Creative Commons Attribution Share-Alike 4.0 License 293 | https://creativecommons.org/licenses/by-sa/4.0/ 294 | Designed by: 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | 1347 | 1348 | 1349 | 1350 | 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1372 | 1373 | 1374 | 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1508 | 1509 | 1510 | 1511 | 1512 | 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | Revision By: 1534 | 1535 | 1536 | 1537 | 1538 | <h3>SparkFun Electronics' preferred foot prints</h3> 1539 | In this library you'll find anything that moves- switches, relays, buttons, potentiometers. Also, anything that goes on a board but isn't electrical in nature- screws, standoffs, etc.<br><br> 1540 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1541 | <br><br> 1542 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1543 | <br><br> 1544 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1556 | 1557 | 1558 | 1559 | 1560 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1567 | 1568 | 1569 | 1570 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1581 | 1582 | 1583 | >NAME 1584 | >Value 1585 | 1586 | 1587 | <b>DPDT Slide Switch SMD</b> 1588 | www.SparkFun.com SKU : Comp-SMDS 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | >Name 1600 | >Value 1601 | 1602 | 1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | <h3>SparkFun Electronics' preferred foot prints</h3> 1634 | In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> 1635 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1636 | <br><br> 1637 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1638 | <br><br> 1639 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | >NAME 1651 | >VALUE 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1658 | 1659 | 1660 | <h3>SparkFun Electronics' preferred foot prints</h3> 1661 | In this library you'll find all manner of digital ICs- microcontrollers, memory chips, logic chips, FPGAs, etc.<br><br> 1662 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1663 | <br><br> 1664 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1665 | <br><br> 1666 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1667 | 1668 | 1669 | <b>Small Outline Transistor</b> 1670 | 1671 | 1672 | 1673 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | 1680 | 1681 | 1682 | >NAME 1683 | >VALUE 1684 | 1685 | 1686 | 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | 1693 | <h3>SparkFun Electronics' preferred foot prints</h3> 1694 | In this library you'll find discrete semiconductors- transistors, diodes, TRIACs, optoisolators, etc.<br><br> 1695 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1696 | <br><br> 1697 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1698 | <br><br> 1699 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1700 | 1701 | 1702 | <B>Diode</B><p> 1703 | Basic SMA packaged diode. Good for reverse polarization protection. Common part #: MBRA140 1704 | 1705 | 1706 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1713 | >NAME 1714 | >VALUE 1715 | 1716 | 1717 | 1718 | 1719 | 1720 | 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | 1727 | 1728 | 1729 | 1730 | 1731 | 1732 | 1733 | 1734 | 1735 | >NAME 1736 | >VALUE 1737 | 1738 | 1739 | 1740 | 1741 | <h3>SparkFun Electronics' preferred foot prints</h3> 1742 | In this library you'll find discrete LEDs for illumination or indication, but no displays.<br><br> 1743 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1744 | <br><br> 1745 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1746 | <br><br> 1747 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1748 | 1749 | 1750 | 1751 | 1752 | 1753 | 1754 | 1755 | 1756 | >NAME 1757 | >VALUE 1758 | 1759 | 1760 | 1761 | 1762 | <h3>SparkFun Electronics' preferred foot prints</h3> 1763 | In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> 1764 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1765 | <br><br> 1766 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1767 | <br><br> 1768 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1769 | 1770 | 1771 | Small solder jumper with no paste layer so it will open after reflow. 1772 | 1773 | 1774 | 1775 | 1776 | 1777 | 1778 | 1779 | 1780 | >NAME 1781 | >VALUE 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | >NAME 1796 | >VALUE 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | <h3>SparkFun Electronics' preferred foot prints</h3> 1803 | In this library you'll find boards and modules: Arduino footprints, breadboards, non-RF modules, etc.<br><br> 1804 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 1805 | <br><br> 1806 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ 1807 | <br><br> 1808 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 1809 | 1810 | 1811 | Uno R3 Compatible Board Layout 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | GND 1876 | GND 1877 | +5V 1878 | RST 1879 | VIN 1880 | +3.3V 1881 | 0 1882 | 1 1883 | 2 1884 | 3 1885 | 4 1886 | 5 1887 | Analog In 1888 | GND 1889 | 13 1890 | 12 1891 | 11 1892 | AREF 1893 | 10 1894 | 9 1895 | 8 1896 | 7 1897 | 6 1898 | 5 1899 | 4 1900 | 3 1901 | 2 1902 | TX 1903 | RX 1904 | 1905 | 1906 | SDA 1907 | SCL 1908 | 1909 | 1910 | IOREF 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | RST 1920 | ISP 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | <b>EAGLE Design Rules</b> 1936 | <p> 1937 | The default Design Rules have been set to cover 1938 | a wide range of applications. Your particular design 1939 | may have different requirements, so please make the 1940 | necessary adjustments and save your customized 1941 | design rules under a new name. 1942 | 1943 | 1944 | 1945 | 1946 | 1947 | 1948 | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2039 | 2040 | 2041 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2057 | 2058 | 2059 | 2060 | 2061 | 2062 | 2063 | 2064 | 2065 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2080 | 2081 | 2082 | 2083 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2105 | 2106 | 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | 2114 | 2115 | 2116 | 2117 | 2118 | 2119 | 2120 | 2121 | 2122 | 2123 | 2124 | 2125 | 2126 | 2127 | 2128 | 2129 | 2130 | 2131 | 2132 | 2133 | 2134 | 2135 | 2136 | 2137 | 2138 | 2139 | 2140 | 2141 | 2142 | 2143 | 2144 | 2145 | 2146 | 2147 | 2148 | 2149 | 2150 | 2151 | 2152 | 2153 | 2154 | 2155 | 2156 | 2157 | 2158 | 2159 | 2160 | 2161 | 2162 | 2163 | 2164 | 2165 | 2166 | 2167 | 2168 | 2169 | 2170 | 2171 | 2172 | 2173 | 2174 | 2175 | 2176 | 2177 | 2178 | 2179 | 2180 | 2181 | 2182 | 2183 | 2184 | 2185 | 2186 | 2187 | 2188 | 2189 | 2190 | 2191 | 2192 | 2193 | 2194 | 2195 | 2196 | 2197 | 2198 | 2199 | 2200 | 2201 | 2202 | 2203 | 2204 | 2205 | 2206 | 2207 | 2208 | 2209 | 2210 | 2211 | 2212 | 2213 | 2214 | 2215 | 2216 | 2217 | 2218 | 2219 | 2220 | 2221 | 2222 | 2223 | 2224 | 2225 | 2226 | 2227 | 2228 | 2229 | 2230 | 2231 | 2232 | 2233 | 2234 | 2235 | 2236 | 2237 | 2238 | 2239 | 2240 | 2241 | 2242 | 2243 | 2244 | 2245 | 2246 | 2247 | 2248 | 2249 | 2250 | 2251 | 2252 | 2253 | 2254 | 2255 | 2256 | 2257 | 2258 | 2259 | 2260 | 2261 | 2262 | 2263 | 2264 | 2265 | 2266 | 2267 | 2268 | 2269 | 2270 | 2271 | 2272 | 2273 | 2274 | 2275 | 2276 | 2277 | 2278 | 2279 | 2280 | 2281 | 2282 | 2283 | 2284 | 2285 | 2286 | 2287 | 2288 | 2289 | 2290 | 2291 | 2292 | 2293 | 2294 | 2295 | 2296 | 2297 | 2298 | 2299 | 2300 | 2301 | 2302 | 2303 | 2304 | 2305 | 2306 | 2307 | 2308 | 2309 | 2310 | 2311 | 2312 | 2313 | 2314 | 2315 | 2316 | 2317 | 2318 | 2319 | 2320 | 2321 | 2322 | 2323 | 2324 | 2325 | 2326 | 2327 | 2328 | 2329 | 2330 | 2331 | 2332 | 2333 | 2334 | 2335 | 2336 | 2337 | 2338 | 2339 | 2340 | 2341 | 2342 | 2343 | 2344 | 2345 | 2346 | 2347 | 2348 | 2349 | 2350 | 2351 | 2352 | 2353 | 2354 | 2355 | 2356 | 2357 | 2358 | 2359 | 2360 | 2361 | 2362 | 2363 | 2364 | 2365 | 2366 | 2367 | 2368 | 2369 | 2370 | 2371 | 2372 | 2373 | 2374 | 2375 | 2376 | 2377 | 2378 | 2379 | 2380 | 2381 | 2382 | 2383 | 2384 | 2385 | 2386 | 2387 | 2388 | 2389 | 2390 | 2391 | 2392 | 2393 | 2394 | 2395 | 2396 | 2397 | 2398 | 2399 | 2400 | 2401 | 2402 | 2403 | 2404 | 2405 | 2406 | 2407 | 2408 | 2409 | 2410 | 2411 | 2412 | 2413 | 2414 | 2415 | 2416 | 2417 | 2418 | 2419 | 2420 | 2421 | 2422 | 2423 | 2424 | 2425 | 2426 | 2427 | 2428 | 2429 | 2430 | 2431 | 2432 | 2433 | 2434 | 2435 | 2436 | 2437 | 2438 | 2439 | 2440 | 2441 | 2442 | 2443 | 2444 | 2445 | 2446 | 2447 | 2448 | 2449 | 2450 | 2451 | 2452 | 2453 | 2454 | 2455 | 2456 | 2457 | 2458 | 2459 | 2460 | 2461 | 2462 | 2463 | 2464 | 2465 | 2466 | 2467 | 2468 | 2469 | 2470 | 2471 | 2472 | 2473 | 2474 | 2475 | 2476 | 2477 | 2478 | 2479 | 2480 | 2481 | 2482 | 2483 | 2484 | 2485 | 2486 | 2487 | 2488 | 2489 | 2490 | 2491 | 2492 | 2493 | 2494 | 2495 | 2496 | 2497 | 2498 | 2499 | 2500 | 2501 | 2502 | 2503 | 2504 | 2505 | 2506 | 2507 | 2508 | 2509 | 2510 | 2511 | 2512 | 2513 | 2514 | 2515 | 2516 | 2517 | 2518 | 2519 | 2520 | 2521 | 2522 | 2523 | 2524 | 2525 | 2526 | 2527 | 2528 | 2529 | 2530 | 2531 | 2532 | 2533 | 2534 | 2535 | 2536 | 2537 | 2538 | 2539 | 2540 | 2541 | 2542 | 2543 | 2544 | 2545 | 2546 | 2547 | 2548 | 2549 | 2550 | 2551 | 2552 | 2553 | 2554 | 2555 | 2556 | 2557 | 2558 | 2559 | 2560 | 2561 | 2562 | 2563 | 2564 | 2565 | 2566 | 2567 | 2568 | 2569 | 2570 | 2571 | 2572 | 2573 | 2574 | 2575 | 2576 | 2577 | 2578 | 2579 | 2580 | 2581 | 2582 | 2583 | 2584 | 2585 | 2586 | 2587 | 2588 | 2589 | 2590 | 2591 | 2592 | 2593 | 2594 | 2595 | 2596 | 2597 | 2598 | 2599 | 2600 | 2601 | 2602 | 2603 | 2604 | 2605 | 2606 | 2607 | 2608 | 2609 | 2610 | 2611 | 2612 | 2613 | 2614 | 2615 | 2616 | 2617 | 2618 | 2619 | Since Version 6.2.2 text objects can contain more than one line, 2620 | which will not be processed correctly with this version. 2621 | 2622 | 2623 | 2624 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | SparkFun License Information 2 | ============================ 3 | 4 | SparkFun uses two different licenses for our files - one for hardware and one for code. 5 | 6 | Hardware 7 | --------- 8 | 9 | **SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).** 10 | 11 | Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode). 12 | 13 | You are free to: 14 | 15 | Share — copy and redistribute the material in any medium or format 16 | Adapt — remix, transform, and build upon the material 17 | for any purpose, even commercially. 18 | The licensor cannot revoke these freedoms as long as you follow the license terms. 19 | Under the following terms: 20 | 21 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. 22 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. 23 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. 24 | Notices: 25 | 26 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. 27 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. 28 | 29 | 30 | Code 31 | -------- 32 | 33 | **SparkFun code, firmware, and software is released under the [MIT License](http://opensource.org/licenses/MIT).** 34 | 35 | The MIT License (MIT) 36 | 37 | Copyright (c) 2015 SparkFun Electronics 38 | 39 | Permission is hereby granted, free of charge, to any person obtaining a copy 40 | of this software and associated documentation files (the "Software"), to deal 41 | in the Software without restriction, including without limitation the rights 42 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 43 | copies of the Software, and to permit persons to whom the Software is 44 | furnished to do so, subject to the following conditions: 45 | 46 | The above copyright notice and this permission notice shall be included in all 47 | copies or substantial portions of the Software. 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 50 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 51 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 52 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 53 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 54 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun MIDI Shield 2 | ==================== 3 | 4 | [![SparkFun MIDI Shield](https://cdn.sparkfun.com//assets/parts/9/7/9/8/12898-05.jpg)](https://www.sparkfun.com/products/12898) 5 | 6 | [*SparkFun MIDI Shield (DEV-12898)*](https://www.sparkfun.com/products/12898) 7 | 8 | The MIDI Shield gives your Arduino access to the MIDI communication protocol, so you can control synthesizers, sequencers, and other musical devices. 9 | 10 | Repository Contents 11 | ------------------- 12 | 13 | * **/Firmware** - Example Arduino .ino sketch 14 | * **/Hardware** - All Eagle design files (.brd, .sch) 15 | * **/Production** - Production panel files (.brd) 16 | 17 | Documentation 18 | -------------- 19 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/midi-shield-hookup-guide?_ga=1.24780723.863167751.1453149924)** - Basic hookup guide for the MIDI Shield. 20 | * **[SparkFun Fritzing repo](https://github.com/sparkfun/Fritzing_Parts)** - Fritzing diagrams for SparkFun products. 21 | * **[SparkFun 3D Model repo](https://github.com/sparkfun/3D_Models)** - 3D models of SparkFun products. 22 | * **[SparkFun Graphical Datasheets](https://github.com/sparkfun/Graphical_Datasheets)** -Graphical Datasheets for various SparkFun products. 23 | 24 | Product Versions 25 | ---------------- 26 | * [DEV-12898](https://www.sparkfun.com/products/12898)- Version 1.5. R3 compatible. Currently live. 27 | * [DEV-09595](https://www.sparkfun.com/products/retired/9595)- Version 1.3. Retired. 28 | 29 | Version History 30 | --------------- 31 | * [V_1.5](https://github.com/sparkfun/MIDI_Shield/tree/V_1.5) - GitHub snapshot at V_1.5. 32 | * [V_1.3](https://github.com/sparkfun/MIDI_Shield/tree/v1.3) - GitHub snapshot at V_1.3 33 | 34 | License Information 35 | ------------------- 36 | 37 | This product is _**open source**_! 38 | 39 | Please review the LICENSE.md file for license information. 40 | 41 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 42 | 43 | Distributed as-is; no warranty is given. 44 | 45 | \- Your friends at SparkFun. 46 | --------------------------------------------------------------------------------