So bought a $7 fan today! Hooked it up to arduino using ground and signal. Found a simple fan controller code and used that to read the signal through the serial output. It works, not sure how accurate it is need to get the fan spinning faster and at a stable speed to determine if it's working. Anyone got any advice on how to get it to display the serial output on to a 20x4 serial LCD?
Thank you
Karl
Cool, I can give you some code that will take a signal on P8 and output the period of the waveform in uS. Calculating RPM is a simple inversion of the period. My code hijacks Timer1 so you won't be able to use the built in PWM on pins 9 and 10. I can tell you that it gives very precise measurements since it is captured by the hardware and not some polling loop in software and it doesn't disable interrupts. It also frees up the foreground so you can do what you like and process the captured time at your convenience. It sticks that timer readings in a circular buffer that you can easily eliminate if you don't need it. I added it because I was using this to determine how much switch bounce was occurring on a push-button switch. I also use it for other timing purposes.
#include "Arduino.h"
volatile unsigned t1captured = 0;
volatile unsigned t1capval = 0;
volatile unsigned t1ovfcnt = 0;
volatile unsigned long t1time;
volatile unsigned long t1last = 0;
#define BUFFER_SIZE 32
volatile unsigned long int buffer[BUFFER_SIZE];
volatile int head = 0;
volatile int tail = 0;
void setup() {
Serial.begin(9600);
TCCR1A = 0x0; // put timer1 in normal mode
TCCR1B = 0x2; // change prescaler to divide clock by 8
// clear any pending capture or overflow interrupts
TIFR1 = (1<<ICF1) | (1<<TOV1);
// Enable input capture and overflow interrupts
TIMSK1 |= (1<<ICIE1) | (1<<TOIE1);
pinMode(8, INPUT);
}
void loop() {
if(head != tail) {
head = (head + 1) % BUFFER_SIZE;
Serial.println(buffer[head]);
}
}
ISR(TIMER1_OVF_vect) {
t1ovfcnt++; // keep track of overflows
}
ISR(TIMER1_CAPT_vect) {
unsigned long t1temp;
// combine overflow count with capture value to create 32 bit count
// calculate how long it has been since the last capture
// stick the result in the global variable t1time in 1uS precision
t1capval = ICR1;
t1temp = ((unsigned long)t1ovfcnt << 16) | t1capval;
t1time = (t1temp - t1last) >> 1;
t1last = t1temp;
tail = (tail + 1) % BUFFER_SIZE;
buffer[tail] = t1time;
}