ATtiny84 PID

Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum

Help Support Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

chuckjaxfl

Well-Known Member
Joined
Feb 16, 2010
Messages
331
Reaction score
23
Location
Jacksonville, FL
Here's another little project I did awhile back, without any specific end use in mind yet.



image-2977205875.jpg
 
Since the LCD has two rows of 8 and the chip has space for two rows of between the pins, I drew the board so that the pins from the chip would mount on the opposite side, and straddle, the pins from the LCD.

It's running the same PID library that runs on the ATmega, and sensing is via a DS18B20.
 
To program it? Via the six-pin connector, the ribbon cable.
In use? Two inputs: setpoint up, setpoint down.

I keep messing with the code, and haven't settled on a 'final' version yet. Right now, it takes 7,800 of 8,192 available. Here it is at the moment, it does work, but I'm open to critiques and tips to tighten it up.



Code:
#include <PID_v1.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>

const int TEMP_PIN=2;
const int ssrPin=0;
const int upPin=8;
const int downPin=3;
//const int Setpoint_address=0;
const int SvHiByteAddress=10;
const int SvLoByteAddress=11;
int TempF100;

const int WindowSize = 1000;
double Setpoint, Input, Output;
unsigned long EEPROMTime, windowStartTime, markTime, displayTime;

LiquidCrystal lcd(10,1,9,4,7,5,6);
OneWire ds(TEMP_PIN);
PID myPID(&Input, &Output, &Setpoint,120,0.05,1.0, DIRECT);


void setup()
{
  lcd.begin(8,2);
  pinMode(ssrPin,OUTPUT);
  pinMode(upPin,INPUT_PULLUP);
  pinMode(downPin,INPUT_PULLUP);
  int SetpointAsInt = word(EEPROM.read(SvHiByteAddress),EEPROM.read(SvLoByteAddress));
  Setpoint = SetpointAsInt;
  myPID.SetOutputLimits(0, WindowSize);
  myPID.SetMode(AUTOMATIC);
}


void loop()
{
  getTemp();
  displayLCD();
  getOutput();
  controlSSR();
  readButtons();
  saveSetpoint(); 
}



void getTemp()
{
  byte data[12];
  ds.reset();
  ds.skip();
  ds.write(0x44,1);
  byte present = ds.reset();
  ds.skip();  
  ds.write(0xBE); 
  for (int i = 0; i < 9; i++) 
  { 
    data[i] = ds.read();
  }
  ds.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  int TempR = ((MSB << 8) | LSB);
  Input = TempR;
}


void saveSetpoint()
{
  if (millis()>EEPROMTime)
  { 
    int SetpointAsInt=(int)Setpoint;
    byte SetpointLoByte=lowByte(SetpointAsInt);
    if (EEPROM.read(SvLoByteAddress)!=SetpointLoByte) EEPROM.write(SvLoByteAddress,SetpointLoByte);
    byte SetpointHiByte=highByte(SetpointAsInt); 
    if (EEPROM.read(SvHiByteAddress)!=SetpointHiByte) EEPROM.write(SvHiByteAddress,SetpointHiByte);
    EEPROMTime+=1000; 
  }
}


void controlSSR()
{
  if ((millis()-markTime)>WindowSize) markTime=millis();
  if ((millis()-markTime)<Output) digitalWrite(ssrPin,HIGH);
  else digitalWrite(ssrPin,LOW);
}



void displayLCD()
{
  lcd.setCursor(0,0);
  TempF100=((Setpoint*90/8)+3200);
  printtemp();

  lcd.setCursor(0,1);
  TempF100=((Input*90/8)+3200);
  printtemp();

}

void printtemp()  
  {
  byte TempF_whole = TempF100 / 100;
  byte TempF_dec   = TempF100 % 100;
  if (TempF_whole<100) lcd.print(" "); 
  lcd.print(TempF_whole); 
  lcd.print("."); 
  if (TempF_dec<10) lcd.print("0"); 
  lcd.print(TempF_dec);
  lcd.print(char(223));  
  lcd.print("F");
  }


void getOutput()
{
  int TempError=abs(Setpoint-Input);
  if (TempError>64) myPID.SetTunings(120,0.0,0.0);    
  else myPID.SetTunings(60,0.05,0.0);    
  myPID.Compute();
}


void readButtons()
{
  if (digitalRead(upPin)==LOW) 
  {
    Setpoint++; 
    delay(5);
  }

  if (digitalRead(downPin)==LOW) 
  {
    Setpoint--; 
    delay(5);
  }
}
 
The three pins on the left on the back. The bottom one goes to ground, the middle on to pin 3 on the chip (downPin) and the top goes to pin 8 (upPin).

They are the three pins next to the blank spots, where I will install the vreg and filter caps when I hook this up to 12v instead of running it off of the programmer.
 
I see, I was a bit confused because I couldn't see any buttons on the front near the LCD display, but the way you have it makes sense for attaching connectors to remote buttons.
 
Back
Top