ciao ragazzi,
documentandomi su internet ho visto un po di progetti riguardanti la trasformazione di una pianola giocattolo, in un device MIDI per mandare segnali al pc
per farvi capire vi rimando a questo video: https://www.youtube.com/watch?v=lXX8v-ZW6Tk
ovviamente il tutto si basa sullo scan matrix dei fili dei tasti del piano, quindi bisogna programmare arduino per fare in modo che interpreti questi segnali, quindi alla pressione del tasto desiderato deve mandare in output la nota musicale desiderata mediante la porta midi.
vi spiego il mio problema:
possiedo arduino uno originale e una pianola Casio con 49 tasti, suddivisi in 15 fili (uno scan matrix di 6 colonne e 9 righe - come da foto)
(tenete in considerazione solo il numero dei fili scritti a penna e le note evidenziate)
nel video utilizza il metodo dello shift register, con l'integrato 74hc595, per demoltiplicare il numero di colonne e utilizzare solo gli ingressi digitali di arduino.
io ho modificato il programma adattandolo alla mia tastiera, gli output funzionano e il pc riceve i segnali midi, il problema è che le note che arrivano al pc non sono quelle che sto premendo! (ad esempio se suono un DO, al pc arriva un SOL
Vi lascio il codice che ho utilizzato:
#define NUM_ROWS 9
#define NUM_COLS 6#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define NOTE_VELOCITY 127//MIDI baud rate
#define SERIAL_RATE 31250// Pin Definitions
// Row input pins
const int row1Pin = 2;
const int row2Pin = 3;
const int row3Pin = 4;
const int row4Pin = 5;
const int row5Pin = 6;
const int row12Pin = 7;
const int row13Pin = 8;
const int row14Pin = 9;
const int row15Pin = 10;// 74HC595 pins
const int dataPin = 11;
const int latchPin = 12;
const int clockPin = 13;boolean keyPressed[NUM_ROWS][NUM_COLS];
uint8_t keyToMidiMap[NUM_ROWS][NUM_COLS];// bitmasks for scanning columns
int bits[] =
{
B11111110,
B11111101,
B11111011,
B11110111,
B11101111,
B11011111,
B10111111,
B01111111
};void setup()
{
int note = 36;for(int colCtr = 0; colCtr < NUM_COLS; ++colCtr)
{
for(int rowCtr = 0; rowCtr < NUM_ROWS; ++rowCtr)
{
keyPressed[rowCtr][colCtr] = false;
keyToMidiMap[rowCtr][colCtr] = note;
note++;
}
}// setup pins output/input mode
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);pinMode(row1Pin, INPUT);
pinMode(row2Pin, INPUT);
pinMode(row3Pin, INPUT);
pinMode(row4Pin, INPUT);
pinMode(row5Pin, INPUT);
pinMode(row12Pin, INPUT);
pinMode(row13Pin, INPUT);
pinMode(row14Pin, INPUT);
pinMode(row15Pin, INPUT);Serial.begin(SERIAL_RATE);
}void loop()
{
for (int colCtr = 0; colCtr < NUM_COLS; ++colCtr)
{
//scan next column
scanColumn(colCtr);//get row values at this column
int rowValue[NUM_ROWS];
rowValue[0] = !digitalRead(row1Pin);
rowValue[1] = !digitalRead(row2Pin);
rowValue[2] = !digitalRead(row3Pin);
rowValue[3] = !digitalRead(row4Pin);
rowValue[4] = !digitalRead(row5Pin);
rowValue[5] = !digitalRead(row12Pin);
rowValue[6] = !digitalRead(row13Pin);
rowValue[7] = !digitalRead(row14Pin);
rowValue[8] = !digitalRead(row15Pin);// process keys pressed
for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
{
if(rowValue[rowCtr] != 0 && !keyPressed[rowCtr][colCtr])
{
keyPressed[rowCtr][colCtr] = true;
noteOn(rowCtr,colCtr);
}
}// process keys released
for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
{
if(rowValue[rowCtr] == 0 && keyPressed[rowCtr][colCtr])
{
keyPressed[rowCtr][colCtr] = false;
noteOff(rowCtr,colCtr);
}
}
}
}void scanColumn(int colNum)
{
digitalWrite(latchPin, LOW);if(0 <= colNum && colNum <= 7)
{
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum]); //left sr
}
else
{
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum-8]); //right sr
}digitalWrite(latchPin, HIGH);
}void noteOn(int row, int col)
{
Serial.write(NOTE_ON_CMD);
Serial.write(keyToMidiMap[row][col]);
Serial.write(NOTE_VELOCITY);
}void noteOff(int row, int col)
{
Serial.write(NOTE_OFF_CMD);
Serial.write(keyToMidiMap[row][col]);
Serial.write(NOTE_VELOCITY);
}
Secondo me il problema è nella gestione dello shift register (io ne uso uno, a differenza dei due utilizzati nel progetto del video, e molto probabilmente sbaglio qualcosa nel codice
sapreste darmi una mano a trovare l'errore?
questa è una foto del prototipo:
NB: i collegamenti sono tutti corretti, lo scan matrix è stato rilevato correttamente sia dal manuale della pianola, che da me personalmente utilizzando il tester
PS:
Ho scoperto che gli ingressi analogici di arduino possono essere utilizzati anche come ingressi digitali, semplicemente chiamandoli come segue:
A0 = pin14
A1 = pin15
A2 = pin16
A3 = pin 17
A4 = pin18
A5 = pin19
quindi volendo, si potrebbe fare a meno di usare lo shift register per demoltiplicare le colonne, visto che così avrei sufficienti input per tutti e 15 i fili del piano
secondo voi in questo modo come faccio a programmare arduino per inviare le note al pc?