#include in più schede

Buonasera, sono 2 giorni che non riesco a venire a capo di questo problema, che magari è anche semplice da risolvere.

Ho creato uno sketch principale con 2 schede secondarie in modo da ordinare il codice e raggruppare le varie funzioni che implemento

il programma è impostato cosi:

"chiavi.ino"
"GiocoLuci.h"
"CelleCarico.h"

nel file principale chiavi.ino ho incluso le 2 righe di codice per includere le altre 2 schede

#include "GiocoLuci.h"
#include "CelleCarico.h"

ho necessita pero anche nel file "CelleCarico.h" di chiamare funzioni che si trovano nella scheda GiocoLuci ma se includo di nuovo con: #include "GiocoLuci.h" mi compila 2 volte la scheda e di conseguenza mi da errore che trova variabili e funzioni duplicate.
Se però non includo mi da errori di funzioni non dichiarate perchè si trovano nell' altra scheda

Come risolvo il problema di includere la stessa scheda in piu schede?

Scusa ma i file .h contengono solo prototipi e definizioni o anche codice? Perché se come immagino è la seconda, sono oggetti diversi compilati separatamente (e poi linkati insieme) quindi non possono "vedersi" implicitamente tra loro.

Temo che tu debba farci vedere i listati per farci capire cosa stai facendo, e soprattutto cosa vuoi fare...

praticamente nel file GiocoLuci.h gestisco la colorazione arcobaleno di una matrice Neopixel che pero mi blocca arduino perchè non potendo fare multitasking non mi va in lettura delle celle di carico "void PesoColonna1 ()"

uint32_t Wheel(byte WheelPos) {
  if (WheelPos < 85) {
    return PixelColonna1.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
  else if (WheelPos < 170) {
    WheelPos -= 85;
    return PixelColonna1.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  else {
    WheelPos -= 170;
    return PixelColonna1.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


void rainbowColonna1(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < PixelColonna1.numPixels(); i++) {
      PixelColonna1.setPixelColor(i, Wheel((i * 1 + j) & 255));
      PesoColonna1();
    }
    PixelColonna1.show();
    delay(wait);
  }
}

di conseguenza durante la funzione rainbow ad ogni cambio colore vado a richiamare la funzione di lettura della cella di carico ma essendo nel file CelleCarico.h non lo esegue perchè lo trova non dichiarato

la funzione PesoColonna1(); fa ciò:

void  PesoColonna1() {
  PesoRilevato = colonna1.get_units(2), 0;
  PesoRilevato = PesoRilevato * -1;
  if ((PesoRilevato >= (Peso4 - 50)) && PesoRilevato <= (Peso4 + 50)) {
    //Peso OK
    c1 = true;
    Serial.println("Colonna 1 OK;");
  } else {
    //Peso Sbagliato
    c1 = false;
  }
}

ho letto da quelche parte che si po ovviare il problema di doppia compilazione utilizzando

#ifdef
#ifndef
ecc..

ma non li ho mai utilizzati e non riesco a capire come procedere

Ciao! Se nell'ide arduino hai più schede con codice, il tutto alla fine viene visto come un unico sorgente "come se fosse un unico file". Ide arduino è diverso da altri ambienti.
Adesso non so cosa succede chiamando i file con estensione .h, ma se le varie schede sono file .ino è come se fosse un unico sorgente per cui tu programmi nelle varie schede come se fossi in un unico file, senza bisogno di #include.

Il tuo programma si chiamerà "chiavi.ino" e conterrà:

  • una prima parte di definizioni globali
  • una sezione "void setup()"
  • una sezione "void loop()"
  • una sezione "uint32_t Wheel(byte WheelPos)"
  • una sezione "void rainbowColonna1(uint8_t wait)"
  • una sezione "void PesoColonna1()"
    tutte di seguito l'una all'altra nello stesso sketch.

Come ti è stato detto, compilate insieme si "vedranno" l'una all'altra.

Ciao,
P.

pgiagno:
Il tuo programma si chiamerà "chiavi.ino" e conterrà:

  • una prima parte di definizioni globali
  • una sezione "void setup()"
  • una sezione "void loop()"
  • una sezione "uint32_t Wheel(byte WheelPos)"
  • una sezione "void rainbowColonna1(uint8_t wait)"
  • una sezione "void PesoColonna1()"
    tutte di seguito l'una all'altra nello stesso sketch.

Come ti è stato detto, compilate insieme si "vedranno" l'una all'altra.

Ciao,
P.

ok cosi so che funziona essendo tutto insieme, io volevo dividere il tutto semplicemente per comodità di lettura del codice, so che in quella sezione andrò a fare tutti i giochi di luce ecc. senza avere poi a fine programma migliaia di righe di codice che poi se devo cercare qulacosa diventa un problema anche in un futuro se dovò rimetterci mano

torn24:
Ciao! Se nell'ide arduino hai più schede con codice, il tutto alla fine viene visto come un unico sorgente "come se fosse un unico file". Ide arduino è diverso da altri ambienti.
Adesso non so cosa succede chiamando i file con estensione .h, ma se le varie schede sono file .ino è come se fosse un unico sorgente per cui tu programmi nelle varie schede come se fossi in un unico file, senza bisogno di #include.

ho fatto come mi hai detto tu, ho tolto le estensioni .h e fatto schede che sono .ino.
Non devo dichiarare nessuna scheda e tutte si vedono tra di loro, l' unica cosa che la chiamata delle varie librerie va definita nell' ino principale altrimenti da che non sono stati dichiarati

l' unica cosa che la chiamata delle varie librerie va definita nell' ino principale altrimenti da che non sono stati dichiarati

Ovviamente, tutti i vari file delle schede vengono messi insieme e considerati un unico sorgente, se usi delle librerie queste dovranno essere incluse un unica volta come se lavorassi con un unico grosso file sorgente :slight_smile:

Aspire92:
praticamente nel file GiocoLuci.h gestisco la colorazione arcobaleno di una matrice Neopixel

Allora, facciamo un attimo di chiarezza.

I file *.h sono degli "Header file" (da qui l'estensione .h) ossia il loro scopo sarebbe quello di contenere solamente le "intestazioni" intese come tutti i prototipi delle funzioni che usi, ed in genere anche le costanti, e le variabili globali. Questo consente al compilatore di compilare quel certo modulo anche senza avere l'imlementazione reale delle funzioni (che verranno linkate alla fine) Nei file *.h formalmente potresti anche metterci tutto, come stai facendo tu, ma è una forzatura che in genere si cerca di evitare.

Se nel progetto (ossia nella cartella) metti dei file *.ino questi, come ti hanno scritto, verranno considerati tutti nel programma principale.

Se poi metti dei file *.cpp questi saranno delle classi separate (se non sei pratico di C++ o di programmazione ad oggetti diciamo, per capirci, come se fossero delle tue librerie) ed anche in tal caso devi mettere l'include al file .h della libreria per le ragioni già citate.

torn24:
per cui tu programmi nelle varie schede come se fossi in un unico file, senza bisogno di #include.

Io generalmente se ho un programma un poco complesso faccio un .ino ed uno o più .cpp (quindi creando delle classi che gestiscono le varie cose, classi che poi uso nel main .ino) quindi non ho mai messo più file .ino nel progetto, ma immagino che servano comunque gli #include perché il compilatore compila separatamente ogni .ino e poi li linka insieme, per cui deve "sapere" come sono fatte le funzioni presenti negli altri .ino. Non ci metto la mano sul fuoco, ma credo che sia così.

docdoc:
... non ho mai messo più file .ino nel progetto, ma immagino che servano comunque gli #include perché il compilatore compila separatamente ogni .ino e poi li linka insieme, per cui deve "sapere" come sono fatte le funzioni presenti negli altri .ino. Non ci metto la mano sul fuoco, ma credo che sia così.

No, NON è cosÌ ed è stato ben spiegato prima ... i vari .ino vengono visti come un unico sorgente (riunendoli) e compilati tutti assieme. Dividere in .ino ha il solo scopo di rendere più leggibile la cosa dividendo il sorgente in più parti, ma NON è come avere il .ino ed una serie di .h/.cpp. :wink:

Guglielmo

gpb01:
i vari .ino vengono visti come un unico sorgente (riunendoli) e compilati tutti assieme.

Ah, ok, grazie, come ho destto non ho mai fatto una cosa del genere (ma progetti solo con un ino ed uno o più cpp) quindi ho scritto infatti che non ci avrei messo la mano sul fuoco... :wink:

docdoc:
Ah, ok, grazie, come ho destto non ho mai fatto una cosa del genere ...

Se guardi il post #8, torn24 aveva spiegato cosa avviene :wink:

Guglielmo

gpb01:
Se guardi il post #8, torn24 aveva spiegato cosa avviene :wink:

Si ma non avendo lui citato esplicitamente se siano necessari o meno i file .h, ho immaginato che il compilatore non facesse degli "include impliciti" ossia compilasse separatamente i .ino per cui necessitasse di avere almeno i prototipi.

gpb01:
No, NON è cosÌ ed è stato ben spiegato prima ... i vari .ino vengono visti come un unico sorgente (riunendoli) e compilati tutti assieme. Dividere in .ino ha il solo scopo di rendere più leggibile la cosa dividendo il sorgente in più parti, ma NON è come avere il .ino ed una serie di .h/.cpp. :wink:

Guglielmo

Chiarissimo, in pratica hai risolto il problema che avevo.
Non sapendo che con piu .ino nella stessa cartella venissero compilati come un file solo utilizzavo il metodo dei .h che conoscevo.
di fatto la mia esigenza era solo quella di fare più schede per semplificare la lettura del codice.

Venendo dalla programmazione in visual-Basic nel C ogni tanto mi sfugge qualcosa, ero diventato matto anche cercando "void globali" dato che su VB se si fa un "PrivateSUB" è esclusivo del form dove lo creiamo ma se si fa un "PublicSub" tutti i form del progetto possono richiamarlo

Aspire92:
Venendo dalla programmazione in visual-Basic nel C ogni tanto mi sfugge qualcosa, ero diventato matto anche cercando "void globali" dato che su VB se si fa un "PrivateSUB" è esclusivo del form dove lo creiamo ma se si fa un "PublicSub" tutti i form del progetto possono richiamarlo

Anche io a suo tempo programmavo anche in VB, e ti capisco. Per questo volevo darti qualche prima "imbeccata".

Non chiamare "i void" le funzioni o le subroutine! Il simbolo "void" è il tipo di dato che restituisce quella funzione ma può essere qualsiasi cosa. Ed in C non ci sono le "subroutine" (procedure che non restituiscono alcun valore), sono tutte funzioni.

Per dire, una funzione dichiarata "void" è come la "Sub" del VB, mentre le Function sono definite con qualcosa di diverso da "void".

Ad esempio l'equivalente C di:

Function MiaFunz(a As Integer) As Integer

è:

int MiaFunz(int a)

mentre:

Sub MiaSub(b as iInteger)

è:

void MiaSub(int b)

Ok? Ciao!