/* Blink Turns an LED on for one second, then off for one second, repeatedly. Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to the correct LED pin independent of which board is used. If you want to know what pin the on-board LED is connected to on your Arduino model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products modified 8 May 2014 by Scott Fitzgerald modified 2 Sep 2016 by Arturo Guadalupi modified 8 Sep 2016 by Colby Newman This example code is in the public domain. https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink */ #include #include #include #include SoftwareSerial midi_uart(10, 11); // RX, TX const double bpm = 140.0; const int led1_pin = 7; const int led2_pin = 9; const int ext_clock_pin = 5; unsigned int reload = 0xF424; volatile unsigned long count = 0; volatile int state = HIGH; int md_notes[16] = {36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62}; volatile unsigned long count_last[8] = {0, 0, 0, 0, 0, 0, 0, 0}; void flash1() { static boolean output = HIGH; digitalWrite(led1_pin, output); output = !output; } void flash2() { static boolean output = HIGH; digitalWrite(led1_pin, output); output = !output; } void ext_clock_pulse() { flash2(); } void setup() { // Console Serial.begin(115200); // LED pinMode(led1_pin, OUTPUT); digitalWrite(led1_pin, LOW); pinMode(led2_pin, OUTPUT); digitalWrite(led2_pin, LOW); // BUT pinMode(ext_clock_pin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ext_clock_pin), ext_clock_pulse, CHANGE); midi_uart.begin(31250); cli(); TCCR1A = 0; TCCR1B = 0; OCR1A = reload; // TCCR1B = (1 << WGM12) | (1 << CS11); // SLOW TCCR1B = (1 << WGM12) | (1 << CS10); // FAST TIMSK1 = (1 << OCIE1A); sei(); // Serial.println("TIMER1 Setup Finished."); } int div_to_clk(float div) { double clk_pulse_per_second = 40.; double beat_per_bar = 4.; double bar_ns = 60. / bpm * beat_per_bar * clk_pulse_per_second; double d_c = bar_ns / div; return d_c; } void noteOn(int cmd, int pitch, int velocity) { midi_uart.write(cmd); midi_uart.write(pitch); midi_uart.write(velocity); } // void subdiv(unsigned int count, unsigned int div, unsigned int md_note_nr) { // if (count % div == 0) { // noteOn(0x90, md_notes[md_note_nr], 0x64); // } // } void subdiv(unsigned int count, unsigned int div, unsigned int md_note_nr) { if (count >= count_last[div] + div_to_clk(div)) { count_last[div] = count; noteOn(0x90, md_notes[md_note_nr], 0x64); } } ISR(TIMER1_COMPA_vect) { count++; // flash1(); for (int i = 0; i < 8; i++) { subdiv(count, i + 1, i); } } void loop() { Serial.println(count); // do anything delay(200); // digitalWrite(LED_pin, state); // // play notes from F#-0 (0x1E) to F#-5 (0x5A): // for (int note = 0x1E; note < 0x5A; note++) { // // Note on channel 1 (0x90), some note value (note), middle velocity // (0x45): noteOn(0x90, note, 0x45); delay(1000); // // Note on channel 1 (0x90), some note value (note), silent velocity // (0x00): noteOn(0x90, note, 0x00); delay(100); // } }