My setup, in case it’s somehow relevant:
- ATTiny84 (dip package)
- 8x2 LCD (HD44780)
- 1 DS18B20 sensor
- 2 normal tactile breadboard buttons
- 1 40A SSR
The code below works as expected; it does what I want it to do. More specifically, it reads the sensor, provides PID control for the SSR, and prints the setpoint & sensor temperatures to the LCD. I’d like to add just a little more functionality. However, I’m having space issues.
I pruned out everything I could think of. I used to have the code for the LCD broken out in void displayLCD(), but moving those lines of code into loop() saved me a few bytes. I even trimmed some code from the getTemp() routine for the sensor regarding error codes. Utimately, I ran out of ideas at 8,168 bytes of the available 8,192. Right now, I can’t even add a degree symbol to the screen without exceeding the maximum. More importantly, I’d really like to add a few lines of code to use adaptive tunings for the PID, if I can.
I’m hoping that some of you more seasoned vets will take a look and point out some of my novice mistakes. Or, if not a mistake, at least point out some more efficient ways to code this.
#include <PID_v1.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
const int DS18S20_Pin=1;
const int ssrPin=0;
const int upPin=9;
const int downPin=10;
const int Setpoint_address=0;
const int WindowSize = 5000;
double Setpoint, Input, Output;
unsigned long EEPROMTime, windowStartTime, markTime, displayTime;
LiquidCrystal lcd(8,7,6,5, 4, 3, 2);
OneWire ds(DS18S20_Pin);
PID myPID(&Input, &Output, &Setpoint,120,0.05,1, DIRECT);
void setup()
{
lcd.begin(8,2);
pinMode(ssrPin,OUTPUT);
pinMode(upPin,INPUT_PULLUP);
pinMode(downPin,INPUT_PULLUP);
Setpoint= EEPROM.read(Setpoint_address);
myPID.SetOutputLimits(0, WindowSize);
myPID.SetMode(AUTOMATIC);
}
void loop()
{
//read the sensor/////////////////////////////////////////////////////////
Input = getTemp();
//print to the LCD////////////////////////////////////////////////////////
lcd.setCursor(0,0);
if (Setpoint<100) lcd.print(" ");
lcd.print(Setpoint);
// lcd.print(char(223));
// lcd.print("F");
lcd.setCursor(0,1);
if (Input<100) lcd.print(" ");
lcd.print(Input);
// lcd.print(char(223));
// lcd.print("F");
//compute output and switch the SSR//////////////////////////////////////
myPID.Compute();
if ((millis()-markTime)>WindowSize) markTime=millis();
if ((millis()-markTime)<Output) digitalWrite(ssrPin,HIGH);
else digitalWrite(ssrPin,LOW);
//check buttons for Setpoint changes//////////////////////////////////////
if (digitalRead(upPin)==LOW) Setpoint++; delay(75);
if (digitalRead(downPin)==LOW) Setpoint--; delay(75);
//check every second to see if the Setpoint has been stored////////////
if ((EEPROM.read(Setpoint_address)!=Setpoint)&&(millis()-EEPROMTime)>1000)
{
EEPROM.write(Setpoint_address,Setpoint);
EEPROMTime=millis();
}
}
float getTemp()
{
byte data[12];
byte addr[8];
if ( !ds.search(addr))
{
ds.reset_search();
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1);
byte present = ds.reset();
ds.select(addr);
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];
float tempRead = ((MSB << 8) | LSB);
float TemperatureSum = tempRead / 16;
TemperatureSum= TemperatureSum*9/5+32;
return TemperatureSum;
}