You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

129 lines
3.3 KiB

/*
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 <Arduino.h>
#include <SoftwareSerial.h>
#include <avr/interrupt.h>
#include <avr/io.h>
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);
// }
}