Introduction: Arduino "Talking" Temp / Humidity on a TFT LCD W/ Relays
From the minds of http://arduinotronics.blogspot.com
UPDATE: Added our SpeakEasy Text-To-Speech (TTS) Shield to make this a "Talking" Weather Station!
UPDATE: Added a 4 port relay board for device control
UPDATE: Added Dew Point and Heat Index calculations
SainSmart sent me a 1.8" TFT LCD (ST7735R), and I decided to upgrade my Weather Station / Thermostat. This time around, I used the slightly less accurate but much less expensive DHT-22 (AM2302) temperature / humidity sensor. I also received a BMP-085 barometric pressure sensor, but it appears dead. More on that in the near future. Tighten your seat belt, and here we go:
Parts:
Arduino Uno
1.8 TFT LCD
DHT-22
10k Ohm Resistor
Relay Board (optional)
Male / Female Jumpers (very helpful)
Step 1: Connections
Connect the DHT-22 sensor and the LCD display as per the schematic. There are also connections on the left side of the display for the SD card, and we will address that at a future edit for logging purposes. Just use the connections on the right side of the display for now.
DHT-22:
(S)ignal to Arduino Pin 2
+5 to Arduino +5vdc
G to Arduino Ground
10k Resistor between S and +5vdc
ST7735R LCD:
VCC to Arduino +5vdc
Gnd to Arduino Ground
SCL to Ardiuino Pin 13
SDA to Arduino Pin 11
CS to Arduino Pin 10
DC to Arduino Pin 9
Reset to Arduino Pin 8
Step 2: Code
The following code is still a work in progress, but is functional. Let us know if you find problems or have suggestions for improvements.
/*
Arduino TFT text example
This example demonstrates how to draw text on the
TFT with an Arduino.
This example code is in the public domain
Created 15 April 2013 by Scott Fitzgerald
http://arduino.cc/en/Tutorial/TFTDisplayText
Modded by Steve Spence of http://arduinotronics.blogspot.com
*/
#include "SPI.h"
#include "ST7735.h"
// Pins SCLK and MOSI are fixed in hardware, and pin 10 (or 53)
// must be an output
//#define sclk 13 // for MEGAs use pin 52
//#define mosi 11 // for MEGAs use pin 51
#define cs 10 // for MEGAs you probably want this to be pin 53
#define dc 9
#define rst 8 // you can also connect this to the Arduino reset
// pin definition for the Leonardo
// #define cs 7
// #define dc 0
// #define rst 1
// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);
// char array to print to the screen
char tempPrintout[6];
char humPrintout[6];
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
// Fahrenheit conversion added by Steve Spence, http://arduinotronics.blogspot.com
#include "DHT.h" //https://learn.adafruit.com/dht/downloads
#define DHTPIN 2 // what pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// Connect pin + (middle) of the sensor to +5V
// Connect pin S (on the right) of the sensor to whatever your DHTPIN is
// Connect pin - (on the left) of the sensor to GROUND
// Connect 10k resistor between S and +
int cycleTime = 2000;
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;
void setup() {
// Put this line at the beginning of every sketch that uses the GLCD:
TFTscreen.begin();
// clear the screen with a black background
TFTscreen.background(0, 0, 0);
// write the static text to the screen
// set the font color to white
TFTscreen.stroke(255,255,255);
// set the font size
TFTscreen.setTextSize(2);
// write the text to the top left corner of the screen
TFTscreen.text("Temp (F)",0,0);
// write the text to the top left corner of the screen
TFTscreen.text("Humidity (%)",0,60);
// ste the font size very large for the loop
TFTscreen.setTextSize(4);
dht.begin();
}
void loop() {
// Read the value of the temp/humidity sensor on D2
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
t = dht.readTemperature();
t = (t*1.8)+32; //C to F conversion
String tempVal = doubleToString(t, 2);
String humVal = doubleToString(h, 0);
// String sensorVal = String(1.234);
// convert the reading to a char array
tempVal.toCharArray(tempPrintout, 6);
humVal.toCharArray(humPrintout, 6);
// set the font color
TFTscreen.stroke(255,255,255);
// print the sensor value
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
// wait for a moment
delay(cycleTime);
// erase the text you just wrote
TFTscreen.stroke(0,0,0);
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
}
//Rounds down (via intermediary integer conversion truncation)
String doubleToString(double input,int decimalPlaces){
if(decimalPlaces!=0){
String string = String((int)(input*pow(10,decimalPlaces)));
if(abs(input)<1){
if(input>0)
string = "0"+string;
else if(input<0)
string = string.substring(0,1)+"0"+string.substring(1);
}
return string.substring(0,string.length()-decimalPlaces)+"."+string.substring(string.length()-decimalPlaces);
}
else {
return String((int)input);
}
}
Step 3: Now With Text-To-Speech
We added our prototype TTS Shield, and made some slight modifications to the code. Now the temperature and humidity is spoken out loud. This can get annoying, so you may want to add a button for speech on demand! We changed the DHT-22 pin to 6 as the original pin 2 interferes with the SpeakEasy Shield. The SpeakEasy Shield (produced for us by http://www.hacktronics.com) is based on the SpeakJet and TTS256 chips, with an onboard amplifier.
//Speak Easy Setup
#include <SoftwareSerial.h>
#define txPin 2
#define rxPin 5
SoftwareSerial sjSerial = SoftwareSerial(rxPin, txPin);
int bufferPin = 4; // monitor buffer half full, or busy (jmp2)
/*
Arduino TFT text example
This example demonstrates how to draw text on the
TFT with an Arduino. The Arduino reads the value
of an analog sensor attached to pin A0, and writes
the value to the LCD screen, updating every
quarter second.
This example code is in the public domain
Created 15 April 2013 by Scott Fitzgerald
http://arduino.cc/en/Tutorial/TFTDisplayText
*/
#include // Arduino LCD library
#include
// pin definition for the Uno
#define cs 10
#define dc 9
#define rst 8
// pin definition for the Leonardo
// #define cs 7
// #define dc 0
// #define rst 1
// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);
// char array to print to the screen
char tempPrintout[6];
char humPrintout[6];
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
// Fahrenheit conversion added by Steve Spence, http://arduinotronics.blogspot.com
#include
#define DHTPIN 6 // what pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// Connect pin + (middle) of the sensor to +5V
// Connect pin S (on the right) of the sensor to whatever your DHTPIN is
// Connect pin - (on the left) of the sensor to GROUND
// Connect 10k resistor between S and +
int cycleTime = 2000;
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;
void setup() {
// initialize the serial communications with the SpeakJet-TTS256
Serial.begin (9600);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(bufferPin, INPUT);
sjSerial.begin(9600);// set the data rate for the SoftwareSerial port
// Put this line at the beginning of every sketch that uses the GLCD:
TFTscreen.begin();
// clear the screen with a black background
TFTscreen.background(0, 0, 0);
// write the static text to the screen
// set the font color to white
TFTscreen.stroke(255,255,255);
// set the font size
TFTscreen.setTextSize(2);
// write the text to the top left corner of the screen
TFTscreen.text("Temp (F)",0,0);
// write the text to the top left corner of the screen
TFTscreen.text("Humidity (%)",0,60);
// ste the font size very large for the loop
TFTscreen.setTextSize(4);
dht.begin();
}
void loop() {
// Read the value of the temp/humidity sensor on D2
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
t = dht.readTemperature();
t = (t*1.8)+32; //C to F conversion
String tempVal = doubleToString(t, 0);
String humVal = doubleToString(h, 0);
// String sensorVal = String(1.234);
// convert the reading to a char array
tempVal.toCharArray(tempPrintout, 6);
humVal.toCharArray(humPrintout, 6);
// set the font color
TFTscreen.stroke(255,255,255);
// print the sensor value
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
// wait for a moment
delay(cycleTime);
// erase the text you just wrote
TFTscreen.stroke(0,0,0);
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
sjSerial.print("temprature ");
delay(250);
sjSerial.print(tempPrintout);
delay(500);
sjSerial.print(" humidity ");
delay(250);
sjSerial.println(humPrintout);
}
//Rounds down (via intermediary integer conversion truncation)
String doubleToString(double input,int decimalPlaces){
if(decimalPlaces!=0){
String string = String((int)(input*pow(10,decimalPlaces)));
if(abs(input)<1){
if(input>0)
string = "0"+string;
else if(input<0)
string = string.substring(0,1)+"0"+string.substring(1);
}
return string.substring(0,string.length()-decimalPlaces)+"."+string.substring(string.length()-decimalPlaces);
}
else {
return String((int)input);
}
}
Step 4: Adding a Relay Board
We are using a SainSmart 4 port relay board, and connecting the 4 input lines to analog ports repurposed as digital outputs. For more information, see http://arduinotronics.blogspot.com/2013/01/working-with-sainsmart-5v-relay-board.html
//SainSmart 4 port relay board setup
//We are out of digital ports, so repurposing
//analog inputs as digital outputs
// GND connected to Arduino GND
int relayPin1 = A0; // IN1 connected to digital pin A0
int relayPin2 = A1; // IN2 connected to digital pin A1
int relayPin3 = A2; // IN3 connected to digital pin A2
int relayPin4 = A3; // IN4 connected to digital pin A3
// VCC connected to Arduino +5v
//Speak Easy Setup
#include
#define txPin 2
#define rxPin 5
SoftwareSerial sjSerial = SoftwareSerial(rxPin, txPin);
int bufferPin = 4; // monitor buffer half full, or busy (jmp2)
/*
Arduino TFT text example
This example demonstrates how to draw text on the
TFT with an Arduino. The Arduino reads the value
of an analog sensor attached to pin A0, and writes
the value to the LCD screen, updating every
quarter second.
This example code is in the public domain
Created 15 April 2013 by Scott Fitzgerald
http://arduino.cc/en/Tutorial/TFTDisplayText
*/
#include // Arduino LCD library
#include
// pin definition for the Uno
// SCL Hardware 13
// SDA Hardware 11
#define cs 10
#define dc 9
#define rst 8
// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);
// char array to print to the screen
char tempPrintout[6];
char humPrintout[6];
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
// Fahrenheit conversion added by Steve Spence, http://arduinotronics.blogspot.com
#include
#define DHTPIN 6 // what pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// Connect pin + (middle) of the sensor to +5V
// Connect pin S (on the right) of the sensor to whatever your DHTPIN is
// Connect pin - (on the left) of the sensor to GROUND
// Connect 10k resistor between S and +
int cycleTime = 2000;
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;
void setup() {
//Initialize SainSmart Relay Board
pinMode(relayPin1, OUTPUT); // sets the analog pin as digital output
pinMode(relayPin2, OUTPUT); // sets the analog pin as digital output
pinMode(relayPin3, OUTPUT); // sets the analog pin as digital output
pinMode(relayPin4, OUTPUT); // sets the sets the analog pin as digital output
digitalWrite(relayPin1, HIGH); // Prevents relays from starting up engaged
digitalWrite(relayPin2, HIGH); // Prevents relays from starting up engaged
digitalWrite(relayPin3, HIGH); // Prevents relays from starting up engaged
digitalWrite(relayPin4, HIGH); // Prevents relays from starting up engaged
// initialize the serial communications with the SpeakJet-TTS256
Serial.begin (9600);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(bufferPin, INPUT);
sjSerial.begin(9600);// set the data rate for the SoftwareSerial port
// Put this line at the beginning of every sketch that uses the GLCD:
TFTscreen.begin();
// clear the screen with a black background
TFTscreen.background(0, 0, 0);
// write the static text to the screen
// set the font color to white
TFTscreen.stroke(255,255,255);
// set the font size
TFTscreen.setTextSize(2);
// write the text to the top left corner of the screen
TFTscreen.text("Temp (F)",0,0);
// write the text to the top left corner of the screen
TFTscreen.text("Humidity (%)",0,60);
// ste the font size very large for the loop
TFTscreen.setTextSize(4);
dht.begin();
}
void loop() {
// Read the value of the temp/humidity sensor on D2
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
t = dht.readTemperature();
t = (t*1.8)+32; //C to F conversion
String tempVal = doubleToString(t, 0);
String humVal = doubleToString(h, 0);
// String sensorVal = String(1.234);
// convert the reading to a char array
tempVal.toCharArray(tempPrintout, 6);
humVal.toCharArray(humPrintout, 6);
// set the font color
TFTscreen.stroke(255,255,255);
// print the sensor value
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
// wait for a moment
delay(cycleTime);
// erase the text you just wrote
TFTscreen.stroke(0,0,0);
TFTscreen.text(tempPrintout, 0, 25);
TFTscreen.text(humPrintout, 0, 85);
sjSerial.print("temprature ");
delay(250);
sjSerial.print(tempPrintout);
delay(500);
sjSerial.print(" humidity ");
delay(250);
sjSerial.println(humPrintout);
if(t>70){
digitalWrite(relayPin1, LOW); // turn on AC);
digitalWrite(relayPin2, HIGH); // turn off Heat);
digitalWrite(relayPin3, LOW); // turn on FAN);
digitalWrite(relayPin4, HIGH); // turn off Dehumidifier);
}
if(t<65 && h<50){
digitalWrite(relayPin1, HIGH); // turn off AC);
digitalWrite(relayPin2, LOW); // turn on Heat);
digitalWrite(relayPin3, LOW); // turn on FAN);
digitalWrite(relayPin4, HIGH); // turn off Dehumidifier);
}
if(t<65 && h>50){
digitalWrite(relayPin1, HIGH); // turn off AC);
digitalWrite(relayPin2, LOW); // turn on Heat);
digitalWrite(relayPin3, LOW); // turn on FAN);
digitalWrite(relayPin4, LOW); // turn on Dehumidifier);
}
if(t>65 && t< 70 && h>50){
digitalWrite(relayPin1, HIGH); // turn off AC);
digitalWrite(relayPin2, HIGH); // turn off Heat);
digitalWrite(relayPin3, LOW); // turn on FAN);
digitalWrite(relayPin4, LOW); // turn on Dehumidifier);
}
if(t>65 && t< 70 && h<50){
digitalWrite(relayPin1, HIGH); // turn off AC);
digitalWrite(relayPin2, HIGH); // turn off Heat);
digitalWrite(relayPin3, HIGH); // turn off FAN);
digitalWrite(relayPin4, HIGH); // turn off Dehumidifier);
}
}
//Rounds down (via intermediary integer conversion truncation)
String doubleToString(double input,int decimalPlaces){
if(decimalPlaces!=0){
String string = String((int)(input*pow(10,decimalPlaces)));
if(abs(input)<1){
if(input>0)
string = "0"+string;
else if(input<0)
string = string.substring(0,1)+"0"+string.substring(1);
}
return string.substring(0,string.length()-decimalPlaces)+"."+string.substring(string.length()-decimalPlaces);
}
else {
return String((int)input);
}
}
Step 5: Future Upgrades
See:
http://arduinotronics.blogspot.com/2012/03/arduino-thermostat.html
http://arduinotronics.blogspot.com/2013/01/working-with-sainsmart-5v-relay-board.html
http://arduinotronics.blogspot.com/2012/11/more-ethernet-read-analog-set-digital.html
http://arduinotronics.blogspot.com/2012/06/building-heating-air-conditioning.html
Add Dew Point and Heat Index calculations to your temperature and humidity project (works with any sensor) - http://arduinotronics.blogspot.com/2013/12/temp-humidity-w-dew-point-calcualtions.html