Как передать статический константный (программный) массив в функцию

Я внедряю чип синтезатора голоса. Чтобы построить фразу, я создаю список фонем, например:

static const uint8_t PROGMEM heybuddy[] = {
  pPA5, pHH1, pEY, pPA5,
  pBB2, pAX, pDD2, pIY, pPA5,pPA5,pPA5,
};

И чтобы воспроизвести их, я делаю следующее:

 for (size_t i=0; i<sizeof(heybuddy); i++){
    say(pgm_read_byte(heybuddy+i));
 }

Поэтому я хотел бы создать функцию, в которой я мог бы просто передать массив функции, которая могла бы позаботиться о цикле и выполнить некоторые другие действия по обслуживанию.

//что я пробовал:
void sayPhrase(const uint8_t *phrase){
  int open = 0;
  for (size_t i=0; i<sizeof(*phrase); i++){

      if(pgm_read_byte(*phrase) != 4 && open == 0){
          Serial.println("mouth open");
          open = 1;
      } else if(pgm_read_byte(*phrase) == 4 && open == 1){
         Serial.println("mouth closed");
         open = 0;
      }
      say(pgm_read_byte(*phrase+i));
    } 
}

Но когда дело доходит до передачи статической константы, я теряюсь. Я пробовал передавать ее как ссылку с помощью *, но ничего из того, что я делаю, не работает — я просто не знаю, как правильно это сделать в C.

То, что у меня есть, компилируется, но, похоже, берет только одну фонему и повторяет ее снова и снова. Остальные теряются.

, 👍2


2 ответа


1

У меня есть несколько подробных примеров доступа к PROGMEM здесь.

Я адаптировал один из примеров, чтобы показать, как вы можете сделать что-то похожее на то, что вам нужно:

const int NUMBER_OF_ELEMENTS = 10;

const char Message0000 [] PROGMEM = "Twas bryllyg, and ye slythy toves"; 
const char Message0001 [] PROGMEM = "Did gyre and gymble"; 
const char Message0002 [] PROGMEM = "in ye wabe:"; 
const char Message0003 [] PROGMEM = "All mimsy were ye borogoves; And ye mome raths outgrabe."; 
const char Message0004 [] PROGMEM = "\"Beware the Jabberwock, my son! \n The jaws that bite, the claws that catch!"; 
const char Message0005 [] PROGMEM = "Beware the Jubjub bird, and shun\n The frumious Bandersnatch!\""; 
const char Message0006 [] PROGMEM = "He took his "; 
const char Message0007 [] PROGMEM = "vorpal sword in hand:"; 
const char Message0008 [] PROGMEM = "Long time the manxome foe he sought - "; 
const char Message0009 [] PROGMEM = "So rested he by the Tumtum tree, \n And stood awhile in thought."; 

const char * const messages[NUMBER_OF_ELEMENTS] PROGMEM = 
   { 
   Message0000, 
   Message0001, 
   Message0002, 
   Message0003, 
   Message0004, 
   Message0005, 
   Message0006, 
   Message0007, 
   Message0008, 
   Message0009, 
   };

void sayPhrase (const char * const * message)
  {
  const char * ptr = reinterpret_cast<const char *>(pgm_read_ptr (message));  // pointer to message
  Serial.println(reinterpret_cast<const __FlashStringHelper *>(ptr));    // and print it
  } // end of sayPhrase

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
    sayPhrase (&messages [i]);

  }  // end of setup

void loop () { } 
,

1

Если вы не против немного поработать с C++:

void sayPhrase(const uint8_t * phrase, size_t size)
{
    bool open = false;
    for (size_t i = 0; i < size; ++i)
    {
        if(pgm_read_byte(phrase) != 4 && !open)
        {
            Serial.println("mouth open");
            open = true;
        }
        else if(pgm_read_byte(phrase) == 4 && open)
        {
            Serial.println("mouth closed");
            open = false;
        }
        say(pgm_read_byte(&phrase[i]));
    } 
}

template< size_t size >
void sayPhrase(const uint8_t (&phrase)[size])
{
    sayPhrase(phrase, size);
}

Который затем можно вызвать непосредственно в массиве:

sayPhrase(heybuddy);

И шаблон выведет размер массива и вызовет нешаблонную функцию.

,