Hey guys,
I've spent the last couple days coding up a sketch to govern the RPM on a 3.8L series III grand prix engine. I'm reading the pulse length of the 18x crankshaft sensor with pulseIn, converting that to RPMs and using that for the PID Input. PID Setpoint is a potentiometer scaled up by 3.9 to match my maximum desired RPM of 4000. The PID output is being scaled down for servo output.
I am finding that when my Setpoint value is above 1024, the PID Ouput is 0 when the Input >= 1024. It's like there's a 10bit limit (1024) for the Setpoint value.
#include <Servo.h>
#include <PID_Beta6.h>
Servo servo; // create servo object to control a servo
int pulselength; // integer to store measured pulse length from pulseIn
double Input, Output, Setpoint;
PID pid(&Input, &Output, &Setpoint, 1, 0, 0);
boolean Ps = 1; // used to toggle negative P-param, '1' = +, '0' = -
int ServoOutput; // store scaled servo ouput
int hz; // store pulse length converted to hz
void setup(){
servo.attach(3); // attaches the servo object to pin 3
servo.write(10); // sets starting servo position
pid.SetOutputLimits(0,4000); //tell the PID to range the output from 0 to 4000
Output = 0.0; //start the output at its min and let the PID adjust it from there
Serial.begin(9600);
Serial.print("Govenor ver.2 Started\r\n");
delay(500);
pid.SetMode(AUTO); //turn on the PID
}
void loop(){
digitalWrite(4, !digitalRead(4)); //for visual reference of loop speed
Setpoint = (double)(analogRead(A0) * 3.9); // Setpoint POT scaled up to max of 4000
pulselength = (int)(2 * pulseIn(8, HIGH)); // read pulse length and double for total length
Input = 1.0 / ((double)pulselength / 1000000.0) / 18.0 * 60.0; //convert total pulse length to RPM
hz = int(1.0 / ((double)pulselength / 1000000.0)); // convert total pulse length to hz
pid.Compute();
ServoOutput = (int)(Output / 23.0); // scale down servo output
if (ServoOutput > 180) ServoOutput = 180; // limit servo values
if (ServoOutput < 10) ServoOutput = 10;
servo.write(ServoOutput);
SendSerialUpdate();
}
void SendSerialUpdate(){
Serial.print("In:");
Serial.print((int)Input,DEC);
Serial.print(" Out:");
Serial.print((int)Output,DEC);
Serial.print(" Set:");
Serial.print((int)Setpoint,DEC);
Serial.print(" Pls:");
Serial.print((int)pulselength,DEC);
Serial.print(" Hz:");
Serial.print((int)hz,DEC);
Serial.print(" Srv:");
Serial.println(ServoOutput,DEC);
}
Am I missing something obvious?
Thanks.
EDIT. I opened up PID_Beta6.h and noticed the SetInputLimits method. After setting that to pid.SetInputLimits(0,4000) it now seems to allow higher Setpoints.