Problemi compilazione libreria Adafruit_MCP4725 dopo aver splittato il codice in più file

Salve a tutti,

ho un problema di compilazione del mio codice dopo averlo diviso in molteplici file per favorirne la lettura. In particolare ricevo i seguenti messaggi di errore:

..\Arduino\libraries\Adafruit_MCP4725/Adafruit_MCP4725.h:25:7: warning: type 'struct Adafruit_MCP4725' violates the C++ One Definition Rule [-Wodr]
 class Adafruit_MCP4725 {
       ^
"...\Arduino\libraries\Adafruit_MCP4725\Adafruit_MCP4725.h:31:7: note: a different type is defined in another translation unit
                   uint32_t dac_frequency = 400000);
       ^
...Arduino\libraries\Adafruit_MCP4725/Adafruit_MCP4725.h:34:33: note: the first difference of corresponding definitions is field 'i2c_dev'
   Adafruit_I2CDevice *i2c_dev = NULL;
                                 ^
"...Arduino\libraries\Adafruit_MCP4725\Adafruit_MCP4725.h:38:11: note: a field with different name is defined in another translation unit

...\Arduino\libraries\Adafruit_MCP4725\Adafruit_MCP4725.cpp:36:1: note: implicit this pointer type mismatch
 /**************************************************************************/


...Arduino\libraries\Adafruit_MCP4725/Adafruit_MCP4725.h:25:7: note: the incompatible type is defined here
 class Adafruit_MCP4725 {
       ^
...\Arduino\libraries\Adafruit_MCP4725\Adafruit_MCP4725.cpp:36:1: note: '__comp_ctor ' was previously declared here
 /**************************************************************************/
 ^
...\Arduino\libraries\Adafruit_MCP4725\Adafruit_MCP4725.cpp:36:1: note: code may be misoptimized unless -fno-strict-aliasing is used

...AppData\Local\Temp\cchM2fBH.ltrans0.ltrans.o: In function `setup':
....Desktop\a_GLOBAL/b_SETUP.ino:20: undefined reference to `Adafruit_MCP4725::begin(unsigned char, TwoWire*)'

...Desktop\a_GLOBAL/b_SETUP.ino:23: undefined reference to `Adafruit_MCP4725::setVoltage(unsigned int, bool, unsigned long)'
collect2.exe: error: ld returned 1 exit status

Di seguito vi riporto il codice sorgente:

File: a_GLOBAL.ino

/**
Configurazione varie applicazioni
 */
// ---------------------------------------------------------------------------
// Configurazione motori BLDC //

#include <Servo.h> 
// ---------------------------------------------------------------------------
// Definire il range di pulsazione in base alla capacità dell'esc
#define MIN_SIGNAL 1000 // Pulsazione Minima in µs
#define MAX_SIGNAL 2000 // Pulsazione Massima in µs

// Pin Driver Motore
#define ESC_PWM_PIN 9 // Pin PWM verso l'Y Harness degli ESC

// Pin Potenziometro
#define Pot_BLDC_PIN A1 // Pin analogico controllo velocità motore BLDC potenziometro

// ---------------------------------------------------------------------------
Servo ESC; // crea oggetto di tipo Servo

int potVal;  // lettura analogica del potenziometro 
int potVal_map; // valore rimappato potenziometro
int bldc_power; // potenza percentuale motori bldc
int bldc_power_old = 0; // inizializzo stato precedente

// ---------------------------------------------------------------------------

// Configurazione motore DC //

//motore connesso tra B1 e B2

//Pin Driver Motore
#define PWMB_PIN 5 // Input PWM per controllo velocità
#define BIN1_PIN 11 // Uno degli Input che determina la Direzione
#define BIN2_PIN 12 // Uno degli Input che determina la Direzione
#define STBY_PIN 10 // Input che controlla lo standby

// Pin Pulsanti
#define dir_BT_PIN 7  //Pulsante Direzione 
#define power_BT_PIN 13  // Pulsante Standby

// Pin Potenziometro
#define Pot_DC_PIN A0   // Pin analogico controllo velocità motore DC potenziometro

// Inizializzo velocità motore e lo stato precedente
int mot_vel = 0;
int mot_power_old = 0;

// Memorizzo stato passato dei pulsanti 

int val_dirBT_Old = LOW;
int val_powBT_Old = LOW;

// Inizializzazione stato uscite
int direzione = LOW;  // LOW significa CCW, HIGH significa CW
int direzione_old = LOW; // stato direzione precedente
int power = LOW;  // LOW spento, HIGH acceso

// Inizializzo i timer

long tempo_pow = 0; // tempo ultima attivazione pin standby
long tempo_dir = 0; // tempo ultima attivazione pin direzione
long debounce = 200; // tempo debouncing

// ---------------------------------------------------------------------------

// Configurazione Laser //

#include <Wire.h>
#include <Adafruit_MCP4725.h>

// Istanzio oggetto di tipo DAC
Adafruit_MCP4725 dac;

// Imposta il seguente valore a 9, 8, 7, 6 o 5 per settare la risoluzione del DAC
#define DAC_RESOLUTION    (8)

#define Pot_Laser_PIN A2   // Pin analogico controllo intensità laser (potenziometro)
#define GATE_PIN 6 // Pin digitale controllo gate laser
#define GATE_BT_PIN 4  // Pulsante gate laser

// Inizializzo potenza laser e lo stato precedente
int laser_Lv = 0;
int laser_current_old = 0;

// Memorizzo stato passato del pulsante 
int val_gateBT_Old = LOW;

// Inizializzazione stato uscita
int power_laser = LOW;  // LOW spento, HIGH acceso

// Inizializzo timer

long tempo_pow_laser = 0; // tempo ultima attivazione pin gate laser


// Prototipi delle funzioni

void accelerazione(int vel, int dir);
void decelerazione(int vel, int dir);
void CalibrazioneESC();
void BLDC_PWM();
void power_DC();
void verso_rotazioneDC();
void standbyDC();
void laser_level();
void laser_gate();



File: b_SETUP.ino

void setup() {

pinMode(STBY_PIN, OUTPUT); // standby mot DC
pinMode(PWMB_PIN, OUTPUT); // PWM mot DC
pinMode(BIN1_PIN, OUTPUT); // in1 mot DC
pinMode(BIN2_PIN, OUTPUT); // in2 mot DC
pinMode(power_BT_PIN, INPUT); // pulsante standby mot DC
pinMode(dir_BT_PIN, INPUT); // pulsante direzione mot DC
pinMode(GATE_PIN, OUTPUT); // gate laser
pinMode(GATE_BT_PIN, INPUT); // pulsante gate laser

// Setta "spento" come stato di partenza del laser
digitalWrite(GATE_PIN, LOW);

// Controllare datasheet: 
// Per Adafruit MCP4725A1 l'indirizzo è 0x62 (default) o 0x63 (se il pin di alimentazione è collegato al VCC)
// Per MCP4725A0 l'indirizzo è 0x60 o 0x61
// Per MCP4725A2 l'indirizzo è 0x64 o 0x65
// per le schede cinesi è 0x60
dac.begin(0x60);  

// Setta "zero" come livello di partenza del laser
dac.setVoltage(laser_Lv, false);

// Setta CCW come senso di rotazione di partenza
digitalWrite(BIN1_PIN, LOW);
digitalWrite(BIN2_PIN, HIGH);

// Setta "spento" come stato di partenza

digitalWrite(STBY_PIN, LOW);

// Setta "zero" potenza iniziale motore
analogWrite(PWMB_PIN, mot_power_old);

Serial.begin(9600); // inizializzo la seriale

// Collego gli ESC al PIN 9    
ESC.attach(ESC_PWM_PIN, MIN_SIGNAL, MAX_SIGNAL);  // (pin, min pulse, max pulse in microsecondi) 
//Procedura di calibrazione degli ESC
void CalibrazioneESC();

// Display stato iniziale motore DC sulla seriale
Serial.print("Stato Motore DC : " ); 
Serial.println("Spento"); // 0 spento, 1 acceso

Serial.print("Direzione Motore DC : " ); 
Serial.println("Antioraria"); // 0 significa CCW, HIGH significa 1

Serial.print("Potenza Motore DC : " ); 
Serial.print(mot_power_old); 
Serial.println(" % ");

// Display stato iniziale Laser sulla seriale
Serial.print("Stato Laser : " ); 
Serial.println("Spento"); // 0 spento, 1 acceso
Serial.print("Corrente attraverso Diodo Laser : " ); 
Serial.print(laser_current_old); 
Serial.println(" % ");

delay(2000);

}

File c_LOOP.ino

void loop() {
  
void BLDC_PWM();
void power_DC();
void verso_rotazioneDC();
void standbyDC();
void laser_level();
void laser_gate();

delay(200);

}

File d_BLDC_FUNCTIONS.ino

// Procedura di Calibrazione degli ESC
void CalibrazioneESC()
{
Serial.println("*** PROCEDURA CALIBRAZIONE ESC ***");
Serial.println();
Serial.println("Premere una lettera qualsiasi + <invio> per avviare procedura di calibrazione");
while (!Serial.available()); // Attesa avvio da seriale
Serial.read();
Serial.println();
Serial.println("Inizio Procedura Calibrazione ESC");
delay(2000);
Serial.println();
Serial.println("Calibrazione Segnale Massimo");
ESC.writeMicroseconds(MAX_SIGNAL);
delay(1000);
Serial.println();
Serial.println("Accendere Alimentatore");
delay(1000);
Serial.println();
Serial.println("si dovrebbero udire 3 beeps(di da di) e dopo un secondo un corto beep(di)");
delay(10000);
Serial.println();
Serial.println("Calibrazione Segnale Minimo");
Serial.println();
Serial.println("si dovrebbero udire 2 beeps(di di) e dopo un secondo un lungo beep");
ESC.writeMicroseconds(MIN_SIGNAL);
delay(5000);  
Serial.println();
Serial.println("CALIBRAZIONE EFFETTUATA");
delay(2000);
Serial.println();
}

// Regolazione PWM della velocità dei motori BLDC basata su input da potenziometro
void BLDC_PWM()
{


// Lettura del potenziometro Motore BLDC e scrittura dell'uscita PWM
 potVal = analogRead(Pot_BLDC_PIN);   // legge il valore del potenziometro (compreso tra 0 e 1024)
 potVal_map = map(potVal, 0, 1024, MIN_SIGNAL, MAX_SIGNAL);   // rimappa il valore analogico all'interno del campo operativo dell'ESC
 ESC.writeMicroseconds(potVal_map);
 bldc_power = map(potVal_map,MIN_SIGNAL, MAX_SIGNAL, 0, 100);

 if (bldc_power != bldc_power_old) {
    Serial.print("Potenza Motore BLDC : " ); 
    Serial.print(bldc_power); 
    Serial.println(" % ");
}

bldc_power_old = bldc_power;

}

File e_DC_FUNCTIONS.ino

// Funzione che realizza una rapa di accelerazione
void accelerazione(int vel, int dir){ 

boolean inPin1 = LOW;
boolean inPin2 = HIGH;

if(dir == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
digitalWrite(BIN1_PIN, inPin1);
digitalWrite(BIN2_PIN, inPin2);

for(int mot_Val = 0 ; mot_Val <= vel; mot_Val +=1){
analogWrite(PWMB_PIN, vel); 
delay(5);      
}
}

// Funzione che realizza una rapa di decelerazione
void decelerazione(int vel, int dir){ 

boolean inPin1 = LOW;
boolean inPin2 = HIGH;

if(dir == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
digitalWrite(BIN1_PIN, inPin1);
digitalWrite(BIN2_PIN, inPin2);

for(int mot_Val = vel ; mot_Val >= 0; mot_Val -=1){
analogWrite(PWMB_PIN, vel); 
delay(5);      
}
}

// Lettura del potenziometro Motore DC e rimappatura per scrittura uscita digitale 
void power_DC()
{

mot_vel = map(analogRead(Pot_DC_PIN), 0, 1024, 0, 255);
int mot_power = map(mot_vel, 0, 255, 0, 100);

if (mot_power != mot_power_old) {
    Serial.print("Potenza Motore DC : " ); 
    Serial.print(mot_power); 
    Serial.println(" % ");
}

mot_power_old = mot_power;

}

// Imposta verso di rotazione CW o CCW premendo un pulsante
void verso_rotazioneDC()
{

// Lettura stato pulsante
int val_dirBT = digitalRead(dir_BT_PIN);

// Inizializzo stringa per la seriale
String dir_string;
 
// Aggiorno lo stato delle uscite in base al fronte di salita del segnale in arrivo dai pulsanti e dopo aver aspettato il tempo necessario a ignorare eventuali rumorosità

  
if (val_dirBT == HIGH && val_dirBT_Old ==  LOW && millis() - tempo_dir > debounce) {
  direzione = !direzione; // inverto lo stato da CCW a CW (e da CW a CCW)
  tempo_dir = millis();
  if (direzione == LOW) {
        dir_string = "Antioraria";  
      } else {
        dir_string = "Oraria";  
      }
  Serial.print("Direzione Motore DC : " ); 
  Serial.println(dir_string); 
}

val_dirBT_Old = val_dirBT;


// Scrivo l'uscita' per il motore DC
if (direzione_old == direzione) {
   analogWrite(PWMB_PIN, mot_vel); // Manda segnale PWM al driver
} else  {

  decelerazione(mot_vel, direzione_old);
  delay(1000);
  accelerazione(mot_vel, direzione);
  analogWrite(PWMB_PIN, mot_vel);      
 }


direzione_old = direzione;

}

// Accendo o spengo il motore DC premendo un pulsante
void standbyDC()
{

// Lettura stato pulsante 
int val_powBT = digitalRead(power_BT_PIN);

// Inizializzo stringa per la seriale
String power_string;
 
// Aggiorno lo stato delle uscite in base al fronte di salita del segnale in arrivo dal pulsante e dopo aver aspettato il tempo necessario a ignorare eventuali rumorosità
if (val_powBT == HIGH && val_powBT_Old ==  LOW && millis() - tempo_pow > debounce) {
  power = !power; // inverto lo stato da spento a acceso (e da acceso a spento)
  tempo_pow = millis();
    if (power == LOW) {
        power_string = "Spento";  
      } else {
        power_string = "Acceso";  
      }
  Serial.print("Stato Motore DC : " ); 
  Serial.println(power_string); 
}
  
val_powBT_Old = val_powBT;

// Scrivo l'uscita per il motore DC

if (power == HIGH) {
     digitalWrite(STBY_PIN, HIGH);  // acceso
  } else {
     digitalWrite(STBY_PIN, LOW); // spento
}

}

File f_LASER_FUNCTIONS.ino

// Setta il livello di corrente attraverso il Diodo Lasere mediante un potenziometro
void laser_level()
{

laser_Lv = map(analogRead(Pot_Laser_PIN), 0, 1023, 0, 4095); // il DAC ha una risoluzione a 12 bit, quindi 4096 valori
int  laser_current = map(laser_Lv, 0, 4095, 0, 100);

dac.setVoltage(laser_Lv, false);  // segnale di comando analogico 0-5 V per pilotare il "LIVELLO" del laser 

if (laser_current !=  laser_current_old) {
  Serial.print("Corrente attraverso Diodo Laser : " ); 
  Serial.print(laser_current); 
  Serial.println(" % ");
}

laser_current_old =  laser_current;

}

// Setta il livello del Gate (laser acceso/spento) mediante un pulsante
void laser_gate()
{

// Lettura stato pulsanti 
int val_gateBT = digitalRead(GATE_BT_PIN);

// Inizializzo stringhe per la seriale
String laser_string;

// Aggiorno lo stato delle uscite in base al fronte di salita del segnale in arrivo dai pulsanti e dopo aver aspettato il tempo necessario a ignorare eventuali rumorosità
if (val_gateBT == HIGH && val_gateBT_Old ==  LOW && millis() - tempo_pow_laser > debounce) {
  power_laser = !power_laser; // inverto lo stato da spento a acceso (e da acceso a spento)
  tempo_pow_laser = millis();
  if (power_laser == LOW) {
      laser_string = "Spento";  
    } else {
      laser_string = "Acceso";  
    }
  Serial.print("Stato Laser : " ); 
  Serial.println(laser_string); 
}

val_gateBT_Old = val_gateBT;

}

Il codice veniva compilato senza problemi quando si trovava tutto all'interno dello stesso file. Ho provato a cercare in rete delle possibili soluzioni ma non sono venuto a capo di nulla, anche perchè non è che io sia così esperto di C++
Avete dei suggerimenti per caso?

Grazie in anticipo a tutti coloro che vorranno aiutarmi

Buongiorno e benvenuto, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà (eventuali risposte verrebbero cancellate), quindi ti consiglio di farla al più presto. :wink:

Va bene grazie mille

Ciao, come hai creato i diversi file? Hai aggiunto tab dall'ide di Arduino o hai creato i singoli file e spostato il codice?