'expression' Cannot be used as a function

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
  
}

I do not know why you are getting the error messages that you are getting.

However...
All C/C++ executable code must be in a function. I notice that this

double setpoint = map(analogRead(A1), 0, 1023, 0, 4095); // Manual setpoint for lock, 12/bit integer

is after the ADCtoTemp function but before the setup function.

I am also concerned (perhaps unnecessarily so) by

ADCtoTemp(analogRead(A0))

I do not believe that the compiler is smart enough to convert this internally to

ADCtoTemp((double)analogRead(A0))

but I may be wrong.

vaj4088:
I do not know why you are getting the error messages that you are getting.

All C/C++ executable code must be in a function. I notice that this...

The code you quoted is an initialization and is fine there. It is a global variable.

@OP:
This is what the IDE produces from your code:

//Function prototypes
double ADCtoTemp(double (*(volatile uint16_t *)(0x78)));

void setup();

void loop();

double ADCtoTemp(double ADC) {  << Function definition

As you can see it has changed ADC (expanded the macro).

ADC is a macro somewhere in the core code, use a different name.

Thank you! It fails with the same error given this code:

void setup(){}

void loop(){}
  
double ADCtoTemp(double ADC)
{ 
return 0;
}

so clearly something was fundamentally wrong.

pYro_65 wrote (in part):

The code you quoted is an initialization and is fine there. It is a global variable.

Yes, I know, it is called dynamic initialization. I explained badly. I hope that all of the other initialization has taken place so that analogRead(A1) works properly.

My apologies. I should have said something like "All C/C++ executable code is best put in a function to agree with C/C++ syntax and to avoid potential initialization issues."

vaj4088:
My apologies. I should have said something like "All C/C++ executable code is best put in a function to agree with C/C++ syntax and to avoid potential initialization issues."

Not really a C/C++ issue at all. The fact that the init() function isn't called until main() is purely an Arduino issue.

But I know what you mean now. With reference to the OP's error, the initialization would not be a problem.