Thanks for the help, I was ready to give up.
Got it working with servolibrary2, I adjusted the library to run closer to 300hz since all my servos work on the higher digital frequency, even the ones not advertised as digital.
Heres the code
// input is hardcoded to D8
#include <FreqMeasure.h>
#include <ServoTimer2.h>
ServoTimer2 servo2; // create servo object to control a servo
int val; // variable
void setup() {
Serial.begin(19200);
FreqMeasure.begin();
servo2.attach(9); // attaches the servo on pin 9 to the servo object
}
double sum = 0;
int count = 0;
void loop() {
if (FreqMeasure.available()) {
// average several reading together
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 1) { // this is how many revs are averaged together, lower number is faster refresh rate
float frequency = FreqMeasure.countToFrequency(sum / count);
float RPM = frequency * 60;
val = RPM; // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 544, 2400); // scale it for use with the servo 544=0 400=full (value between 544 and 2400)
servo2.write(val);
Serial.println(val);
Serial.print(" ");
sum = 0;
count = 0;
}
}
}
I also got it working with QuickPID, tested up to 15000RPM and it seems good, heres that code for the next guy that is looking for something fast and accurate enough to control the rpm of a gas engine on a generator or something similar. I have searched many hours and havent found anything that could be used for that on the web.
// tach input is hardcoded to D8
#include <FreqMeasure.h>
#include <ServoTimer2.h>
#include "QuickPID.h"
ServoTimer2 servo2; // create servo object to control a servo
int val; // variable
//Define variables we'll be connecting to
float Setpoint = 0, Input = 0, Output = 0, Kp = .01, Ki = 0, Kd = 0; // adjust the values in blue
QuickPID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, /* OPTIONS */
myPID.pMode::pOnError, /* pOnError, pOnMeas, pOnErrorMeas */
myPID.dMode::dOnMeas, /* dOnError, dOnMeas */
myPID.iAwMode::iAwCondition, /* iAwCondition, iAwClamp, iAwOff */
myPID.Action::reverse); /* direct, reverse */
void setup() {
Serial.begin(19200);
FreqMeasure.begin();
myPID.SetOutputLimits(0, 1023);
myPID.SetSampleTimeUs(800); // this is sampling frequency delay in microseconds
myPID.SetTunings(Kp, Ki, Kd);
myPID.SetMode(myPID.Control::automatic);
Setpoint = 6000; // this is your rpm setpoint
TCCR0B = TCCR0B & B11111000 | B00000001; // for PWM frequency of 62500.00 Hz
Serial.println();
Serial.print(F(" Setpoint: ")); Serial.println(Setpoint);
Serial.print(F(" Input: ")); Serial.println(Input);
Serial.print(F(" Output: ")); Serial.println(Output);
Serial.print(F(" Pterm: ")); Serial.println(myPID.GetPterm());
Serial.print(F(" Iterm: ")); Serial.println(myPID.GetIterm());
Serial.print(F(" Dterm: ")); Serial.println(myPID.GetDterm());
Serial.print(F(" Control: ")); Serial.println(myPID.GetMode());
Serial.print(F(" Action: ")); Serial.println(myPID.GetDirection());
Serial.print(F(" Pmode: ")); Serial.println(myPID.GetPmode());
Serial.print(F(" Dmode: ")); Serial.println(myPID.GetDmode());
Serial.print(F(" AwMode: ")); Serial.println(myPID.GetAwMode());
servo2.attach(9); // attaches the servo on pin 9 to the servo object
}
double sum = 0;
int count = 0;
void loop() {
if (FreqMeasure.available()) {
// average several reading together
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 1) { // this is how many revs are averaged together, lower number is faster refresh rate
float frequency = FreqMeasure.countToFrequency(sum / count);
int RPM = frequency * 60;
val = Output;
val = map(val, 0, 1023, 544, 2400); // scale it for use with the servo 544=0 400=full (value between 544 and 2400)
servo2.write(val);
Input = RPM;
myPID.Compute();
Serial.print(Input);
Serial.print(" ");
Serial.println(Output);
Serial.print(" ");
Serial.println(Setpoint);
Serial.println(val);
Serial.print(" ");
sum = 0;
count = 0;
}
}
}