Проблема при использовании PROGMEM на нотах массива для динамиков на Arduino

Проблема, с которой я столкнулась, немного странная. Я пытаюсь настроить аудио для моего проекта Arduino и играл с примером, включенным в IDE. Проблема в том, что всякий раз, когда я пытаюсь сделать массив заметок в PROGMEM, он выводит заметку выше той, которую я вставлял. Я не хочу, чтобы это делалось. В случае, если это имеет значение, код, который у меня есть, выглядит следующим образом:

    #define tuneSize 2
    // notes in the melody:
    const int melody[tuneSize] PROGMEM /*This is what's screwing it up*/= {
      NOTE_AS3, 0
    };

    // note durations: 4 = quarter note, 8 = eighth note, etc.:
    int noteDurations[tuneSize] = {
      6, 16
    };

    void setup() {
      // no need to repeat the melody.
      // iterate over the notes of the melody:
      for (int thisNote = 0; thisNote < tuneSize; thisNote++) {

        // to calculate the note duration, take one second
        // divided by the note type.
        //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
        int noteDuration = 1000 / noteDurations[thisNote];
        tone(8, melody[thisNote], noteDuration);

        // to distinguish the notes, set a minimum time between them.
        // the note's duration + 30% seems to work well:
        int pauseBetweenNotes = noteDuration * 1.30;
        delay(pauseBetweenNotes);
        // stop the tone playing:
        noTone(8);
    }
}

(Pitch.h можно найти на вкладке примера Arduino под цифрой)

Моя схема имеет 8-омный резистор на контакте 8. Вот и все.

Единственное, что я могу думать, это то, что, поскольку PROGMEM работает медленнее, данные не доходят до динамиков так быстро, что делает выход странным. Кто-нибудь знает, как решить эту проблему? Кроме того, просто иметь его на SRAM не идеально, потому что я работаю с дисплеем, а используемая им библиотека использует много SRAM.

2 голоса | спросил Jo-Bob Bubba 21 MaramTue, 21 Mar 2017 03:22:08 +03002017-03-21T03:22:08+03:0003 2017, 03:22:08

1 ответ


3

Вы не можете напрямую разыменовать что-то («получить доступ к массиву») во флэш-памяти. Вы должны использовать функции pgm_read_xxx из < avr /pgmspace.h > .

В вашем случае вы должны, вероятно, написать что-то вроде этого:

tone(8, pgm_read_word(&melody[thisNote]), noteDuration);

Pgm_read_word читает два байта. Вы также можете вызвать это внутри вашей функции tone (), функция примет указатель во flash в качестве аргумента.

Я также рекомендовал бы использовать целые типы из stdint. h & gt ;, поскольку они имеют определенные размеры. Чистый int, скорее всего, 32-битный на вашем ПК, но 16-бит на AVR (я узнал это с трудом, когда мой алгоритм работал нормально на ПК, но дал полностью мусорный выход на AVR).

ответил filo 21 MaramTue, 21 Mar 2017 09:07:52 +03002017-03-21T09:07:52+03:0009 2017, 09:07:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132