Go Down

Topic: Digital Read molto lento nel rilevare il cambio di stato (Read 1 time) previous topic - next topic

nienteposta

Buona sera a tutti.
Utilizzo un Arduino mega R3.

questo è il codice in questione

Code: [Select]

// 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


Michele Menniti

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.
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

nienteposta

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

flz47655

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

Michele Menniti


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
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

leo72


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.

MauroTec

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.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

superlol

allora la prima lettura scommetto che avviene dopo 1.3 secondi e la seconda dopo 5.3 secondi  :P

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  ;)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

MauroTec

#8
Sep 11, 2012, 01:08 am Last Edit: Sep 11, 2012, 01:16 am by MauroTec Reason: 1
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. :P

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.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

niki77

#9
Sep 11, 2012, 01:43 am Last Edit: Sep 11, 2012, 01:47 am by niki77 Reason: 1

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. :P

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.
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

leo72


lesto

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?
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

leo72

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

Go Up