Problema tra piezo e schermo oled 0,96 pollici

Ciao a tutti,
spero che qualcuno mi possa aiutare perchè ci sto già sbattendo la testa da un po' e non trovo la soluzione ho questo pezzo di codice trovato qui Pacman Intro Theme – e-boombots | Gideon Buniel (l'ho leggermente modificato per usare la libreria Tone rispetto all'originale, ma nulla di che è identico)

#include <Tone.h>

// Buzzer
const int buzzerPin = 8;
Tone buzzer;

void setup() {
  // Start buzzer
  buzzer.begin(buzzerPin);
}

void loop() {
   jinlePacMan();
}

void jinlePacMan() {
  // change this to make the song slower or faster
  int tempo = 105;
  
  // notes of the moledy followed by the duration.
  // a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
  // !!negative numbers are used to represent dotted notes,
  // so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
  int melody[] = {
    // Pacman
    // Score available at https://musescore.com/user/85429/scores/107109
    NOTE_B4, 16, NOTE_B5, 16, NOTE_FS5, 16, NOTE_DS5, 16, //1
    NOTE_B5, 32, NOTE_FS5, -16, NOTE_DS5, 8, NOTE_C5, 16,
    NOTE_C6, 16, NOTE_G6, 16, NOTE_E6, 16, NOTE_C6, 32, NOTE_G6, -16, NOTE_E6, 8,
    NOTE_B4, 16,  NOTE_B5, 16,  NOTE_FS5, 16,   NOTE_DS5, 16,  NOTE_B5, 32,  //2
    NOTE_FS5, -16, NOTE_DS5, 8,  NOTE_DS5, 32, NOTE_E5, 32,  NOTE_F5, 32,
    NOTE_F5, 32,  NOTE_FS5, 32,  NOTE_G5, 32,  NOTE_G5, 32, NOTE_GS5, 32,  NOTE_A5, 16, NOTE_B5, 8
  };
  // sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
  // there are two values per note (pitch and duration), so for each note there are four bytes
  int notes = sizeof(melody) / sizeof(melody[0]) / 2;
  // this calculates the duration of a whole note in ms
  int wholenote = (60000 * 4) / tempo;
  int divider = 0, noteDuration = 0;

  for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {
    // calculates the duration of each note
    divider = melody[thisNote + 1];
    if (divider > 0) {
      // regular note, just proceed
      noteDuration = (wholenote) / divider;
    } else if (divider < 0) {
      // dotted notes are represented with negative durations!!
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; // increases the duration in half for dotted notes
    }
    // we only play the note for 90% of the duration, leaving 10% as a pause
    buzzer.play(melody[thisNote], noteDuration * 0.9);
    // Wait for the specief duration before playing the next note.
    delay(noteDuration);
    // stop the waveform generation before the next note.
    buzzer.stop();
  }
}

quando lo eseguo su uno sketch nuovo nessun problema, ma quando lo integro alla mia applicazione ho problema di inizializzazione del display, in particolare fallisce qua:

if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
    Serial.println(F("Errore nell'inizializzazione del display OLED"));
    for (;;)
      ;
  }

ed uso già altri buzzer.play nell'applicazione, senza nessun problema, mentre quando aggiungo questo niente da fare, commentando le due righe buzzer.play e buzzer.stop ovviamente tutto funziona correttamente, qualche avrebbe dei suggerimenti?

componenti

scusate ovviamente mancava di specificare che ho questo define e le librerie(come ho detto tolto quelle due righe funziona tutto)

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Tone.h>
#define OLED_I2C_ADDRESS 0x3C  // Indirizzo I2C del display OLED

Sarebbe bene vedere il programma non funzionante per intero, l'ipotesi possibile è che stai usando troppa memoria. L'uno ha 2K di memoria, 1 se lo prende il display (perlomeno con quella libreria), sea hai definito divesri array come quello che hai postato può essere che la memoria non sia sufficiente.

Ciao, Ale.

ciao Ale, grazie della risposta.

Attualmente mi dice che ho margine(commentando solo le due righe che mandano in loop e non fanno andare lo schermo)
Lo sketch usa 22060 byte (68%) dello spazio disponibile per i programmi. Il massimo è 32256 byte.
Le variabili globali usano 991 byte (48%) di memoria dinamica, lasciando altri 1057 byte liberi per le variabili locali. Il massimo è 2048 byte.

Si, sembra che sia dentro i margini, tuttavia è impossibile stabilire la memoria allocata dinamicamente durante l'esecuzione dello sketch.

Detto in altri termini ciò che stampa si riferisce alla memoria allocata staticamente e non tiene conto dell'allocazione dinamica di memoria (perché non esiste modo).

Metodo begin di Adafruit_SSD1306

bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset,
                             bool periphBegin) {

  if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
    return false;

Prova ad inserire questa riga nel setup dopo la Serial.begin():

// WIDTH = 128
// HEIGHT = 64
Serial.println((128 * ((64 + 7) / 8)));

Stamperà 1024.
malloc è la funzione allocatrice di memoria ram a cui viene richiesto di allocare 1024 byte se fallisce restituisce 0.

PS: detta terra terra, non c'è memoria ram sufficiente.

Ciao.

Come ti ha già fatto notare Mauro, no, il margine non c'è... :grinning:

Possibili rimedi sono: cambiare la libreria (come ha fatto qui uno che aveva il tuo stesso problema), oppure ridurre la memoria occupata dal resto del codice (che ancora non vediamo), oppure usare una scheda con più RAM.

Ciao, Ale.

@matte97p: devi fare "grafica" o ti interessa solo il "testo"?

Perché le librerie di Adafruit sono notoriamente dei mattoni e, pur essendo un esempio da cui prendere spunto, spesso vanno evitate.

Se non devi usare la "grafica", c'è l'ottima SSD1306Ascii che trovi nel gestore librerie dell'IDE ... è fatta molto bene, molto leggera, molto ben documentata e funziona bene ... io la uso da molto tempo e la consiglio sempre qui sul forum.

Guglielmo

ciao! non ho ancora provato quanto detto da mauro, mi serve fare grafica in quanto è una simulazione di un gioco di pac man, quindi disegno muro, oggetti da raccogliere, fantasmi(con animazione degli occhi) ed il pac man stesso con apertura della bocca dinamica. grazie provo anche questa libreria e vedo come va, per ora grazie a tutti.

... mi era sfuggita la parte "grafica", quindi quella libreria NON va bene.

Allora, la migliore che puoi usare, è quella fatta da Rinky-Dink Electronics ... la trovi QUI ... anch'essa molto ben documentata e molto efficiente.

QUI altre sue librerie per l'ambiente Arduino ... dovessero servire :wink:

Guglielmo

1 Like