Robin2:
If you are getting an error message from the compiler then you need to post the actual text of the message.
I presume the code in Reply #5 is the exact code that causes the error?
...R
Ehhh, I had mostly given up on the PID_V2. The code in post #5 is for my issue with the voltage. Code below and message are what I get with PID_v2. Its his test code with just the pwm pin changed
// This version of Tacometer auto adjusts for difference in pulses
#include <PID_v2.h> // uses my new version of PID_v1
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, .05, .16, .001, DIRECT);
#define PWMpin 9
int SampleDuration = 30; // in Milliseconds
volatile unsigned long timeX = 1;
int PulsesPerRevolution = 400;
volatile int Counts = 10;
double PulsesPerMinute;
volatile unsigned long LastTime;
volatile int PulseCtrX;
int PulseCtr;
unsigned long Counter;
unsigned long Time;
/*
//Self Test
int RPM = 1;
double TextRPM = 1;
*/
void setup() {
// note that 1666666.67 = (60 seonds * 1000000 microseconds)microseconds in a minute / (36 / 9) pulses in 1 revolution
PulsesPerMinute = (60 * 1000000) / (PulsesPerRevolution / Counts);
Setpoint = 3100;
pinMode(2, INPUT_PULLUP);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
Serial.begin(115200);
Serial.println("aTest Tachometer");
delay(1000);
//Digital Pin 2 Set As An Interrupt for tacho.
attachInterrupt(0, sensorInterrupt, FALLING);
myPID.SetSampleTime(1);
myPID.SetOutputLimits(0, 255);
PulseCtr = 0;
myPID.SetMode(AUTOMATIC);
myPID.PrimeIntegral(100);
myPID.Compute();
analogWrite(PWMpin, Output);
delay(100);
myPID.Compute();
}
void loop() {
readRpm();
// SelfTest();
static unsigned long SpamTimer;
if ((unsigned long)(millis() - SpamTimer) >= 15000) {
SpamTimer = millis();
Setpoint = (Setpoint == 3100) ? 7100 : 3100;
}
}
/*
void SelfTest(){
static unsigned long TestTimer;
static bool done = false;
static unsigned long TestTime;
if(done)return;
if ((unsigned long)(micros() - TestTimer) >= TestTime) { // rpm test
TestTimer += TestTime;// we want an exact duration for our tests
TestTime = (60000000 / (PulsesPerRevolution * RPM));// we are one pulse behind so calculate next delay
sensorInterrupt();
if (RPM <= 850) {
TextRPM += .04;
RPM = (int) TextRPM;
}
else done = true;
}
}
*/
// New version of sensorInterrupt
void sensorInterrupt()
{
static int Ctr;
unsigned long Time;
Ctr++;
if (Ctr >= Counts) { // so we are taking an average of "Counts" readings to use in our calculations
Time = micros();
timeX += (Time - LastTime); // this time is accumulative ovrer those "Counts" readings
LastTime = Time;
PulseCtrX ++; // will usually be 1 unless something else delays the sample
Ctr = 0;
}
}
void sensorInterruptX()
{
static int Ctr;
unsigned long Time;
Ctr++;
if (Ctr >= Counts) { // so we are taking an average of "Counts" readings to use in our calculations
Time = micros();
timeX += (Time - LastTime); // this time is accumulative ovrer those "Counts" readings
LastTime = Time;
PulseCtrX ++; // will usually be 1 unless something else delays the sample
Ctr = 0;
}
}
void readRpm()
{
if (!PulseCtrX) return; // << Added lets not stop interrupts unless we know we are ready (keep other code happy).
cli (); // clear interrupts flag
Time = timeX; // Make a copy so if an interrupt occurs timeX can be altered and not affect the results.
timeX = 0;
PulseCtr = PulseCtrX;
PulseCtrX = 0;
sei (); // set interrupts flag
if (PulseCtr > 0) {
Input = (double) (PulsesPerMinute / (double)(( (unsigned long)Time ) * (unsigned long)PulseCtr)); // double has more percision
// PulseCtr = 0; // set pulse Ctr to zero
AverageCapture(Input);
debug();
myPID.Compute();
analogWrite(PWMpin, Output);
//
if (Time > ((SampleDuration + 1) * 1000))Counts--;
if (Time < ((SampleDuration - 1) * 1000))Counts++;
Counts = constrain(Counts, PulsesPerRevolution * .1, PulsesPerRevolution * 4);
Time = 0; // set time to zero to wait for the next rpm trigger.
Counter += PulseCtr;
PulseCtr = 0; // set pulse Ctr to zero
PulsesPerMinute = (60.0 * 1000000.0) / (double)((double)PulsesPerRevolution / (double)Counts);
}
}
float AvgArray[100];
int Readings = 0;
void AverageCapture(float in) {
static int Position = 0;
AvgArray[Position] = in;
Position++;
Readings++;
Readings = min (100, Readings); // 100 readings 0-99;
if (Position >= 100)Position = 0;//99 spots
}
float AverageValue() {
float Total = 0;
float Average;
if (!Readings)return (0.0);
for (int Position = 0; Position < Readings; Position++) {
Total += AvgArray[Position];
}
Average = Total / Readings;
return (Average);
}
void debug()
{
char S[20];
for (static long QTimer = millis(); (long)( millis() - QTimer ) >= 100; QTimer = millis() ) { // one line Spam Delay at 100 miliseconds
Serial.print("Counts: "); Serial.print(Counts );
// Serial.print(" Target RPM: ");Serial.print(RPM );
// Serial.print(" Counter: "); Serial.print(Counter );
// Serial.print(" time: "); Serial.print(Time );
Serial.print(" DeltaT: "); Serial.print(Time * PulseCtr);
Serial.print(" PulseCtr: "); Serial.print(PulseCtr );
// Serial.print(" PulsesPerMinute: "); Serial.print(dtostrf(PulsesPerMinute, 6, 1, S));
Serial.print(" Average: "); Serial.print(dtostrf(AverageValue(), 6, 1, S));
// Serial.print(" Setpoint: "); Serial.print(dtostrf(Setpoint, 6, 1, S) );
Serial.print(" Calculated RPM: "); Serial.print(dtostrf(Input, 6, 1, S));
Serial.print(" Output: "); Serial.print(dtostrf(Output, 6, 2, S));
Serial.println();
}
}
Error
Tachometer_Final_With_Self_Test.cpp.o*: In function setup
Tachometer_Final_With_Self_Test.ino:48: undefined reference to PID SetSampleTime(int)
Tachometer_Final_With_Self_Test.ino:51: undefined reference to PID SetOutputLimits(double, double)
Tachometer_Final_With_Self_Test.ino:52: undefined reference to PID SetMode(int)
Tachometer_Final_With_Self_Test.ino:53: undefined reference to PID PrimeIntegral(double)
Tachometer_Final_With_Self_Test.ino:54: undefined reference to PID Compute()
Tachometer_Final_With_Self_Test.ino:57: undefined reference to PID Compute()
Tachometer_Final_With_Self_Test.cpp.o*: In function readRpm()
Tachometer_Final_With_Self_Test.ino:136: undefined reference to PID Compute()
Tachometer_Final_With_Self_Test.cpp.o*: In function __static_initialization_and_destruction_0
Tachometer_Final_With_Self_Test.ino:8: undefined reference to PID PID(double*, double*, double*, double, double, double, int)
collect2.exe*: error: ld returned 1 exit status
Error compiling for board Arduino/Genuino Mega w/ ATmega2560 (Mega 2560)
Debug build failed for project 'Tachometer_Final_With_Self_Test'