Pages: [1]   Go Down
Author Topic: Problema lettura stato pulsanti, con digitalRead e delay  (Read 1243 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti,
sono nuovo. Ho un passato da programmatore e nessuna conoscenza elettronica.
Mi sto studiando questo bellissimo oggetto (Arduino UNO) cimentandomi nella realizzazione di un po' di prototipi, per ora, didattici.

Ho un po' di probemi con i pulsanti.

Il seguente codice non funziona se non inserisco un delay dopo la lettura dello stato del pulsante.... mi aiutate a capire il perché? Ho cercato sul forum e su internet ma essendo nuovissimo di questo mondo ho pure difficoltà a fare le giuste domande/ricerche...

Potreste indicarmi quando è necessario usare il delay per questo tipo di INPUT? Per caso si può risolvere/velocizzare la lettura tramite particolari accortezze sul circuito elettrico?

Il circuito che uso per il pulsante è quello allegato.

Di seguito il mio programma
Code:

#define TEST
//#define BUILD


// Definizione PIN per i componenti
#define BUTTON_ONOFF 7
#define LED_ON 13
#define LED_ALARM 12
#define TILT_SENSOR 8
#define BUZZER 4
#define VOLUME_BUZZER A0
/* QUI SOTTO SONO DEFINITI I SENSORI DI TEST PER SIMULAZIONE */
#if defined(TEST)
#define DOOR_SENSOR 2
#endif

// inizializzo variabili globali
bool ON = false; /* false: OFF; true: ON */
bool ALARM = false; /* false: ALARM OFF; true: ALARM ON */
int VOLUME; /* volume buzzer interno*/
unsigned long PREVIOUS_MILLIS;

// =========================================================================
void setup()
{
  // inizializzo i dati in ingresso
  Serial.begin(9600);

  /* riservo e definisco i PIN */
  pinMode(LED_ON, OUTPUT);
  pinMode(LED_ALARM, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(TILT_SENSOR, INPUT);
#if defined(TEST)
  pinMode(DOOR_SENSOR, INPUT);
#endif

  /* inizializzo i LED */
  digitalWrite(LED_ON, HIGH);
  digitalWrite(LED_ALARM, LOW);

  /* imposto il volume del BUZZER*/
  VOLUME = (analogRead(VOLUME_BUZZER)/ 4.015686275); //1024÷255 = 4,015686275

}
// =========================================================================
void loop()
{
// put your main code here, to run repeatedly:
 

/* controllo attivazione/disattivazione monitoraggio allarme*/
if (digitalRead(BUTTON_ONOFF) == HIGH)
{
delay(250);
switch (ON)
{
case false:
ON = true;
Serial.println("Allarme attivato");
break;
case true:
ON = false;
Serial.println("Allarme disattivato");
break;
}
}


/* monitoro i sensori solo se l'allarme è inserito*/
if (ON)
{
Serial.println("Controllo i sensori...");
/* controllo il sensore di TILT*/
Serial.println("\tSensore TILT: ");
if (digitalRead(TILT_SENSOR) == HIGH)
{
ALARM = true;
Serial.println("\tSensore TILT: ATTIVATO");
}
#if defined(TEST)
if (digitalRead(DOOR_SENSOR) == LOW)
{
ALARM = true;
Serial.println("\tSensore DOOR_SENSOR: ATTIVATO");
}
#endif
if (ALARM)
{
Serial.println("Procedura allarme...");
/* in caso di allarme attivo un clock con intervallo di 1000 millisecondi */
int interval = 1000; //clock interval
unsigned long currentMillis = millis();

if((currentMillis - PREVIOUS_MILLIS) > interval)
{

PREVIOUS_MILLIS = currentMillis;

if (digitalRead(LED_ALARM) == HIGH)
{
digitalWrite(LED_ALARM, LOW);
Serial.println("\tLED_ALARM: SPENTO");
noTone(BUZZER);
Serial.println("\tBUZZER: SPENTO");
}
else
{
digitalWrite(LED_ALARM, HIGH);
Serial.println("\tLED_ALARM: ACCESO");
tone(BUZZER, 50000);
Serial.println("\tBUZZER: ACCESO");
}
}

} //ALARM

}
else
{
digitalWrite(LED_ALARM, LOW);
noTone(BUZZER);
} // ON
}


* pulsante ON_bb.png (49.75 KB, 1057x612 - viewed 33 times.)
« Last Edit: May 06, 2012, 06:07:28 am by manuelc » Logged

Capo d'Orlando
Offline Offline
God Member
*****
Karma: 2
Posts: 725
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Premetto di non aver letto attentamente il tuo codice ma il delay per il pulsanti lo si usa per dare all'utente il tempo di rilasciarlo, altrimenti ad un certo punto del codice ti risulterebbe ancora HIGH
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie Sciorty,
ma l'uso del delay in questo modo non mi torna per questi 2 motivi:
1. non posso sapere a priori per quanto tempo sarà premuto il pulsante, quindi il valore preciso di delay è indeterminabile.
2. non trovo corretto bloccare tutta l'esecuzione del programma in attesa della lettura del pulsante.

sono disperato... smiley non trovo una soluzione..... smiley-sad(
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solitamente il delay dopo la lettura di un pulsante viene utilizzato come contromisura software ai "rimbalzi" che il pulsante stesso ha al momento della pressione...
Prova a dare un'occhiata qui: http://www.maffucci.it/2011/06/13/arduino-alcune-precisazioni-sullantirimbalzo/

Per la gestione del pulsante ti consiglio di provare ad usare questa libreria...implementa l'anti-rimbalzo e io mi sono trovato molto bene...

http://www.arduino.cc/playground/Code/Bounce

edit : hai messo una resistenza di troppo sul pulsante... controlla qui: http://arduino.cc/en/Tutorial/Button

« Last Edit: May 06, 2012, 06:44:14 am by paolo_fiorini3 » Logged

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3479
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non disperare,

1) togli la resistenza in più seguendo il link postato da paolo_fiorini3
2) togli tutti i delay selle letture dei contatti sensori volumetrici e magnetici
3) metti questo in parallelo ai contatti http://italian.alibaba.com/product-gs/the-best-selling-ceramic-capacitor-104-302506208.html
4) non usare librerie bounce in questo test

però dovresti farmi sapere il risultato

grazie ciao
« Last Edit: May 06, 2012, 07:29:50 am by pablos » Logged

no comment

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie a tutti per l'aiuto!

Allora,
la resistenza in più era nel vano tentativo di ridurre il rumore abbassando l'intensità della corrente...  smiley-red
Ho provato le libreria Bounce ma con scarsissimi risultati.... macchinosa da gestire nel codice e comunque applica dei delay definiti dall'utente.

Grazie al consiglio di pablos ho iniziato a intuire a cosa servono i condensatori ... (anche grazie a questo link: http://digilander.libero.it/nick47/cond.htm) smiley

Non ho disponibile il condensatore ceramico che mi hai indicato, ma quelli in dotazione del kit base dell'arduino UNO, quindi ho usato quello da 100nF in poliestere  (tra parentesi sulla scatola c'è scritto "ceramic").
Da solo il condensatore non risolve, ma insieme ad un delay di 250msec rende la lettura leggermente più stabile.

Non risolve completamente ma mette una pezza abbastanza grande.

Ho provato anche gli altri condensatori ma è come se non ci fossero.

Ma voi come risolvete nei vostri progetti? Se avete una centralina e volete comandare l'avvio di un servizio tramite pressione di un pulsante, come fate a gestire in modo CERTO la pressione per far partire e poi fermare il servizio?

Grazie,
M.




* pulsante ON_bb2.png (47.11 KB, 1057x612 - viewed 28 times.)
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3479
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Guarda gli esempi dentro al tuo IDE riguardante il pulsante
File > Examples > Digital > Button

oppure

File > Examples > Digital > Debounce
in questo esempio il delay è fatto con un millis() che non interrompe lo svolgimento del programma

oppure

File > Examples > Digital > State change detection

comunque io uso solo un condensatore senza delay, sarò fortunato io smiley
Condensatore cermico da 100.000pF ovvero 100nF: è scritto: 104. Per questo chiedevo un riscontro su altri progetti
 
ciao
« Last Edit: May 06, 2012, 09:14:58 am by pablos » Logged

no comment

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie ancora del suupporto.
Per ora userò il delay.... in attesa di metabolizzare bene le varie tecniche di debounce.

Vi ringrazio soprattutto per avermi fatto conoscere il problema del RIMBALZO che mi era completamente sconosciuto, che da quello che posso intuire dipende anche dalla componentistica utilizzata. Immagino che un pulsante digitale meccanico con una semplice molla ed un paio di contatti avrà più problemi rispetto ad un pulsante digitale con un circuito di filtro dedicato... esiste?

Logged

Pages: [1]   Go Up
Jump to: