Arduino, undefined reference . . .

Salve ragazzi (e ragazze … penso che ce ne siano molte),
ho trovato in giro un programma per Arduino che ho adattato
per la rappresentazione con led dei bit alti di un byte,
convertito ovviamente in binario, il cui valore decimale
viene caricato nella variabile “i” prima
delle chiamate alla subroutine di conversione e
accensione dei led relativi ai bit alti.
Spero di essere stato chiaro . . .

Il codice è questo:

int outPin[] = {13, 12, 11, 10, 9, 8, 7, 6};
    // 13 meno significativo - 6 più significativo
int delayValue = 500; 

void converti();

void setup(){
      int i = 0;
      int j = 0;
      for ( i = 0; i < 8; i++)
      pinMode(outPin[i], OUTPUT);
}
 
void loop(){
      int j = 0;
      int i = 5;  //  carico un valore da visualizzare (5)
//{
//  converti();  // chiamata subroutine per visualizzare 00000101
//}
      delay (500);
      j = 0;
      i = 15;   //  carico un nuovo valore da visualizzare (15)
//{
//  converti();  // chiamata subroutine per visualizzare 00001111
//}
     delay (500);

    void converti();  //subroutine di conversione di "i" in binario
                              // ed accensione dei led relativi
    {
     for ( j = 0; j < 8; j++)
     if ( ( (i >> j) & 1 )  == 1 )
     digitalWrite(outPin[j], HIGH);
     else digitalWrite(outPin[j], LOW);
     delay(delayValue);
    }
}

Poi imparerò ad inserirlo in altra maniera, non vi arrabbiate !

Allora:

così come è scritto viene compilato e mi da come risultato sulla barra di led:
“ 00001111 “ -

se (togliendo le barre // ) inserisco la chiamata alla subroutine:

{
converti(); // chiamata subroutine per visualizzare . . .
}

mi da: “ errore durante la compilazione “ e
“ undefined reference to ‘ converti () ‘

Domande: ( solo due )
1 - Dove ho sbagliato ?
2 - Esiste una casistica di errori, quelli scritti in rosso su fondo nero,
con analisi delle possibili cause e rimedi, in modo che io possa cercare di capire e risolvere autonomamente i problemi ( e quindi imparare ) senza rompere le scatole a voi ?
Vi ringrazio della benevola attenzione.
Ciao a tutti. ( prevale il “maschile” . . . )

Non ci credo che viene compilato senza errori ...

... dichiari : int outPin[] = {13, 12, 11, 10, 9, 8, 7, 6};

... e poi fai nella setup() : pinMode(outPin, OUTPUT);

Non può non darti errore ...
... la pinMode è dichiarata : void pinMode(uint8_t, uint8_t) ... tu gli stai passando un int * e non si incavola ???

Guglielmo

gpb01:
Non può non darti errore ...

Esatto, infatti di errori, oltre a quello che hai segnalato, ce ne sono altrio, non si può definire una funzione all'interno della loop, non bisogna mettere il ; per definire una funzione e altre cosette.

Adesso compila, poi se fa veramente quello che ci si aspetta è da verificare :slight_smile:

int outPin[] = {
  13, 12, 11, 10, 9, 8, 7, 6};
// 13 meno significativo - 6 più significativo
int delayValue = 500; 

void converti(void);

void setup(){
  int i = 0;
  int j = 0;
  for ( i = 0; i < 8; i++)
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
 }

void loop(){
  int j = 0;
  int i = 5;  //  carico un valore da visualizzare (5)

  converti();  // chiamata subroutine per visualizzare 00000101

  delay (500);
  j = 0;
  i = 15;   //  carico un nuovo valore da visualizzare (15)

  converti();  // chiamata subroutine per visualizzare 00001111

  delay (500);
}

void converti()  //subroutine di conversione di "i" in binario
 {
   byte i,j;
    for ( j = 0; j < 8; j++)
      if ( ( (i >> j) & 1 )  == 1 )
        digitalWrite(outPin[j], HIGH);
      else digitalWrite(outPin[j], LOW);
    delay(delayValue);
  }
[code]

[/code]

vonkap:
Poi imparerò ad inserirlo in altra maniera, non vi arrabbiate !

Basta usare i tag [ CODE ], che compaiono premendo l'icona "#" sopra alle emotico. :wink:

Ciao Guglielmo,

gpb01:
Non ci credo che viene compilato senza errori ...

... dichiari : int outPin[] = {13, 12, 11, 10, 9, 8, 7, 6};

... e poi fai nella setup() : pinMode(outPin, OUTPUT);

Non può non darti errore ...
... la pinMode è dichiarata : void pinMode(uint8_t, uint8_t) ... tu gli stai passando un int * e non si incavola ???

Guglielmo

No non si icavola, nota che nella setup() c'è :
" pinMode (outPin [ i ] ,OUTPUT); "

e non dà errore, compila ed esegue come già detto, ma accende solo
00001111 (esadecimale 0F) cioè l'ultimo valore dato ad " i " ,mentre io voglio accendere i led a seconda del valore che io darò ad " i " cambiandolo ogni volta in cui si presenti la necessità che venga cambiato.

In sintesi, io non riesco a chiamare e far eseguire la " void converti() ".

Il codice che mi ha postato astrobeed viene compilato senza errori, ma non dà segni di vita, nel senso che i led rimangono sempre spenti.
La mia mano è sempre tesa . . .
Grazie a tutti.
Paolo

Usi variabili locali con lo stesso nome di quelle globali, studiati la visibilità delle variabili nei blocchi di codice e cambiagli il nome.
La soluzione apparirà per magia. :grin:

P.S. Potresti anche passare dei parametri a converti() invece di usare delle variabili globali.

vonkap:
...
No non si icavola, nota che nella setup() c'è :
" pinMode (outPin [ i ] ,OUTPUT); "
e non dà errore, compila ed esegue come già detto, ma accende solo
...

Paolo, la regola numero UNO è NON BARARE ...

Nel codice originale che avevi postato, e lo abbiamo visto sia io che Leo, tu avevi fatto semplicemente la pinMode(outPin, OUTPUT) senza le parentesi quadre e l'elemento del vettore ... quindi ... non cambiare le carte in tavola, grazie ]:slight_smile:

Guglielmo

Ciao Guglielmo,
la mia età e la mia incompetenza, ma non solo quelle, mi impediscono assolutamente di fare "bambinate" di questo genere.
Mi dispiace e molto di quello che mi hai detto e d'altra parte non credo assolutamente che voi non siate in buona fede (come me)
Ma non riesco a capire cosa sia successo !
Io non ho cambiato niente, la parentesi quadra "fantasma" io la vedo anche ora nel codice che vi ho inviato a suo tempo.
Ripeto non so perché a voi non sia apparsa e non vi appaia come la vedo io !
La mia parola ( ha sempre contato molto nella mia vita) che io non ho cambiato carte ! Che interesse avrei? io voglio imparare, sto imparando, credimi Guglielmo!
Non ho altro modo di convincerti !
Certo che per curiosità vorrei sapere che cos è successo, se qualcuno vuole esprimere un parere . . .
Comunque, per quello che mi riguarda, ho resettato tutto.
Spero che sia così anche per te, amici come prima ???
Ciao
Paolo.

Paolo, ci mancherebbe ... nessun problema ... avevo messo anche lo smile con il diavoletto XD

Allora non so proprio cosa possa essere successo ... nel primo codice che avevi postato mancava proprio quella parentesi, tanto è vero che quello che io riportavo era un copia/incolla di quello che c'era nel codice ...
... mah ... misteri dei forum XD XD XD

Allora, riprendendo, quale è la situazione "up-to-date" ? :slight_smile:

Guglielmo

gpb01:
Paolo, la regola numero UNO è NON BARARE ...

Non ha barato, il [ i ] c'era ma non avendo usato i tag CODE è stato preso come tag italico. Quindi da lì in poi il codice sembrava in italico.
:grin: :grin:

PaoloP:
...
Non ha barato, il [ i ] c'era ma non avendo usato i tag CODE è stato preso come tag italico. Quindi da lì in poi il codice sembrava in italico.
:grin: :grin:

Ahahahahahahahah ... grande ... ecco cosa succedere ad omettere i giusti tag XD XD XD

PaoloP:

gpb01:
Paolo, la regola numero UNO è NON BARARE ...

Non ha barato, il [ i ] c'era ma non avendo usato i tag CODE è stato preso come tag italico. Quindi da lì in poi il codice sembrava in italico.
:grin: :grin:

Esatto.
Quando ho editato il codice, tutto è tornato a posto.

E' vero ! Avevo fatto copia/incolla non sapendo del tag, ecco perché.
Tutto spiegato, grazie !
Adesso devo studiare un po' quello che mi ha suggerito PaoloP, poi vi farò sapere se sono riuscito a fare quanche bracciata da solo.
Bacio le mani . . .
Paolo

NON ci sono riuscito !
questo è il codice:

    int outPin[] = {13, 12, 11, 10, 9, 8, 7, 6};
void setup()
{
  int a = 0;
  for ( a = 0; a < 8; a++)
  pinMode(outPin[a], OUTPUT);
}
void loop() {
  int i = 31;
 /*
 assegno ad " i " un valore qualunque compreso
 tra 0 e 255 che mi viene convertito in binario 
 e rappresentato sulla barra di led e tutto funziona bene.
 Ora io vorrei che tutto il codice che segue diventasse una
 subroutine da richiamare ogni volta che io abbia la
 necessità di cambiare il valore di " i ".
 */         
     {
      int j = 0;
      for ( j = 0; j < 8; j++)
      if ( ( (i >> j) & 1 )  == 1 )
      digitalWrite(outPin[j], HIGH);
      else digitalWrite(outPin[j], LOW);
     }
  }

In Basic, con i Pic ne ho fatte tante e senza problemi . . . ma Arduino parla un'altra lingua.
( Ma non c'è un Basic per Arduino ? )

Scherzo,
dovrò purtroppo convivere con graffe, void, messaggi di errore ecc.
Dai, ragazzi, mettetemi alla via ! ( è un gergo "marinaro" ed è diverso da
" mannateme via " ah ah ah ) non gliela voglio dare vinta !
Grazie e ciao a tutti.
Paolo.

vonkap:
NON ci sono riuscito !
questo è il codice:

Questo è il codice come lo vuoi tu:

int outPin[] = {
  13, 12, 11, 10, 9, 8, 7, 6};

void setup()
{
  int a = 0;
  for ( a = 0; a < 8; a++)
  pinMode(outPin[a], OUTPUT);
}

void loop() {
 int i = 31;
  {
    int j = 0;
    for ( j = 0; j < 8; j++) converti(i,j);
  }
}

void converti (byte i, byte j)
{
  if ( ( (i >> j) & 1 )  == 1 ) digitalWrite(outPin[j], HIGH);
  else digitalWrite(outPin[j], LOW);
}

Le soluzioni possibili sono due, o passi i parametri alla funzione, come nel mio esempio, oppure usi solo variabili globali in modo che siano note a tutto il programma e non solo alla routine dove le hai dichiarate, i nomi delle variabili da inserire nella dichiarazione della funzione non è indispensabile che siano gli stessi delle variabili che devi passare.

vonkap:
In Basic, con i Pic ne ho fatte tante e senza problemi . . . ma Arduino parla un'altra lingua.
( Ma non c'è un Basic per Arduino ? )

Lascia perdere il basic, ma non solo per Arduino , anche per i PIC !!

@Astrobeed : perchè sprecare inutilmente un byte ?? :smiley:

void setup()
{
  uint8_t a = 0;
  for ( a = 0; a < 8; a++)
  pinMode(outPin[a], OUTPUT);
}

:grin:

niki77:
@Astrobeed : perchè sprecare inutilmente un byte ?? :smiley:

Non gli mettere troppa carne al fuoco, prima fagli capire la differenza tra funzioni del C e le suboroutine del basic e la differenza tra variabili globali e quelle locali, poi gli spieghiamo come usare in modo corretto le variabili :slight_smile:

niki77:
@Astrobeed : perchè sprecare inutilmente un byte ?? :smiley:

void setup()

{
 uint8_t a = 0;
 for ( a = 0; a < 8; a++)
 pinMode(outPin[a], OUTPUT);
}

Be.. allora perchè sprecare un'istruzione:

void setup()
{
  for ( uint8_t a = 0; a < 8; a++)
  pinMode(outPin[a], OUTPUT);
}

oppure

void setup()
{
  for (uint8_t a = 0; a < 8; pinMode(outPin[a], OUTPUT), a++) ;
}

:grin:

Si, con troppa carne al fuoco me se brucia la poca cervella rimasta !
Facciamo uno "stufatino" che si cuoce piano piano . . . e che non è male.
Per la "grigliata" c'è ancora tempo.

Grazie ragazzi !
Ho "infilato" nel mio programmino il codice che mi ha inviato
Astrobeed e va che è una meraviglia ! Lo so che non ne avevate
dubbio alcuno !
L'imbranato sono io.
Adesso (ovviamente) devo vedere perché non riuscivo a farlo girare.

Un caloroso grazie a tutti. (siamo ad aprile, va ancora bene . . . )
Paolo.

P.s.:
Tanto vi romperò ancora le scatole . . . ah ah ah

PaoloP:
Be.. allora perchè sprecare un'istruzione:

void setup()

{
 for ( uint8_t a = 0; a < 8; a++)
 pinMode(outPin[a], OUTPUT);
}




oppure



void setup()
{
 for (uint8_t a = 0; a < 8; pinMode(outPin[a], OUTPUT), a++) ;
}




:grin:

Sei proprio convinto che cambi qualcosa tra le due forme PaoloP ?
Dai una vista all'asm una volta compilati :wink: