-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsequencerfinal.ino
146 lines (130 loc) · 4.33 KB
/
sequencerfinal.ino
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
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <USBHost_t36.h>
#define LED_PIN 2
#define NUM_LEDS 16
#define BPM_MIN 50
#define BPM_MAX 180
#define START_STOP_PIN 12
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_RGB + NEO_KHZ800);
usb_midi_class myusbMIDI;
const uint8_t PCF_ADDRESSES_1[6] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
const uint8_t PCF_ADDRESSES_2[8] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27};
bool stepMatrix[16][7] = {0};
const uint8_t LINE_ORDER[7] = {3, 2, 1, 0, 6, 5, 4};
const int POT_PINS[7] = {A15, A1, A16, A17, A6, A7, A8};
uint8_t MIDI_NOTES[7] = {0, 8, 16, 24, 32, 40, 48};
int currentColumn = 0;
bool isRunning = false;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
void configurePCF(uint8_t address, TwoWire &bus);
void checkStartStopButton();
void updateMidiNotes();
int readBPM();
void readButtons();
void displayColumn(int column, int greenValue);
void sendMidiNotes(int column);
void setup() {
Serial.begin(115200);
Wire.begin();
Wire1.setSDA(17);
Wire1.setSCL(16);
Wire1.begin();
pinMode(START_STOP_PIN, INPUT_PULLUP);
strip.begin();
strip.show();
myusbMIDI.begin();
for (uint8_t i = 0; i < 6; i++) configurePCF(PCF_ADDRESSES_1[i], Wire);
for (uint8_t i = 0; i < 8; i++) configurePCF(PCF_ADDRESSES_2[i], Wire1);
}
void configurePCF(uint8_t address, TwoWire &bus) {
bus.beginTransmission(address);
bus.write(0xFF);
bus.endTransmission();
}
void loop() {
checkStartStopButton();
if (!isRunning) {
return;
}
updateMidiNotes();
int bpm = readBPM();
int stepDelay = (60000 / bpm) / 4;
int greenValue = map(bpm, BPM_MIN, BPM_MAX, 165, 50);
readButtons();
displayColumn(currentColumn, greenValue);
sendMidiNotes(currentColumn);
currentColumn = (currentColumn + 1) % 16;
delay(stepDelay);
}
void updateMidiNotes() {
for (int i = 0; i < 7; i++) {
int rawValue = analogRead(POT_PINS[i]);
MIDI_NOTES[i] = map(rawValue, 0, 1023, i * 8, (i * 8) + 7);
}
}
void checkStartStopButton() {
static bool lastButtonState = HIGH;
bool buttonState = digitalRead(START_STOP_PIN);
if (buttonState == LOW && lastButtonState == HIGH) {
isRunning = !isRunning;
Serial.println(isRunning ? "▶️ START" : "⏹️ STOP");
if (!isRunning) {
currentColumn = 0;
strip.clear();
strip.setPixelColor(0, strip.Color(0, 30, 120));
strip.setPixelColor(4, strip.Color(0, 30, 120));
strip.setPixelColor(8, strip.Color(0, 30, 120));
strip.setPixelColor(12, strip.Color(0, 30, 120));
strip.show();
}
}
lastButtonState = buttonState;
}
int readBPM() {
int rawValue = analogRead(A9);
return map(rawValue, 0, 1023, BPM_MIN, BPM_MAX);
}
void readButtons() {
for (uint8_t i = 0; i < 6; i++) {
Wire.requestFrom(PCF_ADDRESSES_1[i], (uint8_t)1);
if (Wire.available()) {
uint8_t state = Wire.read();
uint8_t colOffset = (i % 2) * 8;
uint8_t row = LINE_ORDER[4 + (i / 2)];
for (uint8_t col = 0; col < 8; col++) {
stepMatrix[colOffset + col][row] = (state & (1 << col)) ? 1 : 0;
}
}
}
for (uint8_t i = 0; i < 8; i++) {
Wire1.requestFrom(PCF_ADDRESSES_2[i], (uint8_t)1);
if (Wire1.available()) {
uint8_t state = Wire1.read();
uint8_t colOffset = (i % 2) * 8;
uint8_t row = LINE_ORDER[i / 2];
for (uint8_t col = 0; col < 8; col++) {
stepMatrix[colOffset + col][row] = (state & (1 << col)) ? 1 : 0;
}
}
}
}
void displayColumn(int column, int greenValue) {
strip.clear();
strip.setPixelColor(0, strip.Color(0, 30, 120));
strip.setPixelColor(4, strip.Color(0, 30, 120));
strip.setPixelColor(8, strip.Color(0, 30, 120));
strip.setPixelColor(12, strip.Color(0, 30, 120));
strip.setPixelColor(column, strip.Color(255, greenValue, 0));
strip.show();
}
void sendMidiNotes(int column) {
for (int row = 0; row < 7; row++) {
if (stepMatrix[column][row]) {
myusbMIDI.sendNoteOn(MIDI_NOTES[row], 127, 1);
delay(10);
myusbMIDI.sendNoteOff(MIDI_NOTES[row], 0, 1);
}
}
}