Hello,
I'm working on a thermostat based on Evil Genius book. This is the code:
#include <LiquidCrystal.h>
#define beta 4090 // from your thermistor's datasheet
#define resistance 33
// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4-7 on pins 5-2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int ledPin = 15;
int relayPin = 16;
int aPin = 8;//encoder pin A
int bPin = 7;//encoder pinB
int buttonPin = 6;//encoder push button
int analogPin = 0;
float setTemp = 20.0;
float measuredTemp;
char mode = 'C';
// can be changed to F
boolean override = false;
float hysteresis = 0.25;
void setup()
{
lcd.begin(2, 20);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
pinMode(aPin, INPUT);
pinMode(bPin, INPUT);
pinMode(buttonPin, INPUT);
lcd.clear();
}
void loop()
{
static int count = 0;
measuredTemp = readTemp();
if (digitalRead(buttonPin))
{
override = ! override;
updateDisplay();
delay(500); // debounce
}
int change = getEncoderTurn();
setTemp = setTemp + change * 0.1;
if (count == 1000)
{
updateDisplay();
updateOutputs();
count = 0;
}
count ++;
}
int getEncoderTurn()
{
// return -1, 0, or +1
static int oldA = LOW;
static int oldB = LOW;
int result = 0;
int newA = digitalRead(aPin);
int newB = digitalRead(bPin);
if (newA != oldA || newB != oldB)
{
// something has changed
if (oldA == LOW && newA == HIGH)
{
result = -(oldB * 2 - 1);
}
}
oldA = newA;
oldB = newB;
return result;
}
float readTemp()
{
long a = analogRead(analogPin);
float temp = beta / (log(((1025.0 * resistance / a) - 33.0) / 33.0) +
(beta / 298.0)) - 273.0;
return temp;
}
void updateOutputs()
{
if (override || measuredTemp < setTemp - hysteresis)
{
digitalWrite(ledPin, HIGH);
digitalWrite(relayPin, HIGH);
}float readTemp()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
Serial.print(temp);
return temp;
}
else if (!override && measuredTemp > setTemp + hysteresis)
{
digitalWrite(ledPin, LOW);
digitalWrite(relayPin, LOW);
}
}
void updateDisplay()
{
lcd.setCursor(0,0);
lcd.print("Actual: ");
lcd.print(adjustUnits(measuredTemp));
lcd.print(" o");
lcd.print(mode);
lcd.print(" ");
lcd.setCursor(0,1);
if (override)
{
lcd.print(" OVERRIDE ON ");
}
else
{
lcd.print("Set: ");
lcd.print(adjustUnits(setTemp));
lcd.print(" o");
lcd.print(mode);
lcd.print(" ");
}
}
float adjustUnits(float temp)
{
if (mode == 'C')
{
return temp;
}
else
{
return (temp * 9) / 5 + 32;
}
}
This code works well with the hardware setup. Now, I want to use a DS18B20 temperature sensor instead a thermistor. As I'm not an evil genius, all I've done is to replace the function float readTemp() as follows:
float readTemp()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
//Serial.print(temp);
return temp;
}
Below is the whole program:
#include <LiquidCrystal.h>
#define beta 4090 // from your thermistor's datasheet
#define resistance 33
// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4-7 on pins 5-2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int ledPin = 15;
int relayPin = 16;
int aPin = 8;
int bPin = 7;
int buttonPin = 6;
int analogPin = 0;
float setTemp = 20.0;
float measuredTemp;
char mode = 'C';
// can be changed to F
boolean override = false;
float hysteresis = 0.25;
#include <OneWire.h> //DS18B20
#include <DallasTemperature.h> //DS18B20
#define ONE_WIRE_BUS 9 //DS18B20 connected to..
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup()
{
lcd.begin(2, 20);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
pinMode(aPin, INPUT);
pinMode(bPin, INPUT);
pinMode(buttonPin, INPUT);
lcd.clear();
sensors.begin();
Serial.begin(9600);
}
void loop()
{
static int count = 0;
measuredTemp = readTemp();
if (digitalRead(buttonPin))
{
override = ! override;
updateDisplay();
delay(500); // debounce
}
int change = getEncoderTurn();
setTemp = setTemp + change * 0.1;
if (count == 1000)
{
updateDisplay();
updateOutputs();
count = 0;
}
count ++;
}
int getEncoderTurn()
{
// return -1, 0, or +1
static int oldA = LOW;
static int oldB = LOW;
int result = 0;
int newA = digitalRead(aPin);
int newB = digitalRead(bPin);
if (newA != oldA || newB != oldB)
{
// something has changed
if (oldA == LOW && newA == HIGH)
{
result = -(oldB * 2 - 1);
}
}
oldA = newA;
oldB = newB;
return result;
}
float readTemp()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
Serial.print(temp);
return temp;
}
void updateOutputs()
{
if (override || measuredTemp < setTemp - hysteresis)
{
digitalWrite(ledPin, HIGH);
digitalWrite(relayPin, HIGH);
}
else if (!override && measuredTemp > setTemp + hysteresis)
{
digitalWrite(ledPin, LOW);
digitalWrite(relayPin, LOW);
}
}
void updateDisplay()
{
lcd.setCursor(0,0);
lcd.print("Actual: ");
lcd.print(adjustUnits(measuredTemp));
lcd.print(" o");
lcd.print(mode);
lcd.print(" ");
lcd.setCursor(0,1);
if (override)
{
lcd.print(" OVERRIDE ON ");
}
else
{
lcd.print("Set: ");
lcd.print(adjustUnits(setTemp));
lcd.print(" o");
lcd.print(mode);
lcd.print(" ");
}
}
float adjustUnits(float temp)
{
if (mode == 'C')
{
return temp;
}
else
{
return (temp * 9) / 5 + 32;
}
}
The program compiles and when is loaded the LCD does not show anything until the push switch in the rotary encoder is pressed (the original program displays both the actual temperature and set temperature straight away). Furthermore, when turning the knob the temperature setting does not change (again, this was working fine in the original program).
Why is this happening? All I've done is is to read the value from another pin. The temperature readings are correct, in fact, after pressing the encoder push button, the display shows the temperature but the set temperature cannot be adjusted with the knob.
I would appreciate any help as I really don't know what is what I'm missing. I'm using Arduino Nano (ATmega328)
Thank you.