measure 16 digital frequencies

Hello,

I'm doing a project which involves 16 cpu fans which I want to measure its rpm.
Now the following is going on I found a few examples to measure only one, and I know how to program it only for one.

Program I made is based on:
http://playground.arduino.cc/Main/ReadingRPM

The problem is I really got stuck in how to expand that and using 16 arduino's is certainly not an option.
Btw I have 4 mega's 2560 available so to split it up amongst 2 doesn't matter.
A multiplexer is an option, but let me put it this way my programming skills are beginner like, and i don't know how to shape my program or the total capability of the arduino

thanks

I'm not sure a mux will help you, but you could fairly easily expand the example to use the six external interrupts on your Mega, and then maybe look at pin change interrupts for the other two.

I would try using pulseIn() to measure the length, in microseconds, of the high and low pulses from each fan. A little math would then calculate RPM. This requires no interrupts so any Arduino pin would work.

const int fanPins[16] = {2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2,A3};

unsigned long pulseTime[16];

int fanRPM[16];

void setup() {
    for (int i=0; i<16; i++)
        pinMode(fanPins[i], INPUT);  //  Use INPUT_PULLUP if the fan outputs are Open Collector
}

void loop() {
    for (int i=0; i<16; i++) {
        pulseTime[i] = pulseIn(fanPins[i], LOW) + pulseIn(fanPins[i], HIGH);
        fanRPM[i] = (1000000UL / pulseTime[i]) / 60;
    }

    // Process the RPMs here.
}

The mega 2560 has 24 pin change interrupts available. You should be able to use 16 of those pretty easily if the hall effect pulse lasts long enough to determine which pin caused the interrupt.

If the pulse lasts long enough, you could poll digital I/O pins and do bit twiddling to increment your pulse counts. That's actually easier than it sounds, and I think I would try that first, and see how it goes.

Try this to see if it will work:

// untested code

const byte fan1Pin = 37;  // I think this is PC0
const byte fan2Pin = 36;  // I think this is PC1

int fan1PulseCount = 0;
int fan2PulseCount = 0;

void setup()
{
  pinMode(fan1Pin, INPUT);
  pinMode(fan2Pin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  static unsigned long timeBeginStamp = millis();
  static byte lastPortCStatus = PINC & 3;
  byte currentPortCStatus;

  currentPortCStatus = PINC & 3;  // Read the 8 bits of up to 8 fans.  We're only using 2, so mask out the higher 6 bits.

  if (((lastPortCStatus & 1) == 1) && ((currentPortCStatus & 1) == 0))    // Falling edge
    ++fan1PulseCount;
  if (((lastPortCStatus & 2) == 2) && ((currentPortCStatus & 2) == 0))    // Falling edge
    ++fan2PulseCount;

  lastPortCStatus = currentPortCStatus;

  if (millis() - timeBeginStamp >= 1000)    // One second
  {
    Serial.print("fan1PulseCount = ");
    Serial.println(fan1PulseCount);
    Serial.print("fan2PulseCount = ");
    Serial.println(fan2PulseCount);
    fan1PulseCount = 0;               // Get ready for the next round
    fan2PulseCount = 0;
    timeBeginStamp = millis();        // Start another second
  }
}

AWOL:
but you could fairly easily expand the example to use the six external interrupts on your Mega

Arduino Due and Teensy 3.0 support attachInterrupt on all pins. Using one of those is probably the easiest path to expand the example to 16 channels.

Sorry for late responding and testing.
i've tested both of the programs and both are not working i get some data but doesn't make cense.
At least thank you and hope you can help some more

first program 1 fan shows somthing but second and up is nothing.
second program, is giving me somthing around 8000 on both as soon as i unplug one it rises to 11000 or when i lower fan speed on one of the the other rises

backfromhome:
first program 1 fan shows somthing but second and up is nothing.

Can you show your implementation of 'first program'? If it works for '1 fan' it should work for 'second and up' unless there is a coding or wiring error.