Actually, the Arduino mega maxes out at about 30,000 PPS. It can easily read 3500-5000 RPM depending on your encoder. Rather than sample at 1x/second, you might try sampling at 100x/second and adjusting the RPM accordingly. Here's an example:
/***
File : turret.pde (opens in arduino IDE
www.arduino.cc)
Description : Counts digital pulse on External Interrupt 0 (Digital pin 2) for 100 mseconds and prints the value via UDP
Date : 18th March 2012
Author : Mike Anderson FRC Team #116
Contact :
manderson13@cox.net
***/
// include the library code:
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from:
bjoern@cs.stanford.edu 12/30/2008
#include <SimpleTimer.h>
// Conversion of Analog value to degrees using U.S. Digital
#define ANALOG_TO_DEGREES 2.84
// Number of pulses per revolution on the shaft encoder
#define SHAFT_ENCODER_PPR 64.0
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 1, 16, 9);
static uint8_t crio_ip[4] = { 10,1,16,2 };
unsigned int remPort = 8888;
unsigned int distance = 0;
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
int iTestPin=13; //Pin which generates test pulses, this is not needed when actual pulse is available for measurement
int iPulsePin = 2; //Pin serving as external interrupt (INT 0) to count the pulses
static int siPulseCounter=0; //Variable keeping track of pulse counts
static int reportInterval=1;
static int multiplierFactor = 60 / reportInterval;
int sensorPin = A0; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
int tmpDegrees = 0;
int oldDegrees = 0;
float tempFloat = 0.0;
SimpleTimer rpmTimer;
SimpleTimer hoodAngleTimer;
void sendRPM() {
tempFloat = (siPulseCounter / SHAFT_ENCODER_PPR) * 600.0;
Serial.println(siPulseCounter, DEC);
sprintf(packetBuffer, "1 %d\n\0", (int)(tempFloat));
// send a reply, to the IP address and port that sent us the packet we received
// Serial.write(packetBuffer);
Udp.beginPacket(crio_ip, remPort);
Udp.write(packetBuffer);
Udp.endPacket();
siPulseCounter=0; //Reset counter values for next minute cycle
}
void sendHoodAngle() {
sensorValue = analogRead(sensorPin);
tmpDegrees = (int) (sensorValue / ANALOG_TO_DEGREES);
sprintf(packetBuffer, "2 %d\n\0", tmpDegrees);
// send a reply, to the IP address and port that sent us the packet we received
// Serial.write(packetBuffer);
Udp.beginPacket(crio_ip, remPort);
Udp.write(packetBuffer);
Udp.endPacket();
oldDegrees = tmpDegrees;
}
void setup(void)
{
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
pinMode(iPulsePin, INPUT); // Set Pulsepin to accept inputs
digitalWrite(iPulsePin, HIGH);
pinMode(iTestPin, OUTPUT); // Test signal generator pin as output. Can be ignored if the actual digital signal is available
attachInterrupt(0, count, RISING); // Caputres external interrupt 0 at iPulsepin at rising edge and calls funtion count defined below
Serial.begin(115200); // Begin Serial communication at baudrate 115200 bps
Serial.println(" Initialising, Please wait...");
rpmTimer.setInterval(100, sendRPM);
hoodAngleTimer.setInterval(250, sendHoodAngle);
}
void loop(void)
{
rpmTimer.run();
hoodAngleTimer.run();
/*** Following 4 lines just generate pulses for testing purposes.
All the 4 lines Can be ignored if the actual digital signal is available ***/
//
// digitalWrite(iTestPin, HIGH); // sets the iTestPin ON
// delay(1); // waits for a second
// digitalWrite(iTestPin, LOW); // sets the iTestPin off
// delay(1); // waits for a second
}
void count() // Function called by AttachInterrupt at interrupt at int 0
{
siPulseCounter++; //increment the pulse count
}
/* End of turret.ino */