Zeichenkette in constante verbinden

Hallo,
ich habe hier ein Problem und drehe mich irgendwie auf der Stelle. Ich möchte für eine Konfiguration im Flash einige Zeichenketten speichern. Wenn die Konfigurationsdaten mit einer Externen Datei übereinstimmen, möchte ich für die weitere Bestimmung einen Variablentyp übergeben.

#define VarType1 = 0x02
#define VarType2 = 0x05
#define VarType3 = 0x06

const char Par_TIST[] PROGMEM 	 = VarType1, "TIST";
const char Par_DELAY[] PROGMEM 	 = VarType3, "DELAY";
const char Par_TOUT[] PROGMEM 	 = VarType2, "TOUT";
const char Mod_SOFT[] PROGMEM    = "SOFT";

const char * const ModuleNorm [] [11] PROGMEM = {
			{Mod_SOFT,	Par_TIST, 	Par_DELAY, 	Par_TOUT}
};



strcpy_P(buffer, (char *)pgm_read_word_near(&(ModuleNorm[i][j])));

Beim lesen der Zeichenkette in den buffer, möchte ich im ersten Zeichen von buffer wieder den Variablentyp z.B. 0x02 feststellen, um dann im Programm entsprechend zu verzweigen.

Kann mir hier bitte jemand helfen? Es ist denke ich eine einfache Definitionssache, da das Zusammenführen noch vom Compiler übernommen werden muss. Ich habe nicht die rchtigen Schlüsselworte gefunden, um danach im Netz nach einer Antwort suchen zu können.

Vielen Dank im Voraus!

Gruß, Horst

Ich finde in deinem Text auch nicht die richtigen Schlüsselworte um beurteilen zu können, was du mit Variablentyp meinst.
Üblicherweise nenne ich int, long, float usw. Variablentyp.
In einer externen Datei steht der Einfachheit halber gern nur Text.

Auch hier rätsle ich, was du meinst. Beschreibe doch einfach konkreter, was du willst.

Hilft das?

enum t_typeID : uint8_t {type1 = 0x02, type2 = 0x05, type3 = 0x06};

struct t_data {
  t_typeID dataType;
  char     label[20];
};

const t_data ModuleNorm[]  PROGMEM = {
  {type1, "TIST"},
  {type2, "DELAY"},
  {type3, "TOUT"},
};

const size_t ModuleNormCount = sizeof ModuleNorm / sizeof ModuleNorm[0];

void setup() {
  Serial.begin(115200); Serial.println();
  Serial.print(F("ModuleNorm hat ")); Serial.print(ModuleNormCount); Serial.println(F(" Elemente"));
  for (size_t i = 0; i < ModuleNormCount; i++) {
    Serial.print(F("#")); Serial.print(i);
    Serial.print(F("\tType= 0x")); Serial.print(pgm_read_byte(&ModuleNorm[i].dataType), HEX);
    Serial.print(F("\tLabel= ")); Serial.println((__FlashStringHelper*) ModuleNorm[i].label);
  }
}

void loop() {}

Serial ➜

ModuleNorm hat 3 Elemente
#0	Type= 0x2	Label= TIST
#1	Type= 0x5	Label= DELAY
#2	Type= 0x6	Label= TOUT

Ein Nachteil ist, dass Sie etwas Flash-Speicher verlieren, da alle Elemente unabhängig vom tatsächlichen Bedarf 20 Bytes für das Label haben (wählen Sie, was sinnvoll ist).

3 Likes

Hallo michael_x,

die Varialbentypen haben nichts mit C Variablen zu tun. Ich möchte wie im Beispielprogramm lediglich den Wert 0x02 als ein Sonderzeichen an der ersten Stelle und danach "TIST" haben. Parameter anstatt Variablentype trifft es wohl besser.

const char Par_TIST[] PROGMEM 	 = VarType1, "TIST";

Beim lesen einer externen Datei wird dann nach dem Schlüsselwort "TIST" gesucht. VarType ist für das Programm dann der Hinweis, was mit "TIST" geschehen soll.

Hilft das?

Und wie! Das ist genau das, was ich gesucht habe. Ich habe noch sehr viel zu lernen.

Mein Problem bei der Programmiererei mir fehlen vielen Grundkenntnisse und dann gibt es zu viele Wege für ein und das selbe Problem.

Vielen Dank!

Gruß,
Horst

Wenn Sie üben und eine gute Dokumentation lesen, werden Sie Fortschritte machen.

Habe Spaß!

in C / C++ könnte man das
const char Par_TIST[] PROGMEM = "\x02TIST";
schreiben, aber @J-M-L Jacksons Lösung ist besser: Wenn es kein Text ist, sollte man auch nicht so tun als ob. ( Außerdem gäbe es evtl. Probleme beim Typ 0 )
Jacksons Lösung mit dem cast (__FlashStringHelper*) gefällt mir sehr.

Wenn es auf den Flash-Speicherplatz ankommt, kann man statt fester Längen auch im PROGMEM Zeiger auf Texte im PROGMEM ablegen.

ja, aber es ist mühsam zu schreiben und ich war faul :slight_smile:

Ich habe das jetzt umgesetzt und bin mit dem Ergebnis noch nicht gaz zufrieden und möchte mochmals um eure Unterstützung bitten. Gibt es hier vielleichtr eine elegantere Lösung als:

enum t_modID : uint8_t {type1 = 0x02, type2 = 0x05, type3 = 0x06};

struct t_modData {
	  t_modID  dataType;
	  char     label[11];
	};

const t_modData Modul1[]  PROGMEM = {type1, "TIST"};
const t_modData Modul2[]  PROGMEM = {type1, "DELAY"};
const t_modData Modul3[]  PROGMEM = {type3, "Hallo" };
const t_modData Modul4[]  PROGMEM = {type1, "ABC"};
const t_modData Modul5[]  PROGMEM = {type3, "TEST" };

const t_modData * const ModuleNorm [] [3] PROGMEM = 
 {{Modul1, Modul2, Modul3},
  {Modul1, Modul3, Modul4},
  {Modul1, Modul4, Modul5}};


const size_t ModuleNormCount = sizeof ModuleNorm / sizeof ModuleNorm[0];

char buffer[12];
t_modData buf;

void setup() {
  Serial.begin(115200); Serial.println();
  Serial.print(F("ModuleNorm hat ")); Serial.print(ModuleNormCount); Serial.println(F(" Elemente"));
  for (size_t i = 0; i < ModuleNormCount; i++) {
     for (int j=0; j<3; j++) {
	   
	   // Aus dem Flash in buffer kopieren
       strcpy_P(buffer, (char *)pgm_read_word_near(&(ModuleNorm[i][j])));
	   
       // gefällt mir nicht ! 			
	   buf.dataType = buffer[0];
       Serial.print(F("Type= 0x"));
	   Serial.print(buf.dataType, HEX);
	   Serial.print (" ");
       for (int k=1; k<sizeof(buffer); k++)
           Serial.print(buffer[k]);
	   Serial.println ();
     }
  }
}

void loop() {}

Gibt es hier eine bessere Methode, um mit strcpy_P gleich IN die Variable "buf" vom Typ "t_modData" zu kopieren oder wenigstens die Zeichenkette buffer nach buf zu kopieren, ohne alles vorher zerlegen zu müssen?

Das mit struct gefällt mir sehr, und würde es gerne übernehmen.

Gruß,
Horst

enum t_modID : uint8_t {type1 = 0x02, type2 = 0x05, type3 = 0x06};

struct t_modData {
  t_modID  dataType;
  char     label[11];
};

const t_modData Modul1[]  PROGMEM = {type1, "TIST"};
const t_modData Modul2[]  PROGMEM = {type1, "DELAY"};
const t_modData Modul3[]  PROGMEM = {type3, "Hallo" };
const t_modData Modul4[]  PROGMEM = {type1, "ABC"};
const t_modData Modul5[]  PROGMEM = {type3, "TEST" };

const t_modData * const ModuleNorm [][3] PROGMEM =
{ {Modul1, Modul2, Modul3},
  {Modul1, Modul3, Modul4},
  {Modul1, Modul4, Modul5}
};


const size_t ModuleNormCount = sizeof ModuleNorm / sizeof ModuleNorm[0];


void setup() {
  Serial.begin(115200); Serial.println();
  Serial.print(F("ModuleNorm hat ")); Serial.print(ModuleNormCount); Serial.println(F(" Elemente"));

  // using a local buffer in SRAM
  Serial.println(F("SRAM LOCAL BUFFER"));
  for (size_t i = 0; i < ModuleNormCount; i++) {
    for (size_t j = 0; j < 3; j++) {
      t_modData workData;
      // Aus dem Flash in buffer kopieren
      memcpy_P(&workData, pgm_read_word(&ModuleNorm[i][j]), sizeof workData);

      Serial.print(F("\tType= 0x"));
      Serial.print(workData.dataType, HEX);
      Serial.print("\t");
      Serial.println(workData.label);
    }
    Serial.println();
  }

  // using only flash memory
  Serial.println(F("FLASH MEMORY ACCESS"));
  for (size_t i = 0; i < ModuleNormCount; i++) {
    for (size_t j = 0; j < 3; j++) {
      Serial.print(F("\tType= 0x"));
      Serial.print(pgm_read_byte(&(((const t_modData *) pgm_read_word(&ModuleNorm[i][j]))->dataType)), HEX);
      Serial.print("\t");
      Serial.println((__FlashStringHelper*) (&(((const t_modData *) pgm_read_word(&ModuleNorm[i][j]))->label)));
    }
    Serial.println();
  }
}

void loop() {}

ModuleNorm hat 3 Elemente
SRAM LOCAL BUFFER
	Type= 0x2	TIST
	Type= 0x2	DELAY
	Type= 0x6	Hallo

	Type= 0x2	TIST
	Type= 0x6	Hallo
	Type= 0x2	ABC

	Type= 0x2	TIST
	Type= 0x2	ABC
	Type= 0x6	TEST

FLASH MEMORY ACCESS
	Type= 0x2	TIST
	Type= 0x2	DELAY
	Type= 0x6	Hallo

	Type= 0x2	TIST
	Type= 0x6	Hallo
	Type= 0x2	ABC

	Type= 0x2	TIST
	Type= 0x2	ABC
	Type= 0x6	TEST
1 Like

Das geht! Vielen vielen Dank, J-M-L Jackson!

Ist wirklich ein super Forum hier.

Viele Grüße und noch einen schönen Sonntag,

Horst

Ich bin froh, dass es geholfen hat

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