Pages: [1]   Go Down
Author Topic: Digital Read molto lento nel rilevare il cambio di stato  (Read 1564 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buona sera a tutti.
Utilizzo un Arduino mega R3.

questo è il codice in questione

Code:
// testing motors
//
 int motor1Pin;    // H-bridge leg 1 (pin 2, 1A)
 int motor2Pin;    // H-bridge leg 2 (pin 7, 2A)
 int enablePin;    // H-bridge enable pin
 int fineCorsa;    // Fine Corsa
 
void setup() {
  Serial.begin(9600); // open serial port to receive data
}

//Nome: attivaPin
//ToDo: Attiva i pin relativi al cassetto selezionato
void attivaPin(){
      digitalWrite(enablePin, HIGH);  // accende il motore
      digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge low
      delay(4000);
      digitalWrite(enablePin, LOW);
      digitalWrite(motor1Pin, LOW);     
         
}

void setPin (int pin){
if (pin == 1){
  motor1Pin = pin;
  motor2Pin = pin + 1;
  enablePin = pin + 2;
  fineCorsa = pin + 3;
  pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(fineCorsa, INPUT);
}
else{
   motor1Pin = (pin * 4) - 3;
   motor2Pin = (pin * 4) - 2;
   enablePin = (pin * 4) - 1;
   fineCorsa = (pin * 4);
   pinMode(motor1Pin, OUTPUT);
   pinMode(motor2Pin, OUTPUT);
   pinMode(enablePin, OUTPUT);
   pinMode(fineCorsa, INPUT);
 }
}

int verificaFineCorsa(int inputPin){
    delay(1300);
    int val;
    val = digitalRead(inputPin);
    if (val == HIGH){
      Serial.println("Tutti i fine corsa sono chiusi");
      return 0;
    }
    else{
      Serial.println("FineCorsa Aperto");
      return 1;
    }
}
 
 
void gestioneElettropermanente(int incomingByte){
  setPin(incomingByte);
  if (verificaFineCorsa(fineCorsa) == 0)
      attivaPin();
   
}

 
void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    int incomingByte = Serial.read() - '0';
    gestioneElettropermanente(incomingByte);
    // if it's a capital H (ASCII 72), turn on the LED:
  }
}


Il problema è che il digitalRead(pin) è veramente lento, impiega anche più di 8 secondi a rilevare il cambio di stato, come mai??? come posso risolvere?
avete suggerimenti?

Grazie a tutti in anticipo

Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 574
Posts: 12645
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non ho analizzato il codice, ci sono persone molto più preparate di me che lo faranno meglio.
Voglio solo dirti che il modo migliore, a mio modesto parere, per intercettare in tempo reale il cambio di stato di un pin sia quello di usare un interrupt.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oddio mi apri un mondo nuovo...
Un interrupt fisico (quindi un interruttore, ipotesi da scartare) o un interrupt software?
Arduino permette di utilizzare la logica degli interrupt?? :O
Logged

Parma
Online Online
Edison Member
*
Karma: 21
Posts: 2417
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il comando digitalRead di suo è velocissimo (es. quasi 100KHz), nel codice hai dei delay() che fermano il micro per molto tempo..
usa gli interrupt (software) o rivedi il codice

Ciao
Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 574
Posts: 12645
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oddio mi apri un mondo nuovo...
Un interrupt fisico (quindi un interruttore, ipotesi da scartare) o un interrupt software?
Arduino permette di utilizzare la logica degli interrupt?? :O
Certamente, esistono alcuni pin preposti direttamente dal micro; la libreria pinChangeInt ti permette di scegliere qualsiasi altro pin ed assegnargli questa funzione. Poi puoi intercettare eventi come il change, il falling ed il rising
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22973
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

nel codice hai dei delay() che fermano il micro per molto tempo..
E' questo il problema, se metti un delay equivale a mettere uno stop. ll micro si ferma completamente e non esegue altro. Quindi la tua funzione sta ferma 1,3 secondi e poi legge lo stato dei pin.
Logged


0
Offline Offline
Faraday Member
**
Karma: 31
Posts: 2908
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In sostituzione del delay usa invece millis(), trovi l'esempio di uso nell'ide di Arduino, la logica si complica un poco ma non c'è altra soluzione.
Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Riva del Garda, TN / Forlì
Offline Offline
Edison Member
*
Karma: 8
Posts: 2246
Il piu' modesto al mondo
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

allora la prima lettura scommetto che avviene dopo 1.3 secondi e la seconda dopo 5.3 secondi  smiley-razz

arduino non è multitasking, una funzione non è un task.

ci sono 2 modi per creare un "multitask" (anche se non sarebbe corretto) su arduino:
- l'uso della funzione millis()
- l'uso di un timer che allo scadere scatena un interrupt che va a chiamare una funzione bloccando il processo in atto.

se pensi che la seconda sia più complicata io direi di no in quanto esiste il "leOS":
http://arduino.cc/forum/index.php/topic,111732.0.html
però non credo sia il tuo caso in quanto tu vai a richiamare determinate funzioni nel codice (insomma non vanno a eseguirsi ognuna per conto suo e poi leggi magari una variabile globale apposita ma proprio tu le chiami interrogando il risultato della funzione).

il primo metodo è il più usato, in pratica il comando millis() restituisce i millisecondi da quando il programma è partito.
è preciso in quanto si appoggia al timer0 del microcontrollore e quindi ha risoluzione di 16MHz, con dei controlli if su variabili unsigned long memorizzate puoi arrivare a oltre 50 anni di utilizzo senza che millis() vada in overflow  smiley-wink
Logged

Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

0
Offline Offline
Faraday Member
**
Karma: 31
Posts: 2908
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao superlol, il timer ha risoluzione di 16MHZ??? smiley-eek

Allora a questa ora sono più fresco di te (ma fra poco crollo), rettifico io. smiley-razz

Il timer0 ha un contatore ad 8 bit e quindi ha risoluzione di 8 bit.

il timer di millis() io ricordo che va in overflow molto prima di 50 anni e potrebbe essere un problema se non si prende precauzione, ma comunque si tratta di mesi prima che vada in owerflow.


Ciao.
« Last Edit: September 10, 2012, 06:16:18 pm by MauroTec » Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao superlol, il timer ha risoluzione di 16MHZ??? smiley-eek

Allora a questa ora sono più fresco di te (ma fra poco crollo), rettifico io. smiley-razz

Il timer0 ha un contatore ad 8 bit e quindi ha risoluzione di 8 bit.

il timer di millis() io ricordo che va in overflow molto prima di 50 anni e potrebbe essere un problema se non si prende precauzione, ma comunque si tratta di mesi prima che vada in owerflow.


Ciao.

Ah, annamo  bbene ...
Se un timer a 8 bit ci mette qualche mese ad andare in overflow stiamo freschi!
L'overflow viene generato durante il passaggio del contatore del timer stesso da 255(8 bit) a 0 e questo avviene esattamente (prescaler a parte) con un clock a 16mhz 15625 volte al secondo.
Facciamo che è la funzione millis che restituendo un u long  si azzera ogni 4,294,967,295 millisecondi equivalenti a circa 49 giorni 16 ore e spicci, ma ciò non toglie che poi riparte correttamente da zero ed è pertanto cmq utilizzabile anche in seguito.
« Last Edit: September 10, 2012, 06:47:12 pm by niki77 » Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22973
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non bisogna scrivere dopo le 24:00  smiley-yell
Logged


0
Offline Offline
Shannon Member
****
Karma: 132
Posts: 10500
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

a parte il dealy, ma nessun ha notato che nel loop()

if (Serial.available() > 0) {
balbla
}

ovvero, esegue i controllo SE E SOLO SE ci sono dati nella seriale?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22973
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non ho guardato il codice. Hai fatto bene a farlo notare.
Logged


Pages: [1]   Go Up
Jump to: