Array mit NRF24L01 versenden (Funk-MIDI-Controller)

Hallo zusammen,

mein Projekt ist ein MIDI-Controller, der schlicht Potis und Buttons ausliest, auswertet und über Serial an einen MIDI->USB Converter weiterleitet. Soweit funktioniert das auch alles.

Nun möchte ich aber den Controller kabellos haben, wofür ich den eigentlichen Code der aus den Blöcken Auswertung und Verarbeitung besteht, in diese aufteile, den Transmitter die Auswertung und den Reciever die Verarbeitung übernehmen lasse.

Theoretisch nichts schwieriges, aber in der Praxis funktioniert nichts.

Ich habe beide Funkmodule mit den Beispiel Sketches getestet und "Hello World" problemlos übertragen. Dazu sind 10µF Elkos zwischen Vcc und GND und die Übertragungsstärke ist auf MIN.

Die Auswertung geschieht einfach durch einen for-loop der MUX-Eingänge abklappert und Potis wie Buttons in je einem Array sichert.

Mein ursprünglicher Ansatz war es die radio.write()-Funktion in den for-loop zu integrieren und die Array-Indizies einzeln, und nur falls sie sich geändert haben zu senden. Dafür bin ich davon ausgegangen, dass wenn eine bestimmte Index-Position via radio.write() gesendet wird, die Position mitgesendet wird - das ist aber wohl nicht der Fall.

Dann habe ich versucht den Indexcounter zu übermitteln, um die empfangenen Daten der entsprechendem Index# zuzuordnen, aber dabei wird schlicht der for-loop im Tx angehalten und nichts weiter passiert. Meine Vermutung ist, dass die Übertragung länger dauert als die einzelne for-loop-Iteration.

Der zweite Ansatz war, einfach die ganzen Arrays zu senden, nachdem sie vom for-loop im Tx gefüllt wurden, und dann im Rx auszuwerten. Das funktioniert nicht, warum auch immer.
Ich frage mich was hier der Unterschied zwischen dem Beispiel

if(radio.available){const char text[] = "Hello World";
radio.write(&text, sizeof(text));}

und meiner Implementierung:

if(radio.available){
int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
radio.write(&PotiVal, sizeof(PotiVal));}

ist, wobei ich das Array "PotiVal" schon am Anfang deklariere. Allerdings funktioniert auch der Beispielcode, wenn ich "const char text[] = "Hello World";" schon am Anfang deklariere.

Mein dritter und umständlichster Ansatz ist, das Array nachdem es erstellt wurde, in Einzelvariablen zu sichern, jede Einzelvariable mit radio.write zu versenden, und alle im Rx wieder zu einem Array zusammenzusetzten. Auch das funktioniert nicht.

Die kompletten Codes für Tx & Rx sind im Anhang, ich hätte sonst das Zeichenlimit gesprengt.
Implementiert ist nur der Ansatz die Arrays als ganzes zu senden. Der Rest ist auskommentiert, bzw. der Ansatz im for-loop die jeweiligen Indizies zu senden ist gar nicht mehr implementiert.

Ich danke für jegliche Hilfe im Voraus und bitte um erbarmen. Das ist mein erstes Programmier-Projekt.

Grüße, Tilman

TxArdCC.ino (7.28 KB)

RxArdCC.ino (1.62 KB)

Das nimmt Dir der Compiler ab?

int char text[] = "Hello World";

Was soll das sein?

Gruß Tommy

Das ist aus einem Beispiel im Internet. Es funktioniert jedenfalls und über

radio.read(&text, sizeof(text));
Serial.print(text);

. gibt der Rx über Serial "Hello World" aus.

Edit: https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/ Hier habe ich den Beispielcode her.

  • Mein Fehler: es ist const char text[] nicht int char text[].

RxArdCC.ino (1.62 KB)

TxArdCC.ino (7.28 KB)

if(radio.available()){
  radio.read(&ButtonVal, sizeof(ButtonVal));
  radio.read(&PotiVal, sizeof(PotiVal));///^ Empfang beider Arrays als ganzes funktioniert ebenfalls nicht
}

Ist ein Paket da?

Ja.

Dann gib die beiden her.

:o

Du kannst deine beiden Pakettypen nur über die Länge unterscheiden,
aber die geht bei Senden verloren, da du jedes Paket auf 32 Byte verlängern lässt.

Du könntest eine von den folgenden Techniken benutzen:

  • eine neue Konfiguration die dynamicPayloads erlaubt
  • eine Kennung in einem gemeinsamen Kopfteil der beiden Pakettypen
  • die Pakete an verschiedene Pipe Adressen senden
  • ein Paket aus beiden machen indem man die Buttons in Bits packt

Okay das ergibt Sinn. Ich kenne mich überhaupt nicht mit der Art und Weise aus, wie die Kommunikation letztenendes von Statten geht.

Mir erscheint die Lösung mit seperaten Pipes am einfachsten. Ich werde das ausprobieren. Die anderen Optionen erscheinen mir eleganter, besonders die dynamicPayloads, aber auf den ersten Blick werde ich aus den Beispielen dafür nicht schlau. Da muss ich mich nochmal tiefer einarbeiten.

Danke für deine Hilfe. Ich schreibe hier nochmal, sollte ich keinerlei Erfolg haben.

Grüße, Tilman

Pipes sind ok, receive sieht dann etwa so aus (pipe 0 und pipe 1 für receive geöffnet)

uint8_t pipe;

if(radio.available(&pipe)){
  if (pipe == 0) { 
    radio.read(&ButtonVal, sizeof(ButtonVal));
  } else {
    radio.read(&PotiVal, sizeof(PotiVal));
  }
}

dynamicPayloads sind super simpel, einfach radio.enableDynamicPayloads() bei allen Beteiligten, receive könnte dann so aussehen

if(radio.available()){
  if (radio.getDynamicPayloadSize() == sizeof(ButtonVal)) { 
    radio.read(&ButtonVal, sizeof(ButtonVal));
  } else {
    radio.read(&PotiVal, sizeof(PotiVal));
  }
}

Tilli:
und meiner Implementierung:

if(radio.available){

int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
radio.write(&PotiVal, sizeof(PotiVal));}

Das sendet nichts, weil das Array "leer" ist. Wenn schon am Anfang 0 steht, ist das schon das Ende.
Probier mal:

if(radio.available){
int PotiVal[14] = {'T','e','s','t',13,10,0,0,0,0,0,0,0,0};
radio.write(&PotiVal, sizeof(PotiVal));}

[/quote]

Gruss Chregu

Chregu73:
Das sendet nichts, weil das Array "leer" ist. Wenn schon am Anfang 0 steht, ist das schon das Ende.

Du irrst dich.

Die Methode mit den DynamicPayloads funktioniert im Prinzip, praktisch aber nicht. Ich habe es so gemacht wie du auch geschrieben hast, und in dem eigentlichen Programm funktioniert es einfach nicht.

Ich habe einfache Testprogramme für T/Rx geschrieben, und beide funktionieren genau wie beschrieben.

Tx:

for(count=0;count<15;count++){
  PotiVal[count]= PotiVal[count]+1;
  if(count<14){
  ButtonVal[count]= ButtonVal[count]+3;
  }
   }
radio.write(&ButtonVal, sizeof(ButtonVal));
radio.write(&PotiVal, sizeof(PotiVal));

Rx:

  if(radio.available()){
    if(radio.getDynamicPayloadSize() == sizeof(ButtonVal)){
    radio.read(&ButtonVal, sizeof(ButtonVal));
    }
    
    if(radio.getDynamicPayloadSize() == sizeof(PotiVal)){
    radio.read(&PotiVal, sizeof(PotiVal));
    }
  }
////Serial.print beide Arrays

Wenn ich nun aber den Test-for-loop mit dem MUX-Auslese-loop ersetze geht gar nichts mehr.

Lasse ich im Tx die Arrays vor dem radio.write per Serial ausgeben, werden die Buttons korrekt gelesen, die Potis aber nicht, und nach einem Loop hängt das Programm. Ich werde morgen nochmal einen Versuch starten das Ganze zum laufen zu bringen. Mir ist wirklich schleierhaft was das Problem sein soll. Im Prinzip mache ich nichts anderes als den test-for-loop gegen den eigentlichen MUX-lese-for-loop zu tauschen. Muss ich etwas in der Reihenfolge im void setup() beachten?

Wie glaubst du das ich sehen könnte was du falsch gemacht hast,
wenn du mir nur ein paar Schnipsel vorwirfst?

Will du keine Hilfe?

Tilli:
Wenn ich nun aber den Test-for-loop mit dem MUX-Auslese-loop ersetze geht gar nichts mehr.

Werden Pakete empfangen?

Welche Länge haben die?

Meine Glaskugel antwortet: ja, es werden welche empfangen und die haben die Länge 32.

Schon, bloß wollte ich noch einmal morgen selbst alles unter die Lupe nehmen damit es nicht am Ende irgend ein blöder Flüchtigkeitsfehler ist, den du für mich raussuchst. Aber hier:

RxProgram.ino (2.45 KB)

TxProgram.ino (3.45 KB)

Ich poste die einfach nochmal in Code Tags, dann können Benutzer an Handys oder Tablets das leichter lesen.

Tx

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

int modValA = 0; // Neck Switch
int modValB = 0; // LFO Switch
int modValC = 0; // FX Switch


//ButtonWerte neu und alt
int ButtonVal[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//PotiWerte neu und alt
int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValPreMap[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValMap[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//ArrayCounter:
int count = 0; // General Counter
int countA = 0; //modValA Send Counter
int countB = 0; //modValB Send Counter
int countC = 0; //modValC Send Counter
//Steuerbits:
int bitA = 0;
int bitB = 0;
int bitC = 0;
int bitD = 0;

//RadioVariablen:
RF24 radio(7,8); //CE, CSN


const byte address[6] = "00001";

void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.enableDynamicPayloads();
radio.stopListening();

pinMode(10, INPUT);//Mux Input Digital (Buttons)
pinMode(2, OUTPUT); //Steuerpins MUX
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
  
 
}

void loop() {
  for(count = 0; count <= 14; count ++){
    bitA = bitRead(count,0);
    bitB = bitRead(count,1);
    bitC = bitRead(count,2);
    bitD = bitRead(count,3);
    
    digitalWrite(2, bitA);
    digitalWrite(3, bitB);
    digitalWrite(4, bitC);
    digitalWrite(5, bitD); //^ Zum durchschalten der Muxeingänge

    //Button & Poti Werte sichern:
    ButtonVal[count] = digitalRead(10); // Sichert jeweiligen Buttonwert in [count(0-14)] des Arrays. 
    
    if(count<= 13){
      PotiValPreMap[count] = analogRead(A0); //Potis werden nur von 0-13 gesichert.
      PotiValMap[count] = map(PotiValPreMap[count],0,1023,0,127);
      PotiVal[count] = 0.4*PotiVal[count]+0.6*PotiValMap[count];
    }
   //else{PotiVal[count]=0;}  //unnötig   
  }
/*  
  Serial.print(ButtonVal[0]);
  Serial.print(" ");
  Serial.print(ButtonVal[1]);
  Serial.print(" ");
  Serial.print(ButtonVal[2]);
  Serial.print(" ");
  Serial.print(ButtonVal[3]);
  Serial.print(" ");
  Serial.print(ButtonVal[4]);
  Serial.print(" ");
  Serial.print(ButtonVal[5]);
  Serial.print(" ");
  Serial.print(ButtonVal[6]);
  Serial.print(" ");
  Serial.print(ButtonVal[7]);
  Serial.print(" ");
  Serial.print(ButtonVal[8]);
  Serial.print(" ");
  Serial.print(ButtonVal[9]);
  Serial.print(" ");
  Serial.print(ButtonVal[10]);
  Serial.print(" ");
  Serial.print(ButtonVal[11]);
  Serial.print(" ");
  Serial.print(ButtonVal[12]);
  Serial.print(" ");
  Serial.print(ButtonVal[13]);
  Serial.println("    ");
/*
  Serial.print(PotiVal[0]);
  Serial.print(" ");
  Serial.print(PotiVal[1]);
  Serial.print(" ");
  Serial.print(PotiVal[2]);
  Serial.print(" ");
  Serial.print(PotiVal[3]);
  Serial.print(" ");
  Serial.print(PotiVal[4]);
  Serial.print(" ");
  Serial.print(PotiVal[5]);
  Serial.print(" ");
  Serial.print(PotiVal[6]);
  Serial.print(" ");
  Serial.print(PotiVal[7]);
  Serial.print(" ");
  Serial.print(PotiVal[8]);
  Serial.print(" ");
  Serial.print(PotiVal[9]);
  Serial.print(" ");
  Serial.print(PotiVal[10]);
  Serial.print(" ");
  Serial.print(PotiVal[11]);
  Serial.print(" ");
  Serial.print(PotiVal[12]);
  Serial.print(" ");
  Serial.print(PotiVal[13]);
  Serial.println("    ");
  Serial.println("    ");
  */
  radio.write(&ButtonVal, sizeof(ButtonVal));
  radio.write(&PotiVal, sizeof(PotiVal));
 }

Rx

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>


RF24 radio(7,8); //CE, CSN


const byte address[6] = "00001";
int modValA = 0; // Neck Switch
int modValB = 0; // LFO Switch
int modValC = 0; // FX Switch

int ButtonVal[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ButtonValAlt[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValAlt[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int count = 0;

void setup() {
 radio.begin();
 Serial.begin(9600);
 
 radio.openReadingPipe(0, address);
 radio.setPALevel(RF24_PA_MIN);
 radio.enableDynamicPayloads();
 radio.startListening();

}

void loop(){

  if(radio.available()){
    if(radio.getDynamicPayloadSize() == sizeof(ButtonVal)){
    radio.read(&ButtonVal, sizeof(ButtonVal));
    }
    
    if(radio.getDynamicPayloadSize() == sizeof(PotiVal)){
    radio.read(&PotiVal, sizeof(PotiVal));
    }
  }
  
  /*Serial.print(PotiVal[0]);
  Serial.print(" ");
  Serial.print(PotiVal[1]);
  Serial.print(" ");
  Serial.print(PotiVal[2]);
  Serial.print(" ");
  Serial.print(PotiVal[3]);
  Serial.print(" ");
  Serial.print(PotiVal[4]);
  Serial.print(" ");
  Serial.print(PotiVal[5]);
  Serial.print(" ");
  Serial.print(PotiVal[6]);
  Serial.print(" ");
  Serial.print(PotiVal[7]);
  Serial.print(" ");
  Serial.print(PotiVal[8]);
  Serial.print(" ");
  Serial.print(PotiVal[9]);
  Serial.print(" ");
  Serial.print(PotiVal[10]);
  Serial.print(" ");
  Serial.print(PotiVal[11]);
  Serial.print(" ");
  Serial.print(PotiVal[12]);
  Serial.print(" ");
  Serial.print(PotiVal[13]);
  Serial.println("    ");
  Serial.println("    ");
  */
  
  Serial.print(ButtonVal[0]);
  Serial.print(" ");
  Serial.print(ButtonVal[1]);
  Serial.print(" ");
  Serial.print(ButtonVal[2]);
  Serial.print(" ");
  Serial.print(ButtonVal[3]);
  Serial.print(" ");
  Serial.print(ButtonVal[4]);
  Serial.print(" ");
  Serial.print(ButtonVal[5]);
  Serial.print(" ");
  Serial.print(ButtonVal[6]);
  Serial.print(" ");
  Serial.print(ButtonVal[7]);
  Serial.print(" ");
  Serial.print(ButtonVal[8]);
  Serial.print(" ");
  Serial.print(ButtonVal[9]);
  Serial.print(" ");
  Serial.print(ButtonVal[10]);
  Serial.print(" ");
  Serial.print(ButtonVal[11]);
  Serial.print(" ");
  Serial.print(ButtonVal[12]);
  Serial.print(" ");
  Serial.print(ButtonVal[13]);
  Serial.println("    ");

}

Auf den ersten Blick sehe ich keinen Grund warum das nicht funktionieren sollte.

Ja wie gesagt, ich habe nichts anderes gemacht als zwei funktionierende Programme zu mergen, wobei sich nichtmal viele Fehler einschleichen konnten. Ich bin auch noch ratlos, aber zwischenzeitlich wurden ja wenigstens die Potis gesendet, also ich hoffe dass ich es morgen noch irgendwie zum laufen kriegen kann.

Das die Arrays "leer" sind wenn sie auf 0 initialisiert sind kann nicht sein? Ich denke zwar auch nicht, dass das das Problem ist, immerhin ist 0 auch ein Wert und bevor die Arrays verschickt werden, werden sie ja mit Werten gefüllt.

Jedenfalls vielen Dank für deine Hilfe. Vielleicht sitzt ja auch der Geist in der Maschine und morgen funktioniert es. Notfalls teste ich es nochmal mit den Pipes. Schönen Abend dir noch :slight_smile:

Grüße,
Tilman

Globale Arrays auf 0 zu initialisieren ist sowieso unsinnig. Globale und lokale statische Variablen werden automatisch mit 0 initialisiert. Nur lokale nicht-statische Variablen sind uninitialisiert

Bei mir funktioniert das problemlos.

Ich habe andere Hardwareeinstellungen,
zusätzlich explizit die Übertragungsrate gesetzt, die verwendete Adresse geändert,
sowie weitgehend entfernt was nicht mit Kommunikation zu tun hat.
Die Logik habe ich etwas angepasst und gebe im Fehlerfall auch etwas aus.

TX

#include <RF24.h>

const byte address[6] = "10000";

int ButtonVal[15];
const byte butElements = sizeof(ButtonVal) / sizeof(ButtonVal[0]);
int PotiVal[14];
const byte potElements = sizeof(PotiVal) / sizeof(PotiVal[0]);

RF24 radio(9, 10); //CE, CSN

void setup() {
  Serial.begin(250000);
  Serial.println(F("Buttons and Pots TX"));
  radio.begin();
  radio.openWritingPipe(address);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
}

void loop() {
  static uint32_t lastSend;
  uint32_t topLoop = millis();
  if (topLoop - lastSend >= 1000) {
    lastSend = topLoop;
    for (uint8_t count = 0; count < butElements; count ++) {
      ButtonVal[count] = digitalRead(2);
      if (count < potElements) {
        PotiVal[count] = analogRead(A0);
      }
    }
    if (!radio.write(&ButtonVal, sizeof(ButtonVal))) {
      Serial.println(F("Senden der Buttons fehlgeschlagen"));
    }
    if (!radio.write(&PotiVal, sizeof(PotiVal))) {
      Serial.println(F("Senden der Pots fehlgeschlagen"));
    }
  }
}
Buttons and Pots TX

RX

#include <RF24.h>

const byte address[6] = "10000";

int ButtonVal[15];
const byte butElements = sizeof(ButtonVal) / sizeof(ButtonVal[0]);
int PotiVal[14];
const byte potElements = sizeof(PotiVal) / sizeof(PotiVal[0]);

RF24 radio(9, 10); //CE, CSN

void setup() {
  Serial.begin(250000);
  Serial.println(F("Buttons and Pots RX"));
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    byte payLen = radio.getDynamicPayloadSize();
    if (payLen == sizeof(ButtonVal)) {
      radio.read(ButtonVal, sizeof(ButtonVal));
      Serial.print(F("Buttons "));
      for (byte idx = 0; idx < butElements; idx++) {
        Serial.print(ButtonVal[idx]);
        Serial.write(' ');
      }
      Serial.println();
    } else if (payLen == sizeof(PotiVal)) {
      radio.read(PotiVal, sizeof(PotiVal));
      Serial.print(F("Pots "));
      for (byte idx = 0; idx < potElements; idx++) {
        Serial.print(PotiVal[idx]);
        Serial.write(' ');
      }
      Serial.println();
    } else {
      Serial.print(F("unerwartete Paketlaenge "));
      Serial.println(payLen);
    }
  }
}
Buttons and Pots RX
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 258 258 258 258 258 258 258 258 257 257 257 257 257 257 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 257 257 257 257 257 257 257 257 256 256 256 256 256 256 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 257 257 257 257 257 257 257 257 257 256 256 256 256 256 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 257 257 256 256 256 256 256 256 256 256 256 256 256 256 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 255 255 255 255 255 255 255 255 255 254 255 255 255 255 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 255 255 255 255 255 255 255 255 255 255 255 255 255 255 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 255 255 255 255 254 254 254 254 254 254 254 254 253 253 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 255 255 255 255 254 254 254 254 253 253 253 253 253 253 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 254 254 254 254 254 254 254 254 253 253 253 253 253 253 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 254 254 254 254 254 254 253 253 253 253 253 253 253 253 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 254 254 254 254 254 254 253 253 253 253 253 253 253 252

Die Buttons als int zu Übertragen ist Blödsinn, ich habe das nur in diesem Beispiel so gelassen.

Pack die alle in einen int, den mit den Potis zusammen in ein Paket und all deine
"welches Paket muss ich wie handhaben" Probleme verschwinden.

Zudem wird alles viel schneller. Etwa so:

TX

#include <RF24.h>

const byte address[6] = "10000";
const byte numOfButtons = 15;

class Packet {
  public:
    int Buttons;
    int PotiVal[14];
} packedData;

const byte potElements = sizeof(packedData.PotiVal) / sizeof(packedData.PotiVal[0]);

RF24 radio(9, 10); //CE, CSN

void setup() {
  Serial.begin(250000);
  Serial.println(F("Buttons and Pots TX"));
  radio.begin();
  radio.openWritingPipe(address);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
}

void loop() {
  static uint32_t lastSend;
  uint32_t topLoop = millis();
  if (topLoop - lastSend >= 1000) {
    lastSend = topLoop;
    packedData.Buttons = 0;
    for (uint8_t count = 0; count < numOfButtons; count ++) {
      if (digitalRead(2)) {
        packedData.Buttons |= (1 << count);
      }
      if (count < potElements) {
        packedData.PotiVal[count] = analogRead(A0);
      }
    }
    if (!radio.write(&packedData, sizeof(packedData))) {
      Serial.println(F("Senden des Pakets fehlgeschlagen"));
    }
  }
}
Buttons and Pots TX

RX

#include <RF24.h>

const byte address[6] = "10000";
const byte numOfButtons = 15;

class Packet {
  public:
    int Buttons;
    int PotiVal[14];
} packedData;

const byte potElements = sizeof(packedData.PotiVal) / sizeof(packedData.PotiVal[0]);

RF24 radio(9, 10); //CE, CSN

void setup() {
  Serial.begin(250000);
  Serial.println(F("Buttons and Pots RX"));
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    byte payLen = radio.getDynamicPayloadSize();
    if (payLen == sizeof(packedData)) {
      radio.read(&packedData, sizeof(packedData));
      Serial.print(F("Buttons "));
      for (byte idx = 0; idx < numOfButtons; idx++) {
        Serial.write(packedData.Buttons & (1 << idx) ? '1' : '0');
        Serial.write(' ');
      }
      Serial.println();
      Serial.print(F("Pots "));
      for (byte idx = 0; idx < potElements; idx++) {
        Serial.print(packedData.PotiVal[idx]);
        Serial.write(' ');
      }
      Serial.println();
    } else {
      Serial.print(F("unerwartete Paketlaenge "));
      Serial.println(payLen);
    }
  }
}
Buttons and Pots RX
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 254 253 253 253 253 253 252 252 252 252 252 252 251 251 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 254 254 253 253 253 253 252 252 252 252 252 251 251 251 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 253 253 253 253 252 252 252 252 252 252 252 252 251 251 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 253 253 253 253 253 252 252 252 252 251 251 251 251 251 
Buttons 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Pots 253 253 253 252 252 252 252 252 252 251 251 251 251 251

Mir ist auch klar, dass es unnötig ist die Buttons als int zu übertragen, aber die Bitwise-Operatoren gehen schon ein wenig tiefer und ich habe es vermieden im ersten Projekt soweit zu gehen.

Es ist seltsam. Ich habe jetzt deinen Code übernommen und bloß die CE CSN Pins geändert und die Muxansteuerung im Tx-Code hinzugefügt.

mehr als

Buttons and Pots RX

kommt nicht vom Rx.

Dann habe ich nochmal den test-for-loop in meinem funktionierendem Testsketch mit dem eigentlichen Mux-lese-loop ersetzt, und jetzt werden die Potis wieder korrekt gelesen und übertragen. Die Buttons allerdings nicht. Die werden als 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 gelesen und übertragen, wobei es
0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 sein sollte. Die Übertragung beider Werte in die Variablen funktioniert also, aber aus irgendeinem Grund funktioniert das Füllen von ButtonVal[] nicht.

Ich bin dann auf Fehlersuche gegangen und habe Zeile für Zeile auskommentiert woran es liegen könnte. Sobald radio.begin aufgerufen wird, werden die Buttons nicht mehr korrekt gelesen/ausgegeben. Verschiebe ich den pinMode-Block vom Anfang ans Ende des setups, wird das Button Array korrekt ausgegeben, das Poti Array nicht und keins von beiden wird übertragen. Sobald radio.begin auskommentiert ist, werden beide Arrays korrekt gelesen und ausgegeben.

Es ist wie verhext. Ich probiere jetzt die Lösung mit den seperaten Pipes, vielleicht ändert das ja was. Es ist mir ein absolutes Rätsel, warum die Ansteuerung des MUX solche Folgen hat. Die hat ja im Prinzip überhaupt nichts mit dem Funk zu tun.
Tx:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>


RF24 radio(7,8); //CE, CSN


const byte address[6] = "00001";
int ButtonVal[15] = {1,2,3,4,0,0,0,0,0,0,0,0,0,0,0};
int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValAlt[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //Alt=old
int PotiValPreMap[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValMap[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};

byte bitA = 0; //MUX control bits
byte bitB = 0;
byte bitC = 0;
byte bitD = 0;

int count = 0; // General Counter


void setup() {
  pinMode(10, INPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
 Serial.begin(9600);

 radio.begin();
 radio.openWritingPipe(address);
 radio.setPALevel(RF24_PA_MIN);
 radio.enableDynamicPayloads();
 radio.stopListening();

}

void loop(){

  for(count = 0; count <= 14; count ++){
    bitA = bitRead(count,0);
    bitB = bitRead(count,1);
    bitC = bitRead(count,2);
    bitD = bitRead(count,3);
    
    digitalWrite(2, bitA);
    digitalWrite(3, bitB);
    digitalWrite(4, bitC);
    digitalWrite(5, bitD); //^ Zum durchschalten der Muxeingänge

    //Button & Poti Werte sichern:
    ButtonVal[count] = digitalRead(10); // Sichert jeweiligen Buttonwert in [count(0-14)] des Arrays. 
    
    if(count<= 13){
      PotiValPreMap[count] = analogRead(A0); //Potis werden nur von 0-13 gesichert.
      PotiValMap[count] = map(PotiValPreMap[count],0,1023,0,127);
      PotiVal[count] = 0.4*PotiVal[count]+0.6*PotiValMap[count];
    }
  }
    Serial.print(ButtonVal[0]);
  Serial.print(" ");
  Serial.print(ButtonVal[1]);
  Serial.print(" ");
  Serial.print(ButtonVal[2]);
  Serial.print(" ");
  Serial.print(ButtonVal[3]);
  Serial.print(" ");
  Serial.print(ButtonVal[4]);
  Serial.print(" ");
  Serial.print(ButtonVal[5]);
  Serial.print(" ");
  Serial.print(ButtonVal[6]);
  Serial.print(" ");
  Serial.print(ButtonVal[7]);
  Serial.print(" ");
  Serial.print(ButtonVal[8]);
  Serial.print(" ");
  Serial.print(ButtonVal[9]);
  Serial.print(" ");
  Serial.print(ButtonVal[10]);
  Serial.print(" ");
  Serial.print(ButtonVal[11]);
  Serial.print(" ");
  Serial.print(ButtonVal[12]);
  Serial.print(" ");
  Serial.print(ButtonVal[13]);
  Serial.print("\t");
   Serial.print(PotiVal[0]);
  Serial.print(" ");
  Serial.print(PotiVal[1]);
  Serial.print(" ");
  Serial.print(PotiVal[2]);
  Serial.print(" ");
  Serial.print(PotiVal[3]);
  Serial.print(" ");
  Serial.print(PotiVal[4]);
  Serial.print(" ");
  Serial.print(PotiVal[5]);
  Serial.print(" ");
  Serial.print(PotiVal[6]);
  Serial.print(" ");
  Serial.print(PotiVal[7]);
  Serial.print(" ");
  Serial.print(PotiVal[8]);
  Serial.print(" ");
  Serial.print(PotiVal[9]);
  Serial.print(" ");
  Serial.print(PotiVal[10]);
  Serial.print(" ");
  Serial.print(PotiVal[11]);
  Serial.print(" ");
  Serial.print(PotiVal[12]);
  Serial.print(" ");
  Serial.print(PotiVal[13]);
  Serial.println("    ");
  

  radio.write(&ButtonVal, sizeof(ButtonVal));
  radio.write(&PotiVal, sizeof(PotiVal));
  
}

Rx:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>


RF24 radio(7,8); //CE, CSN


const byte address[6] = "00001";
int modValA = 0; // Neck Switch
int modValB = 0; // LFO Switch
int modValC = 0; // FX Switch

int ButtonVal[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ButtonValAlt[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int PotiVal[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int PotiValAlt[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int count = 0;

void setup() {
 Serial.begin(9600);
 radio.begin();
 radio.openReadingPipe(0, address);
 radio.setPALevel(RF24_PA_MIN);
 radio.enableDynamicPayloads();
 radio.startListening();

}

void loop(){

  if(radio.available()){
    if(radio.getDynamicPayloadSize() == sizeof(ButtonVal)){
    radio.read(&ButtonVal, sizeof(ButtonVal));
    }
    
    if(radio.getDynamicPayloadSize() == sizeof(PotiVal)){
    radio.read(&PotiVal, sizeof(PotiVal));
    }
  }
  Serial.print(ButtonVal[0]);
  Serial.print(" ");
  Serial.print(ButtonVal[1]);
  Serial.print(" ");
  Serial.print(ButtonVal[2]);
  Serial.print(" ");
  Serial.print(ButtonVal[3]);
  Serial.print(" ");
  Serial.print(ButtonVal[4]);
  Serial.print(" ");
  Serial.print(ButtonVal[5]);
  Serial.print(" ");
  Serial.print(ButtonVal[6]);
  Serial.print(" ");
  Serial.print(ButtonVal[7]);
  Serial.print(" ");
  Serial.print(ButtonVal[8]);
  Serial.print(" ");
  Serial.print(ButtonVal[9]);
  Serial.print(" ");
  Serial.print(ButtonVal[10]);
  Serial.print(" ");
  Serial.print(ButtonVal[11]);
  Serial.print(" ");
  Serial.print(ButtonVal[12]);
  Serial.print(" ");
  Serial.print(ButtonVal[13]);
  Serial.print("\t");
  Serial.print(PotiVal[0]);
  Serial.print(" ");
  Serial.print(PotiVal[1]);
  Serial.print(" ");
  Serial.print(PotiVal[2]);
  Serial.print(" ");
  Serial.print(PotiVal[3]);
  Serial.print(" ");
  Serial.print(PotiVal[4]);
  Serial.print(" ");
  Serial.print(PotiVal[5]);
  Serial.print(" ");
  Serial.print(PotiVal[6]);
  Serial.print(" ");
  Serial.print(PotiVal[7]);
  Serial.print(" ");
  Serial.print(PotiVal[8]);
  Serial.print(" ");
  Serial.print(PotiVal[9]);
  Serial.print(" ");
  Serial.print(PotiVal[10]);
  Serial.print(" ");
  Serial.print(PotiVal[11]);
  Serial.print(" ");
  Serial.print(PotiVal[12]);
  Serial.print(" ");
  Serial.print(PotiVal[13]);
  Serial.println("    ");
  
}

Ich habe deine von mir modifizierte Version angehängt. Wie gesagt, ich habe prinzipiell nichts geändert, dass die Funktion stören könnte, außer bitRead(count,x) und digitalWrite(x, bitY) hinzugefügt.

WhandallTx.txt (2.24 KB)

WhandallRx.txt (1.26 KB)

Nimm einen anderen PIN als 10 zum Einlesen, ein INPUT könnte SPI Master Betrieb verhindern.

Note about Slave Select (SS) pin on AVR based boards

All AVR based boards have an SS pin that is useful when they act as a slave controlled by an external master. Since this library supports only master mode, this pin should be set always as OUTPUT otherwise the SPI interface could be put automatically into slave mode by hardware, rendering the library inoperative.

It is, however, possible to use any pin as the Slave Select (SS) for the devices. For example, the Arduino Ethernet shield uses pin 4 to control the SPI connection to the on-board SD card, and pin 10 to control the connection to the Ethernet controller.

Perfekt, das hat es gelöst! Dann wird sicher auch deine Version funktionieren, auch wenn ich es mir bei MIDI leisten kann verschwenderisch zu sein. 31250baud ist maximum. Vielen Dank für deine Hilfe!!! :slight_smile:

Ist mir erst zu spät eingefallen, eigentlich erst durch dein

Tilli:
Es ist mir ein absolutes Rätsel, warum die Ansteuerung des MUX solche Folgen hat.
Die hat ja im Prinzip überhaupt nichts mit dem Funk zu tun.

andererseits steht es in der von mir zitierten Dokumentation der SPI Library. :wink:

Ich würde die Buttons in einen uint16_t packen und mit den Potis gemeinsam übertragen.

Bei dem fetten Paket von 30 Byte lohnt sich dynamicPayload nicht mehr wirklich,
ich halte die Einstellung aber grundsätzlich für sinnvoller.
Padding durch den Äther schicken, wenn man es nicht muss, ist ziemlich unsensibel.