Spostare dei #define

Ho un programmino *.ino che usa una libreria cpp col suo header.
Nellla cpp o un paio di define in cima al codice dopo gli #include.
Tutto funziona senza alcun problema. Gradirei pero' spostare tali define
dalla libreria cpp al file principale ino. Spostandoli senza fare altro pero'
la libreria va in errore in quanto non trova i "valori" riferiti dai define.
Cosa posso fare?
Giorgio Padoan

Non credo tu possa farlo ...
... purtroppo il meccanismo con cui funziona l'IDE di Arduino rende varie cose molto complicate, tra cui la NON possibilità di definire nel .ino alcune cose che poi sono usate nelle "librerie" (che poi tali non sono, perché le vere librerie, negli ambienti di sviluupo, sono pre-compilate).

Ne abbiamo discusso varie volte ed è una vera seccatura, specie con librerie in cui gli #define vanno aggiustati a seconda dell'applicazione ... :roll_eyes:

Guglielmo

Includi direttamente il punto.cpp
Non viene visto nel percorso di ricerca, serve di usare il pathname completo (almeno sotto linux)
Ma va

Oppure copia il testo del punto.cpp nel punto.h e cancella il .cpp ( metti a posto anche i varii #include)

Ne avevo scritto un paio di anni fa

Adesso cerco

Per farla breve il punto.cpp è un'unità di compilazione separata dal punto.ino

Quindi non legge gli #include o le #define che metti nel .ino

O gliele ripeti oppure lo includi esplicitamente nel sorgente

Se lasci solo il suo .h non viene incluso dal compilatore, ma solo collegato dal linker

Cosa che andrebbe assolutamente evitata per come la vedo io. Una libreria dovrebbe essere completamente trasparente per l'utente finale.

Al massimo aggiungi un overload del costruttore o dei metodi che impostano le varie opzioni.

Emmmm ... fortunatamente NON tutto è C++ e costruttori ... :roll_eyes:

... hai presente FreeRTOS? Ha un include, zeppo di #define, che configura TUTTO il sistema operativo :grin:. Sicuramente è il caso più eclatante, ma ci sonno centinaia di altre librerie fatte così.

C'è poco da fare, purtroppo è una grossa limitazione dell'IDE.

Guglielmo

Bhé certo, costruttori in caso di C++, opzioni in caso di C.
FreeRTOS è un intero framework C ben più esteso di una semplice libreria, quindi ci sta che vada configurato per ogni diversa piattaforma considerato anche che può essere usato con numerose MCU anche molto diverse tra loro.

Come hai giustamente fatto notare, le librerie in ambienti di sviluppo diversi da Arduino (compreso MPLAB, che come mi hai confermato non è C++) vengono quasi sempre fornite come dei compilati e senza sorgenti quindi eventuali configurazioni vanno fatte gioco forza lato utente. Certo le NON-limitazioni dell'IDE in questi casi possono essere molto di aiuto.

Che poi ci siano centinaia di librerie cosi, ahimé è vero :frowning:

Eppure anni fa io ho messo dei #define nel .ino che vanno a interagire con la libreria del GPS...

Pura casualità ... un tempo compilava secondo un certo ordine, oggi segue un'altro ordine e le librerie vengono compilate separatamente in modo del tutto indipendente. :confused:

Guglielmo

... perciò se oggi ricompilassi quel programma non funzionerebbe più!!! >:(
Certe cose sono insopportabili!

Non contarci

Dimmi piuttosto che librerie erano
Alcune non hanno il punto.cpp
Su quelle funziona ed ha sempre funzionato

Invece su quelle che sono divise in punto.h e punto.cpp dubito che abbia mai funzionato

// GENERATORE CON DDS E GPS 2019-2021

// Abilitazioni necessarie in NMEAGPS_cfg.h:
#define NMEAGPS_PARSE_GGA
#define NMEAGPS_PARSE_GSV
#define NMEAGPS_PARSE_RMC
#define NMEAGPS_PARSE_SATELLITES
#define NMEAGPS_PARSE_SATELLITE_INFO

#define PREMUTO  (!(PIND&0b00010000)) // I/O 4.
#define NONPREMUTO (PIND&0b00010000)  // I/O 4.

#include <NMEAGPS.h> // Uso la libreria Neo-GPS.
#include <EEPROM.h>
#include <LiquidCrystal.h>
//                R E D4 D5 D6 D7
LiquidCrystal lcd(8,9,10,11,12,13);

char *percorso=__FILE__; // Dalla macro __FILE__ prende il percorso del file in uso. Questa parte di programma,
                         // 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.
char ver[10];

NMEAGPS GPS; // Imposto la seriale per NMEAGPS.
gps_fix fix;

// ATMEGA328P 16MHz con EEPROM Save
// La tolleranza e l'instabilità termica dell'oscillatore interno non garantiscono 
// una comunicazione seriale affidabile con il GPS.

// const byte SW=4; // Il pulsante dell'encoder sta sull'I/O 4.
#define LED_LOCK A0 // pin 23: LED VERDE bicolore verde/rosso.
#define LED_NO_F_NO_LOCK A1 // pin 24: LED ROSSO bicolore verde/rossso.
#define CICALINO A2 // pin 25
#define SWEEP_SINC_OUT A3 // pin 26
// N.B.: Per A0, A1, A3 per far lampeggiare il LED (Giallo) nello sweep ho usato PORT.

Interessante

Mi studio come funziona

Questa cosa potrebbe essere interessante

a prima vista definire delle macro (vuote, attenzione) fa fare un giochino interessante al .h incluso

Il punto.h viene comunque compilato, occhio

esiste un "giochino" di #ifdef.... PROGMEM.... #endif.... che se ho ben capito altera una variabile PROGMEM durante la compilazione del .H (ovvero del .INO, che richiama ll .H)

il .CPP, pur essendo compilato prima, legge dalla FLASH
che viene scritta DOPO la compilazione del programma completo
quindi, pur essendo compilato prima, il .CPP viene influenzato dal programma principale

lo vedo geniale, ma macchinoso

qualcuno può controllare? grazie

PS
Ostia...
ho appena avuto idea per farlo più semplice
stasera provo...

... il problema è che tu puoi trovare tutte le idee geniali che vuoi, ma ... le usi solo TU. Tutte le librerie (che sono migliaia) e l'ambiente, sono fatte diversamente e quindi ... un bell'esercizio teorico, purtroppo dalla scarsa utilità :confused:

Guglielmo

Non mi è chiaro il significato di quello che scrivi, oppure tu non hai chiaro il significato di quello che ho scritto io

data una libreria che "evidentemente" accetta modifiche scritte nel punto.INO, si tratta di capire come ha fatto chi la libreria la ha scritta
come vedi il metodo non lo uso solo io, anzi, io proprio non lo uso...

Ok, no, non era affatto chiaro cosa intendessi ...

Beh, guarda, se ci sono, sono mosche bianche, il 99% NON è scritto così e quindi ... :roll_eyes:

La regola generale, usando l'IDE di Arduino è ... scordatevi di utilizzare nel .ino, con delle #include di librerie, delle #define che possano influenzare la compilazione della librerie.

Che poi ci siano, come detto, delle eccezioni, che con trucchi vari permettono qualche cosa ... tali restano e NON sono, purtroppo, la regola.

Guglielmo

ho trovato questo:

chiarisce qualcosa...

Si fanno prove interessanti, una volta capito il meccanismo...

primo esempio:

come realizzare una libreria dove sia possibile cambiare i parametri, sotto forma di variabili

ammettiamo di avere una libreria che (esempio stupido, solo prova di fattibilità) genera un array locale VLA e ne restituisce la dimensione

abbiamo il file delle dichiarazioni: inclusioni.h

// file inclusioni.h
// prova per delle inclusioni

int inclusione(void);

e il file delle definizioni: inclusioni.cpp


// file inclusioni.cpp
// prova per delle inclusioni
#include "inclusioni.h"
extern int variabile;

int inclusione(void)
{
   int array[variabile];
   return sizeof array / sizeof array[0];
}

come vedete la funzione di libreria inclusione() restituisce la dimensione (calcolata, quindi certamente ottenuta a run-time, di un VLA generata partire da una variabile dichiarata ed inizializzata ... non si sa, dato che è extern

e adesso il programma principale

/* di Nelson-StandardOil
   IDE 1.8.10 -
   Progetto:
   Scopo: provare modifiche a parametri di libreria
*/
#include "inclusioni.h"
int variabile = 10;
void setup(void)
{
   Serial.begin(9600);
   Serial.println(inclusione());
   variabile = analogRead(A1);
   Serial.println(inclusione());
}

void loop(void)
{
}

come vedete la variabile che definisce la dimensione dl VLA di libreria viene dichiarata ed inizializzata nel file.ino
ma ancora più importante si tratta di una variabile, nemmeno di una #define, infatti dopo il primo uso essa viene modificata a run-time con un valore non preconosciuto, quindi siamo certamente nel campo delle variabili pure e dei VLA

certo che tutto questo richiede di essere fatto "prima", non si può applicare a librerie già esistenti, in questo ha ragione Guglielmo