Ciao fer314
grazie di avermi risposto,
per quel poco che so il filo contrassegnato PWM dello scema che allego, sarebbe per mandare da un pin un segnale in PWM per controllare la ventola,
ma se dando tensione alla ventola su quel filo mi trovo 5,3 V il pin di Arduino che fine fa?
Mah ... probabilmente c'è solo una pull-up che tiene normalmente il pin HIGH ... non mi preoccuperei più di tanto, al limite, metti una resistenza da un 100Ω in serie ... nel peggiore dei casi limiti la corrente che scorre
Una buona giornata ragazzi.
allora seguendo il suggerimento di Guglielmo riesco a controllare la ventola in PWM.
Ora vorrei poter leggere la tachimetria e contare i giri,
cercando in rete si trova di tutto, ma non mi fido,
c'è qualcuno che mi può dare qualche dritta su come fare?
Mille grazie a tutti per il tempo che mi dedicate
Quello che segue è il codice finale, senza il pilotaggio dei display. E' il migliore che ho trovato. Con il clock a 16MHz di Uno e Nano misura da 1Hz a 7,8MHz.
Il while nel loop lo blocca per i 100ms necessari per il conteggio senza interferenze, dopodiché appare il valore della frequenza sul monitor seriale. Nel tuo caso i 100ms di blocco non daranno problemi.
Se la funzione start() ti sembra complessa, non credere che una libreria ben fatta, seppure ti nasconda tutto, sia più semplice! Così, invece, hai tutto il codice leggibile e incorporato nel programma, che puoi trasportare senza bisogno di installare librerie e con la certezza che anche tra 10 anni avrai tutto disponibile per ricompilarlo dopo aver apportato delle modifiche.
Usa il PWM sull'I/O 6.
// D5 - Frequency input 1, Counter 1, 16 bit
unsigned long f_freq;
volatile unsigned char f_ready;
volatile unsigned char f_mlt;
volatile unsigned int f_tics;
volatile unsigned int f_period;
void setup()
{
pinMode(5, INPUT); // This is the frequency input
Serial.begin(9600);
}
void loop()
{
start(100); // 100 ms Gate Time
while (f_ready == 0);
unsigned long f=f_freq*10;
Serial.println(f);
}
/*
Martin Nawrath KHM LAB3
Kunsthochschule f¸r Medien Kˆln
Academy of Media Arts
http://www.khm.de
http://interface.khm.de/index.php/labor/experimente/
*/
void start(int ms)
{
TIMSK0 &=~(1<<TOIE0); // disable Timer0 //disable millis and delay
delayMicroseconds(50); // wait if any ints are pending
f_period=ms;
// hardware counter setup ( refer atmega168.pdf chapter 16-bit counter1)
TCCR1A=0; // reset timer/counter1 control register A
TCCR1B=0; // reset timer/counter1 control register A
TCNT1=0; // counter value = 0
// set timer/counter1 hardware as counter , counts events on pin T1 ( arduino pin 5)
// normal mode, wgm10 .. wgm13 = 0
TCCR1B |= (1<<CS10) ;// External clock source on T1 pin. Clock on rising edge.
TCCR1B |= (1<<CS11) ;
TCCR1B |= (1<<CS12) ;
// timer2 setup / is used for frequency measurement gatetime generation
TCCR2A=0;
TCCR2B=0;
// timer 2 presaler set to 128 / timer 2 clock = 16Mhz / 256 = 62500 Hz
TCCR2B |= (1<<CS20) ;
TCCR2B &= ~(1<<CS21) ;
TCCR2B |= (1<<CS22) ;
//set timer2 to CTC Mode with OCR2A is top counter value
TCCR2A &= ~(1<<WGM20) ;
TCCR2A |= (1<<WGM21) ;
TCCR2A &= ~(1<<WGM22) ;
OCR2A = 124; // CTC divider by 125
f_ready=0; // reset period measure flag
f_tics=0; // reset interrupt counter
GTCCR = (1<<PSRASY); // reset presacler counting
TCNT2=0; // timer2=0
TCNT1=0; // Counter1 = 0
TIMSK2 |=(1<<OCIE2A); // enable Timer2 Interrupt
// External clock source on T1 pin. Clock on rising edge.
TCCR1B |= (1<<CS12) | (1<<CS11) | (1<<CS10); // start counting now
}
//******************************************************************
// Timer2 Interrupt Service is invoked by hardware Timer2 every 1ms = 1000 Hz
// 16Mhz / 128 / 125 = 1000 Hz
// here the gatetime generation for freq. measurement takes place:
ISR(TIMER2_COMPA_vect)
{
// multiple 2ms = gate time = 100 ms
if (f_tics >= f_period)
{
// end of gate time, measurement ready
// GateCalibration Value, set to zero error with reference frequency counter
// delayMicroseconds(FreqCounter::f_comp); // 0.01=1/ 0.1=12 / 1=120 sec
TCCR1B = TCCR1B & ~7; // Gate Off / Counter T1 stopped
TIMSK2 &= ~(1<<OCIE2A); // disable Timer2 Interrupt
TIMSK0 |=(1<<TOIE0); // enable Timer0 again // millis and delay
f_ready=1; // set global flag for end count period
// calculate now frequeny value
f_freq=0x10000 * f_mlt; // mult #overflows by 65636
f_freq += TCNT1; // add counter1 value
f_mlt=0;
}
f_tics++; // count number of interrupt events
if (TIFR1 & 1)
{ // if Timer/Counter 1 overflow flag
f_mlt++; // count number of Counter1 overflows
TIFR1 =(1<<TOV1); // clear Timer/Counter 1 overflow flag
}
}
Usando millis(), puoi anche fare una lettura al secondo:
uint32_t t0;
loop:
if(millis()-t0>=1000)
{
t0+=1000;
start(100); // 100 ms Gate Time
while (f_ready == 0);
unsigned long f=f_freq*10;
Serial.println(f);
}
... guarda, esistono DUE ottime librerie per misurare frequenze senza complicarsi troppo la vita, sono la FreqCount e la FreqMeasure ... la prima per frequenze da 1 KHz in su, la seconda per frequenze fino ad 1 KHz. A seconda del segnale che devi misurare usa una delle due e vedrai che non avrai problemi. Solo ... studiati bene la documentazione !
Personalmente ho collegato il pin rpm ad un interrupt fisico di Arduino e contato il numero di impulsi per frazione di minuto, dividendoli poi per il numero di sensori di Hall presenti nella ventola (tipicamente sono due) e moltiplicando il risultato per il numero di frazioni necessarie per fare un minuto. P.es. se leggo 1000 impulsi in 10 secondi significa che avrei 6000 impulsi in 60 secondi, siccome ho due sensori di Hall, un giro è costituito da due impulsi, quindi faccio 6000/2 e ottengo 3000 rpm, senza ricorrere ad altro. Chiaramente la lettura non deve essere disturbata da ritardi dovuti a delay, usando quindi il millis.
Ottima idea, l'unico dubbio che ho è se questo metodo possa avere problemi con ventole ad elevato numero di giri, tipo i 40.000 rpm della turbina che ho usato io. Col mio metodo ho notato che minore era l'intervallo di lettura e maggiore era l'errore. Comunque dovrò rimnettere mano al mio progetto, quindi una prova non mi costa niente, se funziona sarebbe un comodo alleggerimento .
Rieccomi qui, ho provato il programma postato da Datman, ma stranamente al minimo di giri mi da 30, vado su di PWM passa a 110, non ci sono variazioni in funzione della variazione del PWM,
Ciao Datman
si il segnale e ad onda quadra, posto alcune foto:
la prima (come si nota) e co un pwm a 0 mi da 50 ,
la seconda con un pwm a 8 mi da 110 ,
ma anche se salgo col pwm mi da solo 110
non capisco dose sia l'inghippo.