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;
}
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.
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.
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.
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.
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.