Happy HolidaySs Giveaway - Last Sponsor Giveaway of the Year!

Come Enter the BrewDeals/FastFerment Giveaway!


Home Brew Forums > Home Brewing Beer > Automated Brewing Forum > PID settings on arduino based hlt
Reply
 
LinkBack Thread Tools
Old 05-16-2012, 03:23 AM   #11
chuckjaxfl
Feedback Score: 1 reviews
Recipes 
 
Join Date: Feb 2010
Location: Jacksonville, FL
Posts: 327
Liked 19 Times on 12 Posts
Likes Given: 23

Default

Edited per the post below. Thanks for the tip!

Code:
#include <PID_v1.h>
#include <PID_AutoTune_v0.h>

#include <OneWire.h>
int DS18S20_Pin = 8; //DS18S20 Signal pin on digital 8
//Temperature chip i/o
OneWire ds(DS18S20_Pin); // on digital pin 8

#define RelayPin 3
int relayPin = 3;
int WindowSize = 1000;
unsigned long windowStartTime;


byte ATuneModeRemember=2;
double input=80, output=50, setpoint=100;
double kp=2,ki=0.5,kd=2;

double kpmodel=1.5, taup=100, theta[50];
double outputStart=5;
double aTuneStep=500, aTuneNoise=1, aTuneStartValue=500;
unsigned int aTuneLookBack=200;

boolean tuning = true;
unsigned long  modelTime, serialTime;

PID myPID(&input, &output, &setpoint,kp,ki,kd, DIRECT);
PID_ATune aTune(&input, &output);

//set to false to connect to the real world
boolean useSimulation = false;

void setup()
{
  //Setup the pid 
  myPID.SetOutputLimits(0, WindowSize);
  myPID.SetMode(AUTOMATIC);


  if(useSimulation)
  {
    for(byte i=0;i<50;i++)
    {
      theta[i]=outputStart;
    }
    modelTime = 0;
  }

  if(tuning)
  {
    tuning=false;
    changeAutoTune();
    tuning=true;
  }
  
  serialTime = 0;
  Serial.begin(9600);
  
  windowStartTime = millis(); //from pid test Relay
  pinMode(RelayPin,OUTPUT);  //from pid test Relay

}

void loop()
{

 unsigned long now = millis();
 float temperature = getTemp();
 float tempF = temperature * 9/5 + 32;

  if(!useSimulation)
  { //pull the input in from the real world
    input = tempF;
  }
  
  if(tuning)
  {
    byte val = (aTune.Runtime());
    if (val!=0)
    {
      tuning = false;
    }
    if(!tuning)
    { //we're done, set the tuning parameters
      kp = aTune.GetKp();
      ki = aTune.GetKi();
      kd = aTune.GetKd();
      myPID.SetTunings(kp,ki,kd);
      AutoTuneHelper(false);
    }
  }
  else myPID.Compute();
  
  if(useSimulation)
  {
    theta[30]=output;
    if(now>=modelTime)
    {
      modelTime +=100; 
      DoModel();
    }
  }
  else
  {
 //    analogWrite(0,output); // commented out by me
   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);
  }
  
  //send-receive with processing if it's time
  if(millis()>serialTime)
  {
    SerialReceive();
    SerialSend();
    serialTime+=1000;
  }
}

void changeAutoTune()
{
 if(!tuning)
  {
    //Set the output to the desired starting frequency.
    output=aTuneStartValue;
    aTune.SetNoiseBand(aTuneNoise);
    aTune.SetOutputStep(aTuneStep);
    aTune.SetLookbackSec((int)aTuneLookBack);
    AutoTuneHelper(true);
    tuning = true;
  }
  else
  { //cancel autotune
    aTune.Cancel();
    tuning = false;
    AutoTuneHelper(false);
  }
}

void AutoTuneHelper(boolean start)
{
  if(start)
    ATuneModeRemember = myPID.GetMode();
  else
    myPID.SetMode(ATuneModeRemember);
}


void SerialSend()
{
Serial.print("setpoint: ");Serial.print(setpoint); Serial.print(" ");
Serial.print("input: ");Serial.print(input); Serial.print(" ");
Serial.print("output: ");Serial.print(output); Serial.print(" ");
  if(tuning){
Serial.println(" tuning mode ");
//    Serial.print("kp: ");Serial.print(myPID.GetKp());Serial.print(" ");
//    Serial.print("ki: ");Serial.print(myPID.GetKi());Serial.print(" ");
//    Serial.print("kd: ");Serial.print(myPID.GetKd());Serial.println();
  } else {
    Serial.print("kp: ");Serial.print(myPID.GetKp());Serial.print(" ");
    Serial.print("ki: ");Serial.print(myPID.GetKi());Serial.print(" ");
    Serial.print("kd: ");Serial.print(myPID.GetKd());Serial.println();
  }
}

void SerialReceive()
{
  if(Serial.available())
  {
   char b = Serial.read(); 
   Serial.flush(); 
   if((b=='1' && !tuning) || (b!='1' && tuning))changeAutoTune();
  }
}

void DoModel()
{
  //cycle the dead time
  for(byte i=0;i<49;i++)
  {
    theta[i] = theta[i+1];
  }
  //compute the input
  input = (kpmodel / taup) *(theta[0]-outputStart) + input*(1-1/taup) + ((float)random(-10,10))/100;

}

float getTemp(){
 //returns the temperature from one DS18S20 in DEG Celsius

 byte data[12];
 byte addr[8];

 if ( !ds.search(addr)) {
   //no more sensors on chain, reset search
   ds.reset_search();
   return -1000;
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
   Serial.println("CRC is not valid!");
   return -1000;
 }

 if ( addr[0] != 0x10 && addr[0] != 0x28) {
   Serial.print("Device is not recognized");
   return -1000;
 }

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1); // start conversion, with parasite power on at the end

 byte present = ds.reset();
 ds.select(addr);  
 ds.write(0xBE); // Read Scratchpad

 
 for (int i = 0; i < 9; i++) { // we need 9 bytes
  data[i] = ds.read();
 }
 
 ds.reset_search();
 
 byte MSB = data[1];
 byte LSB = data[0];

 float tempRead = ((MSB << 8) | LSB); //using two's compliment
 float TemperatureSum = tempRead / 16;
 
 return TemperatureSum;
 
}
__________________
chuckjaxfl is offline
 
Reply With Quote Quick reply to this message
Old 05-16-2012, 03:28 AM   #12
chuckjaxfl
Feedback Score: 1 reviews
Recipes 
 
Join Date: Feb 2010
Location: Jacksonville, FL
Posts: 327
Liked 19 Times on 12 Posts
Likes Given: 23

Default

I hope it's helpful!

I'm not a programmer, so if it looks butchered it's because I'm pretty new to Aruidino. Like I said in another post, the last thing I wrote was in "Clipper" for dBase III.

__________________
chuckjaxfl is offline
 
Reply With Quote Quick reply to this message
Old 05-16-2012, 03:53 AM   #13
jpalarchio
Feedback Score: 1 reviews
Recipes 
 
Join Date: Jan 2009
Location: Holly, MI
Posts: 562
Liked 50 Times on 41 Posts
Likes Given: 11

Default

I like that some code is starting to show up in this forum!

FYI- You might want to wrap that code using the [ CODE ] [ /CODE ] tags (the # button under advanced). I believe it will make it easier to copy/paste.

Code:
Example of wrapped code
line 1
line 2
line 3
__________________
jpalarchio is offline
 
Reply With Quote Quick reply to this message
Old 05-16-2012, 05:25 AM   #14
rockytoptim
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
rockytoptim's Avatar
Recipes 
 
Join Date: May 2009
Location: Livonia, MI
Posts: 804
Liked 92 Times on 73 Posts
Likes Given: 3

Default

Quote:
Originally Posted by chuckjaxfl View Post
I hope it's helpful!

I'm not a programmer, so if it looks butchered it's because I'm pretty new to Aruidino. Like I said in another post, the last thing I wrote was in "Clipper" for dBase III.
Thanks Chuckjaxfl. No worries on the code. I am a hack when it comes to programming as well. I won't be able to try it out until Thursday.
__________________

On Tap: Bee Cave Robust Porter
On Tap: Bee Cave OktoberFest
On Tap: Bee Cave Kolsch
Primary: None
Up next: ????

rockytoptim is offline
 
Reply With Quote Quick reply to this message
Old 05-18-2012, 04:53 AM   #15
chuckjaxfl
Feedback Score: 1 reviews
Recipes 
 
Join Date: Feb 2010
Location: Jacksonville, FL
Posts: 327
Liked 19 Times on 12 Posts
Likes Given: 23

Default

Quote:
Originally Posted by SimBrew View Post
I will try for sure.
Would you happen to have your autotune code ?

Any luck yet?
__________________
chuckjaxfl is offline
 
Reply With Quote Quick reply to this message
Old 05-18-2012, 04:48 PM   #16
rockytoptim
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
rockytoptim's Avatar
Recipes 
 
Join Date: May 2009
Location: Livonia, MI
Posts: 804
Liked 92 Times on 73 Posts
Likes Given: 3

Default

Quote:
Originally Posted by chuckjaxfl View Post
Any luck yet?
I haven't had time yet as work is kicking my butt this week. I will definelty get to it this weekend and let you know how it goes.
__________________

On Tap: Bee Cave Robust Porter
On Tap: Bee Cave OktoberFest
On Tap: Bee Cave Kolsch
Primary: None
Up next: ????

rockytoptim is offline
 
Reply With Quote Quick reply to this message
Old 05-19-2012, 09:53 AM   #17
jbrewkeggin
Feedback Score: 0 reviews
Recipes 
 
Join Date: Mar 2012
Location: Baltimore, MD
Posts: 29
Liked 1 Times on 1 Posts

Default

Where did you get your ds18b20 probe, or did you build your own? Also, can you describe how you will mount it in your hlt or on the outlet of the hlt? For example, are you using a compression fitting and a T fitting?

-jbrew

__________________
jbrewkeggin is offline
 
Reply With Quote Quick reply to this message
Old 05-20-2012, 03:06 AM   #18
rockytoptim
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
rockytoptim's Avatar
Recipes 
 
Join Date: May 2009
Location: Livonia, MI
Posts: 804
Liked 92 Times on 73 Posts
Likes Given: 3

Default

Quote:
Originally Posted by jbrewkeggin View Post
Where did you get your ds18b20 probe, or did you build your own? Also, can you describe how you will mount it in your hlt or on the outlet of the hlt? For example, are you using a compression fitting and a T fitting?

-jbrew
I got my sensors at Sensors

I got my thermowell from Auberins ThermoWell I took connector off and pulled the thermocouple out then ran a drillbit through the it and the DS1820 probes fit great.
__________________

On Tap: Bee Cave Robust Porter
On Tap: Bee Cave OktoberFest
On Tap: Bee Cave Kolsch
Primary: None
Up next: ????

rockytoptim is offline
 
Reply With Quote Quick reply to this message
Old 05-20-2012, 07:30 AM   #19
jpalarchio
Feedback Score: 1 reviews
Recipes 
 
Join Date: Jan 2009
Location: Holly, MI
Posts: 562
Liked 50 Times on 41 Posts
Likes Given: 11

Default

Quote:
Originally Posted by jbrewkeggin View Post
Where did you get your ds18b20 probe, or did you build your own?
Give www.brewershardware.com a look if you're looking for DS18B20 sensors (listed under "BrewTroller" sensors). His are pretty top notch.

I used his probe ends but put together my own sensors with a right-angle M12 connector on the end of them. I really like this setup better than any others I've had in the past.



__________________
jpalarchio is offline
 
Reply With Quote Quick reply to this message
Old 06-03-2012, 12:28 AM   #20
chuckjaxfl
Feedback Score: 1 reviews
Recipes 
 
Join Date: Feb 2010
Location: Jacksonville, FL
Posts: 327
Liked 19 Times on 12 Posts
Likes Given: 23

Default

Hopefully, I'll have better answers for you guys today. I'm working on it today.

The part that is pertinent to this thread is that I changed the Serial.print parts to work on the LCD (no biggie), and I changed a couple lines in the working code. Specifically, I changed the aTuneStep to 200, and the aTuneStartValue to 250. I'm hoping this will bring the rise & fall of the autotune to a reasonable rate, instead of the huge spike and the take-forever fall I experienced before.

I'll let you know how it goes.

__________________
chuckjaxfl is offline
 
Reply With Quote Quick reply to this message
Reply



Quick Reply
Message:
Options
Thread Tools




Newest Threads

LATEST SPONSOR DEALS