Array di oggetti

Buonasera a tutti!
Vorrei porre una domanda sul codice.

Io sto usando la libreria Adafruit per il display TFT con chip ST7735 congiuntamente con la libreria Adafruit_GFX.

Sto utilizzando due display e vorrei convertire le mie funzioni in funzioni parametriche molto più generiche. Per fare questo però ho bisogno di fare un array con due elementi, ognuno con un "oggetto" display.

Come si deve costruire? Non l'ho mai fatto prima e non ne ho proprio idea.

Vi allego una funzione che voglio "generalizzare" con questo metodo per farvi capire meglio.

void print_Header_Footer(){
  display1.setTextColor(ST7735_WHITE);
  display1.setTextSize(1);
  display1.setCursor(47, 0);
  display1.println("GOSLOT");
  display1.setCursor(8, 150);
  display1.println("vMAX 22 v aMAX 30 A");

  display2.setTextColor(ST7735_WHITE);
  display2.setTextSize(1);
  display2.setCursor(47, 0);
  display2.println("GOSLOT");
  display2.setCursor(8, 150);
  display2.println("vMAX 22 v aMAX 30 A");
}

Voglio chiamare le funzioni con l'oggetto display perché mi sono reso conto che soffro moltissimo la lentezza del cambiamento di indirizzo, per questo motivo voglio fare delle funzioni generiche da chiamare in sequenza per ogni display, finita la sequenza le chiamo per l'altro display, così da fare il cambio di indirizzo il minor numero di volte.

Grazie per le risposte!

Molto molto interessante, hai già provato a fare la funzione passando il display come argomento?
Non so se sia possibile.
Non ho capito perchè vuoi fare un array.

ricki158:
Per fare questo però ho bisogno di fare un array con due elementi, ognuno con un "oggetto" display.
Come si deve costruire? Non l'ho mai fatto prima e non ne ho proprio idea.

Non so, intendi una cosa del genere?

Adafruit_ST7735 tft[2];

void setup() {
  ...
  tft[0] = Adafruit_ST7735(cs0, dc, mosi, sclk, rst);
  tft[1] = Adafruit_ST7735(cs1, dc, mosi, sclk, rst);
  print_Header_Footer(0);
  print_Header_Footer(1);
  ...
}

...

void print_Header_Footer(int disp){
  tft[disp].setTextColor(ST7735_WHITE);
  tft[disp].setTextSize(1);
  tft[disp].setCursor(47, 0);
  tft[disp].println("GOSLOT");
  tft[disp].setCursor(8, 150);
  tft[disp].println("vMAX 22 v aMAX 30 A");
}

???

gianlucaf:
Molto molto interessante, hai già provato a fare la funzione passando il display come argomento?
Non so se sia possibile.
Non ho capito perchè vuoi fare un array.

Voglio fare un array perché ho due oggetti display, poi quando chiamo la funzione generale come argomento do solamente l’elemento che mi interessa (il primo o il secondo display) snellendo così il codice.

docdoc:
Non so, intendi una cosa del genere?

Adafruit_ST7735 tft[2];

void setup() {
  …
  tft[0] = Adafruit_ST7735(cs0, dc, mosi, sclk, rst);
  tft[1] = Adafruit_ST7735(cs1, dc, mosi, sclk, rst);
  print_Header_Footer(0);
  print_Header_Footer(1);
  …
}

void print_Header_Footer(int disp){
  tft[disp].setTextColor(ST7735_WHITE);
  tft[disp].setTextSize(1);
  tft[disp].setCursor(47, 0);
  tft[disp].println(“GOSLOT”);
  tft[disp].setCursor(8, 150);
  tft[disp].println(“vMAX 22 v aMAX 30 A”);
}



???

Si esatto proprio una cosa del genere. Oltretutto non sapevo proprio che tipo di variabile dichiarare sia come argomento che come array.

Adafruit_ST7735 displayTFT[2];

displayTFT[0] = Adafruit_ST7735(cs1, dc1, rst1);
displayTFT[1] = Adafruit_ST7735(cs2, dc2, rst2);

void print_Header_Footer(byte disp){                  /* funzione generica per la stampa dell'intestazione e piè di pagina. per argomento inserisco il display */
  displayTFT[disp].setTextColor(ST7735_WHITE);
  displayTFT[disp].setTextSize(1);
  displayTFT[disp].setCursor(47, 0);
  displayTFT[disp].println("GOSLOT");
  displayTFT[disp].setCursor(8, 150);
  displayTFT[disp].println("vMAX 22 v aMAX 30 A");
}

Non ho scritto le impostazioni iniziali.

Mi da errore sulla prima riga di questo codice

exit status 1
no matching function for call to 'Adafruit_ST7735::Adafruit_ST7735()'

Non so che libreria tu stia usando, se è la "Adafruit_ST7735" (confermi?) dovrebbe accettare la sintassi del costruttore (tra l'altro perché hai raddoppiato le variabili di configurazione? Sono entrambe su SPI, tra le due schede non cambia solo il pin CS?). Ovviamente avrai anche aggiunto la relativa #include, vero?

Insomma, posta il nome e versione della libreria che usi, ed un listato compilabile col quale fai le prove, così capiamo meglio..

Non puoi creare un array di oggetti se la classe non ha un costruttore senza parametri. Devi creare un vettore di puntatori, istanziare gli oggetti parte e inizializzazione il vettore con gli indirizzi.

Quando avrai fatto tutto ciò, ti renderai conto che l'array è inutile: passa direttamente alla funzione come parametro il reference del display su cui vuoi agire, come già suggerito.

docdoc:
Non so che libreria tu stia usando, se è la “Adafruit_ST7735” (confermi?) dovrebbe accettare la sintassi del costruttore (tra l’altro perché hai raddoppiato le variabili di configurazione? Sono entrambe su SPI, tra le due schede non cambia solo il pin CS?). Ovviamente avrai anche aggiunto la relativa #include, vero?

Insomma, posta il nome e versione della libreria che usi, ed un listato compilabile col quale fai le prove, così capiamo meglio…

Si la libreria è proprio quella. La versione non la so ma è l’ultima credo perché l’ho scaricata questo inverno. Negli header c’è soltanto l’anno che è il 2013.

#define sclk 15                                       /* clock della comunicazione SPI, in comune tra i due display. il pin è il 15 per Arduino Pro Micro. */
#define mosi 16                                       /* comunicazione unidirezionale master -> slave, in comune tra i due display. il pin è il 16 per Arduino Pro Micro. */
#define cs1 4                                         /* selezione dello slave 1, primo display. */
#define dc1 5                                         /* pin dc dello slave 1, primo display. */
#define rst1 6                                        /* reset dello slave 1, primo display. */
#define cs2 7                                         /* selezione dello slave 2, secondo display */
#define dc2 8                                         /* pin dc dello slave 2, secondo display */
#define rst2 9                                        /* reset dello slave 2, secondo display */

#include <SPI.h>                                      /* libreria per comunicazione SPI */
#include <Adafruit_GFX.h>                             /* libreria grafica di Adafruit */
#include <Adafruit_ST7735.h>                          /* libreria per il chip ST7735 di gestione del display */

Adafruit_ST7735 displayTFT[2];

displayTFT[0] = Adafruit_ST7735(cs1, dc1, rst1);
displayTFT[1] = Adafruit_ST7735(cs2, dc2, rst2);

void print_Header_Footer(byte disp){                  /* funzione generica per la stampa dell'intestazione e piè di pagina. per argomento inserisco il display */
  displayTFT[disp].setTextColor(ST7735_WHITE);
  displayTFT[disp].setTextSize(1);
  displayTFT[disp].setCursor(47, 0);
  displayTFT[disp].println("GOSLOT");
  displayTFT[disp].setCursor(8, 150);
  displayTFT[disp].println("vMAX 22 v aMAX 30 A");
}

void setup() {
  print_Header_Footer(0);
  print_Header_Footer(1);
}

void loop() {}

Per cui dici che anziché chiamare l’elemento di un array è più semplice se chiamo direttamente il nome dell’oggetto? Che tipo di variabile chiamo?

SukkoPera:
Non puoi creare un array di oggetti se la classe non ha un costruttore senza parametri.

Ok io, come detto, non avendo quella libreria non l'ho mai usata e mi pare eccessivo dovermi mettere io a studiarla.. :wink:

Ma qual è il problema?

Adafruit_ST7735 display1(cs1, dc1, rst1);
Adafruit_ST7735 display2(cs2, dc2, rst2);

void print_Header_Footer(Adafruit_ST7735& disp){
  disp.setTextColor(ST7735_WHITE);
  // ...
}

void loop () {
  print_Header_Footer(display1);
  print_Header_Footer(display2);
}

Avere un array ha senso se puoi averne N e devi fare le stesse cose su tutti. In questo caso:

Adafruit_ST7735 display1(cs1, dc1, rst1);
Adafruit_ST7735 display2(cs2, dc2, rst2);

const byte N_DISPLAYS = 2;

Adafruit_ST7735* displays[N_DISPLAYS] = {
  &display1,
  &display2
};

void loop() {
  for (byte i = 0; i < N_DISPLAYS; ++i) {
    print_Header_Footer(*displays[i]);
  }
}

Basta studiare il linguaggio, guardare in giro come fanno gli altri e sperimentare, senza paura.

SukkoPera:
Ma qual è il problema?

Adafruit_ST7735 display1(cs1, dc1, rst1);

Adafruit_ST7735 display2(cs2, dc2, rst2);

void print_Header_Footer(Adafruit_ST7735& disp){
  disp.setTextColor(ST7735_WHITE);
  // ...
}

void loop () {
  print_Header_Footer(display1);
  print_Header_Footer(display2);
}




Basta studiare il linguaggio, guardare in giro come fanno gli altri e sperimentare, senza paura.

Per trovare cose semplici, si studiano anche. Il problema è trovare cose complesse, capirle e farle proprie e provare. Spesso manca il passo successivo.

Comunque ho provato il tuo codice ma mi da

exit status 1
variable or field 'print_Header_Footer' declared void

Proprio sull'intestazione della funzione

Adafruit_ST7735 display1(cs1, dc1, rst1);  /* creazione oggetto display1 per la libreria Adafruit di gestione del chip del display */
Adafruit_ST7735 display2(cs2, dc2, rst2);  /* creazione oggetto display2 per la libreria Adafruit di gestione del chip del display */

void print_Header_Footer(Adafruit_ST7753& disp){
  disp.setTextColor(ST7735_WHITE);                /* imposta il colore bianco per il carattere */
  disp.setTextSize(1);                            /* imposta la dimensione 1 del carattere */
  disp.setCursor(47, 0);                          /* punta al pixel 47, 0 sul display1 */
  disp.println("GOSLOT");                         /* scrivi GOSLOT*/
  disp.setCursor(8, 150);                         /* punta al pixel 8, 150 sul display1 */
  disp.println("vMAX 22 v aMAX 30 A");            /* scrivi vMAX 22 v aMAX 30 A */
}

Hai lasciato un prototipo vecchio prima?

SukkoPera io sto ancora cercando di decifrare il tuo #6 :smiley:
il tuo #9 è più chiaro per me... è inutile, sono pragmatico :smiley:

SukkoPera:
Hai lasciato un prototipo vecchio prima?

No, sto verificando tramite l’IDE se il codice è corretto

#define sclk 15                                       /* clock della comunicazione SPI, in comune tra i due display. il pin è il 15 per Arduino Pro Micro. */
#define mosi 16                                       /* comunicazione unidirezionale master -> slave, in comune tra i due display. il pin è il 16 per Arduino Pro Micro. */
#define cs1 4                                         /* selezione dello slave 1, primo display. */
#define dc1 5                                         /* pin dc dello slave 1, primo display. */
#define rst1 6                                        /* reset dello slave 1, primo display. */
#define cs2 7                                         /* selezione dello slave 2, secondo display */
#define dc2 8                                         /* pin dc dello slave 2, secondo display */
#define rst2 9                                        /* reset dello slave 2, secondo display */

#include <SPI.h>                                      /* libreria per comunicazione SPI */
#include <Adafruit_GFX.h>                             /* libreria grafica di Adafruit */
#include <Adafruit_ST7735.h>                          /* libreria per il chip ST7735 di gestione del display */

Adafruit_ST7735 display1(cs1, dc1, rst1);             /* creazione oggetto display1 per la libreria Adafruit di gestione del chip del display */
Adafruit_ST7735 display2(cs2, dc2, rst2);             /* creazione oggetto display2 per la libreria Adafruit di gestione del chip del display */

void print_Header_Footer(Adafruit_ST7533& disp){
  disp.initR(INITR_BLACKTAB);                     /* inizializza il chip ST7735 per il display1 */
  disp.fillScreen(ST7735_BLACK);                  /* pulisci il display1 */
  disp.setTextColor(ST7735_WHITE);                /* imposta il colore bianco per il carattere */
  disp.setTextSize(1);                            /* imposta la dimensione 1 del carattere */
  disp.setCursor(47, 0);                          /* punta al pixel 47, 0 sul display1 */
  disp.println("GOSLOT");                         /* scrivi GOSLOT*/
  disp.setCursor(8, 150);                         /* punta al pixel 8, 150 sul display1 */
  disp.println("vMAX 22 v aMAX 30 A");            /* scrivi vMAX 22 v aMAX 30 A */
}

void setup() {

  Serial.begin(9600);                                 /* inizializza la seriale */
  pinMode(sclk, OUTPUT);                              /* imposta il pin sclk in output */
  pinMode(mosi, OUTPUT);                              /* imposta il pin mosi in output */
  pinMode(cs1, OUTPUT);                               /* imposta il pin cs1 in output */
  pinMode(dc1, OUTPUT);                               /* imposta il pin dc1 in output */
  pinMode(rst1, OUTPUT);                              /* imposta il pin rst1 in output */
  pinMode(cs2, OUTPUT);                               /* imposta il pin cs2 in output */
  pinMode(dc2, OUTPUT);                               /* imposta il pin dc2 in output */
  pinMode(rst2, OUTPUT);                              /* imposta il pin rst2 in output */

  print_Header_Footer(display1);
  print_Header_Footer(display2);
}

void loop() {}

E mi restituisce errore

exit status 1
variable or field 'print_Header_Footer' declared void

Alla riga

void print_Header_Footer(Adafruit_ST7533& disp){

ciao...forse l'errore è che tu crei due oggetti Adafruit_ST7735 ma poi nella funzione richiedi un oggetto Adafruit_ST7533 ...cioè con i numeri alla fine diversi...verifica.

Quello è sicuramente da correggere, però non capisco il messaggio di errore nello specifico :/.

Ho corretto ma l’errore rimane uguale.

Comunque per far capire come mai mi serve creare delle funzioni con parametri vi allego il programma che ho fatto e che ha un sacco di funzioni di stampa e cancellazione.

P.S.: questo programma ha la gestione “normale” delle funzioni.

Voltmetro_Pista_TEST_DISPLAY_KEYBOARD.ino (59.6 KB)

...ho fatto una prova...spero di aver scaricato le librerie giuste.
Se lascio tutto come da codice ho anch'io lo stesso errore (ed anche altri)...se correggo il tipo di oggetto richiesto dalla funzione (vedi mio post precedente)...tutto compila senza problemi...se funziona realmente non lo so.

EDIT: questo post l'ho scritto prima dell'ultimo di ricki158

Non c’è niente di male nel creare funzioni, anzi… È cosa buona e giusta.

Io non posso provare, ma visto il post del buon Orso, direi che non hai corretto bene, riprova.

Un altro approccio potrebbe essere quello di derivare la classe del display, se devono fare cose diverse ma in corrispondenza delle stesse azioni:

class MyDisplay1: public Adafruit_ST7735 {
public:
  MyDisplay1(): Adafruit_ST7735(cs1, dc1, rst1) {
  }

  void print_Header_Footer(){
    setTextColor(ST7735_WHITE);
    // ...
  }
}

class MyDisplay2: public Adafruit_ST7735 {
public:
  MyDisplay2(): Adafruit_ST7735(cs2, dc2, rst2) {
  }

  void print_Header_Footer(){
    setTextColor(ST7735_BLUE);    // Notare che qua ho messo blue
    // ...
  }
}

const byte N_DISPLAYS = 2;

MyDisplay1 display1;
MyDisplay2 display2;
Adafruit_ST7735* displays[N_DISPLAYS] = {
  &display1,
  &display2
};

void loop() {
  for (byte i = 0; i < N_DISPLAYS; ++i) {
    displays[i] -> print_Header_Footer();
  }
}

giusto per far vedere cosa succede a me…