// Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC #include #include Adafruit_MCP4728 mcp; float tuning[13]; int m1[] = { 0, 5, 5, 7, 5, 4, 2, 2, 2, 7, 7, 9, 7, 5, 4, 0, 4, 9, 9, 10, 9, 7, 5, 2, 0, 0, 2, 7, 4, 5, 0, 5, 5, 5, 4, 4, 5, 4, 2, 0, 7, 9, 7, 7, 5, 5, 12, 0, 0, 0, 2, 7, 4, 5 }; float d1[] = { 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 4 }; float gate = 0.5; int bpm = 240; float beat_s = 60.0 / (float)bpm; int beat_m = round(1000.0 * beat_s); float voltrange = 5.0; float octave = 4096.0 / voltrange; // number of DAC steps in an octave float mod_b = 3.141592653589793 / 4.0; typedef struct { int s = 0; bool noteOn = false; long play = 0; long rel = 0; long last = 0; long init = 0; int *melody; float *duration; int len = 0; MCP4728_channel_t pitch; MCP4728_channel_t gate; } sequencer; sequencer seq1, seq2; void setup(void) { Serial.begin(115200); while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens if (!mcp.begin(0x64)) { Serial.println("Failed to find MCP4728 chip"); while (1) { delay(10); } Serial.println("MCP4728 initialised"); } mcp.setChannelValue(MCP4728_CHANNEL_B, 0); float n0 = 0; for( int i = 0; i < 13; i++ ) { tuning[i] = round(n0 + octave * (float)i / 12.0); } long now = millis(); seq1.last = now; seq1.pitch = MCP4728_CHANNEL_A; seq1.gate = MCP4728_CHANNEL_B; seq1.melody = m1; seq1.duration = d1; seq1.len = sizeof(m1) / sizeof(m1[0]); Serial.println("length of seq 1 pattern"); Serial.println(seq1.len); // seq2.last = now; // seq2.pitch = MCP4728_CHANNEL_C; // seq2.gate = MCP4728_CHANNEL_D; } void loop() { long now = millis(); runSequencer(seq1, now); Serial.println(seq1.noteOn); } void runSequencer(sequencer seq, long now) { if( seq.noteOn ) { if( now - seq.last > seq.rel ) { Serial.println("off"); noteOff(seq); seq.last = now; seq.play = round(beat_m * seq.duration[seq.s] * (1.0 - gate)); seq.noteOn = false; seq.s += 1; if( seq.s > seq.len ) { seq.s = 0; } } } else { if( now - seq.last > seq.play ) { noteOn(seq, seq.melody[seq.s]); seq.last = now; seq.rel = round(beat_m * seq.duration[seq.s] * gate); seq.noteOn = true; } } } void noteOn(sequencer seq, int note) { if( note > -1 ) { mcp.setChannelValue(seq.pitch, tuning[note]); mcp.setChannelValue(seq.gate, 4095); } } void noteOff(sequencer seq) { mcp.setChannelValue(seq.gate, 0); }