Komisches Verhalten bei Array-Übergabe

Hallo,
ich hab viele Einträge gelesen, komm aber nicht weiter.

Ich möchte beim einschalten einer roten bzw. gelben LED unterschiedliche Beep-Muster ausgeben. Dazu habe ich zwei Arrays definiert:

uint16_t timeBeepYellow[4] = {200,100,200,100};
uint16_t timeBeepRed[6] = {200,200,200,200,200,200};

Nach Schalten der LED rufe ich eine Beep-Funktion:

 void updateDisplay(){
   // Steuern der LEDs auf Grund der Eingaben
   Serial.printf("Status in Kommunikation: %1d / %1d / %1d \n\n", incomingStatus.green, incomingStatus.yellow, incomingStatus.red);
   if (incomingStatus.yellow) {
     digitalWrite(pinLEDyellow, HIGH);
     beep(timeBeepYellow);
   } else {
     digitalWrite(pinLEDyellow, LOW);
   }
   if (incomingStatus.red) {
     digitalWrite(pinLEDred, HIGH);
     beep(timeBeepRed);
   } else {
     digitalWrite(pinLEDred, LOW);
   }
 }

In der Beep-Funktion, möchte ich das definierte Muster ausgeben:

void beep(uint16_t *t) {
   Serial.print("Das Beep-Array: ");
   for( int i=0; i < sizeof(t); i++) {
      Serial.printf("%3d",t[i]);
   }
   Serial.println();
   
   for( int i=0; i < sizeof(t); i++) {
     digitalWrite(pinBeep, HIGH);
     delay(t[i]);
     i++;
     digitalWrite(pinBeep, LOW);
     delay(t[i]);
   }
 }

Es werden aber immer nur 2 Beeps ausgegeben.
Die Kontrollausgabe zu Beginn der Beepfunktion zeigt mir, dass zwar das richtige Array übergeben wurde, es kommen aber immer nur 4 Elemente an??

Was mach ich falsch, bzw. warum ist das so.
Wie kann ich erreichen, dass es bei rot 3x beept?

Gruß Udo

Bei der Konvertierung von einem ArrayType zu einem Pointer geht die Größe des Arrays verloren.
sizeof(t) liefert dir nur die Zeigergröße. Und die hat mit einem Array nichts zu tun

template<typename ArrayType>
void beep(ArrayType &t)
{
  size_t N = sizeof(t) / sizeof(t[0]);
  Serial.print("Das Beep-Array: ");
  for( unsigned i = 0; i < N; i++)
  {
    Serial.printf("%3d",t[i]);
  }
  Serial.println();
  for( unsigned i = 0; i < N; i++)
  {
    digitalWrite(pinBeep, HIGH);
    delay(t[i]);
    i++;
    digitalWrite(pinBeep, LOW);
    delay(t[i]);
  }
}


Ah, danke - das war mir nicht bewußt :wink:

Mein Workaround funktioniert allerding garnicht?
Habe den Aufruf wie folgt geändert:

beep(sizeof(timeBeepYellow), timeBeepYellow);

Die Kontrollausgabe bei gelb ergibt dann:
Das Beep-Array - Anz 37 Elemente: 200:100:200:100: 2: 0: 16: 0:
Die Kontrollausgabe bei rot ergibt dann:
Das Beep-Array - Anz 37 Elemente: 200:200:200:200:200:200:200:100:200:100: 2: 0:

Warum wird als Anzahl 37 übergeben und warum ist da kein Unterschie zwischeen rot und gelb?
Danke Udo

Sorry, da noch ein kleiner Bug bei der Ausgabe drin. die richtige Kontrollausgabe ist:
bei gelb
*Das Beep-Array - Anz 8 Elemente: 200:100:200:100: 2: 0: 16: 0:
bei rot
*Das Beep-Array - Anz 12 Elemente: 200:200:200:200:200:200:200:100:200:100: 2: 0:

Das richtige Ergebnis bei gelb wäre 4, bei gelb 6.
Die Verdopplung liegt dann wohl am Typ, uint16.

Danke, werde anzahl/2 nehmen.
Gruß Udo

Ich finde das schon ok, dass du meinen Vorschlag ignorierst.
Und auch die darin vorhandene Arraygrößenberechnung

Aber einen Rat kann ich dir dennoch geben:
Programmieren ist nicht Ausprobieren, sondern wissen was man tut.
Aus dem Grund verpflichte ich dich dazu, ein modernes C++ Buch, zu lesen.

Hallo @combie hat ja bereits geschrieben das die Anzahl der Elemente bei der Übergabe verloren geht.
Das passiert weil eigentlich nur ein Zeiger auf das erste Element übergeben wird und damit ist die länge futsch. Man kann die Anzahl mit an die Funktion übergeben.


int w1[] = {10, 11,12 };
int w2[] = {20, 21, 22, 23, 24,25};
int anzahl;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  anzahl = sizeof(w1) / sizeof(w1[0]);
  ausgabe(w1, anzahl);
  anzahl = sizeof(w2) / sizeof(w2[0]);
  ausgabe(w2, anzahl);
}

void loop() {
  // put your main code here, to run repeatedly:

}
void ausgabe(int *w, int anz) {
  Serial.print("Anzahl "); Serial.println(anz);
  for ( int i = 0; i < anz; i++ ) {
    Serial.print(w[i]); Serial.print(" ");
  }
  Serial.println();
}

Das hat ihm ja schon versucht, ihm weiß nur nicht, was sizeof tut bzw. wie man Arraygrößen damit berechnet.

Aber sonst ist das der fehlerträchtige C Weg.
Den müssen wir in C++ nicht unbedingt beschreiten, da geht das auch eleganter.



struct Muster
{
  uint16_t leuchtdauer;
  uint16_t ausdauer;
};

Muster   timeBeepYellow[]  {
                              {200, 100},
                              {200, 100},
                           };
                           
Muster   timeBeepRed[]  {
                          {200, 200}, 
                          {200, 200}, 
                          {200, 200},
                        };


const byte pinBeep = 13;



template<typename ArrayType>
void beep(ArrayType &t)
{
  Serial.println("Das Beep-Array: ");
  
  for(Muster &m:t)
  {
    Serial.print("Leuchtdauer: ");
    Serial.print(m.leuchtdauer);
    Serial.print("     Ausdauer: ");
    Serial.println(m.ausdauer);
  }
  Serial.println();


  
  for(Muster &m:t)
  {
    digitalWrite(pinBeep, HIGH);
    delay(m.leuchtdauer);
    digitalWrite(pinBeep, LOW);
    delay(m.ausdauer);
  }
}



void setup()
{
  pinMode(pinBeep, OUTPUT);
  Serial.begin(9600);

}

void loop()
{
  beep(timeBeepYellow);
  beep(timeBeepRed);
}

@combie: Deine Größenberechnung hatte ich tatsächlich übersehen - ein kleiner Hinweis im Text hätte geholfen den Unterschied zu suchen :wink:

Vielen Dank für deine Vorlage. Als Web-Programmierer (PHP, Python) bin ich tatsächlich nicht fit in C++-Arrays. Deine Vorlage ist prima, genau so werde ich es umsetzen.

Danke Udo

ich weiß wohl das es das gibt und was da passiert , jedoch so ganz ist mir das bisher noch nicht in´s Blut über gegengen.
üben , üben , üben :wink:
Gruß Heinz

Die Größe brauchen "wir" nicht, die weiß das Array selber, auch ohne uns.

Ja, verstehen und dann üben, bis es in Fleisch und Blut übergegangen ist.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.