Letture sfasate RPM ventola pc

Ciao a tutti :slight_smile:
Sto provando a fare un'altra delle mie idee strane con arduino.. In pratica la mia idea si basa sul controllare una classica ventola per pc da 12v, e monitorare gli RPM della ventola..
Controllo la velocità tramite un transistor BC337-40 controllato dal pin 3 in PWM (modificando il divisore della frequenza per avere 31.25Mhz), e sembra andare tutto bene.. Insieme ho anche scritto la parte di codice per rilevare gli RPM tramite l'attachInterrupt del pin 2.. Pure questo "sembra" andare bene, solo se tengo l'uscita del pin 3 a 255.. Se provo a portarla sotto il 250 comincia a darmi letture degli RPM sfasate, e non riesco a capirne il perchè..!
Penso sia legato alla regolazione tramite transistor, perchè se cerco di regolare la velocità della ventola tramite resistenza legge gli RPM senza problema..

AleCune93:
modificando il divisore della frequenza per avere 31.25 Mhz

Per avere che frequenza ??? :astonished: :astonished: :astonished:

Guglielmo

P.S. : ... e, comunque, perché cambiare la frequenza del PWM per una ventolina ???

Scusami, 31.25 Khz volevo dire.. Ho fatto confusione con Mhz e Khz.. :slight_smile:
Ho dovuto cambiarla perchè sennò la ventola "fischiava"...

Ah .. ora ci siamo ... :grin:

Allora, immagino tu hai modificato Timer2 (... che, se ben ricordo, governa il PWM sui pin 3 e 11) ... ma la cosa dovrebbe essere ininfluente sul resto ...

Se fai analogWrite(pin, 255) ... praticamente hai fatto un digitalWrite(pin, HIGH) ... per questo funziona, non sta lavorando il PWM, mentre sembra che hai problemi quando entra in funzione il PWM ... :roll_eyes:

Metti il codice e vediamo se scopriamo l'arcano ...

Guglielmo

Ecco qua il codice.. Non è proprio messo bene, ma qualcosa c'è..

int val = 0;
volatile byte half_revolutions = 0;
unsigned int rpm = 0;
unsigned long timeold = 0;

void setup() {
  pinMode(3, OUTPUT);
  setPwmFrequency(3, 1);
  pinMode(A5, INPUT);
  Serial.begin(9600);
  attachInterrupt(0, rpm_fun, RISING);
}

void loop() {
  val=map(analogRead(A5), 0, 1023, 0, 255);
  Serial.print(analogRead(A5));
  Serial.print(" ");
  Serial.print(val);
  Serial.print(" ");
  analogWrite(3, val);
  
  if (half_revolutions >= 20) { 
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*half_revolutions;
     timeold = millis();
     half_revolutions = 0;
   }
   Serial.println(rpm,DEC);
}

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

 void rpm_fun()
 {
   half_revolutions++;
   //Each rotation, this interrupt function is run twice
 }

Scusa, mi insospettisce questa tua frase ...

AleCune93:
Penso sia legato alla regolazione tramite transistor, perchè se cerco di regolare la velocità della ventola tramite resistenza legge gli RPM senza problema..

Hai provato regolare la velocità tramite resistenza (quindi scollegare il transistor dal pin 3), lasciare il codice come è in modo che puoi variare il PWM come dovrebbe essere (... anche se in realtà non regola lui il ventilatore) e vedere se le letture sono corrette ?

Non vorrei fosse qualche cosa legata all'HW :wink:

Guglielmo

Ok, l'ho appena provato.. Da 1200 RPM a 12 v, utilizzando una resistenza da 120 ohm, sono sceso a 720 RPM.. Non so se sia il valore giusto, ma di sicuro non è sballato come gli altri..

... e contemporaneamente hai anche variato A5 così da variare il PWM giusto ??? E tutto andava quindi ???

Guglielmo

No! Non l'avevo fatto inizialmente.. Dopo aver risposto ho riletto il tuo messaggio e l'ho fatto.. Ed in effetti solo se A5 è a 0 o 1023 la lettura è a 720RPM.. Se invece vario A5 mi misura degli RPM errati.. Non sbalza in alto a 20.000 RPM come prima, ma va dagli 800 ai 1040 RPM, in base al valore assunto da A5..!

Puoi fare un altra piccola prova ? Puoi provare a NON cambiare la frequenza del Timer del PWM (non chiamando la setPwmFrequency() ) e lasciare quella di default ? Fai le stesse prove e vedi che letture hai ... :roll_eyes:

Guglielmo

Appena fatto.. E in realtà ora è stabile..
Il problema è che, non contento, ho riprovato ad abilitare la funzione setPwmFrequency().. E la stabilità va a colpi.. Ogni tanto è stabile, e ogni tanto no..

Ho una mia teoria, ma ... facciamo un'altra prova (... ti sto' usando per fare alcune verifiche ... :grin:) ...

... attualmente tu hai l'interrupt sul pin 2 che è PD2 della MCU e usi il PWM sul pin 3 che è PD3. Se puoi e se è libero, potresti cambiare la configurazione ed usare il PWM sul pin 9 che è PB1 ?

In questo modo l'interrupt continueresti ad averlo sulla porta PD, ma il PWM lo sposteremmo sulla porta PB ...

... vedi un po' che succede ... :roll_eyes:

Guglielmo

Non ti preoccupare.. Devo risolvere un mio problema, ovvio che se devi aiutarmi devi farmi fare verifiche :smiley:
Comunque ricapitoliamo.. Sia che la frequenza sia modificata, che non, non noto alcun disturbo (per adesso).. C'è un piccolo calo solo quando cambio PWM, ma sembra abbastanza stabile..

Ho spostato il PWM sul pin 9, e in ogni caso c'è sempre l'instabilità delle misure se non sono a 0 o 1023..

Mmm .. ok, allora nulla, teoria sbagliata, peccato ... :grin:

Ma sono valori completamente sballati o leggermente instabili ? Perché posso immaginare che comunque, per varie cause, la velocità della ventolina, quando non è ferma o a pieno regime, anche se imposti un valore fisso, comunque possa leggermente variare (attriti o altre cause esterne) o anche perché varia la lettura dell'analogRead() e quindi, anche se di poco, varia il PWM ... :roll_eyes:

Guglielmo

Sono leggermente instabili (di un centinaio di RPM) quando è collegata direttamente alla batteria, mentre se è regolata dal PWM di arduino i valori sono completamente sballati.. Va da 50.000 RPM a 100 in un colpo, e continua ad altalenare..

No, allora c'è qualche cosa che non va ...
... però mi dicevi che, se non cambi la frequenza del PWM, la cosa non succede vero ???

Guglielmo

P.S. : Comunque ho allertato Leo ... che molto esperto di Timer, PWM e Interrupt; mi ha confermato che domani mattina darà un occhiata al thread e vediamo se gli salta all'occhio qualche cosa

No allora.. Se cambio la frequenza c'è un leggerissimo sbalzo degli RPM, ma solo se collego la ventola alla batteria.. Comunque nel giro di 3/4 letture torna tutto normale..
Al contrario, se invece collego la ventola all'arduino con il PWM gli RPm restano stabili solo se al PWM do valore 0 o 255 (e il pin A5 è a 0 o 1023).. Se do al PWM un valore tra 1 e 254 gli RPM sono completamente sfasati...

Ti ringrazio.. Spero di riuscire a dare un'occhiata anch'io al thread domani mattina, ma sarà difficile perchè sono all'università..!

Aspetta, ho detto .. se NON cambi la frequenza al PWM ... ovvero, se non usi la setPwmFrequency() ma colleghi il tutto al pin del PWM ... va o è sempre sballato ???

E comunque, posta anche lo schema che stai usando ... giusto per sicurezza :wink:

Guglielmo

gpb01:
E comunque, posta anche lo schema che stai usando
...

E' proprio necessario, direi.
Premesso che gli interrupt sono slegati dai timer/pwm, se cambi il prescaler ad un timer questo non deve influire su altro, a me il problema pare essere nel pilotaggio della ventolina, leggendo qui:

AleCune93:
No allora.. Se cambio la frequenza c'è un leggerissimo sbalzo degli RPM, ma solo se collego la ventola alla batteria.. Comunque nel giro di 3/4 letture torna tutto normale..
Al contrario, se invece collego la ventola all'arduino con il PWM gli RPm restano stabili solo se al PWM do valore 0 o 255 (e il pin A5 è a 0 o 1023).. Se do al PWM un valore tra 1 e 254 gli RPM sono completamente sfasati...

Quindi se alimenti da Arduino sballa tutto. Ma quanto consuma questa ventola? E come fai ad alimentare una ventola a 12V dall'Arduino? Non l'ho capito.

No Leo ... le prove sono state fatte sia con la ventola non controllata dal pin del PWM (praticamente staccando il transistor che va al pin 3) sia con la ventola controllata dal pin del PWM (transistor attaccato al pin 3).

Ma se, come confermi, la parte generazione del PWM non influisce minimamente sulla parte interrupt (... mi era venuto il dubbio visto che usavano lo stesso port PD) ... allora probabilmente iil problema deriva dall'HW ... per questo difatti ho chiesto lo schema di collegamento :wink:

Guglielmo