I've defined a function to take in, and put out, a double. The function itself is at the bottom of the code. Whenever I call it though, I get an error saying " 'ADCtoTemp' cannot be used as a function ".
Putting it at the top of the code, after the #include<> statements, gives an error of " redefinition of double ADCtoTemp ". I get this error even if I rename the function to something clearly not used anywhere else in the code.
The file is in a folder, all by itself on the desktop. It acts like it is remembering some old value for ADCtoTemp, but I don't understand why (restarting the IDE did not help).
// Libraries
//-------
#include <Wire.h> //Include the Wire library to talk I2C
#include <LiquidCrystal.h> // Talk to the LCD
#include <PID_v1.h> // Main PID Library
#define MCP4725_ADDR 0x60 //This is the I2C Address of the MCP4725 (Sparkfun MCP4725A0), by default (A0 pulled to GND).
// DEFINITIONS and DECLARATIONS (GLOBAL)
//-------
double ADCtoTemp(double ADC) {
//Calculation of temperature from resistance measurement through thermistor (assumed to be a Thorlabs 10k).
//Formula from datasheet for temperature as function of resistance
double Vin = ADC*5/(1024*3.15); // Converts the 10-bit ADC input to a voltage, assuming a 3.15x gain stage on board.
double I_bias = 0.0001; // Bias current in A through thermistor from Wavelength Controller
double Rt = Vin/I_bias; // Calculated thermistor resistance
double R25 = 10000; // 25 C resistance of the thermistor
double log_ratio = log(Rt/R25);
double a = 3.3540170*pow(10,-3); // Empirical coefficients from datasheet
double b = 2.5617244*pow(10,-4);
double c = 2.1400943*pow(10,-6);
double d = -7.2405219*pow(10,-8);
double denom = a + b*log_ratio + c*pow(log_ratio,2) + d*pow(log_ratio,3);
double TK = pow(denom,-1); // Temp in Kelvin
double TC = TK - 273.15; // Temp in Celsius
return TC;
}
double setpoint = map(analogRead(A1), 0, 1023, 0, 4095); // Manual setpoint for lock, 12/bit integer
float Kp = 0; // Tuning Parameters
float Ki = 1;
float Kd = 0;
boolean debug = 1; // Print to serial port if true
double output, input;
const int sampleRate = 1; // How often, in milliseconds, the PID algorithm will be evaluated.
LiquidCrystal lcd(7, 8, 5, 4, 3, 2); //Define which Arduino pins do what for the LCD.
PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT); // PID function declaration.
//--------------------------------------------------------------------------
void setup()
{
lcd.begin(16, 2); //LCD's number of (columns,rows)
int input = analogRead(A0); // 10-bit ADC number of thermistor voltage
Wire.begin();
TWBR = 12; // Two wire bit register. Controls the I2C protocol speed (SCL), for talking to the DAC.
//DIGITAL OUTPUT
//-------
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(10, LOW); // Physical switch signal to unlock
digitalWrite(11, HIGH); // Physical switch signal to lock
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
digitalWrite(A2, LOW); //Set A2 as GND
digitalWrite(A3, HIGH); //Set A3 as Vcc, will power the DAC
}
//--------------------------------------------------------------------------
void loop()
{
pinMode(12, INPUT);
boolean lockBool = digitalRead(12); // Enable-Disable Boolean signal from physical switch
input = map(analogRead(A0), 0, 1023, 0, 4095); // Reads in a value (0-1023) depending on the voltage on A0 (0-5V), and maps that number to {0,4095}.
setpoint = map(analogRead(A1), 0, 1023, 0, 4095); // Reads in pot value for the temperature set-point.
double printSetpoint = analogRead(A1); // 10 bit integer setpoint for ADC to Temp (C) calculation
if ( lockBool == 0) // Unlocked
{
myPID.SetMode(MANUAL); // Turns off the PID Controller. Put out 0 Volts.
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(64);
output = 0; // Reset "output" variable. This is crucial, else when locked again, the output jumps right back to where it was before.
int Zero = 0; // The value zero to write. Was not working with just the number 0.
Wire.write(Zero >> 4); // See below for how these commands work.
Wire.write((Zero & 15) << 4);
Wire.endTransmission();
//PRINTS TO SCREEN
//-------
if (millis() % 4000 == 0) // % is modulo operator. Only prints to screen when number of ms is divisible by 4000 (i.e. every 4 seconds).
{
lcd.clear();
lcd.print("Temp: DISABLED");
lcd.setCursor(0, 1); // Sets cursor to second row.
lcd.print("Out(V)= 0");
}
}
else // Locked -----------------------------------------------------------------------------
{
myPID.SetMode(AUTOMATIC); // Turns on the PID Controller
myPID.SetSampleTime(sampleRate);
//CALCULATE PID OUTPUT
//-------
myPID.SetOutputLimits(0, 4095); // Default output is {0,255} for PWM, but our DAC is 12-bit.
myPID.Compute(); // The PID algorithm itself, calculates "output".
int int_output = round(output);
//DAC OUTPUT
//-------
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(64); // command to update the DAC (64 in decimal = The start byte for the DAC.
// I2C uses 8-bit (one byte) packets, so we have to break up the 16-bit integer into two bytes, then
// mask off the first 4 bits (15 in binary is 00001111) because the MPC4725 only can take 12 bits.
// Most significant bit is furthest to the left. The bits are shuffled around so that when
// the Wire.write I2C command writes its 8-bit chunk it will chop off nothing important.
Wire.write(int_output >> 4); // Grab the 8 most significant bits first. (D11.D10.D9.D8.D7.D6.D5.D4)
// The >> and << are bit shift operators.
// They shift the in the left operand to be shifted left or right by the number of positions in the right operand.
// The bits at the end (left or right) that are shifted, go away.
Wire.write((int_output & 15) << 4); // the 4 least significant bits. (D3.D2.D1.D0.x.x.x.x).
Wire.endTransmission();
//PRINTS TO SCREEN
//-------
if (millis() % 4000 == 0) // Only print to the screen if the time is modulo 4s or 2s
{
lcd.clear();
lcd.print("MOT Temp Enabled");
lcd.setCursor(0, 1);
lcd.print("T_actual: "); lcd.print(ADCtoTemp(analogRead(A0)), 2);
}
else if (millis() % 4000 == 2000)
{
lcd.setCursor(0, 1); // Moves cursor back to 2nd row.
lcd.print(" "); //Clears the 2nd row by printing 16 spaces
lcd.setCursor(0, 1);
lcd.print ("T_set: "); lcd.print(ADCtoTemp(printSetpoint*3.15), 2); // 3.15 accounts for not having a gain stage in the setpoint pot
}
} //from else
}