funzione void esterna per sensore a ultrasuoni

salve a tutti,sono nuovo di questo forum e da poco che armeggio con arduino ma me la cavicchio un po con c++.
uso arduino uno con un sensore a ultrasuoni a 4 pin per misurare la distanza.
non riesco a capire come mai non funziona questo codice:

int triggerPort = 7;
int echoPort = 8;
long distanza;

void misuraDistanza()
{   
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT ); 
   
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  
  long duration = pulseIn( echoPort, HIGH );
  long distanza = 0.034 * duration / 2;
} 

void setup() 
{ 
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );  
  Serial.begin(9600);  
} 

void loop() 
{ 
  misuraDistanza(); 
  Serial.print(distanza);
  delay(500);  
}

le ho provate un po tutte,modificando i pinMode e mettendoli direttamente nel setup;
mettendo la funzione misuraDistanza con dentro i pinMode alla fine del loop;
mettendo la funzione misuraDistanza senza i pinMode alla fine del loop e i pinMode all'interno del setup;
cambiando long in int
ma non mi funziona in nessun modo,distanza rimane sempre a 0 come se non considerasse la funzione misuraDistanza.

invece se inserisco i pinMode nel setup e elimino la fuzione misuraDistanza inserendo tutto nel loop funziona e distanza mi da il valore letto dal sensore
questo è il codice funzionante:

int triggerPort = 7;
int echoPort = 8;
long distanza;

void setup() 
{ 
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );  
  Serial.begin(9600);  
} 

void loop() 
{ 
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  
  long duration = pulseIn( echoPort, HIGH );
  long distanza = 0.034 * duration / 2; 
  Serial.print(distanza);
  delay(500);  
}

non capisco dove sbaglio,da quello che ho capito le funzioni esterne con arduino dovrebbero funzionare o sbaglio?oppure sbaglio a scrivere il codice?
spero qualcuno mi illumini perchè sto impazzendo ahahahah

Luca.

Buonasera e benvenuto sul forum,
essendo il tuo primo post, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (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 il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

... un buon ripasso al linguaggio 'C' ed in particolare al concetto di variabili "locali" di variabili "globali" ti farebbe bene.

Detto questo ... ti ho già dato la risposta, prova a trovare tu la soluzione :wink:

Guglielmo

O perlomeno la tua funzione non dovrebbe essere void.

SukkoPera:
O perlomeno la tua funzione non dovrebbe essere void.

... difatti e ... potrebbe risparmiarsi anche tutte quelle variabili globali che sprecano solo memoria :wink:

Guglielmo

grazie per la risposta
vorrei chiarire che è solo una porzione di codice,il codice totale è un po più complesso,la variabile e globale perchè altre funzioni ne faranno uso successivamente

stavo solo facendo delle prove con l'hardware e porzioni di codice

il codice totale è questo:

#include <Servo.h>
Servo myservo;

int triggerPort = 2;
int echoPort = 4;
const int verde=11;
const int blu=10;
const int rosso=9;
long distanza;
int pinmotore1=6;
int pinmotore2=5;
int numeroCasuale;
int tieniDirezione=0;
int lettura=0;



void misuraDistanza()   
{  
  
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );
  
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  
  long duration = pulseIn( echoPort, HIGH );
  long distanza = 0.034 * duration / 2;
} 

void sterza(int direzione)
{        
  if (direzione==1 && distanza<60)  
    myservo.write(120);
  else
  if (direzione==2 && distanza<60)
    myservo.write(60);  
  else
    myservo.write(90);       
}

void marciaAvanti()
{
  if (distanza>=60)
  {
      analogWrite(pinmotore1,0);
      analogWrite(pinmotore2,255);
  }
  else 
      analogWrite(pinmotore2,80);
}

void marciaIndietro()
{
  analogWrite(pinmotore2,0);
  analogWrite(pinmotore1,255);  
}

void ledRosso()
{  
  analogWrite(verde,0);
  analogWrite(blu,0);
  analogWrite(rosso,255);
}

void ledVerde()
{  
  analogWrite(verde,255);
  analogWrite(blu,0);
  analogWrite(rosso,0);
}

void lampledBlu()
{  
  analogWrite(verde,0);
  analogWrite(blu,255);
  analogWrite(rosso,0);
  delay (1000);
  analogWrite(verde,0);
  analogWrite(blu,0);
  analogWrite(rosso,0);
  delay (500);
}

void setup() 
{  
  pinMode(pinmotore1,OUTPUT);  
  pinMode(pinmotore2,OUTPUT);  
  pinMode(verde,OUTPUT);  
  pinMode(blu,OUTPUT); 
  pinMode(rosso,OUTPUT); 
  Serial.begin(9600);  
  myservo.attach(3);
  digitalWrite(verde,HIGH);
  digitalWrite(blu,HIGH);
  digitalWrite(rosso,HIGH);
  ledRosso();      
  delay(10000);
} 

void loop() 
{ 
  randomSeed(numeroCasuale); 
  numeroCasuale=random(1,3);
  misuraDistanza(); 
  
      do
        {
        misuraDistanza();
        delay(200);
        sterza(numeroCasuale);
        tieniDirezione=numeroCasuale;          
        Serial.print("cicloavanti");  
        marciaAvanti();
        ledVerde();
        }       
      while(distanza<60 && distanza>30);

      if (distanza<30)
        {
          do
            {    
            misuraDistanza();
            delay(200);
            sterza(tieniDirezione); 
            Serial.print(numeroCasuale);
            Serial.print("cicloindietro");
            marciaIndietro();
            lampledBlu();
            }
          while(distanza>0 && distanza<120);
        }
      
}

ho usato per la simulazione circuit.123 e non mi dava errori però preferisco testare un componente alla volta,visto che è la mia prima esperienza con arduino...ma tutt'ora non capisco dove sbaglio :frowning:

presumo di sbagliare nella dichiarazione della funzione credo,e forse visto che non ho ancora testato le altre funzioni probabilmente non funzioneranno nemmeno quelle...domani proverò gli altri componenti con porzioni di codice a dare un valore alle variabili globali dove serve

NO, vedo che non hai seguito il mio suggerimeto del post #2 ... male ...
... il problema è in queste due righe:

long duration = pulseIn( echoPort, HIGH );
long distanza = 0.034 * duration / 2;

mettendo quel "long" davanti al "duration" e "distanza", non fai altro che ... dichiarare due NUOVE variabili "locali" (... ovvero che esistono solo fino a quando esiste la funzione) con lo stesso nome delle "globali" che quindi NON vengono più viste perché nascoste da quelle "locali" con lo stesso nome.

Quelle che aggiorni nella lettura dentro la funzione sono quindi le "locali" che hai creato li dentro ed il cui valore perdi all'uscita tornando visibili le "globali" che però ... valgono sempre il valore iniziale che nessuno ha aggiornato !!!

Correggi e prova ... che poi parliamo di come ottimizzare il tutto.

Guglielmo

ok,ho risolto così

int triggerPort = 7;
int echoPort = 8;
long distanza;

long misuraDistanza()
{   
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );     
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  long duration = pulseIn( echoPort, HIGH );
  long distanza = 0.034 * duration / 2;
  return distanza;   
}

void setup() 
{   
  Serial.begin(9600);  
} 

void loop() 
{  
  distanza = misuraDistanza(); 
  Serial.print(distanza);
  delay(2000);  
}

quello che mi lascia un po dubbioso è come mai così non funziona:

int triggerPort = 7;
int echoPort = 8;
long distanza;

long misuraDistanza()
{   
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );     
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  long duration = pulseIn( echoPort, HIGH );
  long distanza = 0.034 * duration / 2;   
}

void setup() 
{   
  Serial.begin(9600);  
} 

void loop() 
{  
  misuraDistanza(); 
  Serial.print(distanza);
  delay(2000);  
}

quando chiamo la funzione misuraDistanza all'interno del void loop non dovrebbe cambiare la variabile globale e aggionarne il valore tramite la funzione?
sbaglio qualcosa io o è proprio una caratteristica di arduino che non riconosce la chiamata?
spero che qualcuno di voi possa delucidarmi su questo
Luca.

Eppure mi sembra di scrivere in buon italiano ...
... ne deduco che NON lo hai manco letto il mio post >:( , quindi ...
... la risposta è vatti a rileggere con ATTENZIONE il mio post #7 e STUDIATI cosa sono le variabili locali e quelle globali che NON mi sembra tu abbia capito !

Guglielmo

scusami Guglielmo,ma effettivamente non avevo letto il tuo post #7,non l'avevo proprio visto purtroppo...

sei stato molto chiaro,grazie,ho capito dove è l'errore e che devo trovare un buon simulatore per arduino visto che quello che uso fa cagare

proverò a rimodificare il codice rispettando quello iniziale con void...spero di farcela :slight_smile:

ok,grazie Guglielmo,l'ho sistemato...ho commesso un errore banale ma sono alle prime armi con c++ e in più ho usato un simulatore che non mi dava errori così non ci ho fatto caso.

se hai qualche consiglio su come ottimizzare il codice sono sempre ben accetti

risolto così:

int triggerPort = 7;
int echoPort = 8;
long distanza;

void misuraDistanza()
{   
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );     
  digitalWrite( triggerPort, LOW );
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );  
  long duration = pulseIn( echoPort, HIGH );
  distanza = 0.034 * duration / 2;     
}

void setup() 
{   
  Serial.begin(9600);  
} 

void loop() 
{  
  misuraDistanza(); 
  Serial.print(distanza);  
  delay(500);  
}

I simulatori fanno quasi tutti schifo :smiley: e le prove conviene sempre farle con Arduino, comunque, tra i tanti, sicuramente il migliore è QUESTO.

Guglielmo

lucartattoo:
se hai qualche consiglio su come ottimizzare il codice sono sempre ben accetti

... beh, intanto riduci l'occupazione di memoria modificando le due righe:

int triggerPort = 7;
int echoPort = 8;

in ...

const byte triggerPort = 7;
const byte echoPort = 8;

... visto che un "int" occupa due bytes ma a te ne basta uno e visto che sono pin cablati (quindi non cambiabili da programma) e quindi puoi dichiararli "const" così che il compilatore ottimizzi.

Guglielmo

Guglielmo grazie per le dritte...sicuramente più avanti troverò altri problemi per adesso testo pezzo per pezzo senza fidarmi del simulatore e se dovessi avere problemi spero sarai così gentile da aiutarmi ancora.

Un saluto.
Luca.

Per "giocare" con il C non serve né Arduino né il simulatore, basta un qualunque compilatore, puoi sperimentare anche facendo programmi per PC, la logica non cambia.

PS: Comunque, secondo me, la soluzione con il return è migliore.

grazie Sukko,sto anche sperimentando con con dev c++,considera che sono ancora alle prime armi.

Se ti va,mi piacerebbe sapere anche il tuo punto di vista e capire come mai secondo te è migliore con il return,dal mio punto di vista, da pivello, sembra uguale,forse intendi a livello di memoria?

Intendo semplicemente che con una return la funzione è rientrante, ovvero non modifica in nessun modo lo stato globale del programma, del resto non ce n'è bisogno. Se domani volessi riciclare quella funzione in un altro sketch ti basta riportarla, senza preoccuparti di quali variabili globali usa/richiede e come.

Le variabili globali sono cosa da usare con attenzione. Sui microcontrollori si tende ad usarle di più che nei programmi "per PC", però è sempre bene evitarle quando è facile farlo.

grazie Sukko,credo di aver capito cosa intendi,comunque studierò meglio l'argomento...più avanti probabilmente posterò il mio primo progetto cosicchè potrete eventualmente darmi altri consigli.

un saluto.
Luca.