After some time with the other sequencers I got I learned what I wanted in a performance device and it seemed an arp is what I need. This build is straight forward but there are a lot of connections to mess up so… ๐ฌ๐

Link to YMNKs Page: Here
Github repo with Version I built: Here

BOM
- 2x Jack female output
- 1x Arduino Nano
- 1x MCP4725
- 14x switches (12 for the notes, 2 for the arp mode)
- 2x 10k resistors
- 1x 100k resistor
- 1x 1k resistor
- 2x Diode 1n5817 (schottky diode)
- 2x 10k potentiometer (4.7 k or 100k is Ok too) for the range and bias control
#include <Wire.h>
#include <Adafruit_MCP4725.h>
#define NOTE_COUNT 12
#define MAX_NOTE 48
enum eMode {
up = 0,
down,
upAndDown,
arpRandom
};
Adafruit_MCP4725 dac;
bool notes[NOTE_COUNT];
int clockState = LOW;
int iterator = 0;
bool goUp = false;
enum eMode mode = arpRandom;
void setup(void) {
Serial.begin(9600);
// For Adafruit MCP4725A1 the address is 0x62 (default) or 0x63 (ADDR pin tied to VCC)
// For MCP4725A0 the address is 0x60 or 0x61
// For MCP4725A2 the address is 0x64 or 0x65
dac.begin(0x62);
for (uint8_t i = 0; i < NOTE_COUNT; i++) {
notes[i] = false;
}
//Clock pin
//pinMode(0,INPUT);
for (int i = 2; i <= 13; i++) {
pinMode(i,INPUT);
}
}
int noteToVolt(int noteIn) {
return (int)round(((float)(4095.0/5.0)/12.0) * noteIn);
}
void loop(void) {
int newClockState = analogRead(0) > 200;
int startPot = analogRead(1);
int rangePot = analogRead(6);
int noteRange = (int)fmin(round(rangePot/21.), (double)MAX_NOTE);
int minRange = (int)fmin(round(startPot/21.), (double)MAX_NOTE);
int maxRange = (int)fmin(minRange + noteRange, (double)MAX_NOTE);
bool modeSwitchUp = analogRead(2) > 500;
bool modeSwitchDown = analogRead(3) > 500;
//Serial.println(analogRead(0));
enum eMode mode;
if (modeSwitchUp && modeSwitchDown) {
mode = upAndDown;
} else if (modeSwitchUp && !modeSwitchDown) {
mode = up;
} else if (!modeSwitchUp && modeSwitchDown) {
mode = down;
} else {
mode = arpRandom;
}
for (int i = 2; i <= 13; i++) {
pinMode(i,INPUT);
int n = 13 - i;
//I inverted pin 6 and 5 ... shame on me
if (n == 6) {
n = 5;
} else if (n == 5) {
n = 6;
}
notes[n] = digitalRead(i) == HIGH;
}
bool trueNoteExist = false;
//if all notes false, all notes true
for (int i = 0; i < NOTE_COUNT; i++) {
trueNoteExist = trueNoteExist || notes[i];
}
if (!trueNoteExist) {
for (int i = 0; i < NOTE_COUNT; i++) {
notes[i] = true;
}
}
//compute min and max note
int minNote = MAX_NOTE;
int maxNote = 0;
for (int i = minRange; i <= maxRange; i++) {
if (notes[i%NOTE_COUNT]) {
if (i < minNote) {
minNote = i;
}
if (i > maxNote) {
maxNote = i;
}
}
}
if (minNote > maxNote) {
for (int i = minRange; i <= MAX_NOTE; i++) {
if (notes[i%NOTE_COUNT]) {
minNote = i;
maxNote = i;
break;
}
}
}
if (mode == arpRandom) {
iterator = random(minNote, maxNote+1);
mode = random(100) > 50 ? up : down;
}
if (newClockState != clockState) {
clockState = newClockState;
if (newClockState == HIGH) {
for (int i = minNote; i <= maxNote; i++) {
switch (mode) {
case up: {
iterator++;
goUp = true;
if (iterator > maxNote) {
iterator = minNote;
}
}
break;
case down: {
iterator--;
goUp = false;
if (iterator < minNote) {
iterator = maxNote;
}
}
break;
case upAndDown: {
if (goUp) {
iterator++;
if (iterator > maxNote) {
iterator = maxNote-1;
goUp = false;
}
} else {
iterator--;
if (iterator < minNote) {
iterator = minNote+1;
goUp = true;
}
}
}
break;
default:
break;
}
iterator = fmin(fmax(iterator, minNote), maxNote);
if (notes[iterator%NOTE_COUNT]) {
break;
}
}
int volt = noteToVolt(iterator);
dac.setVoltage(volt, false);
}
}
}
