Velocità motore

Ciao,
ho messo mano al codice, scusa se l'ho riscritto secondo il mio stile.
Ho modificato la configurazione pin-pulsanti in modo da permettere di usare il pin 2 come interrupt a cui collegare il reed o i reed.
I relè del motore li puoi collegare agli analogici usati come digitali. in questo modo sono liberi anche i pin 10,11,12 e 13 per eventuale Ethernet o collegamenti SPI e A4 e A5 per un eventuale sensore I2C o LCD seriale (collegabile anche tramite SPI).
Il problema da risolvere sono i delay attivati dalla seriale, quelli incasinano tutto il conteggio. Devi trovare il modo di accenderli e spegnerli con la millis oppure usi la libreria Leos, Looper o TimeAction.

Spero che funzioni.
Concettualmente dovrebbe e inoltre "compila" :sweat_smile:

const short int ButtonPinuno = 3;        //pin pulsante incremento
const short int ButtonPindue = 4;    //pin pulsante decremento
int CurrentStateuno;                  //variabile per lo stato uno corrente
int LastStateuno = 0;                //variabile per l'ultimo stato uno
int CurrentStatedue;                  //variabile per lo stato due corrente
int LastStatedue = 0;            //variabile per l'ultimo stato due
int short contprima = 0;          //Holds number of button presses.
const short int ButtonPintre = 5;        //pin pulsante incremento
const short int ButtonPinquattro = 6; //pin pulsante decremento
int CurrentStatetre;                  //variabile per lo stato uno corrente
int LastStatetre = 0;                //variabile per l'ultimo stato uno
int CurrentStatequattro;              //variabile per lo stato due corrente
int LastStatequattro = 0;            //variabile per l'ultimo stato due
int short contseconda = 0;          //Holds number of button presses
const short int ButtonPincinque = 7;        //pin pulsante incremento
const short int ButtonPinsei = 8; //pin pulsante decremento
int CurrentStatecinque;              //variabile per lo stato uno corrente
int LastStatecinque = 0;              //variabile per l'ultimo stato uno
int CurrentStatesei;                  //variabile per lo stato due corrente
int LastStatesei = 0;                //variabile per l'ultimo stato due
int short contterza = 0;            //Holds number of button presses
unsigned long currentTime = 0;
unsigned long loopTime = 0;
unsigned long lastTimeReed = 0;
unsigned long currentTimeRpm = 0;
unsigned long lastTimeRpm = 0;
const short int moton = 14;     // A0
const short int motoff= 15;     // A1
const short int aumenta= 16;    // A2
const short int diminuisci= 17; // A3

const int sensvel = 2; 
const float radius = 13.5;// tire radius (in inches) 
const float circumference = TWO_PI*radius*0.0254; // (in metri)
unsigned int ms = 0;
unsigned int reedCounter; 
const byte reedNumber = 1; // numero di magneti per giro

void setup() 
{ 
  delay(1000);
  Serial.begin(9600);          //Begins communication with computer 
  pinMode(ButtonPinuno,INPUT);    //Sets ButtonPin as input. 
  pinMode(ButtonPindue,INPUT);    //Sets ButtonPin as input. 
  pinMode(ButtonPintre,INPUT);    //Sets ButtonPin as input. 
  pinMode(ButtonPinquattro,INPUT);    //Sets ButtonPin as input. 
  pinMode(ButtonPincinque,INPUT);    //Sets ButtonPin as input. 
  pinMode(ButtonPinsei,INPUT);    //Sets ButtonPin as input. 
  pinMode(moton, OUTPUT); 
  pinMode(motoff, OUTPUT); 
  pinMode(aumenta, OUTPUT); 
  pinMode(diminuisci, OUTPUT); 
  pinMode(sensvel, INPUT); // sensore velocità 
  attachInterrupt(0, Counter, RISING); 
} 

void Counter(){
  reedCounter++;
  lastTimeReed = millis();
}

void loop() 
{ 
  CheckButton();
  CheckSerial();
  ms = SpeedCalc();
  currentTime = millis(); 
  if(currentTime >= (loopTime + 1000)) 
  { 
    Serial.print(contprima); 
    Serial.print(","); 
    Serial.print(contseconda); 
    Serial.print(","); 
    Serial.print(contterza); 
    Serial.print(","); 
    Serial.println(ms); 
    loopTime = currentTime; 
  } 
}

int SpeedCalc(){
  int vel = ms;
  currentTimeRpm = millis();
  if (currentTimeRpm - lastTimeRpm > 999) { 
    int rpm = (60*reedCounter)/reedNumber;
    reedCounter = 0;
    lastTimeRpm = currentTimeRpm;
    vel = ((rpm * circumference)/60); 
  }
  if (lastTimeReed - currentTimeRpm > 2000){ 
    vel = 0;
    reedCounter = 0; 
  } 
  return vel;
}

void CheckButton(void){
  CurrentStateuno = digitalRead(ButtonPinuno);          
  CurrentStatedue = digitalRead(ButtonPindue);        
  CurrentStatetre = digitalRead(ButtonPintre);          
  CurrentStatequattro = digitalRead(ButtonPinquattro);    
  CurrentStatecinque = digitalRead(ButtonPincinque);  
  delay(10);  // debounce                                                 

  if(CurrentStateuno != LastStateuno)
  {
    if(CurrentStateuno == HIGH)
    {
      contprima++;
    }
  }
  LastStateuno = CurrentStateuno;

  if(CurrentStatedue != LastStatedue)
  {
    if(CurrentStatedue == HIGH)
    {
      contprima--;
    }
  }
  LastStatedue = CurrentStatedue;

  if(CurrentStatetre != LastStatetre)
  {
    if(CurrentStatetre == HIGH)
    {
      contseconda++;
    }
  }
  LastStatetre = CurrentStatetre;

  if(CurrentStatequattro != LastStatequattro)
  {
    if(CurrentStatequattro == HIGH)
    {
      contseconda--;
    }
  }
  LastStatequattro = CurrentStatequattro;

  if(CurrentStatecinque != LastStatecinque)
  {
    if(CurrentStatecinque == HIGH)
    {
      contterza++;
    }
  }
  LastStatecinque = CurrentStatecinque;

  if(CurrentStatesei != LastStatesei)
  {
    if(CurrentStatesei == HIGH)
    {
      contterza--;
    }
  }
  LastStatesei = CurrentStatesei;
}

void CheckSerial(void){
  if(Serial.available() >0) 
  { 
    switch (Serial.read()){ 

    case 'A':
      digitalWrite(moton, HIGH); 
      delay(1000); 
      digitalWrite(moton, LOW); 
      break;

    case 'B':
      digitalWrite(motoff, HIGH); 
      delay(1000); 
      digitalWrite(motoff, LOW); 
      break;

    case 'C': 
      digitalWrite(aumenta, HIGH); 
      delay(1000); 
      digitalWrite(aumenta, LOW); 
      break;

    case 'D': 
      digitalWrite(diminuisci, HIGH); 
      delay(1000); 
      digitalWrite(diminuisci, LOW); 
      break;

    default:
      break;
    }
  }   
}

se tu per delay ti riferisci a questi

      digitalWrite(diminuisci, HIGH); 
      delay(1000); 
      digitalWrite(diminuisci, LOW);

non credo costituiscano problema visto che c'erano anche prima e prima mi funzionava bene.Poi non so consigliami tu.

francescoprisco:
Intendi qualcosa del genere?

Una cosa del genere.
In questo modo se il magnete resta fermo per troppo tempo sul sensore 1, hai la sicurezza che è lì perché il sensore 2 non viene attivato.

leo sapresti dirmi come ovviare ai delay? Il codice di Paolo sembra giusto e senza problemi. se usassi quello?

@PaoloP nel caso io non possa cambiare i pin se rimanessi A0 come interrupt ci sarebbero problemi?

Il fatto è che ho già saldato i relè su una millefori e collegati anche i pin.Dovrei rifar tutto da capo.
è possibile rimanere tutto com'era prima a livello pin?

francescoprisco:
leo sapresti dirmi come ovviare ai delay? Il codice di Paolo sembra giusto e senza problemi. se usassi quello?

Usa quello, se funziona perché inventarsi un'altra cosa? :wink:

una domanda:
Ma l'interrupt su pin analogico non funziona?

No, funziona solo sul pin 2 (interrupt 0) o sul pin 3 (interrupt 1). Non c'è scampo. [solo gamberetti!! :sweat_smile:]
Visto che ha già saldato tutto. Ripristina l'ordine dei pin precedente tranne il pin 2. L'unico che dovrai dissaldare e scambiare.

si ho saldato tutto....va bhe cambierò il pulsante al pin due e lo metterò al 12 ho da cambiare solo un pin.Sono sicuro che non userò ne lcd ne Ethernet quindi posso usarli.

PaoloP:
No, funziona solo sul pin 2 (interrupt 0) o sul pin 3 (interrupt 1). Non c'è scampo. [solo gamberetti!! :sweat_smile:]
Hai già saldato i contatti? Non li puoi scambiare?

Può però usare la PinChangeInt, che si aggancia agli interrupt PCINT, disponibili su tutti i pin, compregli gli analogici:
http://code.google.com/p/arduino-pinchangeint/

Ho risolto.Ho collegato il pulsante alla porta A0 dove prima era il magnete e ho collegato il magnete alla 2.Il pulsante funziona ma il magnete pare non funzionare.

Aggiungi un serialPrint(reedCounter); nel loop() e controlla nel serial monitor.

al passaggio della calamita sul sensore rimane a 0 sia la velocità che il reedCounter

int SpeedCalc(){
  int vel = ms;
  currentTimeRpm = millis();
  if (currentTimeRpm - lastTimeRpm > 999) { 
    int rpm = (60*reedCounter)/reedNumber;
    reedCounter = 0;
    lastTimeRpm = currentTimeRpm;
    vel = ((rpm * circumference)/60); 
  }
  if (lastTimeReed - currentTimeRpm > 2000){ 
    vel = 0;
    reedCounter = 0; 
  } 
  return vel;
}

poi nel loop

void loop() 
{ 
[..]
  ms = SpeedCalc();
[...]
  } 
}

non capisco int val = ms; nel SpeedCalc

Come hai collegato il sensore? Hai messo una pull-down?
Il controllo sul pin è di tipo RISING, quindi scatta quando passa dallo stato LOW ad HIGH, però se non c'è una pull-down lo stato potrebbe essere indefinito.

sul pin 2 c'è una resistenza da 10k ohm con un lato collegata alla gnd e dall'altra al pin e al sensore. l'altro capo del sensore è collegato al 5V.E' Corretto?

francescoprisco:

int SpeedCalc(){

int vel = ms;
  currentTimeRpm = millis();
  if (currentTimeRpm - lastTimeRpm > 999) {
    int rpm = (60*reedCounter)/reedNumber;
    reedCounter = 0;
    lastTimeRpm = currentTimeRpm;
    vel = ((rpm * circumference)/60);
  }
  if (lastTimeReed - currentTimeRpm > 2000){
    vel = 0;
    reedCounter = 0;
  }
  return vel;
}



poi nel loop


void loop()
{
[..]
  ms = SpeedCalc();
[...]
  }
}




non capisco int val = ms; nel SpeedCalc

Secondo il mio ragionamento dovrebbe funzionare in questo modo:
entrando nella funzione salvo il valore precedente di ms; poi se il tempo trascorso è maggiore di 1 secondo calcolo in nuovo valore della velocità che quindi viene restituita dalla funzione.
Se invece passa più di 2 secondi dall'ultima lettura metto val=0 (era così anche nel tuo codice).

francescoprisco:
sul pin 2 c'è una resistenza da 10k ohm con un lato collegata alla gnd e dall'altra al pin e al sensore. l'altro capo del sensore è collegato al 5V.E' Corretto?

Si, è corretto.

Forse perchè manca il richiamo alla funzione Counter.Infatti nel loop non c'è di conseguenza reedCounter non si incrementa.

Prova questo codice:

const int sensvel = 2; 
unsigned int reedCounter = 0; 
const byte reedNumber = 1; // numero di magneti per giro

void setup() 
{ 
  delay(1000);
  Serial.begin(9600);          //Begins communication with computer 
  pinMode(sensvel, INPUT); // sensore velocità 
  attachInterrupt(0, Counter, RISING); 
} 

void Counter(){
  reedCounter++;
  //  lastTimeReed = millis();
}

void loop() 
{ 
  delay(1000);
  Serial.println(reedCounter); 
}

Mi sono accorto che in quello precedente ho messo

unsigned int reedCounter;

e non

unsigned int reedCounter = 0;

quindi parte con un valore non definito.