Interfacciare pulsante

Ho un problema riguardante il mio progetto serratura arduino.

non riesco a far si che premendo il pulsante si esegua il ciclo che permette al motorino di sbloccare la porta...

mi era stato suggerito qui nel forum un codice ma se lo inserisco, quando vado a premere il pulsante il tutto da di matto..

allego il codice, grazie in anticipo a chi saprà aiutarmi

#include <Password.h> 
#include <Keypad.h> 
#include <Servo.h>


Servo myservo; //declares servo
Password password = Password( "1923" ); //password to unlock box, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 4; // columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {
    '1','2','3','A'  }  ,
  {
    '4','5','6','B'  }  ,
  {
    '7','8','9','C'  }  ,
  {
    '*','0','#','D'  }
  };
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 
  9, 8, 7, 6 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 
  5, 4, 3, 2 }; 

const int buttonPin = 10;     // the number of the pushbutton pin
// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int sensorValue = digitalRead(10); //NB ho provato a creare un metodo per il bottone, ma ho eliminato
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200); 
  pinMode(11, OUTPUT);  //green light
  pinMode(12, OUTPUT);  //red light
  myservo.attach(13); //servo on digital pin 9 //servo
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);   
}

void loop(){
  Serial.println(sensorValue);
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  pressButton() ;
  keypad.getKey();
  myservo.write(90);
}
//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:

    Serial.print("Enter: ");
    Serial.println(eKey);
    delay(10);

    Serial.write(254);

    switch (eKey){
    case 'A': 
      checkPassword(); 
      delay(1); 
      break;

    case 'C': 
      password.reset(); 
      delay(1); 
      break;

    default: 
      password.append(eKey); 
      delay(1);
    }
  }
}
void checkPassword(){

  if (password.evaluate()){  //if password is right open box

    Serial.println("Accepted");
    Serial.write(254);
    delay(1000);
    //Add code to run if it works
    myservo.write(50); //160deg

    digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off


  }
  else{
    Serial.println("Denied"); //if passwords wrong keep box locked
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    myservo.write(77);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off

  }
}
void pressButton(){
  if (buttonState == HIGH) {     
    Serial.write(254);
    delay(1000);
    //Add code to run if it works
    myservo.write(45); //160deg

    digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off  
  } 
  else {
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    myservo.write(0);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off
  }
}

Non ho esaminato in dettaglio il tuo codice, ma da un veloce esame ... non ho visto tecniche di "debouncing" ...

Tu sai vero che, nel momento in cui tu premi il pulsante, sul piedino "buttonPin" succede questo :

... e che se non usi una tecnica di "debouncing" ti ritrovi il pin che fa HIGH-LOW-HIGH-LOW un infinità di volte (... come se premessi in continuazione il bottone) !!!

Non so gli effetti sul tuo codice ... :roll_eyes:

Guglielmo

gpb01:
Non ho esaminato in dettaglio il tuo codice, ma da un veloce esame ... non ho visto tecniche di "debouncing" ...

Potrei sbagliare, ma credo che in questo pezzo di codice, il ritardo di 1000 ms faccia già da antirimbalzo:

void pressButton(){
  if (buttonState == HIGH) {     
    Serial.write(254);
    delay(1000);
    //Add code to run if it works
    myservo.write(45); //160deg

Non appena viene letto lo stato alto, parte il delay e intanto il pulsante può rimbalzare quanto gli pare. Sempre che sia questa, naturalmente la funzione incriminata.

@330R : ... mmm ... magari nel suo caso forse può anche andare, :roll_eyes: ma di certo NON è quello il sistema di fare un "debouncing" anche perché ... quello NON discrimina una spike dalla vera pressione del pulsante (... che si fa verificando che la pressione ci sia sempre dopo x milliSec) :wink:

Guglielmo

ragazzi, non sapevo proprio cosa fosse.. comunque resto in balia del non sapere che fare

Non credo che sia un problema di debouncing: la libreria prevede già un debouncing time di 10 ms modificabile con setDebounceTime(time).

Dici che "da di matto", ma sarebbe meglio che spiegassi esattamente qual'è il difetto.

Quale libreria cyberhs ? ? ? :o

Non stiamo mica parlando della tastierina numerica, stiamo parlando della lettura del "bottone" che lui fa con una normale digitalRead() :

buttonState = digitalRead(buttonPin);

Guglielmo

E' vero, Guglielmo, non avevo notato che ti riferivi al void pressButton().

Ma a questo punto, dopo aver verificato la validità della password, non converrebbe intercettare il tasto "#" (apertura) oppure "*" (chiusura) passando per la libreria keypad?

focamonca:
comunque resto in balia del non sapere che fare

Bisogna valutare dove sta il problema: lettura del pulsante o comando del motore? Prova a sostituire il motore con un banalissimo LED che esegua istruzioni sulla base del pulsante e, quando il codice funziona, utilizzalo per il motore. Oppure, invia un messaggio al monitor seriale.

Potrebbe anche esserci un guasto nel pulsante stesso: prova a sostituirlo.

Nel tuo codice ci sono cose che non mi convincono molto, ad esempio dei delay di cui non capisco bene lo scopo: sono necessari? Non è che provi a premere il pulsante durante l'esecuzione del delay? Perché scrivere delay(n) è come dire "non fare assolutamnete nulla per n millisecondi, quindi neanche reagire alla pressione del pulsante.

UFFAH ... ma sprecare una resistenza ed un condensatore per farci il debouncing hardware e levarvi dalle scatole tutti i problemi dei delay, vi fa stare proprio cosi male, a voi programmatori ?
:stuck_out_tongue: :smiley: :smiley: :smiley:

mi spiego meglio, all'esterno per sbloccare serve la password, e tutto va a meraviglia, ovvero, metto la password, ho 20 secondi per entrare, dopo 20s si riblocca la porta.
Io avevo bisogno di un pulsante che dall'interno facesse la stessa cosa ma ovviamente senza il codice che sta per fuori, quindi bypassasse la verifica della psw muovendo semplicemente il servo

questo è il codice che mi fuzniona benissimo con il keypad, ora devo implementare il pulsante che da dentro farà sbloccare la porta, sul pin 10

#include <Password.h>
#include <Keypad.h>
#include <Servo.h>

Servo myservo; //declares servo
Password password = Password( "1542" ); //password to unlock box, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 4; // columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 9, 8, 7, 6 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 5, 4, 3, 2 };

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
Serial.begin(9600);
Serial.write(254);
Serial.write(0x01);
delay(200);
pinMode(11, OUTPUT); //green light
pinMode(12, OUTPUT); //red light
myservo.attach(13); //servo on digital pin 9 //servo
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
// initialize the pushbutton pin as an input:

}

void loop(){
keypad.getKey();
myservo.write(85);
}
//take care of some special events
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:

Serial.print("Enter: ");
Serial.println(eKey);
delay(10);

Serial.write(254);

switch (eKey){
case 'A': checkPassword(); delay(1); break;
case 'B': muoviUnPelo(); delay(1); break;

case 'D': password.reset(); delay(1); break;

default: password.append(eKey); delay(1);
}
}
}
void muoviUnPelo(){
myservo.write(53);
delay(50);
myservo.write(49);
}

void checkPassword(){

if (password.evaluate()){ //if password is right open box

Serial.println("Accepted");
Serial.write(254);delay(1000);
//Add code to run if it works
myservo.write(51); //160deg

digitalWrite(11, HIGH);//turn on
delay(20000); //wait 5 seconds
digitalWrite(11, LOW);// turn off

}else{
Serial.println("Denied"); //if passwords wrong keep box locked
Serial.write(254);
delay(10);
//add code to run if it did not work
myservo.write(90);
digitalWrite(12, HIGH); //turn on
delay(500); //wait 5 seconds
digitalWrite(12, LOW);//turn off

}

}

ho provato cosí ma non va...... :disappointed_relieved:

#include <Password.h> 
#include <Keypad.h> 
#include <Servo.h>


Servo myservo; //declares servo
Password password = Password( "1542" ); //password to unlock box, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 4; // columns
int inPin = 10;   // choose the input pin (for a pushbutton)
int val = 0;     // variable for reading the pin status
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 9, 8, 7, 6 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 5, 4, 3, 2 }; 


   

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200); 
  pinMode(11, OUTPUT);  //green light
  pinMode(12, OUTPUT);  //red light
  pinMode(inPin, INPUT);    // declare pushbutton as input
  myservo.attach(13); //servo on digital pin 9 //servo
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  // initialize the pushbutton pin as an input:
   
  }

void loop(){

    // check if the input is HIGH (button released)
  keypad.getKey();
  myservo.write(85);
  }
  //take care of some special events
  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
  
  Serial.print("Enter: ");
  Serial.println(eKey);
  delay(10);
  
  Serial.write(254);
  
  switch (eKey){
    case 'A': checkPassword(); delay(1); break;
    case 'B': muoviUnPelo(); delay(1); break;
    
    case 'D': password.reset(); delay(1); break;
    
     default: password.append(eKey); delay(1);
}
}
  val = digitalRead(inPin);  // read input value
  if (val == HIGH) { 
    Serial.write(254);delay(1000);
    //Add code to run if it works
    myservo.write(51); //160deg
    
        digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off
    
    
}else{
   
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    myservo.write(90);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off
    
}
}
void muoviUnPelo(){
  myservo.write(53);
  delay(50);
  myservo.write(49);
}
  
void checkPassword(){
  
if (password.evaluate()){  //if password is right open box
    
    Serial.println("Accepted");
    Serial.write(254);delay(1000);
    //Add code to run if it works
    myservo.write(51); //160deg
    
        digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off
    
    
}else{
    Serial.println("Denied"); //if passwords wrong keep box locked
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    myservo.write(90);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off
    
}


}

Bastava che nel programma postato all'inizio avessi controllato i valori che invii al servo

void pressButton(){
  if (buttonState == HIGH) {     
    Serial.write(254);
    delay(1000);
    //Add code to run if it works
   // myservo.write(45); //***************************************
    myservo.write(51);
    digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off  
  } 
  else {
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    //myservo.write(0); //****************************************
      myservo.write(90);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off
  }
}

Scusa, ma se quello specifico pulsante e' solo per muovere il servo senza la combinazione, e se gia la funzione checkpassword ti funziona (e non vuoi ribaltare tutto il codice), perche' non aggiungi semplicemente una seconda funzione che legge solo quel pulsante e muove il servo alla pressione del pulsante, e la richiami subito dopo checkpassword ?

il mio problema è come implementarlo
ti dispiacerebbe darmi una mano, ho provato ma non è andata come sperato

Brunello:
Bastava che nel programma postato all'inizio avessi controllato i valori che invii al servo

void pressButton(){

if (buttonState == HIGH) {   
    Serial.write(254);
    delay(1000);
    //Add code to run if it works
  // myservo.write(45); //***************************************
    myservo.write(51);
    digitalWrite(11, HIGH);//turn on
    delay(20000); //wait 5 seconds
    digitalWrite(11, LOW);// turn off 
  }
  else {
    Serial.write(254);
    delay(10);
    //add code to run if it did not work
    //myservo.write(0); //****************************************
      myservo.write(90);
    digitalWrite(12, HIGH); //turn on
    delay(500); //wait 5 seconds
    digitalWrite(12, LOW);//turn off
  }
}

ho provato ma led, motore, tutto, schizza male

Etemenanki:
Scusa, ma se quello specifico pulsante e' solo per muovere il servo senza la combinazione, e se gia la funzione checkpassword ti funziona (e non vuoi ribaltare tutto il codice), perche' non aggiungi semplicemente una seconda funzione che legge solo quel pulsante e muove il servo alla pressione del pulsante, e la richiami subito dopo checkpassword ?

non riesco a capire cosa tu abbia in mente

il problema è questo, l'analogRead legge il 0 quando è il bottone è aperto e questo numero viene letto dal checkPassword che da di cotinuo codice errato e per questo si impianta tutto

Ho realizzato un codice che tramite analogRead legge il valore del pulsante e se premuto mi fa muovere il motorino.. il problema è che se lo implemento con l'altro non succede nulla, porca miseria... !