Perché #define SSD1306_NO_SPLASH non funziona?

Ciao a tutti

Non interessato al logo iniziale Adafruit, inizialmente avevo semplicemente messo nel setup:
display.clearDisplay();
ma il logo veniva comunque caricato, occupando memoria e rallentando il caricamento. Ho visto, allora, che la Adafruit, in seguito a una richiesta, ha inserito:
#ifndef SSD1306_NO_SPLASH
(riga 501 del cpp), ma anche scrivendo:
#define SSD1306_NO_SPLASH
nel codice non ottengo l'effetto sperato, nemmeno mettendolo prima di:
#include <Adafruit_SSD1306.h>
come dicono di fare in SSD1306_NO_SPLASH not working? - adafruit industries

L'unica soluzione che ho trovato è stata inserire
#define SSD1306_NO_SPLASH
direttamente nel cpp della libreria. C'è un'altra soluzione, che funzioni anche su un altro computer con la libreria non modificata o con una versione successiva?

Grazie
Gianluca

Secondo me no. Per come compila i pezzi Arduino IDE.

P.S. La define dovrebbe andare bene anche inserita DENTRO Adafruit_SSD1306.h, include richiamato dal .cpp ma non ti cambia molto, all'aggiornarsi della lib... si perde.

SI, NON usare quel mattone della libreria Adafruit per gli SSD1306 ... ci sono un'infinità di ottime librerie, molto più veloci, efficienti ed ottimizzate ... sei andato a prendere la peggio :confused:

Intanto decidi, ti serve la "grafica" o devi lavorare con solo "testo" ... perché, anche li, le ottimizzazioni nella scelta della libreria cambiano ...

Guglielmo

Ho fatto solo qualche scorrimento di testo.

// Sketch for Arduino magnetometer
// Measures strength of magnetic field with SS49E hall sensor

// #define LCD /* Display LCD 1602, altrimenti OLED SSD1306 */
// E' adatto anche per display OLED  con le 16 righe superiori di colore diverso (p. es. gialle), perché lì scrive nome
// e versione, mentre tutto il resto va nella parte inferiore blu.

const char *percorso=__FILE__; // Dalla macro __FILE__  prende il percorso del file in uso. Questa parte  di programma,
      char ver[10];            // però, si trova  nel file/cartella  dell'IDE c_setup, in cui non è scritta la versione
                               // del programma. La versione è scritta nel file principale, che ha lo stesso nome della
                               // cartella che contiene tutti i file del programma. Questa  riga, quindi, non può stare
                               // nel setup.
#include <EEPROM.h>
#ifdef LCD
  #include <PCF8574_HD44780_I2C.h>
  // LCD 16x2 con indirizzo I2C 0x27:
  PCF8574_HD44780_I2C lcd(0x27,16,2);
#else // OLED
  #include <SPI.h>
  #include <Wire.h>
  #include <Adafruit_SSD1306.h> // v2.5.7 Ok
  #include <Adafruit_GFX.h> // v1.0.6 Ok
  Adafruit_SSD1306 display(128,64,&Wire,-1);
  
  char txtDC_old[10]="         "; // Testo DC precedente per cancellarlo. E' inizializzata con 9 spazi.
  char txtAC_old[10]="         "; // Testo AC precedente per cancellarlo. E' inizializzata con 9 spazi.
#endif

#define nmeas 2000      // stay below 2048 to avoid overflow
uint16_t nmeas_div_2 = nmeas/2;
#define cal_int 0.349*0.582 // calibration constant in mT per ADC count. nominal (5.0/1024)/0.014=0.349:               
#define cal_est 0.349*0.582
float cal=cal_int;
#define per_let_bat 10000 // Periodo di lettura della tensione della batteria in ms: 10 secondi.
bool puls_prec=HIGH;
uint32_t t_press=0; // millis() alla pressione del pulsante.
float zero = 511.0; // nominal 511: halfway 0 and 1023
float temp;
bool zero_fatto=LOW;
bool G_mT=LOW; // HIGH=Gauss; LOW=mT.
bool sonda_int_est=LOW; // HIGH=sonda interna; LOW=sonda esterna.
bool sonda_int_est_prec=HIGH; // HIGH=sonda interna; LOW=sonda esterna.

uint32_t t_int_est=0; // Per la verfica della presenza della sonda esterna.
uint16_t vbat; // Tensione della batteria: lettura di A3: 1023=10V.
uint32_t t_bat=per_let_bat; // Per la lettura periodica della tensione della batteria, impostato per una prima lettura immediata.
uint32_t t_interm_bat; // Per l'intermittenza della batteria scarica.
bool corpo_bat=true; // Corpo della batteria visibile/non visibile per l'intermittenza.


void Bip()  {tone(5,2000,100);}
void Biip() {tone(5,2000,400);}

void batteria()
{
analogReference(INTERNAL);
analogRead(A3); delay(10); vbat=analogRead(A3); // Serve un delay di almeno 7ms.
if(vbat>=860) display.fillRect(111,2,3,7,WHITE);  // Barretta 4.
else         display.fillRect(111,2,3,7,BLACK);
if(vbat>=800) display.fillRect(115,2,3,7,WHITE);  // Barretta 3.
else         display.fillRect(115,2,3,7,BLACK);
if(vbat>=740) display.fillRect(119,2,3,7,WHITE);  // Barretta 2.
else         display.fillRect(119,2,3,7,BLACK);
if(vbat>=680) display.fillRect(123,2,3,7,WHITE);  // Barretta 1.
else         display.fillRect(123,2,3,7,BLACK);
// display.display(); // Anche qui è inutile!...
analogReference(DEFAULT);
analogRead(A3); delay(10); 
}


void test_puls()
{
if(digitalRead(6)==LOW) // Se è premuto:
  {
  if(puls_prec==HIGH) // Se è stato premuto adesso:
    {
    Bip();
    puls_prec=LOW;
    G_mT=!G_mT;
    mask_H_Gauss_L_mT();
    }
  }
else t_press=millis();
}

void mask_H_Gauss_L_mT()
{
#ifdef LCD
  lcd.setCursor(11,0);      if(G_mT) lcd.print("G "); else lcd.print("mT");
  lcd.setCursor(11,1);      if(G_mT) lcd.print("G "); else lcd.print("mT");
#else // OLED
  display.setTextSize(1);
  
  display.setCursor(0,29); // DC.
  if(G_mT) // DC - G.
    {
    display.setTextColor(BLACK); display.print("mT");// Cancella.
    display.setCursor(0,29);
    display.setTextColor(WHITE); display.print('G'); // Scrive.
    } 
  else // DC - mT.
    {
    display.setTextColor(BLACK); display.print('G'); // Cancella.
    display.setCursor(0,29);
    display.setTextColor(WHITE); display.print("mT");// Scrive.
    }
    
  display.setCursor(0,56); // AC.
  if(G_mT) // AC - G.
    {
    display.setTextColor(BLACK); display.print("mT");// Cancella.
    display.setCursor(0,56);
    display.setTextColor(WHITE); display.print('G'); // Scrive.
    } 
  else // AC - mT.
    {
    display.setTextColor(BLACK); display.print('G'); // Cancella.
    display.setCursor(0,56);
    display.setTextColor(WHITE); display.print("mT");// Scrive.
    }
#endif
}


void setup()
{
char *ver_ext=strrchr(percorso,'v'); // Va a cercare l'ultima 'v' nel percorso.
byte n_car=strlen(ver_ext)-4; // Calcola la lunghezza escludendo .ino.
strncpy(ver, ver_ext, n_car); // Copia i primi n_car caratteri da ver_ext a ver.
ver[n_car]='\0'; // Mette il terminatore in fondo.

pinMode(A0,INPUT); // Segnale del sensore Hall interno.
pinMode(A1,INPUT); // Segnale del sensore Hall esterno.
pinMode(5, OUTPUT); // Uscita per cicalino passivo.
pinMode(6,INPUT_PULLUP); // Pulsante a GND G/mT e azzeramento.
pinMode(7,INPUT_PULLUP); // Ingresso del consenso a GND della sonda esterna.
pinMode(8, OUTPUT); // Alimentazione per sonda esterna.
analogReference(DEFAULT);

#ifdef LCD
  lcd.init();
  lcd.backlight(); // Backlight ON
  lcd.setCursor(2,0); lcd.print("MAGNETOMETRO");
  lcd.setCursor((16-strlen(ver))/2, 1); lcd.print(ver);
  delay(1500);
  lcd.clear();
  lcd.setCursor(1,0); lcd.print("DC");
  lcd.setCursor(1,1); lcd.print("AC");
  if(digitalRead(7))
  {
  EEPROM.get(0, temp); // float: 0,1,2,3. Legge lo zero della sonda interna.
  if(temp>-1000 && temp<1000) zero=temp;
  }
  else
    {
    EEPROM.get(4, temp); // float: 4,5,6,7. Legge lo zero della sonda esterna.
    if(temp>-200 && temp<200) zero=temp;
    }
  G_mT=EEPROM.read(8); // HIGH=Gauss.
  mask_H_Gauss_L_mT();
#else // OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 0x3C: Indirizzo I2C.
  // display.clearDisplay(); // Cancella immediatamente il logo automatico Adafruit :)
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(28,0); display.print("MAGNETOMETRO");
  display.setCursor((106-15-6*strlen(ver))/2 +20, 8); display.print(ver);

  display.setCursor(0,16); display.print("Press.breve: G/mT RMS");
  display.setCursor(80,28); display.print(">>");
  display.setCursor(0,40); display.print("Press.lunga: Zero DC");
  display.display();
  display.startscrollright(3,4);
  delay(2500);
  display.stopscroll();
  display.setTextColor(BLACK);
  display.setCursor(80,28); display.print(">>"); // Cancella >> che, non so perché, riappare
  display.setTextColor(WHITE);                   // nella posizione iniziale dello scroll!
  for(uint8_t x=0; x<17; x+=4) {display.fillRect(x,16,4,48,BLACK); display.display();}
  if(digitalRead(7))
    {
    display.setCursor(0,0); display.print("Int"); sonda_int_est_prec=LOW;
    }
  else
    {
    display.setCursor(0,8); display.print("Est"); sonda_int_est_prec=HIGH;
    }
  display.setCursor(0,16); display.print("DC");
  display.setCursor(0,43); display.print("AC");
  if(digitalRead(7))
    {
    EEPROM.get(0, temp); // float: 0,1,2,3. Legge lo zero della sonda interna.
    if(temp>-1000 && temp<1000) zero=temp;
    }
  else
    {
    EEPROM.get(4, temp); // float: 4,5,6,7. Legge lo zero della sonda esterna.
    if(temp>-200 && temp<200) zero=temp;
    }
  G_mT=EEPROM.read(8); // HIGH=Gauss.
  mask_H_Gauss_L_mT();
  for(uint8_t x=17; x<125; x+=4) {display.fillRect(x,16,4,48,BLACK); display.display();}
  display.drawRect(106,3,3,5,WHITE);   // Contatto +.
  display.drawRect(109,0,19,11,WHITE); // Corpo.
  display.display();
#endif
}


void loop()
{
if(millis()/1000==0 || millis()-t_bat>per_let_bat)
  {
  t_bat=millis();
  batteria();
  }
if(vbat<680)
  {
  if(millis()-t_interm_bat>500)
    {
    t_interm_bat=millis();
    if(corpo_bat)
      {
      display.drawRect(109,0,19,11,BLACK); // Cancella il corpo.
      display.drawRect(106,3,3,5,BLACK);   // Cancella il contatto +.
      }
    else
      {
      display.drawRect(109,0,19,11,WHITE); // Disegna il corpo.
      display.drawRect(106,3,3,5,WHITE);   // Disegna il contatto +.
      }
    corpo_bat=!corpo_bat;
    }
  }

if(millis()-t_int_est>=500) // Ogni mezzo secondo controlla se è stata inserita la sonda esterna.
  {
  t_int_est=millis();
  sonda_int_est=digitalRead(7);
  if(sonda_int_est!=sonda_int_est_prec)
    {
    display.setTextSize(1);
    if(sonda_int_est) // Sonda interna.
      {
      digitalWrite(8, HIGH); // Alimenta la sonda interna.
      EEPROM.get(0, temp); // float: 0,1,2,3. Legge lo zero della sonda interna.
      if(temp>-1000 && temp<1000) zero=temp;
      cal=cal_int; // Carica la calibrazione della sonda interna.
      display.setCursor(0,8); display.setTextColor(BLACK); display.print("Est"); // Cancella.
      display.setCursor(0,0); display.setTextColor(WHITE); display.print("Int"); // Scrive.
      }
    else // Sonda esterna.
      {
      digitalWrite(8, LOW); // Toglie tensione alla sonda interna per risparmiare energia.
      EEPROM.get(4, temp); // float: 4,5,6,7. Legge lo zero della sonda esterna.
      if(temp>-1000 && temp<1000) zero=temp;
      cal=cal_est; // Carica la calibrazione della sonda esterna.
      display.setCursor(0,0); display.setTextColor(BLACK); display.print("Int"); // Cancella.
      display.setCursor(0,8); display.setTextColor(WHITE); display.print("Est"); // Scrive.
      }
    delay(200);
    }
  sonda_int_est_prec=sonda_int_est;
  }
  
uint32_t sum=0;
uint32_t sumsq=0;
for(uint16_t n=0; n<nmeas; n++) // Impiega 224ms (112us a lettura), pari a 11 cicli a 50Hz.
  {
  uint32_t val;
  if(sonda_int_est) val=analogRead(A0); // Sonda interna.
  else val=analogRead(A1); // Sonda esterna.
  sum+=val;
  sumsq+=val*val;
  if(n==nmeas_div_2) test_puls(); // Il controllo della pressione del pulsante ogni 224ms 
  }                               // era troppo lento: a volte la pressione non era rilevata,
test_puls();                      // perciò lo faccio anche a metà misura.

if(digitalRead(6)==HIGH) // Se il pulsante non è premuto
  {
  if(puls_prec==LOW) EEPROM.update(8,G_mT); // Se è stato appena lasciato, memorizza G/mT.
  puls_prec=HIGH;
  zero_fatto=LOW;
  }
if(millis()-t_press>1000 && !zero_fatto)
  {
  zero_fatto=HIGH;
  G_mT=!G_mT; // Ripristina la visualizzazione precedente alla pressione lunga.
  mask_H_Gauss_L_mT();
  zero=(float)sum/nmeas;
  if(sonda_int_est) EEPROM.put(0, zero); // Memorizza lo zero della sonda interna.
  else EEPROM.put(4, zero); // Memorizza lo zero della sonda esterna.
  Biip();
  }

// Calculate DC and AC field strength. AC corresponds to RMS of the fluctuations
float B_DC = ((float)sum/nmeas - zero)*cal;
float B_ACsq = ((float)sumsq/nmeas - pow((float)sum/nmeas, 2))*pow(cal, 2);
float B_AC = 0.0;
if (B_ACsq>0.000025) B_AC=pow(B_ACsq, 0.5);
B_AC=pow(B_ACsq, 0.5);

char txt[10]; // Text buffer needed to print formatted float  
#ifdef LCD
  lcd.setCursor( 3, 0);
#else
  display.setTextSize(3);
#endif

if(!G_mT) // DC in mT.
  {
  dtostrf(B_DC,7,2,txt);
  }
else // DC in G.
  {
  dtostrf(B_DC*10,7,1,txt);
  }

#ifdef LCD
  lcd.print(txt);
#else // OLED
  display.setCursor(0,16);
  display.setTextColor(BLACK); display.print(txtDC_old); // Cancella.
  display.setCursor(0,16);
  display.setTextColor(WHITE); display.print(txt); // Scrive.
#endif

#ifdef LCD
  lcd.setCursor( 3, 1);
#else // OLED
  strcpy(txtDC_old, txt);
#endif

if(!G_mT) // AC in mT.
  {
  dtostrf(B_AC,7,2,txt);
  }
else // AC in G.
  {
  dtostrf(B_AC*10,7,1,txt);
  }
  
#ifdef LCD
  lcd.print(txt);
#else // OLED
  display.setCursor(0,43);
  display.setTextColor(BLACK); display.print(txtAC_old); // Cancella.
  display.setCursor(0,43);
  display.setTextColor(WHITE); display.print(txt); // Scrive.
  display.display();
  strcpy(txtAC_old, txt);
#endif
}


/* 
Fis.I/OPorta
 1   - RS
 2   0 PD0
 3   1 PD1
 4   2 PD2 
 5   3 PD3 
 6   4 PD4 Consenso sonda esterna (a GND).
--
11   5 PD5 Uscita per cicalino passivo.
12   6 PD6 Pulsante di azzeramento DC (con INPUT_PULLUP) verso GND con 100nF in parallelo.
13   7 PD7
14   8 PB0 Alimentazione per sonda interna.
----------
15   9 PB1 
16  10 PB2    
17  11 PB3    
18  12 PB4
19  13 PB5
--
23  14 PC0 A0 SS49E int.
24  15 PC1 A1 SS49E est.
25  16 PC2 A2 
26  17 PC3 A3       Vbat/2
27  18 PC4 A4 SDA | Al display
28  19 PC5 A5 SCL |  SSD1306.
29  20     A6 (solo in Arduino Nano)
          
Fis
 9     PB6 XTAL 16MHz In : compensatore a GND (ho messo 22+10pF).
10     PB7 XTAL 16MHz Out: 22pF a GND.
21    ARef
7,20: Vcc
8,22: GND

EEPROM
0-3: float zero_int.
4-7: float zero_est.
  8: bool Gauss/mT.
*/

.. lascia stare la prova che hai fatto, a te COSA serve? Perché ci sono librerie diverse per le diverse esigenze ... :roll_eyes:

Guglielmo

All'accensione, scorre ">>" per indicare il pulsante:
display.startscrollright(3,4); // Dalla terza alla quarta riga, per come le intende la libreria, per spostare tutto il simbolo ">>".

Poi scorre un sottile rettangolo nero (4x48 pixel) per cancellare progressivamente il messaggio iniziale:
for(uint8_t x=17; x<125; x+=4) {display.fillRect(x,16,4,48,BLACK); display.display();}

A parte la piccola difficoltà nell'eliminare il logo iniziale, però, per quelle poche funzioni che uso va benissimo.

Penso che Guglielmo si riferisca al fatto che c'è almeno una libreria SSD1306 che gestisce solo testo, no grafica e credo sia molto più leggera.

Sì, capisco. Che libreria potrei usare per fare:

  • Scritte piccole e grandi
  • Il simbolo della batteria
  • ">>" che scorre pixel per pixel
  • La tendina che cancella?

Allo stato attuale, il programma occupa 19622 byte (60%) e le variabili 590 byte sul 328p. Prima di modificare la libreria, il programma occupava circa 2kB in più (65%).

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