Gestione pompa peristaltica

Buongiorno, appena presentatomi, ecco il quesito: L'idea è quella di un lubrificatore automatico, a bordo , in regime di marcia, dalle dimensioni ridotte per catene di trasmissione motociclistiche. Si tratta di gestire una piccola pompa peristaltica il cui motore è un servo per modellismo modificato per rotazione completa. Facendo grossomodo uno schema a blocchi il funzionamento dovrebbe essere questo: lettura dei giri ruota (o corona) mediante contatto reed conteggio impulsi del contatto azionamento del servo ad un determinato numero di impulsi ricevuti ( il servo è regolato per compiere una rotazione di 120° ad ogni accensione) stop ciclo e ripartenza. Secondo voi è fattibile con arduino uno?

ciao e benvenuto
in linea di massima direi che è fattibile, l’unica cosa da verificare è la frequenza di lettura del reed e se utilizzando gli interrupt non perdi il conto (credo comunque che la velocità del micro batta quella della moto XD )

Ciao, Ipotizzando una velocità di 150 km/h il reed farebbe circa 20 contatti al sec. Ho escluso un sensore di tipo ottico perchè si potrebbe sporcare, visto l' ambiente in cui lavora. Quello che non riesco a fare però è il conteggio e la totalizzazione degli impulsi con lo sketch . Inutile dire che ho cercato nel forum......, forse sbaglio le parole di ricerca.

ciao Giacomo

Con un contatto reed non riesci a fare questa cosa … anche perché hai poi il problema dei rimbalzi dei contatti …

… ti conviene usare un sensore ad effetto di Hall che mandi su uno degli ingressi Interrupt di Arduino. Nella relativa ISR non fai altro che incrementare un contatore e … altro che venti impulsi al secondo arrivi a contare :grin:

Cerca su Google Arduino “sensore hall arduino” e ti verrano fuori un bel po’ di pagine … oppure fai una ricerca qui sul forum perché, di questa cosa, se ne è già parlato …

Guglielmo

giacomo2: Ciao, Ipotizzando una velocità di 150 km/h il reed farebbe circa 20 contatti al sec. Ho escluso un sensore di tipo ottico perchè si potrebbe sporcare, visto l' ambiente in cui lavora. Quello che non riesco a fare però è il conteggio e la totalizzazione degli impulsi con lo sketch . Inutile dire che ho cercato nel forum......, forse sbaglio le parole di ricerca.

ciao Giacomo

Al posto del reed userei un sensore magnetico a effetto Hall. per Esempio: http://www.robot-domestici.it/joomla/component/virtuemart/robotica-domotica/sensori/sensori-magnetici/hall-effect-sensor

Usa l' interrupt. A ogni interrupt incrementi una variabile di tipo volatile. Fuori dall interrupt controlli la variabile. Non so se il tubo della variabile sopporta l' olio.

Ciao Uwe

Il sensore non verrebbe comunque a contatto con l' olio. la pompa peristaltica è stata scelta proprio per non avere perdite d' olio in nessun modo (salvo rottura del tubo)

Buonasera a tutti: Oggi mi sono perso, ho compilato questo sketch per leggere gli impulsi del sensore e funziona:

const int hallPin = 2; // pin connesso al sensore const int ledPin = 13; // pin connesso al led // variables will change: int hallState = 0;// variabile per la lettura dello stato int lasthallState = LOW; volatile int state = LOW; void setup() { // abilitazione pin in uscita pinMode(ledPin, OUTPUT); // abilitazione pin in ingresso pinMode(hallPin, INPUT);

}

void loop(){ hallState = digitalRead(hallPin); if (hallState == LOW) { // turn LED on: digitalWrite(ledPin, HIGH);

} else { // turn LED off: digitalWrite(ledPin, LOW);

} }

Sono anche riuscito a visualizzare su serial monitor (la parte relativa di sketch l'ho cancellata perchè non mi serve) non riesco però ad impostare un conteggio progressivo, in modo da gestirlo con gli interrupt. in particolare non riesco a capire che cosa sia l ' interrupt service routine. help me "aiutino" needed

Già letto tutto quello che c'è QUI ???

Guglielmo

ciao Guglielmo, si avevo già spulciato in alcune di quelle pagine..... questo significa che devo includere qualche libreria?

giacomo2:
questo significa che devo includere qualche libreria?

No, no, guarda nel reference la attachInterrupt() … c’è anche un piccolo esempio :wink:

Guglielmo

EDIT: non ricordo da dove l’avevo salvato/scaricato, ma magari l’articolo che ti allego ti può aiutare :wink:

Interrupt come Arduino gestisce le interruzioni con i parametri.pdf (104 KB)

o.k. Guglielmo, ho aggiunto l' interrupt al mio sketch e funziona, il mio problema principale però rimane il come utilizzare il cambio di stato che nell'esempio va al pin8, per eseguire un conteggio, memorizzarne il totale ed eseguire un secondo interrupt al raggiungimento del conteggio voluto.

Allora, comincia a scrivere un programma minimo in cui dichiari la ISR e ci metti dentro l'incremento del tuo contatore, poi mettilo qui (... mi raccomando, racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone # ... terzultimo della seconda fila) e cerchiamo di sistemarlo passo passo ... ;)

Guglielmo

Ahimè, dopo un bel po' di smanettamenti ho compilato questo Sketch, ma non conteggia. L' ISR si chiama stepServo perché ad ogni reset del contatore deve azionare un servo, che per ora si chiama ledBianco

const int hallPin = 2;      // pin connesso al sensore
const int ledPin =  13;     // pin connesso al led
int hallState = 0;          // variabile per la lettura dello stato
int ledBianco = 7;

void setup() {                   
  pinMode(ledPin, OUTPUT);       // abilitazione pin in uscita
  pinMode(hallPin, INPUT);       // abilitazione pin in ingresso
  pinMode(ledBianco, OUTPUT);
  
  attachInterrupt(0,stepServo,RISING);

}

void loop(){
 hallState++;

  hallState = digitalRead(hallPin);
  if (hallState == LOW) {     
   digitalWrite(ledPin, HIGH);      // turn LED on:
 } 
  else {
   digitalWrite(ledPin, LOW);      // turn LED off:
  }
   if(hallState == 10)
  { hallState = 0;
   digitalWrite (ledBianco,LOW);
  }
  }


void stepServo()
{
  digitalWrite(ledBianco,HIGH);
}
/code]

Noto subito alcune cose ...

Prima di tutto ... in una ISR bisogna fare un minimo di cose e uscire il prima possibile, quindi, evita comandi come digitalWrite() o cose simili, ma usa una tua flag (una variabile byte ... mi raccomando dichiarata volatile) per indicare se devi accendere o spegnere, ma l'accensione/spegnimento fisico lo fai poi [u]fuori dalla ISR[/u] nel loop(), tipo :

volatile byte miaFlag;
...
...
if (miaFlag) {
  ... se è vera fai qualche cosa
}
else {
  ... se falsa fai qualche cosa d'altro
}
...
...
void miaISR() {
   miaFlag = true;
}

Poi, nel tuo codice ... ... non capisco cosa vorresti fare qui :

void loop(){
  hallState++;
  hallState = digitalRead(hallPin);
  ...

prima incrementi la variabile hallState e immediatamente dopo ... gli assegni il valore true/false che leggi dal pin ??? :astonished: :astonished: :astonished:

Semplicemente NON ha senso !

Prova a ragionare su cosa vuoi esattamente fare (fatti un bel diagramma logico) e rimetti giù il codice ;)

Guglielmo

effettivamente un bel po' di casino lo sto facendo. il led sul pin 13 mi serve che lampeggi , almeno in fase di messa a punto dello sketch, per verificare l' avvenuto cambio di stato del pin 2 a cui è collegato il sensore. tramite l' interrupt vorrei contare gli impulsi e, dopo aver totalizzato ad es. 500 impulsi, attivare un servocomando per 1 secondo, resettando contemporaneamente il conteggio. gli impulsi vengono dati da un sensore di hall che legge un magnete e la frequenza è variabile, perchè ciò che deve determinare l'azionamento del servo è solo il n° di impulsi.

giacomo2: effettivamente un bel po' di casino lo sto facendo. ...

XD XD XD XD ... segui quello che ti ho detto ... e comincia ad impostare una cosa semplice ... prova prima di tutto il semplice conteggio degli impulsi, poi, mano mano, ci si aggiungono le cose ;)

Guglielmo

Ebbene si, con tanta fatica sono riuscito a contare gli impulsi e totalizzarli . per accertarmene li ho visualizzati sul serial monitor

const int hallPin = 2; // pin assegnato al sensore


int hallState = 0; // variabile per la lettura del sensore 
int hallState_old = 0; // variabile per evitare doppio conteggio

int Conteggio = 0;// variabile che contiene il conteggio delle pulsazioni
                                 



void setup() {
    Serial.begin(9600);   //attiva la porta seriale
    pinMode(hallPin, INPUT);// mette in ascolto del reed il pin 2
    
}void loop() 
{
  hallState = digitalRead(hallPin); // legge il sensore

  if (hallState != hallState_old) // si verifica se è cambiato
  {
    hallState_old = hallState;   // se SI si aggiorna lo stato
  
   if (hallState == HIGH)  // si controlla SE è alto ( passaggio magnete)
    {
     
    
      Conteggio = Conteggio + 1; // si aggiorna il contatore      
    
    
     Serial.print("progressivo = ");
           Serial.println(Conteggio);

     }
    }
  }
/code]

Giacomo ... hai visto cosa hai messo nel tuo post ??? Come pretendi che leggiamo quel codice ??? :astonished: :astonished: :astonished:

NON usare la funzione copia per il forum, usa solo il classico copia e incolla all'interno dei tag CODE (... quelli che hai usato).

Guglielmo

errore di sbaglio, Pardon

Ok, questo è il modo banale senza l'interrupt ... basta che il sensore cambi stato un po' velocemente e tu così non riesci più a contarlo !

Guarda QUESTO tutorial e cerca di implementare il conteggio con l'interrupt ... ;)

Guglielmo