Variablenangabe dynamisch erzeugen??

Hallo,

gibt es eine Möglichkeit eine Variablenangabe dynamisch zu erzeugen?

Ich habe drei unterschiedliche Werte (K_mode, K_temp, K_fspeed), die einzeln geändert werden können
und zusammen einen Wert ergeben (K_code).

Wie kann man anhand dieser Angabe das passende Array (insgesamt sind es 149 Arrays) auswählen
und an die Funktion " SendIRCode();" übergeben?

Ich möchte es nach Möglichkeit vermeiden, es mit 149 If-Abfragen zu lösen.
Es gibt doch sicherlich eine elegantere Möglichkeit...

#include <IRremote.h>
#include <avr/pgmspace.h>

IRsend irsend;

// IR-Codes
PROGMEM unsigned int Cool23A[100]  = {4400,4250,550,1600,550,550,500,1650,500,1650,500,550,550,550,500,1600,550,550,600,500,500,1600,550,550,550,500,550,1600,550,1600,550,550,550,1600,550,1600,500,550,550,1600,550,1600,550,1600,550,1600,550,1600,550,1600,600,450,550,1600,550,550,500,550,550,550,500,550,550,550,550,500,600,500,550,1600,550,500,550,1600,550,550,550,500,550,550,550,500,600,1550,550,550,550,1600,550,500,550,1600,550,1600,550,1600,550,1600,550,5050};
PROGMEM unsigned int Cool24A[100]  = {4400,4250,600,1600,550,500,550,1600,550,1600,550,550,500,550,550,1600,550,550,550,500,550,1600,550,550,500,550,550,1600,550,1600,550,500,550,1600,600,1550,550,550,550,1600,550,1600,500,1650,500,1600,550,1600,550,1600,600,500,550,1600,550,500,550,550,550,500,550,550,550,500,550,550,550,500,550,1600,550,550,550,500,550,550,550,500,550,550,550,550,550,1550,550,550,550,1600,550,1600,550,1600,500,1650,500,1650,500,1600,600,5050};
...
PROGMEM unsigned int Heat20L[100]  = {4400,4250,600,1600,550,500,550,1600,550,1600,550,550,500,550,550,1600,550,550,550,500,550,1600,550,550,500,550,550,1600,550,1600,550,500,550,1600,600,1550,550,550,550,500,550,1600,550,1600,550,1600,550,1600,550,1600,550,500,550,1600,550,1600,550,550,500,550,550,550,500,550,550,550,550,500,550,550,500,1650,500,550,550,1600,550,1600,550,550,500,550,550,1600,550,1600,550,500,550,1600,550,550,550,500,550,1600,550,1600,550,5050};
PROGMEM unsigned int Heat21L[100]  = {4400,4250,550,1600,550,550,550,1600,550,1600,550,500,550,550,550,1600,550,500,650,450,550,1600,500,550,550,550,550,1600,500,1650,500,550,550,1600,550,1600,550,500,550,550,550,1600,550,1600,550,1600,500,1650,500,1600,600,500,550,1600,550,1600,550,500,550,550,550,500,550,550,550,500,600,500,550,1600,550,1600,500,550,550,1600,550,1600,550,550,500,550,600,1550,550,550,500,550,550,1600,550,500,550,550,550,1600,550,1600,550,5050};
...


String K_mode = "Cool";   // Speichert gewählten Modus
byte K_temp = 23;         // Speichert gewählte Temperatur
char K_fspeed = 'A';      // Speichert gewählte Lüftergeschwindigkeit

String K_code = K_mode + K_temp + K_fspeed;


void setup() {
  Serial.begin(9600);
  
  SendIRCode(Cool23A);
  
  //SendIRCode(K_code);
}

void loop() {
}

void SendIRCode(unsigned int code[]) {
  unsigned int irc[100] = {};
  
  Serial.print(F("IRcode: "));
  for (byte i=0; i<100; i++) {
    irc[i] = pgm_read_word_near(code+i);
    Serial.print(irc[i]);
    if (irc[i] != 5050) { // Nach der letzten Zahl "5050" kein Komma einfügen
      Serial.print(F(","));
    }
  }
  Serial.println();
  
  for (byte i=0; i<2; i++) { // Befehle müssen 2x gesendet werden (Comfee Klimaanlage)
    irsend.sendRaw(irc,100,38); // sendRaw(unsigned int buf[], int len, int hz);
  }
  Serial.println(F(">> IR-Code gesendet!"));
}

Hallo und willkommen im Forum!
Spontan würde ich das mit einem zweidimensionalen Feld lösen, wobei "Cool23A" dann "0" und "Cool24A" "1" usw. werden müßte.

Es geht auch eindimensional mit der Berechnung des Anfangspunktes über n * 100.

Könntest du mir ein Codebeispiel posten?

Schau mal hier: click oder click

Das von mir wird Dir eher nicht nutzen, denke ich:

const unsigned char CH[] PROGMEM = {
  3, B00000000, B00000000, B00000000, B00000000, B00000000, // space
  1, B01011111, B00000000, B00000000, B00000000, B00000000, // |
  3, B00000011, B00000000, B00000011, B00000000, B00000000, // "
  5, B00010100, B00111110, B00010100, B00111110, B00010100, // #
...
  memcpy_P(sprite + 1, CH + (zeichen - 32) * 6, 6);  // Das ist die von mir gemeinte Berechnung

ich habe jetzt mal folgendes zusammengebastelt, allerdings ist wohl einiges falsch.
Ich bekomme nicht die richtigen Werte...

#include <IRremote.h>
#include <avr/pgmspace.h>
#include "IRcodes.h" // IR-Codes

//PROGMEM unsigned int Cool23L[100]  = {4450,4250,550,1600,550,500,550,1600,550,1600,550,550,500,550,550,1600,550,550,550,500,550,1600,550,550,500,550,550,1600,550,1600,550,500,550,1600,600,1550,550,550,550,500,550,1600,550,1600,550,1600,550,1600,550,1600,550,500,550,1600,550,1600,550,550,500,550,550,550,500,550,550,550,550,500,550,1600,550,550,500,1650,500,550,550,550,550,500,550,550,550,1600,500,550,550,1600,550,550,500,1650,500,1650,500,1600,550,1600,600,5050};

IRsend irsend;

String K_mode = "Cool";   // Speichert gewählten Modus                => Auto, Cool, Heat, Dry, Fan
byte K_temp = 23;         // Speichert gewählte Temperatur            => 17,18,19,20,21,22,23,24,25,26,27,28,29,30
char K_speed = 'L';       // Speichert gewählte Lüftergeschwindigkeit => A, L, M, H

unsigned int K_code[100] = {0};

unsigned int IRcode[5][4][14] = {
  {
    { Auto17A[100], Auto18A[100], Auto19A[100], Auto20A[100], Auto21A[100], Auto22A[100], Auto23A[100], Auto24A[100], Auto25A[100], Auto26A[100], Auto27A[100], Auto28A[100], Auto29A[100], Auto30A[100] }
  },
  {
    { Cool17A[100], Cool18A[100], Cool19A[100], Cool20A[100], Cool21A[100], Cool22A[100], Cool23A[100], Cool24A[100], Cool25A[100], Cool26A[100], Cool27A[100], Cool28A[100], Cool29A[100], Cool30A[100] },
    { Cool17L[100], Cool18L[100], Cool19L[100], Cool20L[100], Cool21L[100], Cool22L[100], Cool23L[100], Cool24L[100], Cool25L[100], Cool26L[100], Cool27L[100], Cool28L[100], Cool29L[100], Cool30L[100] },
    { Cool17M[100], Cool18M[100], Cool19M[100], Cool20M[100], Cool21M[100], Cool22M[100], Cool23M[100], Cool24M[100], Cool25M[100], Cool26M[100], Cool27M[100], Cool28M[100], Cool29M[100], Cool30M[100] },
    { Cool17H[100], Cool18H[100], Cool19H[100], Cool20H[100], Cool21H[100], Cool22H[100], Cool23H[100], Cool24H[100], Cool25H[100], Cool26H[100], Cool27H[100], Cool28H[100], Cool29H[100], Cool30H[100] }
  },
  {
    { Heat17A[100], Heat18A[100], Heat19A[100], Heat20A[100], Heat21A[100], Heat22A[100], Heat23A[100], Heat24A[100], Heat25A[100], Heat26A[100], Heat27A[100], Heat28A[100], Heat29A[100], Heat30A[100] },
    { Heat17L[100], Heat18L[100], Heat19L[100], Heat20L[100], Heat21L[100], Heat22L[100], Heat23L[100], Heat24L[100], Heat25L[100], Heat26L[100], Heat27L[100], Heat28L[100], Heat29L[100], Heat30L[100] },
    { Heat17M[100], Heat18M[100], Heat19M[100], Heat20M[100], Heat21M[100], Heat22M[100], Heat23M[100], Heat24M[100], Heat25M[100], Heat26M[100], Heat27M[100], Heat28M[100], Heat29M[100], Heat30M[100] },
    { Heat17H[100], Heat18H[100], Heat19H[100], Heat20H[100], Heat21H[100], Heat22H[100], Heat23H[100], Heat24H[100], Heat25H[100], Heat26H[100], Heat27H[100], Heat28H[100], Heat29H[100], Heat30H[100] }
  },
  {
    { Dry17A[100], Dry18A[100], Dry19A[100], Dry20A[100], Dry21A[100], Dry22A[100], Dry23A[100], Dry24A[100], Dry25A[100], Dry26A[100], Dry27A[100], Dry28A[100], Dry29A[100], Dry30A[100] }
  },
  {
    { FanA[100] },
    { FanL[100] },
    { FanM[100] },
    { FanH[100] }
  }
};

void setup() {
  Serial.begin(9600);
  
  byte m; if (K_mode == "Auto") m=0; else if (K_mode == "Cool") m=1; else if (K_mode == "Heat") m=2; else if (K_mode == "Dry") m=3; else if (K_mode == "Fan") m=4;
  byte t = K_temp-17;
  byte s; if (K_speed == 'A') s=0; else if (K_speed == 'L') s=1; else if (K_speed == 'M') s=2; else if (K_speed == 'H') s=3;
  
  Serial.print("m:");
  Serial.print(m);
  Serial.print(" t:");
  Serial.print(t);
  Serial.print(" s:");
  Serial.println(s);
  
  K_code[100] = IRcode[m][s][t];
  SendIRCode(K_code);
  //SendIRCode(Cool23A);
}

void loop() {
}

void SendIRCode(unsigned int code[]) {
  unsigned int irc[100] = {};
 
  Serial.print(F("IRcode: "));
  for (byte i=0; i<100; i++) {
    irc[i] = pgm_read_word_near(code+i);
    Serial.print(irc[i]);
    if (irc[i] != 5050) { // Nach der letzten Zahl "5050" kein Komma einfügen
      Serial.print(F(","));
    }
  }
  Serial.println();
 
  for (byte i=0; i<2; i++) { // Befehle müssen 2x gesendet werden (Comfee Klimaanlage)
    irsend.sendRaw(irc,100,38); // sendRaw(unsigned int buf[], int len, int hz);
  }
  Serial.println(F(">> IR-Code gesendet!"));
}

Wo sind die 5 * 4 * 14 = 280 Wertezuweisungen so wie in Cool23L[100]? Du definierst ein Feld aber ohne Inhalt.

Du nutzt #include <avr/pgmspace.h> nicht, warum? Welchen Arduino nutzt Du eigentlich bei 56 kByte Array?

marco9010:
gibt es eine Möglichkeit eine Variablenangabe dynamisch zu erzeugen?

Mit Arrays, die dynamische Auswahl erfolgt über einen Index.

Ich habe drei unterschiedliche Werte (K_mode, K_temp, K_fspeed), die einzeln geändert werden können
und zusammen einen Wert ergeben (K_code).

Das klingt nach einer struct mit diesen 3 Elementen. Wobei die Strings durch eine enum ersetzt werden sollten, zur leichteren Handhabung.

Wie kann man anhand dieser Angabe das passende Array (insgesamt sind es 149 Arrays) auswählen
und an die Funktion " SendIRCode();" übergeben?

Was ist "passend"?
Was steht in welchem Array drin?
Wieso mal 100 und mal 149?

String K_mode = "Cool";   // Speichert gewählten Modus                => Auto, Cool, Heat, Dry, Fan
byte K_temp = 23;         // Speichert gewählte Temperatur            => 17,18,19,20,21,22,23,24,25,26,27,28,29,30
char K_speed = 'L';       // Speichert gewählte Lüftergeschwindigkeit => A, L, M, H

Falls das die möglichen Vorgabewerte sind, komme ich auf 5144=280 mögliche Kombinationen (= arrays?).

Wenn ich das richtig verstanden habe, hast Du letztendlich ein Daten-Array
unsigned int IRcode[5][4][14][100] = { ... };
mit 2801002=56k. Wenn Du aber verwendest
unsigned int* IRcode[5][4][14]
dann gibt das nochmal ein Array mit 560 Bytes(?) Pointern (okay, verschmerzbar), aber dann auch den '*' nicht vergessen!

Wo sind die 5 * 4 * 14 = 280 Wertezuweisungen so wie in Cool23L[100]? Du definierst ein Feld aber ohne Inhalt.

Die sind alle hier #include "IRcodes.h" // IR-Codes

Du nutzt #include <avr/pgmspace.h> nicht, warum?

Ich muss dazu sagen, dass ich Anfänger bin! Beschäftige mich mit dem Arduino erst seit kurzem.

Was sollte ich davon nutzen?
Eingebunden habe ich es hierfür irc = pgm_read_word_near(code+i);.

Welchen Arduino nutzt Du eigentlich bei 56 kByte Array?

Mega 2560

Mit Arrays, die dynamische Auswahl erfolgt über einen Index.

Also das, was ich gerade versuche oder?

Das klingt nach einer struct mit diesen 3 Elementen. Wobei die Strings durch eine enum ersetzt werden sollten, zur leichteren Handhabung.

Wie würde das in meinem Fall aussehen?

Was ist "passend"?

Gemeint habe ich das so:

String K_mode = "Cool"; byte K_temp = 23; char K_speed = 'L'; => "Passendes" Array aus IRcodes.h Cool23L[100]

String K_mode = "Fan"; byte K_temp = 23; char K_speed = 'H'; => "Passendes" Array aus IRcodes.h FanH[100]

Was steht in welchem Array drin?

Ich hab mal die Datei IRcodes.h im Anhang gepackt.

Falls das die möglichen Vorgabewerte sind, komme ich auf 5144=280 mögliche Kombinationen (= arrays?).

Ich habe "nur" 144 Kombinationen, weil der Modus "Fan" z.B. keine Temperatur hat.
Hier gibt es nur diese Kombinationen "FanA", "FanL", "FanM" und "FanH".
Die Modi "Dry" und "Auto" haben alle Temperaturen (17-30) aber nur eine mögliche Lüftergeschwindigkeit => "A".

Wenn ich das richtig verstanden habe, hast Du letztendlich ein Daten-Array
unsigned int IRcode[5][4][14][100] = { ... };
mit 2801002=56k. Wenn Du aber verwendest
unsigned int* IRcode[5][4][14]
dann gibt das nochmal ein Array mit 560 Bytes(?) Pointern (okay, verschmerzbar), aber dann auch den '*' nicht vergessen!

Ich möchte die Angabe für das Array in SendIRCode(Cool23A); dynamisch gestalten, wenn es irgendwie machbar ist.

Also ohne 144 mal soetwas zu schreiben:

if (K_code == "Cool23A") {
  SendIRCode(Cool23A);
} else if (K_code == "Cool24A") {
  SendIRCode(Cool24A);
} ...

Sondern soetwas in der Art:

K_code = "Cool24A";

SendIRCode(K_code);

Und je nachdem was in "K_code" steht, wird das entsprechende Array aus "IRcodes.h" ausgewählt und an die Funktion "SendIRCode()" übergeben.

Wie löst man das am einfachsten?
Der Vorschlag von "agmue" war es, das Ganze mit Mehrdimensionale Arrays zu lösen.

IRcodes.h (68 KB)

Warnung dazu:
PROGMEM Daten können insgesamt nicht größer als 64kB sein, da du hier mit 16 Bit Adressen hantierst.

Man kann auch mehr Daten im Flash ablegen, aber dazu muss man etwas ausholen.

Soweit ich das sehe ist Dein Code schon fast richtig, bis auf

 K_code[100] = IRcode[m][s][t];
 SendIRCode(K_code);

K_code soll ein Pointer auf das Array sein, das ausgegeben werden soll. Deshalb muß IRCode und K_code deklariert sein als

 unsigned int * K_code;
 unsigned int * IRcode[5][4][14] = {
 {
   { Auto17A, Auto18A, Auto19A, Auto20A, Auto21A, Auto22A, Auto23A, //usw.
...
 K_code = IRcode[m][s][t];

Soweit ich das sehe ist Dein Code schon fast richtig, bis auf

K_code[100] = IRcode[m][t];
SendIRCode(K_code);

K_code soll ein Pointer auf das Array sein, das ausgegeben werden soll. Deshalb muß IRCode und K_code deklariert sein als

unsigned int * K_code;
unsigned int * IRcode[5][4][14] = {
{
{ Auto17A, Auto18A, Auto19A, Auto20A, Auto21A, Auto22A, Auto23A, //usw.
...
K_code = IRcode[m][t];

ok Danke, jetzt scheint alles richtig zu sein.
Datei hab ich mal im Anhang gepackt. Man kann zum testen über die Serielle Eingabe Befehle eingeben.

Warnung dazu:
PROGMEM Daten können insgesamt nicht größer als 64kB sein, da du hier mit 16 Bit Adressen hantierst.

Danke für den Hinweis.
Überschreite ich in meinem jetzigen Sketch die 64kB? Wie kann ich das feststellen/errechnen?
Da die IDE keine Fehler meldet und das Programm auf dem Arduino, soweit ich es testen konnte auch fehlerfrei läuft, gehe ich davon aus, dass ich unter der Grenze bin. Stimmts?

Eine ganz andere Frage, gibt es irgendein Unterschied zwischen den folgenden Deklarationsmöglichkeiten:

unsigned int irc[100];
unsigned int irc[100] = {};
unsigned int irc[100] = {0};

int test;
int test = 0;

IRsendCode3_Klimaanlage.zip (7 KB)