led che si accende da solo quando avvicino la mano??!?!?

ciao ragazzi,
sono all'inizio con arduino e sto avendo problemi strani che non riesco a capire..
faccio un esempio,
se provo a far accendere un led premendo il pulsante (esempio Button) il led si accende prima di premere il pulsante!! basta avvicinare il dito senza premere!! o addirittura basta dare un colpo al tavolo sul quale lavoro ed il led si accende!
normale?? non credo! come mai? la causa è arduino tarocco preso su ebay sicuramente proveniente dalla cina? esiste un modo per rislovere??
ho provato a mettere una R da 220 ma non cambia nulla , solo l'intensità luminosa del led!!

ciao
Piero

  1. La R in serie al LED è OBBLIGATORIA o prima o poi brucerai Arduino.

  2. Probabilmente hai lasciato il pin di Arduino, a cui è connesso il bottone, normalmente flottante. Data l'alta impedenza dei pin in ingresso, essi NON vanno mai lasciati flottanti o ... captano qualsiasi disturbo.
    Devi quindi forzare il pin, ad un valore opposto a quello cui lo porta il bottone, tramite una resistenza (detta di pull-up se porta verso il +Vcc, o di pull-down se porta verso massa).

Esempio con Pull-Up (... bottone che chiude verso massa):

Guglielmo

fatto! perfetto ora va!

grazie

Ottimo e, mi raccomando, mai collegare i LED direttamente hai pin senza una resistenza in serie, difatti ...

... ogni pin di Arduino può dare al massimo, a Vcc, 40 mA (... ma quello è veramente un limite, nel normale funzionamento occorre stare al 60-70% di detto valore) ed inoltre la somma di tutti i pin e dell'assorbimento del chip, non deve superare al massimo i 200 mA (... e anche qui massimo va considerato come valore limite, ma nel normale funzionamento occorre stare al 60-70% di detto valore).

Assorbimenti oltre detti limiti possono danneggiare irrimediabilmente il chip.

Guglielmo

gpb01:

  1. La R in serie al LED è OBBLIGATORIA o prima o poi brucerai Arduino.

  2. ....Devi quindi forzare il pin, ad un valore opposto a quello cui lo porta il bottone, tramite una resistenza (detta di pull-up se porta verso il +Vcc, o di pull-down se porta verso massa).

Guglielmo

Grande Guglielmo...in poche righe una esemplificazione eccellente. Chapeau! :slight_smile:

valenposta:
Grande Guglielmo...in poche righe una esemplificazione eccellente. Chapeau! :slight_smile:

:smiley: ... Grazie !

Guglielmo

ciao...
ma le Resistenze che valore devono avere?? inizialmente ho provato con una da 330 e ho avuto l'impressione che funzionasse, poi ha ridato gli stessi problemi iniziali...

Metti lo schema che stai usando ed il sorgente del programma che stai usando (... mi raccomando racchiuso tra i tag CODE, quelli che inserisce il bottone </>) perché altrimenti non si capisce di cosa stai parlando e cosa succede ...

Guglielmo

*P.S.: Come resistenze di pull-up/down su un interruttore vanno bene 10K. *

la scheda è un arduino UNO (clone compatibile preso su ebay)

e il codice che voglio far girare è:

const int PinBottoneUNO = 2;
const int PinBottoneCINQUE = 3;
const int PinBottoneNOVE = 4;
const int PinBottoneTRE = 5;
const int PinBottoneASTERISCO = 6;
int StatoBottoneUNO = 0;
int StatoBottoneCINQUE = 0;
int StatoBottoneNOVE = 0;
int StatoBottoneTRE = 0;
int StatoBottoneASTERISCO = 0;

void setup() {
  
  pinMode(2,INPUT);//tasto 1
  pinMode(3,INPUT);//tasto 5
  pinMode(4,INPUT);//tasto 9
  pinMode(5,INPUT);//tasto 3
  pinMode(6,INPUT);//tasto *
  pinMode(7,OUTPUT);//led
  pinMode(8,OUTPUT);//led
  pinMode(9,OUTPUT);//led
  pinMode(10,OUTPUT);//led
  pinMode(11,OUTPUT);//rele

}


void loop() {
  StatoBottoneUNO = digitalRead(PinBottoneUNO);
  if (StatoBottoneUNO == HIGH){
    digitalWrite(7,HIGH);
    delay(5000);
     StatoBottoneCINQUE = digitalRead(PinBottoneCINQUE);
  if (StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH){
    digitalWrite(8, HIGH);
    delay(4000);
   StatoBottoneNOVE = digitalRead(PinBottoneNOVE);
  if (StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH){
    digitalWrite(9, HIGH);
    delay(3000);
     StatoBottoneTRE = digitalRead(PinBottoneTRE);
  if (StatoBottoneTRE == HIGH && StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH){
    digitalWrite(10, HIGH);
    delay(2000);
     StatoBottoneASTERISCO = digitalRead(PinBottoneASTERISCO);
  if (StatoBottoneASTERISCO == HIGH && StatoBottoneTRE == HIGH && StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH){
    digitalWrite(11, HIGH);//eccita il relè
    delay(1000);
    digitalWrite(11,LOW);
    digitalWrite(10,LOW);
    digitalWrite(9,LOW);
    digitalWrite(8,LOW);
    digitalWrite(7,LOW);
    delay(1000);
  }
  }
  }
  }
  }

  
  
  
}

come pulsanti utilizzo un tasterino numerico composto da 16 tasti.
L'idea di partenza era quella di far eccitare un relè dopo aver premuto la combinazione esatta di pulsanti, quindi i led sui pin 7,8,9,10 possono anche non essere messi.

grazie per l'aiuto
Piero

ora sembra riandare tutto, chiedo scusa forse avevo sbagliato io i collegamenti di pullup /pulldown...sorry!
ne approfitto per chiedere spiegazioni sul codice che sto provando a scriverte!

void loop() {
  StatoBottoneUNO = digitalRead(PinBottoneUNO);
  if (StatoBottoneUNO == HIGH){
    digitalWrite(7,HIGH);
    delay(1500);
     
     StatoBottoneCINQUE = digitalRead(PinBottoneCINQUE);
  if (StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH){
    digitalWrite(8, HIGH);
    delay(4000);
    digitalWrite(7, LOW);
    digitalWrite(8,LOW);

questo semplice codice dovrebbe portare a livello logico alto il pin 8 SOLO se precedentemente è stato portato a livello logico alto il pin 7, giusto??
il delay(1500) nel primo if, cosa fa di preciso??
mantiene a livello logico alto per 1500 ms il pin 7? quindi io devo premere (nell'arco di questo tempo) l'altro pulsante per portare a livello logico il pin 8 e soddisfare il secondo if ?!
opure devo attendere 1500ms prima di poter premere il secondo pulsante e portare il pin 8 in HIGH ??

chiedo questo perchè non funziona sempre quindi ho pensato che il problema consista in questo e quindi mi funziona solo quando azzecco la combinazione giusta dei tempi!!

ancorea grazie
Piero

Secondo me è sbagliato l'approccio ...
... invece di questa serie di IF, per di più con nel mezzo delle delay() bloccanti (... la delay() blocca l'esecuzione del codice per il tempo specificato), sarebbe molto meglio utilizzare una logica a "stati" ... a seconda dello "stato" in cui ti trovi fai qualche cosa.

Esempio ...
... parti con lo stato 0 ... nello stato 0 ti aspetti che venga premuto il primo tasto giusto, se viene premuto passi a stato 1, altrimenti torni a stato 0.
Nello stato 1 ti aspetti che venga premuto il secondo tasto giusto. Se viene premuto passi a stato 2, altrimenti torni a 0.
Nello stato 2 ti aspetti che venga premuto il terzo tasto giusto. Se viene premuto passi a stato 3, altrimenti torni a 0.
E così via.
Se arrivi allo stato X (dipenda dalla lunghezza della combinazione), allora lil codice è stato introdotto correttamente, altrimenti, come uno sbaglia, si riparte sempre da 0 :wink:

  • Unico ciclo per leggere la tastiera.
  • struttura switch/case per esaminare le condizioni del singolo stato
  • eviti l'uso di delay()

Prova a metterti li ed ha riprogettare il programma con questa logica (... se ti va :slight_smile:) ... vedrai che ottieni un qualche cosa di molto più pulito e flessibile.

Guglielmo

L'idea mi sembra ECCELLENTE,
avevo pensato a qualcosa di simile , del tipo:

ad ogni tasto premuto giusto far incrementare una variabile di 1, e ad ogni tasto premto non desiderato, far azzerare il contatore!
quando il contatore arriva ad esempio a contare 4 vuol dire che sono stati premuti i 4 tasti giusti...
solo che questo modo molto simile a quello che suggerisci, ha i seguenti limiti:

  • premendo 4 volte di seguito uno dei 4 tasti giusti , incremento il contatore facendolo arrivare a quota 4!
  • posso raggiungere quota 4 premendo i tasti giusti senza avere un ordine..

mi sono spiegato? cmq grazie ottiimo suggerimento, mi guardo il link e cerco di capirci qualcosa, se hai altro materiale dove posso trovare qualcosa di fatto e prendere spunto, passa pure!!

grazie
Piero

... leggi bene il mio post ... NON funziona come dici tu e fa esattamente quello che deve fare !

Guglielmo

Infatti Guglielmo aveva scritto:

Nello stato 1 ti aspetti che venga premuto il secondo tasto giusto

e così via

Quindi se sei ad 1 e premi di nuovo il primo tasto giusto, ti si resetta il contatore.
Lo stesso per gli altri valori.

quando il contatore arriva ad esempio a contare 4 vuol dire che sono stati premuti i 4 tasti giusti...

questo metodo funziona se non ti interessa la sequenza esatta. 1234..OK e 2413..OK se possono essere mescolati i 4 numeri che codice di sicurezza è? :slight_smile:

Salve
provo a scrivere il codice ma non sono in grado...
allora:
parto dallo stato 0(tutto è fermo e mi aspetto che venga premuto ad esempio il tasto 1 e poi il tasto5)
quindi nel void loop provo a scrivere:

switch (var) {
    case 1: 
    StatoBottoneUNO = digitalRead(PinBottoneUNO);
    digitalWrite(12,HIGH);
    break;
    case 2: 
    StatoBottoneCINQUE = digitalRead(PinBottoneCINQUE);
    digitalWrite(13, HIGH);
    break;
  }

ma ovviamente nn da segni di vita!!credo che qst codice non abbia senzo...
mi sono perso...all'interno dei "case" cosa dovrei scrivere? la logica utilizzata con gli if mi tornava ma questa no.
in ogni case devo inserire gli if usati nel codice scritto in partenza?( " if (StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH)..." ) e poi eliminare il delay() ??

spero di ricevere ancora aiuto..

ciao

Ciao

lo switch è corretto per gestire una macchina a stati. Nel tuo caso la variabile var indica lo stato in cui ci si trova. Manca invece, in ogni case, il passaggio allo stato successivo. Manca inoltre l'if che controlla se StatoBottoneXXX è quello che desideri.

Per esemplificare:

switch (var) {
    case 1: 
    StatoBottoneUNO = digitalRead(PinBottoneUNO);
    if (StatoBottoneUNO == HIGH)
    {
        digitalWrite(12,HIGH);
        var = 2;
    }
    break;
    case 2: 
    StatoBottoneCINQUE = digitalRead(PinBottoneCINQUE);
    if (StatoBottoneCINQUE == HIGH)
    {
        digitalWrite(13, HIGH);
        var = xxxx; // qui devi mettere lo stato in cui vuoi andare quando si preme il bottoneCINQUE
    }
    break;
  }

E' solo un esempio, in realtà devi anche gestire il caso in cui quando ci si trova in un certo stato, si ritorna allo stato 0 (attesa sequenza) se premo un tasto diverso da quello atteso o se passa un certo timeout.

Ciao.
Vittorio

ci siamo quasi...
allora ho scritto grazie al vostro aiuto il seguente codice che in parte funziona:

const int PinBottoneUNO = 2;
const int PinBottoneCINQUE = 3;
const int PinBottoneNOVE = 4;
const int PinBottoneTRE = 5;
const int PinBottoneASTERISCO = 6;
int StatoBottoneUNO = 0 ;
int StatoBottoneCINQUE = 0 ;
int StatoBottoneNOVE = 0 ;
int StatoBottoneTRE = 0 ;
int StatoBottoneASTERISCO = 0 ;
int var = 1;//inizializzo la variabile "var" a 1

void setup() {
  
  pinMode(2,INPUT);//tasto 1
  pinMode(3,INPUT);//tasto 5
  pinMode(4,INPUT);//tasto 9
  pinMode(5,INPUT);//tasto 3
  pinMode(6,INPUT);//tasto *
  pinMode(7,OUTPUT);//led
  pinMode(8,OUTPUT);//led
  pinMode(9,OUTPUT);//led
  pinMode(10,OUTPUT);//led
  pinMode(11,OUTPUT);//rele

}


void loop() {
  switch (var){
    case 1:
    StatoBottoneUNO = digitalRead(PinBottoneUNO);
     if (StatoBottoneUNO == HIGH )
  {
    digitalWrite(7,HIGH);
    var = 2 ;
    break;
  }
  case 2:
     StatoBottoneCINQUE = digitalRead(PinBottoneCINQUE);
  if (StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH )
  {
    digitalWrite(8, HIGH);
    var = 3 ;
    break;
  }
  case 3:
   StatoBottoneNOVE = digitalRead(PinBottoneNOVE);
  if (StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH )
  {
    digitalWrite(9, HIGH);
    var = 4 ;
    break;
  }
  case 4:
     StatoBottoneTRE = digitalRead(PinBottoneTRE);
  if (StatoBottoneTRE == HIGH && StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH )
  {
    digitalWrite(10, HIGH);
    var = 5 ;
    break;
  }
   case 5:
   StatoBottoneASTERISCO = digitalRead(PinBottoneASTERISCO);
  if (StatoBottoneASTERISCO == HIGH && StatoBottoneTRE == HIGH && StatoBottoneNOVE == HIGH && StatoBottoneCINQUE == HIGH && StatoBottoneUNO == HIGH )
  {
    digitalWrite(11, HIGH);//eccita il relè
    delay(1000);
    digitalWrite(8,LOW);
    digitalWrite(9,LOW);
    digitalWrite(11,LOW);
    digitalWrite(10,LOW);
    digitalWrite(7,LOW);    
    delay(1000);
    var = 1;
  }
  }
  }

allora, subito dopo aver caricato il codice su arduino si accendono i led sui pin 7 e 8 come se i pulsanti sui pin 2 e 3 fossero stati premuti, quando invece nessuno li ha toccati!
premendo i pulsanti a seguire tutto va come previsto dal codice...
sembrerebbe un problema risolvibile con R di pullup o pulldown ma non è così perche le R ci sono e infatti su tre pin funzionano, non problemi!
Se inizializzo la variabile VAR a 3 ed elimino il case 1 e 2 , quindi riducendo la combinazione a soli 3 pulsanti, funziona!
introducndo nuovamente i case 2 e 3 ridà lo stesso problema (anche se gli assegno pin differenti dal 2 e dal 3)

sono 2 giorni che provo a fare tutte le combinazioni e prove possibili...ma niente! ho anche cambiato arduino...

suggerimenti??

grazie

dopo altre decine di prove credo che quello che ho scritto prima , e cioè che non poteva essere un problema di R di pullup è errato!! è proprio un problema del genere!

le R che ho messo sono tt uguali e pari a 1.5 K... troppo piccole? troppo grandi?? che devo mettere per risolvere qst problema di instabilità??

grazie

ciao

il valore consigliato per le resistenze di pull-up è di 10K. A questo proposito ti ricordo che il microcontrollore dispone di resistenze interne di pull-up che puoi attivare con pinmode(x, INPUT_PULLUP). In questo caso non hai bisogno di montare alcuna resistenza esterna.

Per quanto riguarda il valore HIGH iniziale delle uscite, prova, nel setup, a mettere delle digitalwrite(x, LOW) per tutti e cinque di piedini di output.

Ciao.
Vittorio