diff --git a/.gitmodules b/.gitmodules
index 8cba6a8..917faaa 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -8,3 +8,7 @@
 	path = dht22-esp8266/lib/esp8266-dht22
 	url = https://github.com/Defozo/esp8266-dht22.git
 	branch = patch-1
+[submodule "EEITemperature/lib/esp8266-dht22"]
+	path = EEITemperature/lib/esp8266-dht22
+	url = https://github.com/Defozo/esp8266-dht22.git
+	branch = patch-1
diff --git a/EEITemperature/EEITemperature.ino b/EEITemperature/EEITemperature.ino
new file mode 100644
index 0000000..5c5ac37
--- /dev/null
+++ b/EEITemperature/EEITemperature.ino
@@ -0,0 +1,66 @@
+#include <Wire.h>
+
+#include "lib/esp8266-dht22/dht22.h"
+#include "lib/esp8266-dht22/dht22.c"
+#include "lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.h"
+#include "lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.cpp"
+
+// ~~~
+
+// LCD Display Settings
+#define LCD_PIN_SDA	12
+#define LCD_PIN_SCL	14
+
+// DHT22 Settings
+#define DHT_TYPE		DHT22
+// Pin D1 on the NodeMCU v0.9
+#define DHT_PIN_DATA	5
+
+// ~~~
+
+HC_LiquidCrystal_I2C lcd(0x3F,20,4);
+
+// ~~~
+
+void dht_init() {
+	Serial.print("Initialising the DHT - ");
+	DHT_init(DHT_PIN_DATA, DHT_TYPE, 1);
+	DHT_begin();
+	
+    Serial.println("done"); 
+	Serial.print("Waiting to warm DHT22 up - ");
+	delay(2000 - millis()); // Give the DHT22 time to warm up
+}
+void lcd_init() {
+	// Deprecated, but in this instance there's nothing we can do about it 
+	// since we aren't running I2C over the default pins (default pins? what 
+	// default pins?)
+	Wire.pins(LCD_PIN_SDA, LCD_PIN_SCL);
+	lcd.begin();
+}
+
+void setup() {
+	lcd_init();
+	dht_init();
+}
+
+void loop() {
+	lcd.backlight();
+	
+	float temp, humidity;
+	
+	lcd.setCursor(0, 0);
+	temp = readTemperature(false);
+	humidity = readHumidity();
+	
+	lcd.print("Temperature: ");
+	lcd.print(temp);
+	lcd.print("C");
+	
+	lcd.setCursor(0, 1);
+	lcd.print("Humidity: ");
+	lcd.print(humidity);
+	lcd.print("%");
+	
+	delay(1000);
+}
diff --git a/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.cpp b/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.cpp
new file mode 100644
index 0000000..eb0a33a
--- /dev/null
+++ b/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.cpp
@@ -0,0 +1,253 @@
+#include "HC_LiquidCrystal_I2C.h"
+#include <inttypes.h>
+#include <Arduino.h>
+#include <Wire.h>
+
+// When the display powers up, it is configured as follows:
+//
+// 1. Display clear
+// 2. Function set: 
+//    DL = 1; 8-bit interface data 
+//    N = 0; 1-line display 
+//    F = 0; 5x8 dot character font 
+// 3. Display on/off control: 
+//    D = 0; Display off 
+//    C = 0; Cursor off 
+//    B = 0; Blinking off 
+// 4. Entry mode set: 
+//    I/D = 1; Increment by 1
+//    S = 0; No shift 
+//
+// Note, however, that resetting the Arduino doesn't reset the LCD, so we
+// can't assume that its in that state when a sketch starts (and the
+// LiquidCrystal constructor is called).
+
+HC_LiquidCrystal_I2C::HC_LiquidCrystal_I2C(uint8_t lcd_addr, uint8_t lcd_cols, uint8_t lcd_rows, uint8_t charsize)
+{
+	_addr = lcd_addr;
+	_cols = lcd_cols;
+	_rows = lcd_rows;
+	_charsize = charsize;
+	_backlightval = LCD_BACKLIGHT;
+}
+
+void HC_LiquidCrystal_I2C::begin() {
+	Wire.begin();
+	_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+
+	if (_rows > 1) {
+		_displayfunction |= LCD_2LINE;
+	}
+
+	// for some 1 line displays you can select a 10 pixel high font
+	if ((_charsize != 0) && (_rows == 1)) {
+		_displayfunction |= LCD_5x10DOTS;
+	}
+
+	// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
+	// according to datasheet, we need at least 40ms after power rises above 2.7V
+	// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
+	delay(50); 
+
+	// Now we pull both RS and R/W low to begin commands
+	expanderWrite(_backlightval);	// reset expanderand turn backlight off (Bit 8 =1)
+	delay(1000);
+
+	//put the LCD into 4 bit mode
+	// this is according to the hitachi HD44780 datasheet
+	// figure 24, pg 46
+
+	// we start in 8bit mode, try to set 4 bit mode
+	write4bits(0x03 << 4);
+	delayMicroseconds(4500); // wait min 4.1ms
+
+	// second try
+	write4bits(0x03 << 4);
+	delayMicroseconds(4500); // wait min 4.1ms
+
+	// third go!
+	write4bits(0x03 << 4); 
+	delayMicroseconds(150);
+
+	// finally, set to 4-bit interface
+	write4bits(0x02 << 4); 
+
+	// set # lines, font size, etc.
+	command(LCD_FUNCTIONSET | _displayfunction);  
+	
+	// turn the display on with no cursor or blinking default
+	_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
+	display();
+	
+	// clear it off
+	clear();
+	
+	// Initialize to default text direction (for roman languages)
+	_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
+	
+	// set the entry mode
+	command(LCD_ENTRYMODESET | _displaymode);
+	
+	home();
+}
+
+/********** high level commands, for the user! */
+void HC_LiquidCrystal_I2C::clear(){
+	command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
+	delayMicroseconds(2000);  // this command takes a long time!
+}
+
+void HC_LiquidCrystal_I2C::home(){
+	command(LCD_RETURNHOME);  // set cursor position to zero
+	delayMicroseconds(2000);  // this command takes a long time!
+}
+
+void HC_LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){
+	int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+	if (row > _rows) {
+		row = _rows-1;    // we count rows starting w/0
+	}
+	command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
+}
+
+// Turn the display on/off (quickly)
+void HC_LiquidCrystal_I2C::noDisplay() {
+	_displaycontrol &= ~LCD_DISPLAYON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void HC_LiquidCrystal_I2C::display() {
+	_displaycontrol |= LCD_DISPLAYON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns the underline cursor on/off
+void HC_LiquidCrystal_I2C::noCursor() {
+	_displaycontrol &= ~LCD_CURSORON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void HC_LiquidCrystal_I2C::cursor() {
+	_displaycontrol |= LCD_CURSORON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turn on and off the blinking cursor
+void HC_LiquidCrystal_I2C::noBlink() {
+	_displaycontrol &= ~LCD_BLINKON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void HC_LiquidCrystal_I2C::blink() {
+	_displaycontrol |= LCD_BLINKON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// These commands scroll the display without changing the RAM
+void HC_LiquidCrystal_I2C::scrollDisplayLeft(void) {
+	command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
+}
+void HC_LiquidCrystal_I2C::scrollDisplayRight(void) {
+	command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
+}
+
+// This is for text that flows Left to Right
+void HC_LiquidCrystal_I2C::leftToRight(void) {
+	_displaymode |= LCD_ENTRYLEFT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This is for text that flows Right to Left
+void HC_LiquidCrystal_I2C::rightToLeft(void) {
+	_displaymode &= ~LCD_ENTRYLEFT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'right justify' text from the cursor
+void HC_LiquidCrystal_I2C::autoscroll(void) {
+	_displaymode |= LCD_ENTRYSHIFTINCREMENT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'left justify' text from the cursor
+void HC_LiquidCrystal_I2C::noAutoscroll(void) {
+	_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// Allows us to fill the first 8 CGRAM locations
+// with custom characters
+void HC_LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
+	location &= 0x7; // we only have 8 locations 0-7
+	command(LCD_SETCGRAMADDR | (location << 3));
+	for (int i=0; i<8; i++) {
+		write(charmap[i]);
+	}
+}
+
+// Turn the (optional) backlight off/on
+void HC_LiquidCrystal_I2C::noBacklight(void) {
+	_backlightval=LCD_NOBACKLIGHT;
+	expanderWrite(0);
+}
+
+void HC_LiquidCrystal_I2C::backlight(void) {
+	_backlightval=LCD_BACKLIGHT;
+	expanderWrite(0);
+}
+
+/*********** mid level commands, for sending data/cmds */
+
+inline void HC_LiquidCrystal_I2C::command(uint8_t value) {
+	send(value, 0);
+}
+
+inline size_t HC_LiquidCrystal_I2C::write(uint8_t value) {
+	send(value, Rs);
+	return 1;
+}
+
+
+/************ low level data pushing commands **********/
+
+// write either command or data
+void HC_LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
+	uint8_t highnib=value&0xf0;
+	uint8_t lownib=(value<<4)&0xf0;
+	write4bits((highnib)|mode);
+	write4bits((lownib)|mode); 
+}
+
+void HC_LiquidCrystal_I2C::write4bits(uint8_t value) {
+	expanderWrite(value);
+	pulseEnable(value);
+}
+
+void HC_LiquidCrystal_I2C::expanderWrite(uint8_t _data){                                        
+	Wire.beginTransmission(_addr);
+	Wire.write((int)(_data) | _backlightval);
+	Wire.endTransmission();   
+}
+
+void HC_LiquidCrystal_I2C::pulseEnable(uint8_t _data){
+	expanderWrite(_data | En);	// En high
+	delayMicroseconds(1);		// enable pulse must be >450ns
+	
+	expanderWrite(_data & ~En);	// En low
+	delayMicroseconds(50);		// commands need > 37us to settle
+}
+
+void HC_LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){
+	createChar(char_num, rows);
+}
+
+void HC_LiquidCrystal_I2C::setBacklight(uint8_t new_val){
+	if (new_val) {
+		backlight();		// turn backlight on
+	} else {
+		noBacklight();		// turn backlight off
+	}
+}
+
+void HC_LiquidCrystal_I2C::printstr(const char c[]){
+	//This function is not identical to the function used for "real" I2C displays
+	//it's here so the user sketch doesn't have to be changed 
+	print(c);
+}
diff --git a/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.h b/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.h
new file mode 100644
index 0000000..817889e
--- /dev/null
+++ b/EEITemperature/lib/HC_LiquidCrystal_I2C/HC_LiquidCrystal_I2C.h
@@ -0,0 +1,164 @@
+#ifndef FDB_LIQUID_CRYSTAL_I2C_H
+#define FDB_LIQUID_CRYSTAL_I2C_H
+
+#include <inttypes.h>
+#include <Print.h>
+
+// commands
+#define LCD_CLEARDISPLAY 0x01
+#define LCD_RETURNHOME 0x02
+#define LCD_ENTRYMODESET 0x04
+#define LCD_DISPLAYCONTROL 0x08
+#define LCD_CURSORSHIFT 0x10
+#define LCD_FUNCTIONSET 0x20
+#define LCD_SETCGRAMADDR 0x40
+#define LCD_SETDDRAMADDR 0x80
+
+// flags for display entry mode
+#define LCD_ENTRYRIGHT 0x00
+#define LCD_ENTRYLEFT 0x02
+#define LCD_ENTRYSHIFTINCREMENT 0x01
+#define LCD_ENTRYSHIFTDECREMENT 0x00
+
+// flags for display on/off control
+#define LCD_DISPLAYON 0x04
+#define LCD_DISPLAYOFF 0x00
+#define LCD_CURSORON 0x02
+#define LCD_CURSOROFF 0x00
+#define LCD_BLINKON 0x01
+#define LCD_BLINKOFF 0x00
+
+// flags for display/cursor shift
+#define LCD_DISPLAYMOVE 0x08
+#define LCD_CURSORMOVE 0x00
+#define LCD_MOVERIGHT 0x04
+#define LCD_MOVELEFT 0x00
+
+// flags for function set
+#define LCD_8BITMODE 0x10
+#define LCD_4BITMODE 0x00
+#define LCD_2LINE 0x08
+#define LCD_1LINE 0x00
+#define LCD_5x10DOTS 0x04
+#define LCD_5x8DOTS 0x00
+
+// flags for backlight control
+#define LCD_BACKLIGHT 0x08
+#define LCD_NOBACKLIGHT 0x00
+
+#define En B00000100  // Enable bit
+#define Rw B00000010  // Read/Write bit
+#define Rs B00000001  // Register select bit
+
+/**
+ * This is the driver for the Liquid Crystal LCD displays that use the I2C bus.
+ *
+ * After creating an instance of this class, first call begin() before anything else.
+ * The backlight is on by default, since that is the most likely operating mode in
+ * most cases.
+ */
+class HC_LiquidCrystal_I2C : public Print {
+public:
+	/**
+	 * Constructor
+	 *
+	 * @param lcd_addr	I2C slave address of the LCD display. Most likely printed on the
+	 *					LCD circuit board, or look in the supplied LCD documentation.
+	 * @param lcd_cols	Number of columns your LCD display has.
+	 * @param lcd_rows	Number of rows your LCD display has.
+	 * @param charsize	The size in dots that the display has, use LCD_5x10DOTS or LCD_5x8DOTS.
+	 */
+	HC_LiquidCrystal_I2C(uint8_t lcd_addr, uint8_t lcd_cols, uint8_t lcd_rows, uint8_t charsize = LCD_5x8DOTS);
+
+	/**
+	 * Set the LCD display in the correct begin state, must be called before anything else is done.
+	 */
+	void begin();
+	
+	 /**
+	  * Remove all the characters currently shown. Next print/write operation will start
+	  * from the first position on LCD display.
+	  */
+	void clear();
+	  
+	/**
+	 * Next print/write operation will will start from the first position on the LCD display.
+	 */
+	void home();
+
+	 /**
+	  * Do not show any characters on the LCD display. Backlight state will remain unchanged.
+	  * Also all characters written on the display will return, when the display in enabled again.
+	  */
+	void noDisplay();
+	  
+	/**
+	 * Show the characters on the LCD display, this is the normal behaviour. This method should
+	 * only be used after noDisplay() has been used.
+	 */ 
+	void display();
+
+	/**
+	 * Do not blink the cursor indicator.
+	 */
+	void noBlink();
+	 
+	/**
+	 * Start blinking the cursor indicator.
+	 */ 
+	void blink();	 
+
+	/**
+	 * Do not show a cursor indicator.
+	 */
+	void noCursor();
+
+	/**
+ 	 * Show a cursor indicator, cursor can blink on not blink. Use the
+	 * methods blink() and noBlink() for changing cursor blink.
+	 */ 
+	void cursor();
+
+	void scrollDisplayLeft();
+	void scrollDisplayRight();
+	void printLeft();
+	void printRight();
+	void leftToRight();
+	void rightToLeft();
+	void shiftIncrement();
+	void shiftDecrement();
+	void noBacklight();
+	void backlight();
+	void autoscroll();
+	void noAutoscroll(); 
+	void createChar(uint8_t, uint8_t[]);
+	void setCursor(uint8_t, uint8_t); 
+	virtual size_t write(uint8_t);
+	void command(uint8_t);
+
+	inline void blink_on() { blink(); }
+	inline void blink_off() { noBlink(); }
+	inline void cursor_on() { cursor(); }
+	inline void cursor_off() { noCursor(); }
+
+// Compatibility API function aliases
+	void setBacklight(uint8_t new_val);				// alias for backlight() and nobacklight()
+	void load_custom_character(uint8_t char_num, uint8_t *rows);	// alias for createChar()
+	void printstr(const char[]);
+	 
+private:
+	void send(uint8_t, uint8_t);
+	void write4bits(uint8_t);
+	void expanderWrite(uint8_t);
+	void pulseEnable(uint8_t);
+	uint8_t _addr;
+	uint8_t _displayfunction;
+	uint8_t _displaycontrol;
+	uint8_t _displaymode;
+	uint8_t _cols;
+	uint8_t _rows;
+	uint8_t _charsize;
+	uint8_t _backlightval;
+};
+
+#endif // FDB_LIQUID_CRYSTAL_I2C_H
diff --git a/EEITemperature/lib/esp8266-dht22 b/EEITemperature/lib/esp8266-dht22
new file mode 160000
index 0000000..b949ac3
--- /dev/null
+++ b/EEITemperature/lib/esp8266-dht22
@@ -0,0 +1 @@
+Subproject commit b949ac35a553e4089f3e81dc7e4d739a02a00f78
diff --git a/Examples/LCDTest/LCDTest.ino b/Examples/LCDTest/LCDTest.ino
index 9fa19d1..22c4a80 100644
--- a/Examples/LCDTest/LCDTest.ino
+++ b/Examples/LCDTest/LCDTest.ino
@@ -55,53 +55,53 @@ HC_LiquidCrystal_I2C lcd(0x3F,20,4);
 
 void setup()
 {
-  /* Initialise the LCD */
-  lcd.begin();
-  /* Transfer the custom characters into the LCD's memory */
-  lcd.createChar(0, TopLeftCorner);
-  lcd.createChar(1, TopRightCorner);
-  lcd.createChar(2, BottomLeftCorner);
-  lcd.createChar(3, BottomRightCorner);
-  lcd.createChar(4, VerticalBar);
+    // Wire.pins(12, 14);
+    /* Initialise the LCD */
+    lcd.begin();
+    /* Transfer the custom characters into the LCD's memory */
+    lcd.createChar(0, TopLeftCorner);
+    lcd.createChar(1, TopRightCorner);
+    lcd.createChar(2, BottomLeftCorner);
+    lcd.createChar(3, BottomRightCorner);
+    lcd.createChar(4, VerticalBar);
 }
 
 /* Main program loop */
 void loop()
 {
-  /* Make sure the backlight is turned on */
-  lcd.backlight();
+    /* Make sure the backlight is turned on */
+    lcd.backlight();
 
-  /* Use the custom graphic characters to draw a border */
-  lcd.setCursor(0, 0);
-  lcd.write(0); //Write the top left graphic
-  lcd.print("==================");
-  lcd.write(1); //Write the top right graphic
-  lcd.setCursor(0, 1);
-  lcd.write(4); //Write the vertical bar graphic
-  lcd.setCursor(0, 2);
-  lcd.write(4); //Write the vertical bar graphic
-  lcd.setCursor(19, 1);
-  lcd.write(4); //Write the vertical bar graphic
-  lcd.setCursor(19, 2);
-  lcd.write(4); //Write the vertical bar graphic
-  lcd.setCursor(0, 3);
-  lcd.write(2); //Write the bottom left graphic
-  lcd.print("==================");
-  lcd.write(3); //Write the bottom right graphic
- 
-  /* Display some text inside the border */
-  while (1)
-  {
-    lcd.setCursor(2,1);
-    lcd.print("HOBBY COMPONENTS");
-    lcd.setCursor(2,2);
-    lcd.print("**HELLO WORLD**");
-    delay(500);
-    lcd.setCursor(2,1);
-    lcd.print("                ");
-    lcd.setCursor(2,2);
-    lcd.print("               ");
-    delay(500);
-  }
+    /* Use the custom graphic characters to draw a border */
+    lcd.setCursor(0, 0);
+    lcd.write(0); //Write the top left graphic
+    lcd.print("==================");
+    lcd.write(1); //Write the top right graphic
+    lcd.setCursor(0, 1);
+    lcd.write(4); //Write the vertical bar graphic
+    lcd.setCursor(0, 2);
+    lcd.write(4); //Write the vertical bar graphic
+    lcd.setCursor(19, 1);
+    lcd.write(4); //Write the vertical bar graphic
+    lcd.setCursor(19, 2);
+    lcd.write(4); //Write the vertical bar graphic
+    lcd.setCursor(0, 3);
+    lcd.write(2); //Write the bottom left graphic
+    lcd.print("==================");
+    lcd.write(3); //Write the bottom right graphic
+
+    /* Display some text inside the border */
+    while (1)
+    {
+        lcd.setCursor(2,1);
+        lcd.print("HOBBY COMPONENTS");
+        lcd.setCursor(2,2);
+        lcd.print("**HELLO WORLD**");
+        delay(500);
+        lcd.setCursor(2,1);
+        lcd.print("                ");
+        lcd.setCursor(2,2);
+        lcd.print("               ");
+        delay(500);
+    }
 }
-
