// +5V
// ST_CP 74HC595
#define latchPin 11
// SH_CP 74HC595
#define clockPin 13
// DS 74HC595
#define dataPin 12
// +5V
#define latchPin_IN 9
#define clockPin_IN 10
#define dataPin_IN 8
// , 1-16
#define BUT_OUT0 7
#define BUT_OUT1 6
#define BUT_OUT2 5
#define BUT_OUT3 4
byte but_out[4] = {BUT_OUT0, BUT_OUT1, BUT_OUT2, BUT_OUT3};
//
byte kbd_in[5] = {0, 0, 0, 0, 0};
byte kbd_in_new[5] = {0, 0, 0, 0, 0};
//
byte btn_in[4] = {0, 0, 0, 0};
byte btn_in_new[4] = {0, 0, 0, 0};
// 3 - (1 - , 0 - )
byte kbd_out = 0b11100000;
//
void init_electronics() {
// , +5V
// OUTPUT
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// , +5V
pinMode(latchPin_IN, OUTPUT);
pinMode(clockPin_IN, OUTPUT);
pinMode(dataPin_IN, INPUT);
//
for (byte i = 0; i < 4; i++) pinMode(but_out[i], OUTPUT);
}
// 74HC595
void write_5V(byte a) {
digitalWrite(latchPin, LOW);
// dataPin
shiftOut(dataPin, clockPin, MSBFIRST, a);
//"" ,
digitalWrite(latchPin, HIGH);
}
void read_5V(byte *btn, byte *kbd) {
digitalWrite(clockPin_IN, HIGH);
digitalWrite(latchPin_IN, LOW);
digitalWrite(latchPin_IN, HIGH);
// -
*btn = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
// -
*kbd = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
}
void setup() {
init_electronics();
write_5V(kbd_out);
Serial.begin(115200);
}
// ,
void read_kbd_and_btn_state(byte *btn, byte *kbd) {
byte tmp;
for (byte i = 0; i < 5; i++) {
write_5V(kbd_out | (1 << i));
read_5V(&tmp, &kbd[i]);
}
}
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(cmd);
Serial.write(pitch);
Serial.write(velocity);
}
// num ,
// 0 - 0, 0
// 1 - 0, 1
// 2 - 1, 1
// 3 - 1, 0
byte compare_bit(byte old_state, byte new_state, byte num) {
byte tmp_old, tmp_new;
tmp_old = (old_state >> num) & 1;
tmp_new = (new_state >> num) & 1;
if ((tmp_old == 0) && (tmp_new == 0)) return 0;
if ((tmp_old == 0) && (tmp_new == 1)) return 1;
if ((tmp_old == 1) && (tmp_new == 1)) return 2;
if ((tmp_old == 1) && (tmp_new == 0)) return 3;
}
void loop() {
read_kbd_and_btn_state(btn_in_new, kbd_in_new);
for (byte i = 0; i < 5; i++) {
for (byte j = 0; j < 8; j++) {
switch (compare_bit(kbd_in[i], kbd_in_new[i], 7 - j)) {
//
case 1: noteOn(0x90, 0x1D + (8 * i + j), 0x7F);
break;
//
case 2: //noteOn(0x00, 0x1D + (8 * i + j), 0x7F);
break;
//
case 3: noteOn(0x90, 0x1D + (8 * i + j), 0x00);
break;
}
}
kbd_in[i] = kbd_in_new[i];
}
}