Count how many pulses per second

I think you two are discussing different circuits. The one Majenko laid out before has no led?

Himym, for a red led needs IIRC at least 180 ohms resistance with 5V to keep it from burning up. Most are using 220 ohm, I don't like it so bright so I use 330, 470 or more. What you did shows that even boosted, your fan to transistor is not enough to allow much current flow or maybe some other resistor is moderating current flow.
Do you have a resistor between the fan and transistor grid? Or one between power and transistor collector?

Isn't that Ohms law I have used.

Yes, that is Ohms law, and it is possible to calculate it using Ohms law, but it is rather convoluted. You calculate the current through the divider, then calculate the voltage drop across one resistor using that current.

It is much easier to calculate the ratio of the resistors (220/(1000+220)) and then multiply that by the voltage across the whole divider. That way you don't need to worry about the current. The ratio will be a static value regardless of the voltage. If you use a voltage divider to, for example, reduce a voltage to fit into the range of an ADC input, then the voltage coming in will be changing. Thus, the current will be changing. Your way would mean calculating the current for every possible voltage to know what the output of the divider would be for that voltage. Using the ratio you know that it will always be a specific proportion of the input.

GoForSmoke:
I think you two are discussing different circuits. The one Majenko laid out before has no led?

Himym, for a red led needs IIRC at least 180 ohms resistance with 5V to keep it from burning up. Most are using 220 ohm, I don't like it so bright so I use 330, 470 or more. What you did shows that even boosted, your fan to transistor is not enough to allow much current flow or maybe some other resistor is moderating current flow.
Do you have a resistor between the fan and transistor grid? Or one between power and transistor collector?

I'm using majenkos circuit. I just conected a led to the collector on the transistor. But I'm not using a resistor in serie with the led, becuase when I used a 220ohm resistor the led didn't work.

That's because it wasn't getting enough power, probably because it's running off 5V through the internal pullup resistor which is about 20k ohms. Whatever you do, don't set that pin to OUTPUT!

GoForSmoke:
That's because it wasn't getting enough power, probably because it's running off 5V through the internal pullup resistor which is about 20k ohms. Whatever you do, don't set that pin to OUTPUT!

What do you mean. Which pin should I not set to output?

The one that you are using for INPUT to read the fan. I did forget that in Majenko's circuit (that I just looked at again) the internal pin pullup isn't the only possible power source to the transistor. It also gets Vcc (5V) through 10k ohms. When the transistor is OFF the pin will read HIGH. When the transistor is ON it grounds the power, the pin will read LOW, and your led gets 5V through 10k ohms which is enough to light it dim.

I bet you could put 220-1k ohms instead of the 10k resistor, get a brighter led and hurt nothing.
But you don't need to now since you know the fan data must be readable.

Use digital instead of analog read and set up a Pin Change Interrupt. The interrupt will stop the regular program, turn interrupts off, run a special -short- routine you make (like "pulse++;") and turn interrupts back on (plus some register saving you don't care about now) and then resume your regular code like nothing happened. Your program can watch microseconds go by (with micros()) until 1 second is up and see how many pulses were counted. You can know to within 4 microseconds I think.

If instead you just watch the pin you might be able to tell about how even the pulses are.

There is a pulseIn command to measure ulse widths but I see people get results with variance using it.

GoForSmoke:
The one that you are using for INPUT to read the fan. I did forget that in Majenko's circuit (that I just looked at again) the internal pin pullup isn't the only possible power source to the transistor. It also gets Vcc (5V) through 10k ohms. When the transistor is OFF the pin will read HIGH. When the transistor is ON it grounds the power, the pin will read LOW, and your led gets 5V through 10k ohms which is enough to light it dim.

I bet you could put 220-1k ohms instead of the 10k resistor, get a brighter led and hurt nothing.
But you don't need to now since you know the fan data must be readable.

Use digital instead of analog read and set up a Pin Change Interrupt. The interrupt will stop the regular program, turn interrupts off, run a special -short- routine you make (like "pulse++;") and turn interrupts back on (plus some register saving you don't care about now) and then resume your regular code like nothing happened. Your program can watch microseconds go by (with micros()) until 1 second is up and see how many pulses were counted. You can know to within 4 microseconds I think.

If instead you just watch the pin you might be able to tell about how even the pulses are.

There is a pulseIn command to measure ulse widths but I see people get results with variance using it.

Can you please give me an idea how that code would look like?

It looks like the code here:
http://arduino.cc/playground/Main/PcInt

I have started to try to learn the interrupt library. But i don´t get what they are doing here:

uint8_t latest_interrupted_pin;
uint8_t interrupt_count[20]={0}; // 20 possible arduino pins
void quicfunc() {
  latest_interrupted_pin=PCintPort::arduinoPin;
  interrupt_count[latest_interrupted_pin]++;
}

I understand that they are creating a function, but what is the uint8_t things?

uint8_t is unsigned integer 8 bits long. It's the same as byte or unsigned char.

Is this code ok?

#include <PinChangeInt.h>

int pulseCount = 0;
int inPin = 2;
int printVal = 0;

void pulseFunc(){
  pulseCount = pulseCount + 1;
  
}

void setup(){
 pinMode(inPin, INPUT); 
 PCintPort::attachInterrupt(inPin, &pulseFunc, RISING);
 Serial.begin(9600); 
}



void loop(){
  printVal = pulseCount * 60;
  Serial.println(printVal, DEC);
  delay(1000); 
  
}

Two things -

  1. You should reset pulseCount after each displaying so that you don't just accumulate a huge value.
  2. pulseCount is modified inside an interrupt. You should declare it volatile and wrap any non-interrupt based access to it in disable and enable interrupt calls.

majenko:
Two things -

  1. You should reset pulseCount after each displaying so that you don't just accumulate a huge value.
  2. pulseCount is modified inside an interrupt. You should declare it volatile and wrap any non-interrupt based access to it in disable and enable interrupt calls.

I've fixed the first one. Can you please try to explain the second one again, i didn't understand. I guess it has something to do with that i give pulseCount it's value inside a void?

A void has nothing to do with it.

When you change a value inside an interrupt routine there is no knowing what the program was doing at the time the interrupt routine was called. If you were doing anything with any variables that are changed inside the interrupt routine at the time the interrupt routine was called, then you will end up corrupting your data. You also have to let the compiler know that the variable should never be assumed to be what is cached in an internal register - it should always use the value in memory.

The second thing there is tackled by adding the "volatile" keyword when defining your variable:

volatile int pulseCount = 0;

The first, and more overlooked, problem is to place a cli(); before, and a sei(); after any access to the variables in question:

  cli();
  printVal = pulseCount * 60;
  pulseCount = 0;
  sei();

That will delay the interrupt from running while you are modifying the value outside the interrupt.

So the code should look like this:

#include <PinChangeInt.h>

volatile int pulseCount = 0;
int inPin = 2;
int printVal = 0;

void pulseFunc(){
  pulseCount = pulseCount + 1;
  
}

void setup(){
 pinMode(inPin, INPUT); 
 PCintPort::attachInterrupt(inPin, &pulseFunc, RISING);
 Serial.begin(9600); 
}



void loop(){
  cli();
  printVal = pulseCount * 60;
  pulseCount = 0;
  sei();
  Serial.println(printVal, DEC);
    
  delay(1000);
  
  
}

Looks good to me.

It works. But when i conected a small 5v fan it gets me very high numbers, i read somewere that the fan gives 2 pulses per round. So instead of 7200 rpm, the fan does 3600? Or what do you think?

I had that with a fan once - had to divide by 2 to get the real number.

himym:
It works. But when i conected a small 5v fan it gets me very high numbers, i read somewere that the fan gives 2 pulses per round. So instead of 7200 rpm, the fan does 3600? Or what do you think?

2 pulses per round of a 7200rpm fan would be 14400ppm (pulse per minute). Divide by 60 gives 240pps (pulse per second)

Riva:

himym:
It works. But when i conected a small 5v fan it gets me very high numbers, i read somewere that the fan gives 2 pulses per round. So instead of 7200 rpm, the fan does 3600? Or what do you think?

2 pulses per round of a 7200rpm fan would be 14400ppm (pulse per minute). Divide by 60 gives 240pps (pulse per second)

No, I think you misuderstand... He's measuring it at 7200 when in reality it's 3600 (which is a normal kind of figure for a small BLDC fan).