Problemi con servomotore

Buongiorno, sono nuovo nel forum. Mi chiamo Nicolas, sono un ragazzo che si è approcciato da poco nell'uso di Arduino. Frequento l'ultimo anno di scuola superiore in un istituto tecnico con specializzazione in meccanica e meccatronica, quindi la mia conoscenza dell'elettronica è molto basilare.

Per l'esame ho iniziato un progetto di un "Distributore di pennarelli" attivato da un RFID con un Arduino Uno. La carta la riconosce però poi non capisco perché non aspetta che io prema il pulsante per attivare il servomotore che rilascia il pennarello. Appena finisce la lettura, se non premo velocemente il pulsante, il programma termina.

Questo è il codice(creato prendendo spunti qua e là da internet), per adesso ho provato a farlo usando un solo servomotore ma poi ne dovrò usare 4:

int  val = 0; 
char code[10]; 
int bytesread = 0; 
int ledPin = 3;      //led scheda autorizzata
int errPin = 5;     // led stato

String TagCode = "";   //codice letto


String codAuto = "02006CFB98";
String codAuto1 = "02002B29B0";
String codAuto2 = "02002B2DF1";
String codAuto3 = "02002AAB67";
String codAuto4 = "02006D85A5";
String codAuto5 = "02006D2B52";
String codAuto6 = "02002AABB8";
String codAuto7 = "02002B2DF0";
String codAuto8 = "02002B4131";
String codAuto9 = "02006D40AE";


//SERVO
#include <Servo.h>
 
Servo myservo;
int puls=7;
int vals1=0;
int pos = 0;
int countButton     = 0;      // Conteggio del bottone  




void setup() { 

Serial.begin(2400); // RFID reader SOUT pin connected to Serial RX pin at 2400bps 
pinMode(2,OUTPUT);   // Set digital pin 22 as OUTPUT to connect it to the RFID /ENABLE pin 
digitalWrite(2, LOW);                  // Activate the RFID reader
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
pinMode(errPin, OUTPUT);
digitalWrite(errPin, LOW);

//SERVO
pinMode(puls,INPUT);
myservo.attach(9);


}  


 void loop() { 

 //RFID

  if(Serial.available() > 0) {          // if data available from reader 
    if((val = Serial.read()) == 10) {   // check for header 
      bytesread = 0; 
      while(bytesread<10) {              // read 10 digit code 
        if( Serial.available() > 0) { 
          val = Serial.read(); 
          if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading 
            break;                       // stop reading 
          } 
          code[bytesread] = val;         // add the digit           
          bytesread++;                   // ready to read next digit  
        } 
      } 
      if(bytesread == 10) {              // if 10 digit read is complete 
        
      Serial.print("TAG code is: ");   // possibly a good TAG 
      Serial.println(code);            // print the TAG code 


      } 
      bytesread = 0;
      delay(50); 
      digitalWrite(2, HIGH);                  // deactivate the RFID reader for a moment so it will not flood
      delay(1000);                            // wait for a bit 
      digitalWrite(2, LOW);                  // Activate the RFID reader
      TagCode="";  
    } 
   
   }
      if (Serial.available()>0){       
          Serial.read();
   }
      TagCode+= code;         //copia il codice nella strnga Tagcode

   
    if (TagCode == codAuto or TagCode == codAuto1 or TagCode == codAuto2 or TagCode == codAuto3 or TagCode == codAuto4 or TagCode == codAuto5 or TagCode == codAuto6 or TagCode == codAuto7 or TagCode == codAuto8 or TagCode == codAuto9) {  //verifica codice
      digitalWrite(ledPin, HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);
    
  
       //SERVO
      vals1= digitalRead(puls);
     if(vals1==HIGH) {
        for(pos = 0; pos < 180; pos += 1)
     {
     myservo.write(pos);
     delay(15);
     }

     for(pos = 180; pos>=1; pos-=1)
    {
    myservo.write(pos);
    delay(15);    
     }
      }
       }
        }

Se qualcuno riuscisse ad aiutarmi a capire come faccio a far aspettare al programma la pressione del tasto ne sarei molto grato.
Ringrazio in anticipo.
Buona giornata

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (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. :slight_smile:

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

Ciao, il copia e incolla è una pratica che porta a brutti risultati!

Non hai descritto cosa deve fare esattamente il programma passo per passo, l'algoritmo il problema che deve risolvere. Quindi non ti si può dire come modificare al meglio il programma per ottenere quello che vuoi.

Ma il problema per cui non riesci ad "utilizzare il pulsante" è che hai messo la lettura del pulsante
all'interno di un blocco if() e non nel loop()

E' sbagliata la logica del programma, che a seconda di cosa devi ottenere è certamente da rivedere e modificare!

Il distributore è composto da un RFID, pulsanti per la selezione del pennarello che azionano i servomotori relativi che rilasciano il pennarello.

Il programma deve:
-leggere la scheda attraverso il RFID
-verificare che il codice sia autorizzato
-aspettare la selezione del pennarello
-rilasciare il pennarello attraverso la rotazione del servo.

Il mio problema è che dopo aver letto la tessera e aver autorizzato il codice il programma non aspetta che io prema il pulsante per selezionare il pennarello.

Spero possiate aiutarmi e se c'è bisogno di altre precisazioni chiedete pure.

Buona giornata.

if(vals1==HIGH) {
        for(pos = 0; pos < 180; pos += 1)
     {
     myservo.write(pos); 
     delay(15);
     }

     for(pos = 180; pos>=1; pos-=1)
    {
    myservo.write(pos);
    delay(15);    
     }

ci sono gravi errori nella sintassi. Perciò non fa quello che vuoi...
non so a cosa to serve spostare il servo di 1 grado alla volta se tu vuoi che vada semplicemente da un fine corsa ad un altro.
e poi ancora, il tuo programma termina perché lo stato del pulsante deve essere letto subito dopo aver letto la scheda (quindi mentre sta leggendo la tessera per farti capire), non è stata creata nessuna condizione nel loop al di fuori della funzione che legge la scheda che controlli lo stato del pulsante e verificare che l'ultima tessera che ha letto è accettata (quindi una tra quelle abilitate se così vuoi definirle) e quindi erogare.
Le graffe sembrano messe a caso...
In altre parole hai incollato pezzi di codice dove lo hai trovato più comodo farlo senza preoccuparti in quali momenti l'mcu lo sta eseguendo..
Adesso ti basta tradurre in codice quanto appena spiegato.
EDIT: considera che per leggere la scheda ci perde forse 2 decimi di secondo, dopo questa breve attesa hai forse qualche microsecondo per premere il pulsante, altrimenti il codice va avanti e ricomincia da capo..

Allora ti do qualche dritta su come ottenere quello che vuoi, MA non so se ho capito bene quello che vuoi fare, comunque puoi adattarlo alle tue esigenze con poche modifiche

  1. ti crei una variabile globale flag che può assumere due valori 1 e 0
  2. Leggi la tessera. Questa parte del codice hai detto che funziona quindi puoi lasciarla cosi.
    2)Confronti i codici se ESATTO porti la variabile flag a 1 flag=1;
    3)Nella funzione loop() leggi il pulsante solo se flag==1, in questo caso muovi il servo e rilasci il pennarello.

Esempio:

// SE flag == 1 VUOL DIRE CHE IL CODICE è ESATTO

byte flag=0;


char pennarello=0;
void loop(){


    if (TagCode == codAuto or TagCode == codAuto1 or TagCode == codAuto2 or TagCode == codAuto3 or TagCode == codAuto4 or TagCode == codAuto5 or TagCode == codAuto6 or TagCode == codAuto7 or TagCode == codAuto8 or TagCode == codAuto9) {  //verifica codice
       
     
          digitalWrite(ledPin, HIGH);
          delay(500);
          digitalWrite(ledPin, LOW);
          flag=1; // Attivo la lettura del pulsante
  
       
 }// END IF

     //NEL LOOP
    
     if(flag==1){

         while(flag){// Attende fino a che si preme un pulsante

             //Leggo i pulsanti
             if(digitalRead(pulsante1)==HIGH){

                  pennarello=1;
                  flag=0; // Esce dal ciclo
 
             }else if(digitalRead(pulsante2)==HIGH){

                  pennarello=2;
                  flag=0; // Esce dal ciclo
 
             }else if(digitalRead(pulsante3)==HIGH){

                  pennarello=3;
                  flag=0; // Esce dal ciclo
 
             }else if(digitalRead(pulsante4)==HIGH){

                  pennarello=4;
                  flag=0; // Esce dal ciclo
 
             }


        }// END WHILE


    }// END IF

   switch(pennarello){

        case 1:
            myservo.write(90);// rilascio il pennarello 1
            pennarello=0;// Annulla l'apertura del servo
            break;
        case 2:
            myservo.write(90);// rilascio il pennarello 2
            pennarello=0;// Annulla l'apertura del servo
            break;
        case 3:
            myservo.write(90);// rilascio il pennarello 3
            pennarello=0;// Annulla l'apertura del servo
            break;
         case 4:
            myservo.write(90);// rilascio il pennarello 4
            pennarello=0;// Annulla l'apertura del servo
            break;
   }

}

Grazie mille torn24 il programma funziona benissimo. Esegue tutti i passaggi e soprattutto aspetta la pressione del pulsante.

Avrei solo un altro piccolo problema riguardante il RFID. Quando passo la tessera una volta mi legge più volte il codice, come se io strisciassi più volte la carta. Non riesco a trovare un modo per fermare la lettura della tessera dopo averla letta una volta.

Spero di essermi spiegato bene sull'errore.
Forse è anche solo la mia non praticità nello scrivere il programma in modo corretto.

Grazie ancora, Buona serata