once I got the LCD working, I combined it with the temp sensor and created a simple thermostat. Then I couldn't resist to make a processing sketch to draw a curve with received temperature value's.
There are 3 main screens, switched by the up/down buttons,
the value's are set by the left/right buttons
(for more info about connecting a lcd to arduino http://arduino.cc/en/Tutorial/LiquidCrystal)
Arduino sketch:
#include <LiquidCrystal.h>
// LCD, initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //pins(rs, enable, d4, d5, d6, d7)
byte lcdCharDegree[8] = {B00000, B00111, B00101, B00111, B00000, B00000, B00000}; //LCD "°"
byte lcdCharLeft[8] = {B00000, B00010, B00110, B01110, B00110, B00010, B00000}; //LCD "<"
byte lcdCharRight[8] = {B00000, B01000, B01100, B01110, B01100, B01000, B00000}; //LCD ">"
//button
const int btnUp = 6;
const int btnRight = 7;
const int btnDown = 8;
const int btnLeft = 9;
int btnMenu = 0; //needed to change menu item
int btnSet; //needed to change settings
//temperature
const int sensorPin = A0; //input pin for tempsensor
float temperature; //temperature value in °C
long previousMillis = 0; //needed for 'measure-delay'
long interval = 1000; //measure-delay (1 sec)
//Thermostat ON-OFF
boolean thermostatStatus = LOW; //thermostat is turned off at startup
String textStatus; //String printed on LCD
//Set temperature
float tempSet = 20.00; //set 20.00°C at startup
//ledpin variables (2color-led instead of relais)
const int ledAPin = 10;
const int ledCPin = 13;
void setup() {
Serial.begin(9600);
// set up the number of columns and rows on the LCD
lcd.begin(16, 2);
//create special charset for LCD
lcd.createChar(0, lcdCharDegree);
lcd.createChar(1, lcdCharLeft);
lcd.createChar(2, lcdCharRight);
// setup buttonpins as input
pinMode(btnUp,INPUT);
pinMode(btnDown,INPUT);
pinMode(btnLeft,INPUT);
pinMode(btnRight,INPUT);
//setup ledpins as output
pinMode(ledAPin,OUTPUT);
pinMode(ledCPin,OUTPUT);
// Print a message on startup
lcd.setCursor(0, 0); // set cursor to column 0, line 0 (top line)
lcd.print("THERMOSTAT"); // print to LCD
lcd.setCursor(0, 1); // set cursor to column 0, line 1 (bottom line)
lcd.print("Version 0130.0"); //print to LCD
delay(2000); //delay keeps startup message on LCD for 2 sec
lcd.clear(); //clear LCD before starting loop()
}
void loop() {
//switch led when changing between menu-options
wndSwitchLed();
//switch menu-screen
switch (btnMenu){ /* int btnMenu holds value 0 or 1 or 2
* when btnUp/btnDown is pressed, 1 is added/removed to value btnMenu
*/
case 0:
wndScreenTopical();
break;
case 1:
wndScreenOnOff();
break;
case 2:
wndScreenTempSet();
}
}
void wndScreenTopical(){
//static text, printed once on LCD
//variable text, update print until menu-option is changed
//static text
lcd.setCursor(0, 0);
lcd.print("Topical Temp.");
lcd.setCursor(9, 1);
lcd.print(temperature);
lcd.setCursor(14, 1);
lcd.write(byte(0));
lcd.setCursor(15, 1);
lcd.print("C");
//variable text
while ((digitalRead(btnUp) == LOW) && (digitalRead(btnDown) == LOW)){ //check buttons, if up/down is pressed leave loop and change screen/ledstatus
//when left/right is pressed change value and loop
wndGetTemperature(); //get temperature
lcd.setCursor(9, 1); //set cursor back in position
lcd.print(temperature); //print topical temperature to LCD
wndSwitchLed(); //change led color when temperature > tempSet
wndBtnPressed(); //check buttons, if button is pressed, change screen/value
}
}
void wndScreenOnOff(){
//static text
lcd.setCursor(0, 0);
lcd.print("Thermostat");
lcd.setCursor(0, 1);
lcd.write(byte(1));
lcd.setCursor(15, 1);
lcd.write(byte(2));
//variable text
while ((digitalRead(btnUp) == LOW) && (digitalRead(btnDown) == LOW)){ //check buttons, if up/down is pressed change screen/ledstatus
// when left/right is pressed change value and loop
if (thermostatStatus){
textStatus = "ON ";
} else {
textStatus = "OFF";
}
lcd.setCursor(6, 1);
lcd.print(textStatus);
wndBtnPressed();
}
}
void wndScreenTempSet(){
//static text
lcd.setCursor(0, 0);
lcd.print("Set Temperature");
lcd.setCursor(0, 1);
lcd.print("-");
lcd.setCursor(15, 1);
lcd.print("+");
//variable text
while ((digitalRead(btnUp) == LOW) && (digitalRead(btnDown) == LOW)){ //loop until menu-option is changed
lcd.setCursor(4, 1); //set cursor back in position
lcd.print(tempSet); //print variable value
wndBtnPressed(); //check buttons, if up/down is pressed leave loop and change screen
// if left/right is pressed change value and loop
}
}
void wndGetTemperature(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
int sensorVal = analogRead(sensorPin);
float voltage = (sensorVal/1024.0) * 5.0; // convert the ADC reading to voltage
temperature = (voltage - .5) * 100; /* convert to °C
* the sensor changes 10 mV per degree
* the datasheet says there's a 500 mV offset
* ((volatge - 500mV) times 100)*/
Serial.println(temperature);
}
}
void wndBtnPressed(){
if (digitalRead(btnUp)){
if (btnMenu != 0){ //0 is lowest value for btnMenu
lcd.clear();
btnMenu = btnMenu--;
}
} else if (digitalRead(btnDown)){
if (btnMenu != 2){ //2 is highest value for btnMenu
lcd.clear();
btnMenu = btnMenu++;
}
} else if (digitalRead(btnLeft) && btnMenu == 1){ //btnleft in thermostat ON/OFF
if (thermostatStatus){ //thermostat ON?
thermostatStatus = LOW; //turn OFF
}
} else if (digitalRead(btnLeft) && btnMenu == 2){ //btnleft in set temperature, switch-temperature - 0.5°C
if (tempSet > 0){ //tempset cannot go below 0°c
tempSet = tempSet - 0.5; //if button is pressed substract 0.5 from settemp
delay(200); //delay 0.2 sec, otherwise value subracts to fast
}
} else if (digitalRead(btnRight) && btnMenu == 1){ //btnright in thermostat ON/OFF
if (thermostatStatus == LOW){ //thermostat OFF?
thermostatStatus = HIGH; //turn ON
}
} else if (digitalRead(btnRight) && btnMenu == 2){ //btnright in set temperature, switch-temperature + 0.5°C
if (tempSet < 100){ //tempset cannot go above 100°c
tempSet = tempSet + 0.5; //if button is pressed add 0.5 from settemp
delay(200); //delay 0.2 sec, otherwise value adds to fast
}
}
}
void wndSwitchLed(){
if (tempSet > temperature && thermostatStatus){
digitalWrite(ledAPin, LOW);
digitalWrite(ledCPin, HIGH);
} else {
digitalWrite(ledCPin, LOW);
digitalWrite(ledAPin, HIGH);
}
}
processing:
import processing.serial.*;
Serial myPort; // Serial port object
int lf = 10; // Linefeed in ASCII-code, when linefeed is received, string is complete
String myString = null; // empty string wich input data from arduino is saved in, when string is completed its converted to float
float num; // float converted from received string
float [] valScreen = new float [30]; //30 temperatures values
int lengthScreen = 30;
PShape valCurve; //Shape object value curve
void setup(){
size(640,480,P2D);
frameRate(1); //every second the screen is updated once
myPort = new Serial(this, Serial.list()[0], 9600); //setup serial object for serial communication
myPort.clear(); //empty serial buffer
for (int i = 0; i < lengthScreen; i ++){ //fill temp value array with 0's
valScreen[i]=0;
}
}
void draw(){
for (int i = 0; i < lengthScreen; i++){ // replace temperature value's in array one place
if (i < lengthScreen-1){ // oldest is lost, new value is added from data-input
valScreen[i]=valScreen[i+1];
} else {
while (myPort.available() > 0) { // read data while avaible
myString = myPort.readStringUntil(lf); // string ends when linefeed is received
if (myString != null) { // when string is not empty
print(myString); // Prints String to console-window
num=float(myString); // Converts string to float
valScreen[i]= num*(-4); // New value, for visual reasons multiply by -4, negative so higher value is
drawn above lower value,
// 4* real value because difference between value's are small
}
}
myPort.clear(); // clear serial buffer
background(200);
stroke(0, 0, 255);
line(25, height/2, 480, height/2); // draw X-axis
line(25, height/2-150, 25, height/2+20); // draw Y-axis
}
}
valCurve = createShape(); // create curve-shape
valCurve.beginShape();
valCurve.noFill();
valCurve.strokeWeight(2);
valCurve.stroke(200,0,0);
for (int i = 0; i < lengthScreen; i++){ // for loop for reading curve-data
valCurve.curveVertex(15*i, valScreen[i]);
if (i == 0 || i == lengthScreen-1){ // at start/end curve ad same value once again (more info see Vertex in Processing-Refference)
valCurve.curveVertex(15*i, valScreen[i]);
}
noStroke();
fill(0, 0, 0);
ellipse(25+(15*i), height/2+valScreen[i], 5, 5); // value points on curve, code is not part of shape(curve) but is placed here because of 'for-loop'
}
valCurve.translate(25,height/2); // move shape object to right position
valCurve.endShape();
shape(valCurve); // draw curve
textSize(15);
fill(0, 0, 200);
textAlign(RIGHT);
text("Realtime temp: "+valScreen[lengthScreen-1]/(-4)+"°C", 480, height/2+50); //text output on screen
}