Hilfe bei Arduino MIDI

Ist doch kein Problem , es eilt gar nicht , bin froh dass es mit diesem Projekt doch noch weiter geht , habe es schon Anfang 2024 begonnen , Platinen gefertigt , um zu Testen ob der ganz oben angefuegte code funktioniert . Das tat er aber nicht und so habe ich alles moegliche selbst probiert , bin aber auf Grund fehlender Programmierkentnisse nicht mehr weiter gekommen

Ich glaub ich habs:
grafik

Die Klammer unter der Codezeile muss ĂŒber die Codezeile.

MIDI Ausgabe funktioniert prima ,genau wie es soll , beim ersten druecken EIN , beim zweiten Aus , alle Taster , bin ganz froh damit ., die LEDS nicht , aber wie gesagt es eilt nicht

Ok, wenn die MIDI-Sequenzen laufen, dann geht auch das mit dem LED-Kram.
Denn:

          if (out.ch[chip].outPinState[pin] == ledOn)                      // Ist nicht gesetzt ?
          { noteOn(midiChannel, out.ch[chip].note[pin], anschlag); }       // Note senden
          else                                                             // War gesetzt ?
          { noteOff(midiChannel, out.ch[chip].note[pin], 0); }             // Note löschen

hier frage ich die LED-Kaskade ab und setze passend dazu die Note.
Wenn die Note geht, dann wird es an der Sequenz fĂŒr das einleiten der Übetragung auf den 595 liegen.
Schau ich nochmal drauf.

Wie ich mirs gedacht habe.
In void setLedState()
auch eine Klammer in falscherZeile.

Hier wÀre jetzt der gesamte Code:

[code] #include "MIDIUSB.h"

constexpr uint8_t shiftRegs {3}; // Anzahl ShiftRegister - IN und OUT sollen die gleiche Anzahl haben!
constexpr uint8_t pinsOnRegs {8}; // Anzahl Pins am Register - FĂŒr beide gleich!

constexpr bool isPressed {LOW}; // Vorbelegung Taste aktiv

constexpr bool ledOn {HIGH};
constexpr bool ledOff {!ledOn};

constexpr uint32_t debounceTime {50}; // Entprellzeit in ms / Abfrageintervall

constexpr uint8_t midiChannel {0};
constexpr uint8_t anschlag {127}; // MidiNote

struct CHIPIN // Input Chip 4021 - was zusammengehört
{
bool pinState[pinsOnRegs]; // Zustand der Taste - HIGH/LOW
bool lastPinState[pinsOnRegs]; // Letzter Zustand der Taste
};

constexpr uint8_t shiftClockPin {2}; // erklÀrt sich selbst

struct IN // Input Kaskade
{
static constexpr uint8_t latchPin {3};
static constexpr uint8_t dataPin {4};
uint32_t pinTime; // Zeitpunkt letzte Abfrage

CHIPIN ch[shiftRegs] =
{
{{0, 0, 0, 0, 0, 0, 0, 0, }, {0, 0, 0, 0, 0, 0, 0, 0, },}, // {pinStatus}, {lastPinStatus},
{{0, 0, 0, 0, 0, 0, 0, 0, }, {0, 0, 0, 0, 0, 0, 0, 0, },},
{{0, 0, 0, 0, 0, 0, 0, 0, }, {0, 0, 0, 0, 0, 0, 0, 0, },},
};
} in;

struct CHIPOUT // Output Kanal - was zusammengehört (und fĂŒr die gleiche Darstellung im Code)
{
bool outPinState[pinsOnRegs]; // 8 PIN je Chip - jeweils 1 LED
// HINWEIS: Ich habe mich gegen das durchzĂ€hlen entschieden Es kann fĂŒr jede Taste die Note festgelegt werden!
const uint8_t note[pinsOnRegs]; // Note die ausgegeben wird
};

struct OUT
{
static constexpr uint8_t latchPin {5};
static constexpr uint8_t dataPin {6};
CHIPOUT ch[shiftRegs] = // Wie IN
{
{{0, 0, 0, 0, 0, 0, 0, 0,}, {20, 21, 22, 23, 24, 25, 26, 27,},}, // {LED-Status}, {Note}
{{0, 0, 0, 0, 0, 0, 0, 0,}, {28, 29, 30, 31, 32, 33, 34, 35,},},
{{0, 0, 0, 0, 0, 0, 0, 0,}, {36, 37, 38, 39, 40, 41, 42, 43,},},
};
} out;

void setup()
{
Serial.begin(115200);
MidiUSB.flush(); // Initialize the MIDIUSB library
pinMode(shiftClockPin, OUTPUT);
digitalWrite(shiftClockPin, HIGH);
initShiftIn();
initShiftOut();
}

void loop()
{
if (millis() - in.pinTime > debounceTime)
{
getShiftInData();
setShiftOutData();
}

// Mididaten wiederholen?
}

void initShiftIn() // Initialisation und Vorbelegung
{
pinMode(in.latchPin, OUTPUT);
digitalWrite(in.latchPin, LOW);
pinMode(in.dataPin, INPUT);
getShiftInData();
}

void initShiftOut()
{
pinMode(out.latchPin, OUTPUT);
digitalWrite(out.latchPin, LOW);
pinMode(out.dataPin, OUTPUT);
digitalWrite(out.dataPin, LOW);
setShiftOutData();
}

void shiftReadStart() // Startsequenz zum lesen
{
digitalWrite(shiftClockPin, HIGH); // Vorbereitung zum Takten
digitalWrite(in.latchPin, HIGH); // Vorbereiten zum auslesen
delayMicroseconds(20);
digitalWrite(in.latchPin, LOW);
}

void shiftTakt()
{
digitalWrite(shiftClockPin, LOW); // Takt zum schieben
delayMicroseconds(2);
digitalWrite(shiftClockPin, HIGH);
}

void getShiftInData() // Liest alle Register ein
{
shiftReadStart();

for (uint8_t chip = 0; chip < shiftRegs; chip++) // ZĂ€hle durch die Chips
for (uint8_t pin = 0; pin < pinsOnRegs; pin++) // ZĂ€hle die Pins je Chip
{
in.ch[chip].pinState[pin] = digitalRead(in.dataPin); // Status ĂŒbernehmen
shiftTakt();
}

in.pinTime = millis(); // Auslesezeit merken
} // Alle Pins ausgelesen

void setLedState()
{
digitalWrite(shiftClockPin, LOW);
digitalWrite(out.dataPin, LOW);
digitalWrite(shiftClockPin, LOW);

for (uint8_t chip = 0; chip < shiftRegs; chip++) // ZĂ€hle durch die Chips
{
for (uint8_t pin = 0; pin < pinsOnRegs; pin++) // ZĂ€hle die Pins je Chip
{
digitalWrite(shiftClockPin, LOW);
digitalWrite(out.dataPin, out.ch[chip].outPinState[pin]);
digitalWrite(shiftClockPin, HIGH);
digitalWrite(out.dataPin, LOW);
}
}

digitalWrite(shiftClockPin, LOW);
digitalWrite(out.latchPin, HIGH);
}

void setShiftOutData()
{
bool isNew = false;

for (uint8_t chip = 0; chip < shiftRegs; chip++) // ZĂ€hle durch die Chips
{
for (uint8_t pin = 0; pin < pinsOnRegs; pin++) // ZĂ€hle die Pins je Chip
{
if (in.ch[chip].pinState[pin] != in.ch[chip].lastPinState[pin]) // Das BIT hat sich geÀndert?
{
if (in.ch[chip].pinState[pin] == isPressed) // Taste gedrĂŒckt?
{
out.ch[chip].outPinState[pin] = !out.ch[chip].outPinState[pin];

      if (out.ch[chip].outPinState[pin] == ledOn)                      // Ist nicht gesetzt ?
      { noteOn(midiChannel, out.ch[chip].note[pin], anschlag); }       // Note senden
      else                                                             // War gesetzt ?
      { noteOff(midiChannel, out.ch[chip].note[pin], 0); }             // Note löschen

      isNew = true;
    }
  }

  in.ch[chip].lastPinState[pin] = in.ch[chip].pinState[pin];           // Status merken
}

}

if (isNew)
{ setLedState(); }
}

void controlChange(byte channel, byte control, byte value)
{
byte chan = 0xB0 | channel;
midiEventPacket_t event = {0x0B, chan, control, value};
MidiUSB.sendMIDI(event);
MidiUSB.flush();
}

void noteOn(byte channel, byte pitch, byte velocity)
{
byte chan = 0x90 | channel;
midiEventPacket_t noteOn = {0x09, chan, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
MidiUSB.flush();
}

void noteOff(byte channel, byte pitch, byte velocity)
{
byte chan = 0x80 | channel;
midiEventPacket_t noteOff = {0x08, chan, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
MidiUSB.flush();
}
[/code]

Mal sehen, obs funkioniert....

Und dann war da noch eine Frage offen:

Nein.
Der erste Wert ist der Channel, auf dem das empfangende GerÀt hört.
Ich habe in meinem Code eine Konstante:
constexpr uint8_t midiChannel {0};

Die wird verknĂŒpft mit der Vorgabe, wo gestartet wird:

          { noteOn(midiChannel, out.ch[chip].note[pin], anschlag); }       // Note senden

hier wird ĂŒbergeben

und hier wird ĂŒbernommen:


void noteOn(byte channel, byte pitch, byte velocity)
{
  byte chan = 0x90 | channel;

Und dann ist da noch die Frage, ob die Kommentare von mir ausreichend und verstÀndlich sind?

nach dem hochladen leuchteten alle 8 LED-s auf dem ersten Schieberegister ( bei den anderen habe ich das nicht geprueft , danach habe ich den ersten Taster betaetigt und alle 8 gingen aus , danach leuchtet keine mehr auch bei Betaetigung der Taster , MIDI wird korrekt ausgegeben

Ach schau..
Es tut sich was :slight_smile:
Vielleicht latch und clock vertan...
Dauert nen Moment...

Tausche mal die Funktion aus:

void setLedState()
{
  digitalWrite(shiftClockPin, LOW);
  digitalWrite(out.dataPin, LOW);
  digitalWrite(shiftClockPin, LOW);

  for (uint8_t chip = 0; chip < shiftRegs; chip++)     // ZĂ€hle durch die Chips
  {
    for (uint8_t pin = 0; pin < pinsOnRegs; pin++)     // ZĂ€hle die Pins je Chip
    {
      digitalWrite(out.dataPin, out.ch[chip].outPinState[pin]);
      digitalWrite(shiftClockPin, HIGH);
      digitalWrite(shiftClockPin, LOW);
      digitalWrite(out.dataPin, LOW);
    }
  }

  digitalWrite(out.latchPin, HIGH);
  digitalWrite(out.latchPin, LOW);
}

Ach Kacke!

 digitalWrite(shiftClockPin, LOW);

Eine von den zeilen muss auf den latchPin gesetzt werden!!!!

  digitalWrite(out.latchPin, LOW);

es ist immer noch so wie vorher , nach upload leuchten alle , nachTaster druecken alle aus und nicht mehr an

jetzt ist nach upload die erste LED an , die nach Tasterbetaetigung aus geht , danach geht keine mehr an

Kannst Du den Seriellen Monitor nutzen, wenn ich das debuggen will?

ja klar

egal welche Taste ich druecke , es kommt keine Info am seriellen Monitor

Logisch :slight_smile:
HIer kommt jetzt was:

void setLedState()
{
  Serial.println(F("LED-OUT Start"));
  Serial.print(F("LED-Data: "));
  digitalWrite(shiftClockPin, LOW);
  digitalWrite(out.dataPin, LOW);
  digitalWrite(shiftClockPin, LOW);

  for (uint8_t chip = 0; chip < shiftRegs; chip++)     // ZĂ€hle durch die Chips
  {
    for (uint8_t pin = 0; pin < pinsOnRegs; pin++)     // ZĂ€hle die Pins je Chip
    {
      Serial.print(out.ch[chip].outPinState[pin]);
      Serial.print(", ");
      digitalWrite(out.dataPin, out.ch[chip].outPinState[pin]);
      digitalWrite(shiftClockPin, HIGH);
      digitalWrite(shiftClockPin, LOW);
      digitalWrite(out.dataPin, LOW);
    }
  }

  Serial.println(F("\r\nLED-OUT END\r\n"));
  digitalWrite(out.latchPin, HIGH);
  digitalWrite(out.latchPin, LOW);
}

Und ich schau mal zwischendurch, das ich mal ein Blick ins Datenblatt tÀtige....
Mit jedem auslösendem Tastendruck sollten jetzt die tatsÀchlchen 24 LED-Stati angezeigt werden.

beim schalten des ersten und des zweiten Tasters , jeweils einmal ein , dann aus

Das passt.
In Zeile 2 ist es bit 7 - also Chip 1 - letzter Pin
Zeile 3 ist der wieder aus.
Zeile 4 bit 6 - Chip 1
Zeile 5 ebenso

Ich hadere noch mit der 1
Das ist Chip 2 - bit 7
Da wir falsch rum zÀhlen, wÀre es Chip 2 der erste Pin.
Kannst Du mal schaun, ob da die Kontakte alle richtig sind?

Und ich such mal, warum das nicht so ausgegeben wird.
Ich mach das leider alles ohne Hardware - da dauerts eben....

Anscheinend ist etwas verkehrt , aber das wuerde mich nicht stoeren , Ihr code funktioniert jetzt , aber das erste Input schieberegister steuert anscheinend den Ausgang de dritten Led IC-s

es ist auch so in Ordnung , dann stecke ich eben die Ausgaenge so wie es jetzt ist