Errore compilazione a seguito dell'unione di due sketch funzionanti

Ciao a tutti ragazzi;

Grazie all'aiuto degli utenti del forum sono riuscito a creare i due codici di cui ho bisogno per realizzare il progetto che ho in mente. I due codici funzionano perfettamente se testati separatamente, e sono stati provati fino a qualche minuto fa.

Il problema nasce nel momento in cui vado a scriverli nello stesso sketch affinché possa caricare su Arduino un unico programma che funzioni simultaneamente.

E' possibile che si creino particolari conflitti tra le librerie? E' l'unico dubbio che mi viene.

Vi allego i codici e confido nelle vostre conoscenze. Sono certo si tratta di piccolezze dato che individualmente sono funzionanti come già ribadito. Grazie a chiunque risponderà :wink:

#include <PinChangeInterrupt.h>

const byte ingresso = 4;pin
double flusso;
volatile int count;

void setup() {
  pinMode (ingresso, INPUT);
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso), impulso, RISING);
  Serial.begin (9600);
}

void loop() {
  count = 0;
  enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));
  delay (1000);
  disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));

  flusso = (count * 2.25);
  flusso = flusso * 60;
  flusso = flusso / 1000;
  Serial.print( "FLUSSO = " );
  Serial.println (flusso);
}

void impulso() {
  count = count + 1;
}
#include <GSM.h>


GSM gsmAccess;
GSM_SMS sms;


 
int rele=10;
int ledConnessione=12;

void setup() 
{

  
  pinMode(ledConnessione, OUTPUT); 
  
  boolean connessione = true;
  
  
  while(connessione)
  {
    if(gsmAccess.begin()==GSM_READY)
      connessione = false;
  }
  
 
  digitalWrite(ledConnessione,HIGH);
}


int i=0;
char vettore[10];
char ricevuto[10];
String accendi="On";
String spegni="Off";
String casting;

void loop() 
{
  char c;
  
  if (sms.available())
  {
 
    while(c=sms.read())
    {
      digitalWrite (ledConnessione, HIGH);
      delay (200); 
      digitalWrite (ledConnessione, LOW);
      delay (200);
      Serial.print(c);
      vettore[i]=c;
      i++;
      
      
    }
    digitalWrite (ledConnessione, HIGH);
    delay (200); 
    digitalWrite (ledConnessione, LOW);
    delay (200);
    digitalWrite(ledConnessione,HIGH);
    for(int j=0;j<i;j++)
    ricevuto[j]=vettore[j];
    
    casting=String(ricevuto);
    
    if(casting.equals(accendi)) 
    {
       pinMode(rele, OUTPUT);
       digitalWrite(rele,HIGH);
       i=0;
       pulisciStringa(ricevuto,10);
       
    }
      
    if(casting.equals(spegni)) 
    {
      pinMode(rele, OUTPUT);
        digitalWrite(rele,LOW);
        i=0;
       pulisciStringa(ricevuto,10);
     }
      
    i=0;
    pulisciStringa(ricevuto,10);
    

    sms.flush();
   
  }

  delay(1000);

}

void pulisciStringa(char* tmp,int dim) 
{

int x;
for (x=0; x < dim; x++)
tmp[x] = 0;

tmp[0] = '\0';
}

Posta lo sketch unificato, come possiamo capire dai due separati?

Questo, comunque, è un errore:

const byte ingresso = 4;pin

Va bene, anche se non ho fatto altro che scriverli nello stesso sketch:

#include <GSM.h>
#include <PinChangeInterrupt.h>

GSM gsmAccess;
GSM_SMS sms;

const byte ingresso = 4;
double flusso;
volatile int count;

int rele=10;
int ledConnessione=12;

void setup() 
{
  pinMode (ingresso, INPUT);
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso), impulso, RISING);
  Serial.begin (9600);
  
  pinMode(ledConnessione, OUTPUT); 
  
  boolean connessione = true;
  
 
  while(connessione)
  {
    if(gsmAccess.begin()==GSM_READY)
      connessione = false;
  }
  
  
  digitalWrite(ledConnessione,HIGH);
}


int i=0;
char vettore[10];
char ricevuto[10];
String accendi="On";
String spegni="Off";
String casting;

void loop ()
{
  funzione1;
  funzione2;
  }
void funzione1() 
{
  char c;
 
  if (sms.available())
  {
  
    while(c=sms.read())
    {
      digitalWrite (ledConnessione, HIGH);
      delay (200); 
      digitalWrite (ledConnessione, LOW);
      delay (200);
      Serial.print(c);
      vettore[i]=c;
      i++;
      
      
    }
    digitalWrite (ledConnessione, HIGH);
    delay (200); 
    digitalWrite (ledConnessione, LOW);
    delay (200);
    digitalWrite(ledConnessione,HIGH);
    for(int j=0;j<i;j++)
    ricevuto[j]=vettore[j];
    
    casting=String(ricevuto);
    
    if(casting.equals(accendi)) 
    {
       pinMode(rele, OUTPUT);
       digitalWrite(rele,HIGH);
       i=0;
       pulisciStringa(ricevuto,10);
       
    }
      
    if(casting.equals(spegni)) 
    {
      pinMode(rele, OUTPUT);
        digitalWrite(rele,LOW);
        i=0;
       pulisciStringa(ricevuto,10);
     }
      
    i=0;
    pulisciStringa(ricevuto,10);
    
 
    sms.flush();
   
  }

  delay(1000);

}

void funzione2() {
  count = 0;
  enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));
  delay (1000);
  disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));

  flusso = (count * 2.25);
  flusso = flusso * 60;
  flusso = flusso / 1000;
  Serial.print( "FLUSSO = " );
  Serial.println (flusso);
}

void pulisciStringa(char* tmp,int dim) 
{

int x;
for (x=0; x < dim; x++)
tmp[x] = 0;

tmp[0] = '\0';
}

void impulso() {
  count = count + 1;
}

Comunque quell'errore sarà sorto in fase di copia-incolla perchè ho controllato il codice ed e corretto.

Spero che qualcuno riesca ad illuminarmi perchè sto impazzendo :disappointed_relieved:

... ma da quando le funzioni si richiamano in questo 'orrendo' modo ? :o

void loop ()
{
  funzione1;
  funzione2;
}

A me è sempre risultato che la corretta sintassi fosse:

void loop ()
{
  funzione1();
  funzione2();
}

Guglielmo

Okok ahhahaha :grin: l'ho appena sistemato, ormai non connetto più.

Comunque continua a dare ancora lo stesso errore, vi posto in allegato lo screen delle ultime righe..

Quelle due righe non servono a nulla ...
... apri l'IDE, vai nelle impostazioni e metti il segno di spunta in "Show verbose output during:" (... non so come è in Italiano) per la "compilazione" (... se vuoi anche per l'upload, che male non fa, da solo più indicazioni).

Dopo di copia e incolla qui gli errori (... cortesemente anche loro racchiusi tra i tag code).

Guglielmo

E premi CTRL+T nell'IDE, ti formatterà meglio il sorgente e magari evidenzierà qualcosa di sbagliato.

Non smetterò mai di ringraziarvi per le dritte!

Gli errori che mi restituisce gli ho allegati in un txt poichè avrei dovuto inviare non so quanti messaggi per evitare di superare il numero massimo di caratteri consentito :stuck_out_tongue_closed_eyes:

Vi riallego anche il codice correttamente formattato:

#include <PinChangeInterrupt.h>
#include <GSM.h>


GSM gsmAccess;
GSM_SMS sms;

const byte ingresso = 4;
double flusso;
volatile int count;

int rele = 10;
int ledConnessione = 12;

void setup()
{
  pinMode (ingresso, INPUT);
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso), impulso, RISING);
  Serial.begin (9600);

  pinMode(ledConnessione, OUTPUT);

  boolean connessione = true;


  while (connessione)
  {
    if (gsmAccess.begin() == GSM_READY)
      connessione = false;
  }


  digitalWrite(ledConnessione, HIGH);
}


int i = 0;
char vettore[10];
char ricevuto[10];
String accendi = "On";
String spegni = "Off";
String casting;

void loop ()
{
  funzione1();
  funzione2();
}
void funzione1()
{
  char c;

  if (sms.available())
  {

    while (c = sms.read())
    {
      digitalWrite (ledConnessione, HIGH);
      delay (200);
      digitalWrite (ledConnessione, LOW);
      delay (200);
      Serial.print(c);
      vettore[i] = c;
      i++;


    }
    digitalWrite (ledConnessione, HIGH);
    delay (200);
    digitalWrite (ledConnessione, LOW);
    delay (200);
    digitalWrite(ledConnessione, HIGH);
    for (int j = 0; j < i; j++)
      ricevuto[j] = vettore[j];

    casting = String(ricevuto);

    if (casting.equals(accendi))
    {
      pinMode(rele, OUTPUT);
      digitalWrite(rele, HIGH);
      i = 0;
      pulisciStringa(ricevuto, 10);

    }

    if (casting.equals(spegni))
    {
      pinMode(rele, OUTPUT);
      digitalWrite(rele, LOW);
      i = 0;
      pulisciStringa(ricevuto, 10);
    }

    i = 0;
    pulisciStringa(ricevuto, 10);


    sms.flush();

  }

  delay(1000);

}

void funzione2() {
  count = 0;
  enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));
  delay (1000);
  disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(ingresso));

  flusso = (count * 2.25);
  flusso = flusso * 60;
  flusso = flusso / 1000;
  Serial.print( "FLUSSO = " );
  Serial.println (flusso);
}

void pulisciStringa(char* tmp, int dim)
{

  int x;
  for (x = 0; x < dim; x++)
    tmp[x] = 0;

  tmp[0] = '\0';
}

void impulso() {
  count = count + 1;
}

Responso errori.txt (21.4 KB)

LucaM:
Gli errori che mi restituisce gli ho allegati in un txt poichè avrei dovuto inviare non so quanti messaggi per evitare di superare il numero massimo di caratteri consentito :stuck_out_tongue_closed_eyes:

Anche perché ti era stato detto ci copiare/incollare gli errori, NON tutta la compilazione ... :smiling_imp:

\Users\Tommaso\AppData\Local\Temp\arduino_build_951194/..\arduino_cache_514426\core\core_arduino_avr_uno_5a371a7b9347cf4f0e46e15fae85cf22.a" "-LC:\Users\Tommaso\AppData\Local\Temp\arduino_build_951194" -lm
C:\Users\Tommaso\AppData\Local\Temp\arduino_build_951194\libraries\GSM\GSM3SoftSerial.cpp.o (symbol from plugin): In function `GSM3SoftSerial::spaceAvailable()':

(.text+0x0): multiple definition of `__vector_5'

PinChangeInterrupt2.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

Uso la libreria PinChangeInterrupt alla versione 1.2.4 nella cartella: C:\Users\Tommaso\Documents\Arduino\libraries\PinChangeInterrupt 
Uso la libreria GSM alla versione 1.0.6 nella cartella: C:\Program Files\Arduino\libraries\GSM 
exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.

... direi che le due librerie sono incompatibili tra di loro dato che usano lo stesso vettore di interrupt.

La soluzione è usare due pin diversi dal 2 e 3 ... basta andare nella libreria del GSM e vedere dove li definisce, tanto sono sicuro che li usa solo per la SoftwareSerial ... ::slight_smile:

Guglielmo

o piu' semplicemente usare un pin diverso per la variabile ingresso.
Da D0 a D7 = NO
da D8 a D13 = SI
Da A0 a A5 = SI

https://playground.arduino.cc/Main/PinChangeInterrupt

Praticamente quindi come dovrei agire?

La soluzione è usare due pin diversi dal 2 e 3

Questi dovrebbero essere il TX ed RX del modulo GSM. Se vado a variare la libreria non rischio che Arduino e modulo non comunichino più?

Attendo dritte perché ho compreso il problema ma non ho affatto capito come devo risolverlo :confused:

o piu' semplicemente usare un pin diverso per la variabile ingresso.
Da D0 a D7 = NO
da D8 a D13 = SI
Da A0 a A5 = SI

Inizialmente utilizzavo D8, poi sono passato a D4 avendo intuito la possibilità di risolvere in questa maniera.. Ora ho appena provato con A0. Purtroppo non ha funzionato in nessuno dei tre casi.
Devo provare con qualche altro pin magari può essere una soluzione più sbrigativa del modificare la libreria (che non ho la minima idea di come si faccia)?

brunello22:
Arduino Playground - HomePage

C'è anche da dire che quella libreria è ormai obsoleta ed è meglio usare la molto più flessibile EnableInterrupt ... :wink:

Guglielmo

.. nel file GSM3IO.h, della libreria GSM trovo:

#if defined(__AVR_ATmega328P__) 
	#ifdef TTOPEN_V1
		#define __TXPIN__ 3
		#define __RXPIN__ 4
		#define __RXINT__ 3
	#else
		#define __TXPIN__ 3
		#define __RXPIN__ 2
		#define __RXINT__ 3
	#endif
#elif

... quindi, purtroppo, NON è possibile spostarsi dal 2,3 o 3,4 visto che comunque gli serve un pin di interrupt :confused:

Guglielmo

quindi, purtroppo, NON è possibile spostarsi dal 2,3 o 3,4 visto che comunque gli serve un pin di interrupt  :confused:

Non c'è quindi soluzione oppure posso utilizzare l'altra libreria e recuperare la situazione?

... puoi provare, come ti ha detto Brunello, a cambiare pin scegliendone uno del gruppo D8 .. D13 e vedere se da sempre l'errore ::slight_smile:

In pratica, nella riga

const byte ingresso = 4;

metti, ad esempio:

const byte ingresso = 9;

e vedi se compila.

Se non va ... riporta l'errore e vediamo se è lo stesso ...

Guglielmo

... mi sa che NON c'è soluzione ... stesso caso QUI ::slight_smile:

Le due librerie dichiarano gli stessi vettori di interrupt e quindi sono in conflitto tra di loro.

Guglielmo

E se utilizzassi la libreria che mi hai proposto? Anche quella andrebbe in conflitto?

LucaM:
E se utilizzassi la libreria che mi hai proposto? Anche quella andrebbe in conflitto?

Ho idea di SI visto che alla fine sempre il pinChangeInt usa ... ::slight_smile:

Guglielmo

E provare a spostare ( anche fisicamente ) l' Rx sul pin 4

#if defined(__AVR_ATmega328P__) 
	#ifdef TTOPEN_V1
		#define __TXPIN__ 3
		#define __RXPIN__ 4
		#define __RXINT__ 3
	#else
		#define __TXPIN__ 3
		#define __RXPIN__ 2
		#define __RXINT__ 3
	#endif
#elif

ed usare un normale attachInterrupt() sul pin 2 ?

Potresti usare una Arduino Leonardo che ha più pin con interrupt hardware.