Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Rendere visibili a una libreria le macro nello sketch

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteWALTERmwp, Foto Utentexyz

0
voti

[1] Rendere visibili a una libreria le macro nello sketch

Messaggioda Foto Utentelemure64 » 18 apr 2023, 11:05

Ciao Forum,

Sto scrivendo una libreria che fa uso di un'altra libreria, che ha bisogno di essere inizializzata a livello di costruttore di un'istanza di classe, e non può settare i valori a runtime. Ha un solo costruttore e vuole due parametri. Nello specifico gli servono come parametri due interi che identificano dei pin.

Tutto ovviamente funziona se questi parametri vengono creati e forniti all'interno della mia libreria, ma supponiamo che voglia assegnarli l'utente. Nello sketch posso scrivere, anzi vorrei poter scrivere:

Codice: Seleziona tutto

// codice errato!

#define  PIN_1      12
#define  PIN_2      14

#include <mialibreria.h>

void setup ()
{
    // Non so come, ma la mia libreria "vede" PIN_1 e PIN_2
}

void loop ()
{
}


Ovviamente la mia libreria non "vede" PIN_1 e PIN_2 e difatti mi dà errore in compilazione dei files della mia libreria, non dello sketch. La libreria che devo utilizzare non permette di cambiare i pin a runtime e credo che non sarà l'ultima volta che avrò avuto questo problema.

Ci sono due soluzioni, che ho provato e funzionano.

1) Costringo l'utente a creare l'oggetto che mi occorre e passarlo o come puntatore o come referenza. In questo caso la dipendenza dalla libreria è esplicita per l'utente (dovrebbe sapere che sta usando due librerie) mentre vorrei che non fosse così. Avrei:

Codice: Seleziona tutto
#define  PIN_1      12
#define  PIN_2      14

#include <dipendenza.h>
#include <mialibreria.h>

DependClass      GV_instance (PIN_1, PIN_2) ;

void setup ()
{
    mylib_use (&GV_instance) ;
}

void loop ()
{
}


2) Creo una funzione che accetta i parametri ma devo memorizzare i valori in variabili visibili solo alla libreria, poi usarli per chiamare il costruttore. L'utente vede solo la mia libreria ma spreco una ventina di bytes. E' vero che posso riutilizzare le variabili se le rendo globali alla libreria ma è la strada migliore per creare bugs difficili da identificare. D'altro canto sprecare anche un byte sui micro o arduino mi dà veramente fastidio. In questo caso:

Codice: Seleziona tutto
#define  PIN_1      12
#define  PIN_2      14

#include <mialibreria.h>

void setup ()
{
    /*
     *  I valori passati verranno memorizzati in variabili
     *  globali allocate nell'ambito di visibilità della
     *  mia libreria, poi utilizzate per l'inizializzazione
     *  della libreria che uso nella mia.
     */

    mylib_setup (PIN_1, PIN_2) ;
}

void loop ()
{
}


So che molto dipende dai "numeri". Lo sketch dovrebbe poter girare anche su Arduini di piccola taglia e quanto ai parametri parliamo di una decina di "int", appunto 20-30 byte considerando parametri che ancora non si sono dimostrati necessari. Su "Nano" lo spazio occupato dalla mia e altre libreria inizia a essere impattante. Persino sul Mega arrivo al 18-20% e senza codice utente.

So anche che ci potrebbero essere strade "esoteriche", come derivare una classe da quella della libreria che devo usare, creare un costruttore con parametri dell'oggetto relativo alla mia libreria e passarglieli. Ebbene, queste cose non mi sono mai riuscite o non hanno mai funzionato. Solo leggere i messaggi di errore in gcc quando sono di mezzo questi problemi è un problema a sua volta. Di fatto conosco troppo male il C++ su tanti aspetti, a cominciare appunto dall'annidamento dei parametri dei costruttori. Ma se esiste una soluzione chiara e semplice rispetto alla mia incompetenza e soprattutto è una pratica standard su Arduino suppongo varrà la pena di studiarla. Magari con un esempio se possibile :)

La cosa strana è che la libreria Mysensors sembra riuscire a fare quello che vorrei. Prima dell'istruzione #include è possibile cambiare dei parametri. Ovviamente lo sketch vede le macro ma come fa a vederle la libreria se ciascuno dei suoi sorgenti non vede lo sketch utente?

Grazie per qualsiasi suggerimento. Se non c'è una soluzione migliore sceglierò la seconda perché una libreria ha senso solo se nasconde il più possibile all'utente e se scrivo con cura posso anche riutilizzare le variabili globali. Ma vorrei tanto sapere come fa Mysensors :D
Avatar utente
Foto Utentelemure64
689 3 6
Stabilizzato
Stabilizzato
 
Messaggi: 421
Iscritto il: 23 giu 2020, 12:26

0
voti

[2] Re: Rendere visibili a una libreria le macro nello sketch

Messaggioda Foto Utentelemure64 » 18 apr 2023, 12:57

Mi spiace essere arrivato fuori tempo massimo per cancellare ma google mi ha per una volta aiutato. Pare non sia strutturalmente possibile. I workaround usati sono uno più inelegante dell'altro e mi rassegno a riscrivere parte del codice sprecando un po' di spazio non solo per le variabili di cui al post precedente, ma anche di codice. Sperando che sia possibile riorganizzarlo tenendo conto di questo limite.

Il modo standard a quanto pare è trasformare tutti i .cpp in .h, come si fa in aclune librerie come ad esempio boost. Ma il mio problema è che comunque servono istanze di classi visibili a livello globale, e che queste devono essere diverse a seconda dei casi. Fare queste cose fuori dai normali file .cpp è sempre un pasticcio se mai è possibile.
Avatar utente
Foto Utentelemure64
689 3 6
Stabilizzato
Stabilizzato
 
Messaggi: 421
Iscritto il: 23 giu 2020, 12:26

1
voti

[3] Re: Rendere visibili a una libreria le macro nello sketch

Messaggioda Foto UtenteGioArca67 » 18 apr 2023, 13:29

Magari è una risposta stupida, ma non puoi far mettere i define dei pin in un include di "configurazione" che è incluso sia dalle librerie che ti servono sia (anche se inutile, ma solo per ricordare che deve impostare delle cose) dallo sketch (con gli appropriati controlli per evitare i duplicati di inclusione?).
Avatar utente
Foto UtenteGioArca67
4.580 4 6 9
Master EY
Master EY
 
Messaggi: 4591
Iscritto il: 12 mar 2021, 9:36

0
voti

[4] Re: Rendere visibili a una libreria le macro nello sketch

Messaggioda Foto Utentelemure64 » 18 apr 2023, 17:34

GioArca67 ha scritto:Magari è una risposta stupida, ma non puoi far mettere i define dei pin in un include di "configurazione" che è incluso sia dalle librerie che ti servono sia (anche se inutile, ma solo per ricordare che deve impostare delle cose) dallo sketch (con gli appropriati controlli per evitare i duplicati di inclusione?).


Non è stupida, anzi mi hai dato l'ispirazione per realizzare in parte la tua idea.

L'IDE di Arduino non accetta percorsi relativi per cose fuori dalla cartella dello sketch, in rete trovo che è una scelta "by design". Quindi se inserissi questo file di configurazione nella cartella della libreria bisognerebbe che l'utente editasse un file nella cartella delle librerie di arduino, cosa ovviamente pericolosa. Ma si potrebbe risolvere creando una sottocartella in cui ci fosse questo solo file di configurazione.

Se devo giudicare sulla mia esperienza personale, appena lo "sbattimento" va oltre inserire #include<libreriapippo> nello sketch, una libreria non la usa quasi nessuno. Per ora è per un problema mio ma non mi dispiacerebbe renderla disponibile, assieme a un'altra a cui sto lavorando.

Il problema è che la mia libreria vorrebbe essere un sistema che permetta la comunicazione tra un master e più slave, che in linea di principio potrebbero essere tutte board diverse; i parametri mi servono per specificare i pin RX/TX, dato che sto usando SoftwareSerial per tenere libera la seriale. Quindi l'utente dovrebbe compilare ciascuno sketch modificando di volta in volta il file di configurazione per ciascun arduino che intende usare. Ho paura che il pericolo di lasciare la libreria in uno stato incoerente sia un po' alto.

Nel frattempo ho risolto con una delle alternative che avevo ipotizzato: dichiaro esplicitamente la dipendenza, "costringo" l'utente a creare un'istanza dell'oggetto SoftwareSerial specificando i pin nello sketch tramite il costruttore, e poi passa alla mia libreria il relativo puntatore che viene memorizzato e utilizzato.

Non mi piace nemmeno un po' ma penso sia la strada esteticamente meno brutta compatibilimente con il fatto di non costringere l'utente ad accedere direttamente ai files della libreria.

Ho invece utilizzato il tuo suggerimento per i parametri che cambiano meno, nello specifico le velocità in baud. Dato che in questo caso sto privilegiando la robustezza e trasmetto il messaggio più di una volta con delle triplette di caratteri di controllo a inizio e fine, ho già visto che sotto 9600 uno scambio di messaggi va oltre i 1000 ms di tempo, che inizia a essere troppo persino in questo caso. Ma se pure in circostanze specialissime, si potrebbe voler ridurlo e allora c'è quel solo file dedicato a quel genere di parametri.
Avatar utente
Foto Utentelemure64
689 3 6
Stabilizzato
Stabilizzato
 
Messaggi: 421
Iscritto il: 23 giu 2020, 12:26


Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti