PID does not name a type

I am attempting to integrate the example PID library into my wireless oven controller but I keep getting the “PID does not name a type” error. I am able to run the PID code separately, but it doesn’t work when integrated into the main program.

/*************************************************** 
  This is a sketch to use the CC3000 WiFi chip & Xively
  
  Written by Marco Schwartz for Open Home Automation
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include<stdlib.h>
#include <PID_V1.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// Define Thermo Pins
#define Thermistor1PIN 1                  // Cabinet Thermistor
#define Thermistor2PIN 2                  // Meat Thermistor 1
#define Thermistor3PIN 3                  // Meat Thermistor 2
#define Thermistor4PIN 4                  // Meat Thermistor 3

//Define Pin for the Relay
#define RelayPin 6

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIV2); // you can change this clock speed
                                         


// WLAN parameters
#define WLAN_SSID       "XXXXXXXXX"
#define WLAN_PASS       "XXXXXXXXX"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2



// Xively parameters
#define WEBSITE  "api.xively.com"
#define API_key  "XXXXXXXXX"
#define feedID  "XXXXXXX"

//////Thermometer Function
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
int WindowSize = 5000;
unsigned long windowStartTime;
////////

uint32_t ip;

int x=0;
String readString;

void setup()
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
      windowStartTime = millis();

  //initialize the variables we're linked to
  int Setpoint = 100;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  }
 
 
}

void loop(void)
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  
  senddata();
  
  delay (1000);
  
  getdata();
    
  cc3000.disconnect();
  
  ////////////////
  Input = analogRead(0);
  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);
  
  
  // Wait 10 seconds until next update
  delay(50000);
}
/////sending additional request

  int getdata(){
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    clientb.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println();  
    
  Serial.println(F("-------------------------------------"));
  while (clientb.connected()) {
    while (clientb.available()) {
       delay(2);  //delay to allow byte to arrive in input buffer
      char c = clientb.read();
      if (c=='"') x=(x+1);
      if (x==7) readString += c;
  }
    if (readString.length() >0) {
      readString = readString.substring(1);
      Serial.print("Your value is: ");
      Serial.println(readString);
      int Setpoint = readString.toInt();
      Serial.println(Setpoint);
      readString="";
      x=0;
      return Setpoint;
  } 
      }
      
        
  clientb.close();
  
  }
  
  
  void senddata(){  
  // Get data & transform to integers
  int temp1=Thermistor(analogRead(Thermistor1PIN));
  int temp2=Thermistor(analogRead(Thermistor2PIN));
  int temp3=Thermistor(analogRead(Thermistor3PIN));
  int temp4=Thermistor(analogRead(Thermistor4PIN));
  
  // Prepare JSON for Xively & get length
  
  int messagelength = 0;
  String message2;
  
  message2 = messages(temp1, temp2, temp3);
  
  Serial.print("priting message");
  Serial.print (message2);
  
  messagelength = message2.length();
  Serial.print("Data length");
  Serial.println(messagelength);
  Serial.println();
  
  // Send request
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    Serial.println("Connected!");
    clientb.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.println("Content-Length: " + String(messagelength));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println(message2);
    clientb.println();  

  
  while (clientb.connected()) {
    while (clientb.available()) {
      char c = clientb.read();
      Serial.print(c);
    }
  }
  
  

  clientb.close();
  
 }
    
  
  
  

  




//////Functions//////


/////Thermometer Function
float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 109800;                     // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 222000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=((1024 * pad / RawADC) - pad);
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (-0.000631535825 + (0.0003824312118 * Temp) + (-0.0000003752313105 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                     
  

  // Uncomment this line for the function to return Fahrenheit instead.
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}




/////////Data Function

String messages(int temp1, int temp2, int temp3){
  String message2;
  String message = "";
  message2 = message + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"CabinetTemp\",\"current_value\" : \"" + String(temp1) + "\"}," + "{\"id\" : \"Thermo1\",\"current_value\" : \"" + String(temp2) + "\"}," + "{\"id\" : \"Thermo2\",\"current_value\" : \"" + String(temp3) + "\"}]}";
  return message2;
}

I am able to run the PID code separately, but it doesn't work when integrated into the main program.

Where did you install the library?

It’s installed within the libraries folder.

It's installed within the libraries folder.

Which one of them?

Basically the error means the compiler didn't find "PID_V1.h", or that that file doesn't
define a class or type "PID"

If a library is called "Foo" it must live inside a directory called "Foo" inside libraries and contain a "Foo.h" file. Case matters.

Mark and Paul, thanks for the reply. It was a capitalization mistake.

Now I’m having another issue. For some reason the variable that holds my HTTP PUT request gets reset to zero before it is sent to the server. Any idea whats happening here? I didn’t change any of the code, simply fixed that capitalization error.

/*************************************************** 
  This is a sketch to use the CC3000 WiFi chip & Xively
  
  Written by Marco Schwartz for Open Home Automation
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include<stdlib.h>
#include <PID_v1.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// Define Thermo Pins
#define Thermistor1PIN 1                  // Cabinet Thermistor
#define Thermistor2PIN 2                  // Meat Thermistor 1
#define Thermistor3PIN 3                  // Meat Thermistor 2
#define Thermistor4PIN 4                  // Meat Thermistor 3

//Define Pin for the Relay
#define RelayPin 6

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIV2); // you can change this clock speed
                                         


// WLAN parameters
#define WLAN_SSID       "XXXXXXX"
#define WLAN_PASS       "XXXXXXX"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2



// Xively parameters
#define WEBSITE  "api.xively.com"
#define API_key  "XXXXXXXXXXX"
#define feedID  "XXXXXXXXX"

//Define parameters for PID Function
double Setpoint, Input, Output;


//////PID shenanigans
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
int WindowSize = 5000;
unsigned long windowStartTime;
int temp1;
////////

uint32_t ip;

int x=0;
String readString;

void setup()
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
      windowStartTime = millis();

  //initialize the variables we're linked to
  int Setpoint = 100;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  }
 
 
}

void loop(void)
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  
  senddata();
  
  delay (5000);
  
  getdata();
 
  ////////////////
  Input = temp1;
  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);
  
  
  // Wait 10 seconds until next update

    
  cc3000.disconnect();
  
  delay(5000);
}
/////sending additional request

  int getdata(){
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    clientb.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println();  
    
  Serial.println(F("-------------------------------------"));
  while (clientb.connected()) {
    while (clientb.available()) {
       delay(2);  //delay to allow byte to arrive in input buffer
      char c = clientb.read();
      if (c=='"') x=(x+1);
      if (x==7) readString += c;
  }
    if (readString.length() >0) {
      readString = readString.substring(1);
      Serial.print("Your value is: ");
      Serial.println(readString);
      int Setpoint = readString.toInt();
      Serial.println(Setpoint);
      readString="";
      x=0;
      return Setpoint;
  } 
      }
      
        
  clientb.close();
  
  }
  
  
  int senddata(){  
  // Get data & transform to integers
  int temp1=Thermistor(analogRead(Thermistor1PIN));
  int temp2=Thermistor(analogRead(Thermistor2PIN));
  int temp3=Thermistor(analogRead(Thermistor3PIN));
  int temp4=Thermistor(analogRead(Thermistor4PIN));
  
  // Prepare JSON for Xively & get length
  
  int messagelength = 0;
  String message2;
  
  message2 = messages(temp1, temp2, temp3);
  
  Serial.print("priting message");
  Serial.print (message2);
  
  messagelength = message2.length();
  Serial.print("Data length");
  Serial.println(messagelength);
  Serial.println();
  
  // Send request
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    Serial.println("Connected!");
    clientb.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.println("Content-Length: " + String(messagelength));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println(message2);
    clientb.println();  

  
  while (clientb.connected()) {
    while (clientb.available()) {
      char c = clientb.read();
      Serial.print(c);
    }
    return temp1;
  }
  
  

  clientb.close();
  
 }
    
  
  
  

  




//////Functions//////


/////Thermometer Function
float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 109800;                     // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 222000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=((1024 * pad / RawADC) - pad);
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (-0.000631535825 + (0.0003824312118 * Temp) + (-0.0000003752313105 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                     
  

  // Uncomment this line for the function to return Fahrenheit instead.
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}




/////////Data Function

String messages(int temp1, int temp2, int temp3){
  String message2;
  String message = "";
  message2 = message + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"CabinetTemp\",\"current_value\" : \"" + String(temp1) + "\"}," + "{\"id\" : \"Thermo1\",\"current_value\" : \"" + String(temp2) + "\"}," + "{\"id\" : \"Thermo2\",\"current_value\" : \"" + String(temp3) + "\"}]}";
  return message2;
}

Now I'm having another issue. For some reason the variable that holds my HTTP PUT request gets reset to zero before it is sent to the server.

Which variable would that be?

The number of Strings that you have in your code is likely to be causing issues. I'd recommend that ZERO is the correct number of instances to be using.

Which Arduino? Have you measured how much free memory you have? String class is
renowned for issues (space leaks) and if you can avoid it I would.

The variable that holds my PUT request is "message2"

Do you have any tips to eliminate some of my Strings?

Do you have any tips to eliminate some of my Strings?

You should eliminate ALL of them. Static arrays and sprintf() to the rescue.

I was able to get the program to run by eliminating some Strings. Thanks for the help guys.

For some reason the PID ins’t working as it should. Actually it isn’t working at all, seems to have no interaction with the program. Is there anything you see wrong with the placement or passing of variables?

rookie177:
I was able to get the program to run by eliminating some Strings. Thanks for the help guys.

For some reason the PID ins't working as it should. Actually it isn't working at all, seems to have no interaction with the program. Is there anything you see wrong with the placement or passing of variables?

  int Setpoint = 100;

Local variables with the same name as global variables are NOT a good idea. The PID process is dealing with the global SetPoint, not this local one.

I’m lost again. I removed the local variable to that the Global Setpoint is directly adjusted. Was this the proper fix?

The PID still isn’t working. Thanks again for your help.

/*************************************************** 
  This is a sketch to use the CC3000 WiFi chip & Xively
  
  Written by Marco Schwartz for Open Home Automation
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include<stdlib.h>
#include <PID_v1.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// Define Thermo Pins
#define Thermistor1PIN 1                  // Cabinet Thermistor
#define Thermistor2PIN 2                  // Meat Thermistor 1
#define Thermistor3PIN 3                  // Meat Thermistor 2
#define Thermistor4PIN 4                  // Meat Thermistor 3

//Define Pin for the Relay
#define RelayPin 6

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIV2); // you can change this clock speed
                                         


// WLAN parameters
#define WLAN_SSID       "XXXXXXX"
#define WLAN_PASS       "XXXXXX"

// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2



// Xively parameters
#define WEBSITE  "api.xively.com"
#define API_key  "XXXXXXXXXX"
#define feedID  "XXXXXXXXXXX"

//Define parameters for PID Function
double Setpoint, Input, Output;


//////PID shenanigans
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
int WindowSize = 20000;
unsigned long windowStartTime;
int temp1;
////////

uint32_t ip;

int x=0;
String readString;

void setup()
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);

  
  }
  
  windowStartTime = millis();

  //initialize the variables we're linked to
  Setpoint = 50;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
 
}

void loop()
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  
  //int Setpoint = 100;
  
  getdata();
  
  senddata();
  

  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime) digitalWrite(RelayPin,LOW);
  else digitalWrite(RelayPin,HIGH);
  
  
  
  
  
  delay (5000);
  
  
  
    
  cc3000.disconnect();
  
}
/////sending additional request

  int getdata(){
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    clientb.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println();  
    
  Serial.println(F("-------------------------------------"));
  while (clientb.connected()) {
    while (clientb.available()) {
       delay(2);  //delay to allow byte to arrive in input buffer
      char c = clientb.read();
      if (c=='"') x=(x+1);
      if (x==7) readString += c;
  }
    if (readString.length() >0) {
      readString = readString.substring(1);
      Serial.print("Your value is: ");
      Serial.println(readString);
      int Setpointint = readString.toInt();
      Setpoint = Setpointint;
      readString="";
      x=0;
  } 
      }
      
        
  clientb.close();
  
  }
  
  
int senddata(){  
  // Get data & transform to integers
  int temp1=Thermistor(analogRead(Thermistor1PIN));
  int temp2=Thermistor(analogRead(Thermistor2PIN));
  int temp3=Thermistor(analogRead(Thermistor3PIN));
  int temp4=Thermistor(analogRead(Thermistor4PIN));
  Input = temp1;
  
  // Prepare JSON for Xively & get length
  
  int messagelength = 0;
  String message2;
  
  message2 = messages(temp1, temp2, temp3);
  
  Serial.print("printing message");
  Serial.print (message2);
  
  messagelength = message2.length();
  Serial.print("Data length");
  Serial.println(messagelength);
  Serial.println();
  
  // Send request
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
    Serial.println("Connected!");
    clientb.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.println("Content-Length: " + String(messagelength));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println(message2);
    clientb.println();  

  
  while (clientb.connected()) {
    while (clientb.available()) {
      char c = clientb.read();
      Serial.print(c);
    }
  }
  
  

  clientb.close();
  
 }
    
  
  
  

  




//////Functions//////


/////Thermometer Function
float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 109800;                     // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 222000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=((1024 * pad / RawADC) - pad);
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (-0.000631535825 + (0.0003824312118 * Temp) + (-0.0000003752313105 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                     
  

  // Uncomment this line for the function to return Fahrenheit instead.
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}




/////////Data Function

String messages(int temp1, int temp2, int temp3){
  String message2;
  message2 = message2 + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"CabinetTemp\",\"current_value\" : \"" + temp1 + "\"}," + "{\"id\" : \"Thermo1\",\"current_value\" : \"" + temp2 + "\"}," + "{\"id\" : \"Thermo2\",\"current_value\" : \"" + temp3 + "\"}]}";
  return message2;
}

The PID still isn't working.

Yes, it is. It may not be achieving the results that you want, but, then, you haven't defined what they are or what results are actually achieved. You've not shown what the input values are, or the outputs.

  //PID Check 
  Serial.print("PID Variables");
  Serial.print("The Output is:");
  Serial.print (Output);
  Serial.print("The Input is:"); 
  Serial.print (Input);
  Serial.print("The Setpoint is:");
  Serial.print (Setpoint);
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);

Using the print statements above I am able to see that the variables (Setpoint, Input, and Output) are responding correctly. However, my test rig is not responding as expected. For some reason the pin is always HIGH even if the Output = 0

Using the print statements above I am able to see that the variables (Setpoint, Input, and Output) are responding correctly.

Does the value of Output correspond to a time?

  if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);

This makes it look like Output is related to time. That is, it defines the portion of the WindowSize that the relay should be on. Given that WindowSize is 20 seconds, you'll be banging the relay on and off a lot. I hope it's a SSR to take that kind of abuse.

Hi Paul, yes I am using a SSR.

I decided to check and see if the HIGH/LOW messages were being sent, or at least if that portion of the code was executed, and it looks like it is sending the appropriate message. Is there something wrong with this portion of the code and the digitalWrite statements? I've tested the hardware and the pin/relay work fine.

  if(Output > now - windowStartTime) 
    {
      digitalWrite(relaypin,HIGH);
      Serial.print("Sending High Message");
    }
   
    else 
    {
      digitalWrite(relaypin,LOW);
      Serial.print("Sending low message");
    }

Every single loop of the code it is printing the correct "Sending low message" or "Sending High Message", but it isn't actually triggering the relay.

Thanks again

but it isn't actually triggering the relay.

Then, the problem is with the hardware. Possibly, the relay takes more current to turn on than the Arduino is providing. If that's the case, the Arduino needs to be turning a transistor on and off, and the transistor needs to be turning the relay on and off.