Go Down

Topic: Problema con millis() (Read 7180 times) previous topic - next topic

mooger

Dunque,un miglioramento c'e ' (il problema della selezione dello switch era dovuto a problemi di connessione hardware) che ho risolto.Ho dichiarato le  variabili all'inizio dello sketch (e' stata una mia svista,in effetti non me ne ero accorto che le avevo dichiarato 2 volte).
startTime = millis() ,l'ho dichiarato appena viene riconosciuta la simcard:
Ho pero' 2 problemi:
1. Al secondo inserimento della CARD,il pulsante di selezione materiale non funziona e va subito in timeout.
Ecco un esempio
- Arduino appena resettato:

Inserire la simcard prego........OK

SIMCARD VALIDA

Effettua la scelta del materiale da conferire entro 10 secondi..
Scelta effettuata : PET
PREGO CONFERIRE PET
Estrarre la SIMCARD,Grazie...
Operazione conclusa


------------------------------------------

Al secondo tentativo,togliendo e reinserendo la SIMCARD

Inserire la simcard prego........OK

SIMCARD VALIDA

Effettua la scelta del materiale da conferire entro 10 secondi..
Estrarre la SIMCARD,Grazie...
Operazione conclusa

-------------------------------------------------------

Va in timeout!Per farlo funzionare di nuovo devo resettare arduino.
Inoltre la void contaPet() non viene eseguita,al conteggio lo sketch si blocca e poi dopo 10 secondi va in timeout

Ecco lo sketch completo con le ultime modifiche:

Code: [Select]


// includi libreria Smartcard:
#include <Smartcard.h>

// includi la libreria del sensore SHARP GP2Y0A21YK:
#include <DistanceGP2Y0A21YK.h>

// include libreria SPI:
#include <SPI.h>

// initialize the library with address of slave select pin
Smartcard smartcard(7);


  //Definizione dei PIN dei pulsanti che simulano i controlli CTRL1 e CTRL2

  const int CTRL1 = 3;
  const int CTRL2 = 4;
 
   //Definizione dei PIN dei pulsanti di scelta materiale:

  const int PET = 5;
  const int PS = 6;
  const int ALU = 8;
  const int Rele_PET = 9;
 
 



//convert from hexadecimal to ASCII for display the result
void HexToAsc(char *c){
if (((*c&0x0F)>=0)&&((*c&0x0F)<=9))
*(c+1) = (*c&0x0F)+0x30;
else
*(c+1) = (*c&0x0F)+0x37;

if ((((*c&0xF0)>>4)>=0)&&(((*c&0xF0)>>4)<=9))
*c = ((*c&0xF0)>>4)+0x30;
else
*c = ((*c&0xF0)>>4)+0x37;
}


   int VAL_CTRL1=0;
   int VAL_CTRL2=0;
   int VAL_PET=0;
   int VAL_PS=0;
   int VAL_ALU=0;
 
 
// Setup relativo al sensore IR GP2Y0A21YK  q

   DistanceGP2Y0A21YK Dist;
   int distance;
   unsigned long Timer = 0;
   unsigned int Contatore = 0;
   const unsigned long Timeout = 10000;  // Costante di timeout= 10 secondi
   
   
   boolean giaPremuto = false;
   boolean premuto=false;
   boolean impulso_mandato = false;
   
   long startTime;
   long duration;
   
   int stato = 0;

///////////////////////////////////////////////////////////////////////////////////////////////

 
  void setup() {
   
    // start the serial library:
       Serial.begin(9600);
       pinMode(2, OUTPUT);  // LED DI STATO ON -> CARD RICONOSCIUTA
 
    // Definizione dei pin relativi ai controlli del compattatore:
       pinMode(CTRL1,INPUT_PULLUP);
       pinMode(CTRL2,INPUT_PULLUP);
 
    // Definizione dei pin relativi al materiale da conferire:
       pinMode(PET,INPUT_PULLUP);
       pinMode(PS,INPUT_PULLUP);
       pinMode(ALU,INPUT_PULLUP);
 
    // Definizione dei pin dei RELE' Relativi all' apertura delle bocche:
       pinMode (Rele_PET,OUTPUT);
 
 
  ///////////////////////////////////////////////////////////////////////
 
    // Pin analogico a cui è collegato il sensore IR,che gestisce la presenza del materiale PET:
       Dist.begin(A0);
 
   // Pin analogico a cui è collegato il sensore IR,il quale misura il riempimento del contenitore PET:
       Dist.begin(A1);
 
                 
                  } // Fine setup
                   
////////////////////////////////////////////////////////////////////////////////////////////////



  void loop() {
 
      unsigned char data[16];
      char ascii_data[2];
   
      Serial.print("Inserire la simcard prego........");
     
      //wait smartcard
      while(!smartcard.IsCardPresent(1)){
        delay(500); 
      }
      Serial.println("OK");
      Serial.println();

      //reset smartcard
      smartcard.PowerOnATRSC(data);
     
   //   Serial.println(">> ReadByte4442 <<");
    //  Serial.println();
     
      ascii_data[0] = smartcard.ReadByte4442(0x20);
      HexToAsc(ascii_data);     
   
      if((ascii_data[0] == '5')&&(ascii_data[1] == '0'))
      {
       
       // Se la simcard è riconosciuta,accendi il led
        digitalWrite(2, HIGH);  // LED CHE INDICA IL RICONOSCIMENTO DI UNA SIM CARD VALIDA
        Serial.println("SIMCARD VALIDA");
        Serial.println();
        startTime = millis();
         VAL_CTRL1=digitalRead(CTRL1);
         VAL_CTRL2=digitalRead(CTRL2);
         
       
         // Verifica se ci sono malfunzionamenti nel compattatore:
     
       
         if ((VAL_CTRL1==LOW) || (VAL_CTRL2==LOW)) { // simulazione errori tramite i pulsanti
         
           Serial.println("Attenzione!Errore compattatore!");
          }
         
          else {
           
                Serial.println ("Effettua la scelta del materiale da conferire entro 10 secondi..");
               
                // Parte il conto alla rovescia per la scelta del materiale da conferire:
               
               
               
                while (stato <1)
                 {
                 
                duration =millis() - startTime;
               // Serial.print(duration);
               // Serial.println();
                if ( duration > Timeout)
                 {   
                  stato = 1;
                   // Manda l'impulso solo se non l'ha già mandato prima
                   if (impulso_mandato == false)
                    {
                     Serial.println("BLOCCATO");
                     impulso_mandato = true;
                    }
                 }
     
                else   
                {
                 //CurrentDurata=millis();
             
                 if (pulsantePremuto(PET) == true && giaPremuto == false)
                   {
                     stato = 1;
                   giaPremuto = true;
                   Serial.println("Scelta effettuata : PET");
                   apriportelloPET();
                   Contatore=0;
                   contaPET();
                   }
                }
               }
            }
      }
       
       // CHIUSURA PARENTESI if ascii
       else
        {
         //Se la simcard non e' riconosciuta,spegni il led
         digitalWrite(2, LOW);
        Serial.println("Simcard non valida!");
        Serial.println();
      }
      Serial.print("Estrarre la SIMCARD,Grazie...");
      Serial.println();
     
      smartcard.PowerOffSC();

      //wait smartcard extraction
      while(smartcard.IsCardPresent(1)){
        delay(500); 
      }
     
      chiudiportelloPET(); // Chiude portello PET quando si estrae la scheda.
     
      Serial.println("Operazione conclusa");
      Serial.println();
     
     
  } // Fine LOOP
 

///////////////////////////////////////////////////////////////////////


  void apriportelloPET ()  // Procedura per l'apertura del portello PET
  {
    digitalWrite (Rele_PET,HIGH); // pin 9
    Serial.print("PREGO CONFERIRE PET");
    Serial.println();
  }
     
 
  void chiudiportelloPET ()
  {
    digitalWrite (Rele_PET,LOW); // pin 9
   
  }
     
  void contaPET()
  {
    Timer = millis();  // PARTE IL TIMER
     while((millis() - Timer) < Timeout) {   // Mentre t < timeout
        distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
         if (distance>=7) { // Se la distanza e' maggiore di 7,non contare
            premuto = false;
                          }
            if ((distance<7) && premuto == false) {  // Se la distanza e'minore di 7 comincia a contare
              Contatore ++;  // incrementa contatore
              Timer = millis();  // timer partito/resettato
              premuto = true;
              Serial.print("Contatore: ");
              Serial.println(Contatore);
                    }         
              }
  }
         
         
bool pulsantePremuto(int pinPulsante)
{
  // pulsante premuto
  if (digitalRead(pinPulsante) == LOW)
  {
    delay(20);  // ritardo antiribalzo
   
    // conferma pulsante premuto
    if (digitalRead(PET) == LOW )
    {       
      //Pulsante premuto, ritorna true e ferma la funzione
      return true;
    }
  }
 
  //Nessun pulsante è stato premuto, la funzione ritorna false
  return false;

 

pippo72

ciao
per quanto riguarda il primo problema:
Quote
1. Al secondo inserimento della CARD,il pulsante di selezione materiale non funziona e va subito in timeout.

la variabile stato la poni a 0 quando la inizializzi, ma poi non la azzeri più quindi la seconda volta che arrivi al while (stato<1) stato vale già 1 ed esce subito.
aggiungi
Code: [Select]
stato = 0;prima del while.
per il secondo non so.

ciao
pippo72

mooger

#17
Aug 05, 2014, 07:09 pm Last Edit: Aug 05, 2014, 07:11 pm by mooger Reason: 1
Aggiunto:
Code: [Select]

               stato=0;
               while (stato <1)
                {
                 
               duration =millis() - startTime;


Sempre stesso problema.. :(
O meglio,non va in timeout,ma non reagisce quando premo lo switch.


pippo72

ciao

Sempre stesso problema.. :(
O meglio,non va in timeout,ma non reagisce quando premo lo switch.

E' lo stesso errore di prima: tutte le variabili che usi per sapere se una cosa è stata premuta, mandata come impulso ecc. le devi rimettere "a posto" per poterle riutilizzare.
In questo caso:
Code: [Select]
if (pulsantePremuto(PET) == true && giaPremuto == false)
non rimetti giaPremuto a false quindi questo if (la seconda volta) non si avvera mai.
stessa soluzione: metti
Code: [Select]
giaPremuto = false;prima del while.

ciao
pippo72

mooger

#19
Aug 05, 2014, 07:33 pm Last Edit: Aug 05, 2014, 07:43 pm by mooger Reason: 1
Ora funziona grazie!!! :) Per il secondo problema,pare sia il cavo difettoso! :) Speriamo!!

pippo72

Mi fa piacere, però ho risposto di fretta e ho commesso un errore: da un punto di vista di logica del programma le varie variabili (scusa pe il gioco di parole    :)) andrebbero azzerare a operazione conclusa cioè quando chiedi di estrarre la carta.
Visto che funziona lo stesso puoi non cambiare niente, ma ci tenevo a puntualizzare.

ciao
pippo72


mooger

#21
Aug 05, 2014, 10:58 pm Last Edit: Aug 05, 2014, 10:59 pm by mooger Reason: 1

Mi fa piacere, però ho risposto di fretta e ho commesso un errore: da un punto di vista di logica del programma le varie variabili (scusa pe il gioco di parole    :)) andrebbero azzerare a operazione conclusa cioè quando chiedi di estrarre la carta.
Visto che funziona lo stesso puoi non cambiare niente, ma ci tenevo a puntualizzare.

ciao
pippo72



Cioe',le avrei dovuto azzerare a operazione conclusa? (volevi scrivere "andrebbero azzerate?" Beh al limite lo modifico,visto che devo aggiungere anche altre cose,non vorrei magari portarmi dietro questo "errore" che magari ora da problemi e poi piu in la aggiungendo pezzi,mi creerebbe problemi,facendomi impazzire!Poi anche per imparare!Cosa avrei dovuto fare esattamente?

Brado

#22
Aug 06, 2014, 11:25 am Last Edit: Aug 06, 2014, 11:28 am by Brado Reason: 1
Per una correttezza logica, quando l'utente estrae la card, vuol dire che l'operazione è conclusa; a quel punto dovresti porre tutte le variabili di appoggio che hai utilizzato ad uno stato pulito, in modo che un secondo utente inserisce la card ed il programma funziona correttamente.

Quindi hai risolto anche il problema 2? Ora funziona?

Ho bene o male capito cosa stai facendo, e se posso permettermi secondo me chiudiportelloPET() sarebbe da inserire prima di attendere che l'utente abbia rimosso la card.
Leggendo lo sketch tu conti i pezzi che l'utente inserisce, una volta che scade il timeout, esci da contaPET(), e quindi stampi la dicitura di rimuovere la card, ma lo sportello è ancora aperto.
Quindi l'utente può tranquillamente caricare pezzi PET e tu non te ne accorgi.
Io la chiusura portello la sposterei prima di questa riga smartcard.PowerOffSC().
Così l'utente ha tutto il tempo di rimuovere la tessera. Poi quando dici che l'operazione è conclusa, se il sensore lo ritiene necessario fai partire il compattatore. Questo controllo penso che sarà da inserire anche in contaPET. ;)
Scusa se mi son permesso di andar oltre alle tue domande, ma mi sembrava corretto farti presente una problematica che penso ti fosse sfuggita.

Ciao.


mooger

"Dovresti porre tutte le variabili di appoggio che hai utilizzato ad uno stato pulito, in modo che un secondo utente inserisce la card ed il programma funziona correttamente."
Cioe' come dovrei fare praticamente?


"Quindi hai risolto anche il problema 2? Ora funziona?"
Sembra che sia problema di contatti...Quando li muovo comincia a conteggiare...


"Io la chiusura portello la sposterei prima di questa riga smartcard.PowerOffSC()."

Si grazie mille dei preziosissimi suggerimenti!Anzi mi fa piacere..In realta' ci avevo gia' pensato a questa modifica,ma l'avrei fatta in un secondo momento,comunque grazie.! :)


Brado

Praticamente quando l'utente ha tolto la tessera, devi fare in modo di portare le variabili utilizzate, allo stato originale (solo se necessario).
Un esempio è la variabile stato, che come hai visto se non la riportavi a 0, il secondo utilizzo ti manda già in timeout.
Come ti ha detto Pippo72 anche giaPremuto lo devi riportare a false.
Credo che anche impulso_mandato debba essere rimesso a false.

Fai una prova:
Inserisci la card e lasci scadere il timeout.
Poi estrai la card e riprovi ad inserirla.
Controlla se funziona correttamente o se ti blocca all'istante.

mooger

La variabile gia_premuto era gia su "false",ma ho aggiunto come tu suggerivi anche impulso_mandato=false;
Ho fatto la prova che mi hai suggerito,in effetti fa quello che deve fare:

Inserire la simcard prego........OK

SIMCARD VALIDA

Effettua la scelta del materiale da conferire entro 10 secondi..
BLOCCATO
Estrarre la SIMCARD,Grazie...

Dopo che per 10 secondi non si effettua una scelta si blocca (in effetti qui ci andrebbero altre cose,ma per ora ho solo questo messaggio".

Purtroppo,come prevedevo il secondo problema non e' risolto mi spiego:
Ho provato con lo sketch che ho usato per la sola funzione che e' questo:
Code: [Select]
#include <DistanceGP2Y0A21YK.h>

DistanceGP2Y0A21YK Dist;
int distance;


unsigned long Timer = 0;
const unsigned long Timeout = 10000;  // 10 secondi
boolean premuto = false;
unsigned int Contatore = 0;

void setup() {
 
 
 
//  pinMode (SwitchPin, INPUT_PULLUP);  // pulsate chiude verso massa (per evitare il resistore di pullup si usa quello interno)
  Serial.begin(9600);
  Dist.begin(A0);
}

void loop() {
 
  distance = Dist.getDistanceCentimeter();

  if ((millis() - Timer) > Timeout) {  // raggiunto timeout
    Serial.println("BLOCCATO");
  }
  else {
 
    if (distance>=7) { //pulsante non premuto
   
      premuto = false;
                    }
   
        if ((distance<7) && premuto == false) {  // pulsante premuto
     
        if (distance<7) {  // conferma pulsante premuto
     
        Contatore ++;  // incrementa contatore
        Timer = millis();  // timer partito/resettato
        premuto = true;
        Serial.print("Contatore: ");
        Serial.println(Contatore);
      }
    }

  }
}


E funziona benissimo. Invece nello sketch completo,conta solo quando smuovo il collegamento con il pin A0!
Ovviamente non e' questione di cavo,perche' nelle stesse condizioni l'altro sketch funziona! :(

Brado


La variabile gia_premuto era gia su "false",ma ho aggiunto come tu suggerivi anche impulso_mandato=false;
Ho fatto la prova che mi hai suggerito,in effetti fa quello che deve fare:

Inserire la simcard prego........OK

SIMCARD VALIDA

Effettua la scelta del materiale da conferire entro 10 secondi..
BLOCCATO
Estrarre la SIMCARD,Grazie...

Dopo che per 10 secondi non si effettua una scelta si blocca (in effetti qui ci andrebbero altre cose,ma per ora ho solo questo messaggio".

Quello che intendevo io, era fare 3/4/5/6 prove consecutive, senza interrompere.
Come se fosse una fila di persone che deve buttare le bottigliette, e non sono capaci, quindi fai scattare i timeout.
Il primo va inserisce la tessera e scatta il primo timeout, e leva la tessera.
Poi va il secondo, mette la tessera, e seleziona PET, ma non fa nulla.
Il terzo fa scattare ancora il primo timeout.
Il quarto è il più furbo, mette la tessera, seleziona PET e finalmente butta 4 bottigliette.
Poi riprovi con un altro e fai scattare il timeout.
Ci riprovi e fai buttare 2/3 bottiglie.
Quello dopo si ferma alla selezione PET e non fa niente.

Fatte queste prove, e tutte funzionano al 100%, puoi passare oltre.


Cosa intendi con
conta solo quando smuovo il collegamento con il pin A0!
?

pippo72

ciao.
parlando del secondo problema: ma il sensore è collegato sul pin A0 o A1?
nel void setup tu scrivi:
Code: [Select]
  ///////////////////////////////////////////////////////////////////////
 
    // Pin analogico a cui è collegato il sensore IR,che gestisce la presenza del materiale PET:
       Dist.begin(A0);
 
   // Pin analogico a cui è collegato il sensore IR,il quale misura il riempimento del contenitore PET:
       Dist.begin(A1);
 

Credo che così cerchi il sensore su A1 (visto che è l'ultimo che dichiari).

o ci sono più sensori?
In questo caso credo dovresti chiamare in maniera diversa i 2 sensori es:
Code: [Select]

...
DistanceGP2Y0A21YK Dist;
   int distance;
DistanceGP2Y0A21YK Dist1;
   int distance1;
...
  // Pin analogico a cui è collegato il sensore IR,che gestisce la presenza del materiale PET:
       Dist.begin(A0);
 
   // Pin analogico a cui è collegato il sensore IR,il quale misura il riempimento del contenitore PET:
       Dist1.begin(A1);
...

Non so quando usi il sensore collegato al pin A1, ma così non dovresti fare confusione.
ciao
pippo72

mooger

Si in realta'  ci sono 2 sensori (dovro' tra l'altro aggiungere degl'altri). Per ora sto utilizzando solo quello collegato al pin A0
Quello collegato invece al pin A1 e' solo parzialmente dichiarato,ma non utilizzato (almeno per ora).Basta che quando conteggia,muovo un po il connettore del cavetto che proviene dal sensore,e collegato al pin A0,che funziona..conteggia..e' molto strana sta cosa...

mooger


[
Quello che intendevo io, era fare 3/4/5/6 prove consecutive, senza interrompere.
Come se fosse una fila di persone che deve buttare le bottigliette, e non sono capaci, quindi fai scattare i timeout.
Il primo va inserisce la tessera e scatta il primo timeout, e leva la tessera.
Poi va il secondo, mette la tessera, e seleziona PET, ma non fa nulla.
Il terzo fa scattare ancora il primo timeout.
Il quarto è il più furbo, mette la tessera, seleziona PET e finalmente butta 4 bottigliette.
Poi riprovi con un altro e fai scattare il timeout.
Ci riprovi e fai buttare 2/3 bottiglie.
Quello dopo si ferma alla selezione PET e non fa niente.

Fatte queste prove, e tutte funzionano al 100%, puoi passare oltre.


Cosa intendi con
conta solo quando smuovo il collegamento con il pin A0!
?


Si ho fatto varie prove e funziona bene ,(A parte il conteggio),come dicevo nel post sopra,il conteggio funziona se muovo il cavetto proveniente dal sensore ,il quale e' collegato al pin A0.

Go Up