erledigt Arduino als DCO - aktualisiert

Das Thema wurde geklärt (die eigentliche Frage des Threads ist beantwortet)
Baugruppe funktioniert, die Oktavreinheit lässt in den oberen Lagen nach. Ursache ist die Dividerberechnung für den 8-bit-Timer mit Vorteiler.
Frequenzen mit Multimeter nachgemessen und die Frequenzliste per Dreisatz als Iteration korrigiert.
Habe als Dateityp WORD genommen.

TUNE funktioniert über einen AnalogIN, ein bißchen Mathe mit Fliesskomma :)
Der DAC für SAW ist ebenfalls keine Liste, sondern eine Formel, Kennlinie ist ja linear und kleine Abweichungen wirken sich nur unwesentlich auf den Pegel aus.

arduino-dco.gif

// MIDI DCO w/ tone(); & saw DAC

#include <SPI.h>

// pins
byte note = 8; // note pin
byte cs = 10; // DAC CS pin
byte gate = 4; // gate pin
byte mute = 5; // mute the SAW
byte s0 = 6; // 4512 S0
byte s1 = 7; // 4512 S1
// values
float tune; // tune value
int pot; // tune pot
word value; // actual DAC value
byte mid[3]; // MIDI data
byte midimin = 12; // min. MIDI note
byte midimax = 96; // max. MIDI note

const word freq[]{0,
523,554,587,622,659,698,740,784,831,880,932,988,
1047,1109,1175,1245,1319,1397,1480,1568,1661,1760,1865,1976,
2093,2217,2349,2489,2637,2794,2960,3136,3322,3520,3729,3951,
4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902,
4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902,
4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902,
4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902,
8372};

const byte divider[]{0,
3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,
2,2,2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,
0};


void setup()
{
pinMode(cs,OUTPUT);
pinMode(gate,OUTPUT);
pinMode(note,OUTPUT);
pinMode(A0,INPUT);
pinMode(mute,OUTPUT);
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);

digitalWrite(gate,LOW);
digitalWrite(cs,HIGH);
digitalWrite(mute,LOW);

Serial.begin(31250);
SPI.begin();
DAC(0);
}

void DAC(word value)
{
digitalWrite(cs,LOW);
SPI.beginTransaction(SPISettings(4000000,MSBFIRST,SPI_MODE0));
bitWrite(value,15,LOW); // bit 15 - dual DAC selector - LOW
bitWrite(value,14,LOW); // bit 14 - buffer - LOW
bitWrite(value,13,HIGH); // bit 13 - double GAIN - HIGH
bitWrite(value,12,HIGH); // bit 12 - output shut down - HIGH
SPI.transfer(highByte(value));
SPI.transfer(lowByte(value));
SPI.endTransaction();
digitalWrite(cs,HIGH);
bitClear(value,15);
bitClear(value,14);
bitClear(value,13);
bitClear(value,12);
}

// noteOn = 144
// noteOff = 128

void loop()
{
midicomm:
if (Serial.available() == 1)
{
mid[0] = Serial.read();
if (bitRead(mid[0],7) == HIGH && bitRead(mid[0],6) == LOW && bitRead(mid[0],5) == LOW) goto midinote;
}
else
{
goto midicomm;
}

midinote:
if (Serial.available() == 1)
{
mid[1] = Serial.read();
if (bitRead(mid[1],7) == HIGH && bitRead(mid[1],6) == LOW && bitRead(mid[1],5) == LOW)
{
mid[0] = mid[1];
goto midinote;
}
pot = (analogRead(A0) / 4) - 128 ;
tune = 1 / ((float(pot) / 1100) + 1);
}
else
{
goto midinote;
}

midivol:
if (Serial.available() == 1)
{
mid[2] = Serial.read();
if (bitRead(mid[2],7) == HIGH && bitRead(mid[2],6) == LOW && bitRead(mid[2],5) == LOW)
{
mid[0] = mid[2];
goto midinote;
}
}
else
{
goto midivol;
}

if (bitRead(mid[0],4) == HIGH && mid[2] > 0 && mid[1] >= midimin && mid[1] <= midimax)
{
// note ON
tone(note,word(freq[mid[1] - midimin + 1] * tune));
value = ((mid[1] - midimin + 1) * 34) + 1000 ;
DAC(value);
digitalWrite(s0,bitRead(divider[mid[1] - midimin + 1],0));
digitalWrite(s1,bitRead(divider[mid[1] - midimin + 1],1));
digitalWrite(gate,HIGH);
digitalWrite(mute,HIGH);
}
else
{
// note OFF
digitalWrite(mute,LOW);
digitalWrite(gate,LOW);
noTone(note);
DAC(0);
digitalWrite(s0,LOW);
digitalWrite(s1,LOW);
}
}

 
Zuletzt bearbeitet:


Zurück
Oben