String Modifikation aus Multi-Array

Hallo Zusammen

Hab ein kleines Problem beim ändern eines Strings.
Hab ein kleines Menü gebaut und durch mehrfaches drücken eines Keys soll man sich durchswitchen können. (wie auf alten Handys früher)
In Codeblocks läuft es, aber auf dem Arduino dann doch nicht.

Irgndwie verliert er die Position im Programm. Mit String bekomme ich es gelöst, aber soll nicht die Lösung sein.

Habt ihr ne Hilfestellung?

Folgender Sketch:

const byte PROGMEM keys[5][4][7] = {
                                         {{"ABCDEF"},                          {"abcdef"},                           {"12345"},                               {0x22, 0xA7, 0x24, 0x25, 0x26, 0x27, 0}},
                                         {{"GHIJKL"},                          {"ghijkl"},                           {"67890"},                               {0x3C, 0x3E, 0x2F, 0x5C, 0x40, 0x5E, 0}},
                                         {{"MNOPQR"},                          {"mnopqr"},                           {0x2E, 0x2C, 0x3A, 0x3B, 0x21, 0x3F, 0}, {0x5F, 0x60, 0x7C, 0x7E, 0xA3, 0xA8, 0}},
                                         {{"STUVWX"},                          {"stuvwx"},                           {0x2B, 0x2D, 0x2A, 0xF7, 0xB1, 0x3D, 0}, {0xA9, 0xAE, 0xAB, 0xBB, 0xB5, 0xBA, 0}},
                                         {{'Y','Z',0xC4, 0xD6, 0xDC, 0xDF, 0}, {'y','z', 0xE4, 0xF6, 0xFC, 0xDF, 0}, {0x28, 0x29, 0x5B, 0x5D, 0x7B, 0x7D, 0}, {0xD8, 0xB4, 0xF8, 0}}
                                         };
  uint8_t key_block = 0;
  uint8_t key_subpos = 0;

  char msg_temp[21] = {"12345678901234567890"};
  uint8_t msg_pos = 0;
  

void set_char_in_text(uint8_t key) {
  static uint8_t key_temp = 255;
  
  if (key_temp == key ) key_subpos += 1; 
  else key_subpos = 0;
  
  Serial.print("key_subpos:");
  Serial.println(key_subpos);
  
  msg_temp[msg_pos] = keys[key][key_block][key_subpos];

  key_temp = key;

}

void setup()
{
    Serial.begin(9600);
    Serial.print("origin:");
    Serial.println(msg_temp);

    for (int i = 0; i < 5; i++) {
       set_char_in_text(0);
     
       Serial.print("modded:");
       Serial.println(msg_temp);
    }
    
}

void loop()
{
  ;
}

CodeBlocks:
codeblocks.png

Arduino:

codeblocks.png

Für PROGMEM benötigst Du wohl eine spezielle Zugriffsmethode1).


Anm.:

  1. gemeint ist das umgangssprachlich, nicht als C++

Hallo,
was soll denn dein Programm machen? Einfach die Strings in deinem mehrdimensionalen Array ausgeben?

Da stimmt deine Array-Index Berechnung vorn und hinten nicht. z.B.:

 msg_temp[msg_pos] = keys[key][key_block][key_subpos];

da wird msg_pos nie verändert, Du schreibst immer in die Position 0.
Wie agmue schon schrieb, brauchst Du für den Zugriff auf das Progmem eine spezielle Funktion, sonst versucht er das aus dem Ram zu holen:

 msg_temp[msg_pos] = pgm_read_byte(&keys[key][key_block][key_subpos])

Einfach mit einer mehrfach geschachtelten for-Schleife geht's:

void setup()
{
  Serial.begin(9600);
  Serial.print("origin:");
  Serial.println(msg_temp);

  for (int key = 0; key < 5; key++) {
    for ( key_block = 0; key_block < 4; key_block++ ) {
      for ( key_subpos = 0; key_subpos < 7; key_subpos++ ) {
        //set_char_in_text(0);
        msg_temp[key_subpos] = pgm_read_byte(&keys[key][key_block][key_subpos]);
      }
      Serial.print("modded:");
      Serial.println(msg_temp);
    }
  }
}

Die Arduino IDE bietet aber auch spezielle Funktionen für den Stringzugriff auf das Progmem.

MicroBahner:
Die Arduino IDE bietet aber auch spezielle Funktionen für den Stringzugriff auf das Progmem.

Diese Funktionen kommen aus der AVR libc. Nicht von der Arduino Software:
https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Zwei-dimensionale Arrays für C Strings sind ok. Aber bei mehr Dimensionen sollte man sich mal Gedanken über vernünftige Datenstrukturen machen

Serenifly:
Diese Funktionen kommen aus der AVR libc. Nicht von der Arduino Software:

Stimmt. Aber dazu muss man erstmal wissen, dass die Arduino IDE intern die AVR libc nutzt. Den meisten hier wird das erstmal nichts sagen :wink: . Wer sich näher mit den Internas der Arduino IDE befasst, wird schnell merken, dass da vieles nicht 'Arduino Software' ist.

Riesen Dank, pgm_read_byte() hat es geregelt.
Die Zuweisung der zu editierten Position erfolgt durch ändern msg_pos.

Vor habe ich damit, den Text der Welcomenachricht zu definieren, um sie dann Tacho meines Autos anzuzeigen.

Das ganze sieht dann so aus (click pic for video):