Salve a tutti,
ho cercato molto ma forse sbaglio le parole chiave, volevo descrivere il quesito qui:
è possibile utilizzare i sensori ad ultrasuoni come veri e proprio interruttori?
ade esempio, se la luce è accesa e mi avvicino ad una distanza minore di 5 cm al sensore la luce si spegne e rimane spenta anche si mi allontano.
sono riuscito a programmare fino ad arrivare a far spegnere la luce se il sensore ha un ostacolo vicino, ma tolto l'ostacolo la luce si riaccende.
cappello82:
sono riuscito a programmare fino ad arrivare a far spegnere la luce se il sensore ha un ostacolo vicino, ma tolto l'ostacolo la luce si riaccende.
Se non posti il codice è un po difficile consigliarti come modificarlo :
Potrei dirti aggiungi un flag da usare, assieme alla distanza, per spegnere e mantenere spenta la luce, ma potrebbe non funzionare, visto che non è chiaro cosa succede una volta spenta la luce, cioè come la riaccendi? L'accensione è indipendente dal sensore?
il codice è questo ho usato un sensore SR-hc04 le luci si accendono random e quando mi avvicino dovrebbero spegnersi ed accendere un altro colore...ma non va, scusate ma sicuramente dovrò capire un po di piu di compilazione codice
int triggerPort = 13;
int echoPort = 12;
int rosso = 11;
int verde = 10;
int blu = 9;
long randNumber;
void setup() {
pinMode( triggerPort, OUTPUT );
pinMode( echoPort, INPUT );
pinMode( button, INPUT );
pinMode( rosso, OUTPUT );
pinMode( verde, OUTPUT );
pinMode( blu, OUTPUT );
randomSeed(analogRead(A0));
}
void loop() {
labelD:
digitalWrite(rosso, LOW);
digitalWrite(verde, LOW);
digitalWrite(blu, HIGH);
randNumber = random(1, 4);
digitalWrite(blu, LOW);
if (randNumber == 1) digitalWrite(rosso, HIGH);
else goto label1;
{
labelA:
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
if( r < 1) goto labelD;
else goto labelA;
}
label1:
if (randNumber == 2) digitalWrite(verde, HIGH);
else goto label3;
{
labelB:
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
if( r < 1) goto labelD;
else goto labelB;
}
if (randNumber == 3) digitalWrite(blu, HIGH);
{
labelA:
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
if( r < 1) goto labelD;
else goto labelA;
}
}
cappello82:
il codice è questo ho usato un sensore SR-hc04 le luci si accendono random e quando mi avvicino dovrebbero spegnersi ed accendere un altro colore...
Perdonami, ma dopo il secondo goto mi si sono incrociati gli occhi, e mi è parso di capire che non esci mai dal loop principale (ma non ne sono sicuro)!!!!
L'uso del goto è fortemente sconsigliato per vari motivi, tra cui (appunto) l'illeggibilità del codice, inoltre, il loop principale non deve (dovrebbe) mai essere bloccato!
Quindi ricominciamo, qual'è l'obiettivo del progetto?
Ipotesi 1:
si accende casualmente un led e resta acceso
ogni volta che avvicino (e allontano) un ostacolo, il led acceso si spegne e se ne accende casualmente un altro
Ipotesi 2:
i led si accendono e spengono casualmente
ogni volta che avvicino un ostacolo, tutti i led si spengono e restano spenti anche se allontano l'ostacolo
passato un certo tempo, i led ricominciano ad accendersi casualmente
Facci sapere se una delle ipotesi è corretta, o descrivi meglio quello che vuoi fare.
ipotesi 1 è quella che vorrei scusa ma le mie basi di fortran 77 non si addicono tanto con il linguaggio di arduino,
cmq accendo un led casuale, quando avvicino ostacolo al sensore il led si spegne e se ne accende un altro, poi quando funziona vorrei mettere ad ogni led un sensore diverso quindi 3 led e tre sensori, ma adesso nn ho materiale disponibile per provare con 3 sensori
Il codice che hai postato segnala subito tre errori sintattici: 'label3' non trovata, 'labelA' duplicata, 'button' non dichiarato, che naturalmente vanno sistemati affinché la compilazione arrivi a buon fine.
Poi per farlo leggere ad altri il codice va indentato (se non si vuole farlo a mano lo fa automaticamente l'IDE con strumenti->formattazione automatica).
A quel punto si può iniziare a parlare di logica e funzionamento. Ad esempio non so come si usa un SR-HC04, ma vedo definito un pin 'triggerPort' che immagino debba servire a qualcosa, ma non lo vedo usato da nessuna parte.
Dopo di che, seguendo la logica che è scritta come in un vecchio BASIC non strutturato, mi pare di capire che il problema sia non continuare a cambiare colore finché il sensore sensa, ma solo alla prima sensata, il che è semplice se la logica di lettura si struttura in questo modo, in cui 'comando' viene eseguito solo una volta nel momento in cui il sensore sente meno di 5cm:
attuale = lettura sensore
Se (minore di 5cm) E (precedente NON minore di 5cm): esegui comando
precedente = attuale
Nel tuo codice invece è più semplice inserire un'attesa di 'lontano' e solo poi proseguire.
Ma naturalmente è valido il suggerimento di riscrivere tutto senza goti e compattando per bene
Come ti ha fatto notare @Claudio_FF, nel tuo codice l'uso del sensore non è corretto, quindi, visto che siamo proprio all'inizio, ti consiglio di fare piccoli passi.
Iinizia a studiare come rilevare correttamente la distanza utilizzando il sensore, SR-HC04. Ad esempio guarda questo, ci trovi anche la teoria di come funziona il sensore, oppure questo.
Quindi per esercizio, collega solo il sensore e visualizza la distanza rilevata sulla finestra seriale.
Se poi crei una funzione (getDistance()) che ti ritorna la distanza in cm, renderai il codice nel loop più "pulito" e leggibile.
cappello82:
nel tuo codice però le luci si accendo e spengono di continuo da sole
Quello che ho scritto è solo un esempio di come compattare l'accensione dei led, poi ci va la parte del sensore Banalmente: attendi che sia distante seguito da attendi che sia vicino.
Il comando GOTO si usava ai tempi del GWBASIC e del FORTRAN, poi è stato sostituito dai comandi LOOP, WHILE, FOR che rendono il programma più leggibile. Non c'è motivo di usare GOTO e LABEL, è sempre possibile ovviare, già il QuickBasic (1988) permetteva di scrivere programmi senza GOTO.
Etichette e GOTO è meglio non usarle mai.
A parte etichette mancanti o duplicate che impediscono la compilazione ci sono da correggere le seguenti cose:
digitalWrite(blu, HIGH) seguito dopo due righe da digitalWrite(blu, LOW), ciò invia un impulso di acensione e spegnimento al LED così veloce che non è possibile vedere, forse il LED neanche si accende, non ha senso.
Il sensore HC-SR04 funziona così: prima invii un impulso sul pin Trig poi vedi quanto tempo impiega a ritornare il segnale sul pin Echo. Se non invii il Trig non otterrai mai Echo.
Non è necessario usare il comando GOTO nell'ELSE come rafforzativo per evitare che ARDUINO esegua lo stesso le istruzioni anche se l'IF non è verificato.
L'etichetta non è l'inizio di un blocco di codice, è solo un punto quindi non ha senso racchiudere delle righe dopo un'etichetta tra due parentesi graffe.
Se in ogni caso devi leggere la distanza, non ha senso scriverla 3 volte all'interno dei 3 IF, la leggi una sola volta e basta, per la CPU è la stessa cosa (a parte il codice compilato un po' più lungo) ma il programma è meno ordinato e si commettono errori più facilmente.
Ti occorre una variabile per capire se c'è già un LED acceso.
Il sensore HC-SR04 non legge misure inferiori a 10cm quindi non leggerà mai 1cm.
Dopo l'accensione dei LED, metterei un ritardo di 100uS come antirimbalzo.
Io modificherei nel seguente modo.
int triggerPort = 13;
int echoPort = 12;
int rosso = 11;
int verde = 10;
int blu = 9;
long randNumber;
bool acceso = false;
void setup() {
pinMode( triggerPort, OUTPUT );
pinMode( echoPort, INPUT );
pinMode( rosso, OUTPUT );
pinMode( verde, OUTPUT );
pinMode( blu, OUTPUT );
digitalWrite(triggerPort, LOW);
randomSeed(analogRead(A0));
}
void loop() {
digitalWrite(triggerPort, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPort, LOW);
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
if (r<15){
digitalWrite(rosso, LOW);
digitalWrite(verde, LOW);
digitalWrite(blu, LOW);
acceso=false;
} else {
if (acceso==false) {
randNumber = random(1, 4);
if (randNumber == 1) digitalWrite(rosso, HIGH);
if (randNumber == 2) digitalWrite(verde, HIGH);
if (randNumber == 3) digitalWrite(blu, HIGH);
acceso=true;
delayMicroseconds(100);
}
}
}