I have a project with a .INO main file and a .h/.cpp file pair with some additional code.
The code in the .cpp file references several libraries, including the PID library. I have found that the .cpp won't compile unless the #include <PID.h> statement is in BOTH the .INO and the .CPP file. Removing the line from either file generates an error.
I'm using VS 2013 Community with the Visual Micro PRO add-in.
Here is the code for the .CPP file:
//10/15/15 apparently these includes need to be here *and* in main .INO file!
#include <TimerThree.h> // used for ultrasonic PWM motor control
#include <PID.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <SerialCommand.h>
#include "XV11.h"
//10/09/15 added #defines for Teensy 2.0 vs Mega boards. These are used to switch PWM pins
#define _MEGA_2560
//10/15/15 struct has to be defined in .CPP
struct EEPROM_Config {
byte id;
char version[6];
int motor_pwm_pin; // pin connected to mosfet for motor speed control
double rpm_setpoint; // desired RPM (uses double to be compatible with PID library)
double rpm_min;
double rpm_max;
double pwm_max; // max analog value. probably never needs to change from 1023
double pwm_min; // min analog pulse value to spin the motor
int sample_time; // how often to calculate the PID values
// PID tuning values
double Kp;
double Ki;
double Kd;
boolean motor_enable; // to spin the laser or not. No data when not spinning
boolean raw_data; // to retransmit the seiral data to the USB port
boolean show_dist; // controlled by ShowDist and HideDist commands
boolean show_rpm; // controlled by ShowRPM and HideRPM commands
unsigned int show_angle; // controlled by ShowAngle (0 - 359, 360 shows all)
}
xv_config;
const byte EEPROM_ID = 0x05; // used to validate EEPROM initialized
double pwm_val = 500; // start with ~50% power
double pwm_last;
double motor_rpm;
unsigned long now;
unsigned long motor_check_timer = millis();
unsigned long motor_check_interval = 200;
unsigned int rpm_err_thresh = 10; // 2 seconds (10 * 200ms) to shutdown motor with improper RPM and high voltage
unsigned int rpm_err = 0;
unsigned long curMillis;
unsigned long lastMillis = millis();
PID rpmPID(&motor_rpm, &pwm_val, &xv_config.rpm_setpoint, xv_config.Kp, xv_config.Ki, xv_config.Kd, DIRECT);
And the code from the .INO file
//XV11 LIDAR required includes
#include <TimerThree.h> // used for ultrasonic PWM motor control
#include <PID.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <SerialCommand.h>
#include "XV11.h"
#include "MotorDemo.h"
MotorDemoClass myMotorDemo;
XV11Class myXV11;
void setup()
{
myMotorDemo.init();
}
void loop()
{
/* add main program code here */
myMotorDemo.demoOne();
delay(1000);
myMotorDemo.demoTwo();
delay(1000);
}
When I comment out the #include in the .INO file, the error is:
Compiling 'XV11On4WDRobot' for 'Arduino Mega w/ ATmega2560 (Mega 2560)'
XV11.cpp:4:17: fatal error: PID.h: No such file or directory
Error compiling
When I comment out the same line in the .CPP file, I get:
XV11.cpp:53:1: error: 'PID' does not name a type
XV11.cpp:In member function 'void XV11Class::init()'
XV11.cpp:100:2: error: 'rpmPID' was not declared in this scope
XV11.cpp:103:17: error: 'AUTOMATIC' was not declared in this scope
XV11.cpp:In function 'void setKp()'
XV11.cpp:644:3: error: 'rpmPID' was not declared in this scope
XV11.cpp:In function 'void setKi()'
XV11.cpp:677:3: error: 'rpmPID' was not declared in this scope
XV11.cpp:In function 'void setKd()'
XV11.cpp:710:3: error: 'rpmPID' was not declared in this scope
XV11.cpp:In function 'void setSampleTime()'
XV11.cpp:743:3: error: 'rpmPID' was not declared in this scope
Error compiling
I looked through the FAQ's at arduino.land/FAQ, and found a reference to the fact that the Arduino IDE copies all the sources to a temporary location, and then makes some Arduino-specific edits to the .INO file. And, if I read this correctly, it actually replaces each #include line with the actual source code from the referenced library, before starting the compile. It makes some sort of sense that the #include in the .INO file is required in order to make that #include/source replacement happen, but that doesn't explain why the .CPP compile fails (or even why it succeeds!) with its copy of the #include <PID.h> line commented out or in.
Any ideas?
TIA,
Frank