Introduction: Arduino and ENC28J60 Ethernet Controller, (320x480) TFT LCD, DHT22 Temperature / Humidity Web Server

Abstract

For embedded design, adding an Ethernet port, opens many possibility of connecting it to the external world. ENC28J60 is a 28-pin, 10BASE-T standalone Ethernet Controller with on board MAC & PHY, 8 Kbytes of Buffer RAM and an SPI serial interface. It can be used for Industrial Automation, Building Automation, Home Control, Security and Instrumentation applications. In this instructable a web based temperature server is explained by using ENC28J60.

TFT LCD screens are getting cheaper and using it in an embedded design, makes it more user friendly. In this instructable, explains connecting the 320x480, 3.5Inch TFT LCD, with ILI9488 driver and SPI interfacing into Arduino. The LCD can be connected to the Arduinos SPI bus. It needs minimum number of port pins (4).

The DHT22 (AM2302) is a high precision temperature sensor module, provide calibrated temperature and humidity which is connected to digital IO pin of Arduino. The DHT22 provides the temperature in Celsius format. The Arduino program converts the temperature into Fahrenheit, Kelvin and Rankine, and sends via serial port also displays on TFT LCD, and transmits over the Ethernet port.

Parts and components

Arduino Uno board = 1 No

ENC28J60 Ethernet Controller Module= 1 No

DHT22 (AM2302) = 1 No

320x480 TFT LCD (SPI interface, ILI9488 LCD controller) = 1 No

10K Resistor = 1No

Step 1: Schematic

The ENC28J60 is an IEEE 802.3 compatible Ethernet Controller with Integrated MAC and 10BASE-T PHY.

It has 8 Kbyte Transmit/Receive Packet Dual Port Buffer SRAM, Programmable Automatic Retransmit on Collision, Programmable Padding and CRC Generation, Programmable Automatic Rejection of Erroneous Packets Buffer and Configurable transmit/receive buffer size.

ENC28J60 needs 3.3 Volt power, but its SPI pins are 5 Volt tolerant.

ENC28J60 SPI pins are connected to Arduino SPI pins.

ENC28J60 MOSI to Arduino digital IO D11

ENC28J60 SCLK to Arduino digital IO D13

ENC28J60 CS to Arduino digital IO D8

ENC28J60 MISO to Arduino digital IO D12

The TFT LCD and ENC28J60 shares the SPI pins (SCLK, MOSI, MISO).

However the TFT LCD uses Arduino D10 pin for CS. Whereas ENC28J60 uses Arduino D8 pin for CS.

The TFT LCD (3.5 inch, 320x480 pixel, ILI9488 LCD controller), is used for this instructable.

The LCD is easily interfaced with Arduino SPI bus, and it needs minimum of four Digital IO lines.

The ILI9488 LCD Controller is a 16.7M single-chip SoC driver for a-Si TFT liquid crystal display panels with a resolution of 320(RGB) x 480 dots.

The ILI9488 is comprised of a 960-channel source driver, a 480-channel gate driver, 345,600 bytes GRAM for graphic data of 320 (RGB) x 480 dots, and power supply circuit. The LCD operates at 3.3 Volt Logic.

Arduino SPI port is connected to the LCD ( D13- SCLK, and D11 – MOSI). Arduino Digital IO pin D9 and D10 is connected to RS and CS pin of LCD.

DHT22 digital temperature / humidity sensor delivers temperatures between -40°C and +80°C and humidity between 0% to 100%. The temperature accuracy is ±0.1°C (maximum).

The DHT22 data pin is connected with Arduino digital IO pin, and pulled up to Vcc, via 10K ohm resistor.

DHT22 (AM2302) outputs calibrated digital data signal. Every DHT22 sensor of this model is temperature compensated and calibrated in accurate calibration chamber and the calibration-coefficient is saved in internal OTP memory.

The sensor supports long transmission distance.

Arduino reads the temperature and humidity at 5 second interval and sends to the serial port, Ethernet port as well as displays on LCD screen.

The conversion formula for Celsius to other scale are given below.

Fahrenheit:- T(°F) = T(°C) × 9/5 + 32

Kelvin:- T(K) = T(°C) + 273.15

Rankine:- T(°R) = (T(°C) + 273.15) × 9/5

Step 2: Software

The EtherCard library performs low-level interfacing with network interfaces, based on the MicroChip ENC28J60 device.

High-level routines are provided to allow a variety of purposes including simple data transfer through to HTTP handling.

EtherCard is a driver for the ENC28J60 chip, compatible with Arduino IDE.

Install Ethercard library. Fill in the mymac and myip variable.

myip is a unique Arduino temperature server IP in the network. (This example uses 198.168.1.214)

mymac is unique Arduino temperature server MAC address. (This example uses 76:69:69:2D:30:31)

DHT22 uses floating point for temperature measurements. Hence Ethercard, BufferFiller class should support floating point. So the FLOATEMIT, compile time option needs to be activated at EtherCard.cpp file

// uncomment line to enable $T in emit_P for float emitting

#define FLOATEMIT

EtherCard library uses Arduino D8 as ENC28J60 chip select pin. If one wants different pin assignment for CS, should modify the following function at EtherCard.h file

static uint8_t begin (const uint16_t size, const uint8_t* macaddr, uint8_t csPin =8);

Install Adafruit GFX and Adafruit ILI9341 device libraries.

Adafruit ILI9341 library is best suitable for the ILI9488 device.

Adafruit ILI9341 library is modified for adopting ILI9488 LCD controller.

Only, the Height and Width parameters at Adafruit_ILI9341.h file is modified to

#define ILI9341_TFTWIDTH 320

#define ILI9341_TFTHEIGHT 480

And at the Adafruit_ILI9341.cpp file, at the function Adafruit_ILI9341::begin(void), the following lines are modified for adapting ILI9488 device (320x480 pixels).

writecommand(ILI9341_DFUNCTR); // Display Function Control

writedata(0x02);

writedata(0x02);

writedata(0x3B);

Included DHT library offers the read interface for the sensor.

Arduino reads the temperature and humidity values at 5 seconds interval.

The temperature is in Celsius format, which is converted into Fahrenheit, Kelvin and Rankine format by the software.

A two column five row, multi colored table is drawn by using Arduino GFX lib, for displaying the temperature and humidity.

The time library is used, and a call back function is defined ( printTemperature() ) for refreshing the TFT LCD screen and Serial port debug print at every 5 seconds interval.

Converted four formats of temperature are send to the Ethernet port, Serial port and also displayed on the TFT LCD.

Step 3: Code

<p>//Experiment of ENC28J60 Temperature Web Server<br>//With 3.5 Inch LCD (320x480), ILI9488 SPI Interface driver
//And experiment of DHT22 digital temperature / humidity sensor
//Adafruit ILI9341 library is modified for ILI9488 (320x480)
//Demonstrates the use ENC28J60 Ethernet controller</p><p>// DHT22 Data line connected to Arduino digital IO 2</p><p>// ENC28J60 MOSI to Arduino digital IO D11
// ENC28J60 SCLK to Arduino digital IO D13
// ENC28J60 CS to Arduino digital IO D8
// ENC28J60 MISO to Arduino digital IO D12</p><p>// LCD MOSI to Arduino digital IO D11
// LCD SCLK to Arduino digital IO D13
// LCD CS to Arduino digital IO D10
// LCD RS / DS to Arduino digital IO D9</p><p>// Name:- M.Pugazhendi
// Date:-  08thSep2016
// Version:- V0.1
// e-mail:- muthuswamy.pugazhendi@gmail.com</p><p>//Include Libraries
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include  <DHT.h><dht.h>
#include "Timer.h"
#include "EtherCard.h"</dht.h></p><p>//Ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x76,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,1,214 };</p><p>byte Ethernet::buffer[500];
BufferFiller bfill;</p><p>// For the LCD shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10</p><p>// DHT22
#define DHTPIN 2    
#define DHTTYPE DHT22</p><p>#define SERIAL_DEBUG</p><p>// Initialize LCD
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);</p><p>// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);</p><p>// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);</p><p>//Initialize / create timer
Timer t;</p><p>//Variables
//Stores humidity value
float hum;  </p><p>//Stores temperature value
float temp; 
float fa,ke,ra = 0.00;</p><p>void setup () 
{</p><p> #ifdef SERIAL_DEBUG
    Serial.begin(9600);
    Serial.println("ENC28J60 Ethernet Temperature Server Test"); 
    Serial.println("DHT22 temperature / humidity sensor Test");
 #endif
 
 //Initialize TFT LCD
 tft.begin();
 //Rotate the screen to right direction
 tft.setRotation(1);</p><p> //Print the headers
 printHeader();
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
  {
    Serial.println(F("Failed to access Ethernet controller"));
  }
  ether.staticSetup(myip);</p><p>//Initialize the DHT sensor
  dht.begin();</p><p>  t.every(5000, printTemperature);
}</p>
<p>void loop () <br>{
  t.update();
  
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if (pos)
  {
  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
  }</p><p>   //Read data and store it to variables hum and temp
  hum = dht.readHumidity();
  temp= dht.readTemperature();</p><p>  //Fahrenheit
    //T(°F) = T(°C) × 9/5 + 32
    fa = ( temp * 1.8 ) + 32;
    
  //Kelvin
    //T(K) = T(°C) + 273.15          
    ke = temp + 273.15;</p><p>    //Rankine
    //T(°R) = (T(°C) + 273.15) × 9/5          
    ra = temp + 273.15;
    ra = (ra * 1.8);
}</p><p>//Print header on LCD
unsigned long printHeader() 
{
   tft.fillRect(0,0,240, 64,ILI9341_GREEN);
  tft.fillRect(0,64,240, 64,ILI9341_RED);
  tft.fillRect(0,128,240, 64,ILI9341_CYAN);
  tft.fillRect(0,192,240, 64,ILI9341_YELLOW);
  tft.fillRect(0,256,240, 64,ILI9341_ORANGE);</p><p>  unsigned long start = micros();
  tft.setTextColor(ILI9341_BLACK);   
  tft.setTextSize(3);
  //
  tft.setCursor(50,0+20);
  tft.print("CELCIUS");</p><p>  //
  tft.setCursor(50,64+20);
  tft.print("FAHRENHEIT");
  //
  tft.setCursor(50,128+20);
  tft.print("KELVIN");</p><p>    //
  tft.setCursor(50,192+20);
  tft.print("RANKIN");</p><p>   //
  tft.setCursor(50,256+20);
  tft.print("HUMIDITY");
  
  return micros() - start;
}</p><p>//Print Temperature / humidity value
void printTemperature() 
{
  tft.fillRect(241,0,240, 64,ILI9341_CYAN);
  tft.fillRect(241,64,240, 64,ILI9341_YELLOW);
  tft.fillRect(241,128,240, 64,ILI9341_ORANGE);
  tft.fillRect(241,192,240, 64,ILI9341_GREEN);
  tft.fillRect(241,256,240, 64,ILI9341_RED);
    
  //tft.fillScreen(ILI9341_BLUE);
   tft.setTextColor(ILI9341_BLACK);   
  tft.setTextSize(4);</p><p>  #ifdef SERIAL_DEBUG
    Serial.print("Celsius = ");
    Serial.print(temp);
    //Print degree symbol
    Serial.write(176); 
    Serial.println("C");
  #endif
        
  tft.setCursor(250,0+20);
  tft.print(temp);
  tft.print(" ");
  tft.print((char)247);
  tft.println("C");</p><p>    //Fahrenheit
    //T(°F) = T(°C) × 9/5 + 32
   // converted = ( temp * 1.8 ) + 32;
  #ifdef SERIAL_DEBUG
    Serial.print("Fahrenheit = ");
    Serial.print(fa);
    //Print degree symbol
    Serial.write(176); 
    Serial.println("F");
  #endif
      
    tft.setCursor(250,64+20);
    tft.print(fa);
    tft.print(" ");
    tft.print((char)247);
    tft.println("F");</p><p>//Kelvin
    //T(K) = T(°C) + 273.15          
    //converted = temp + 273.15;
 #ifdef SERIAL_DEBUG    
    Serial.print("Kelvin = ");
    Serial.print(ke);
    Serial.println(" K");
 #endif
  tft.setCursor(250,128+20);
  tft.print(ke);
  tft.print(" ");
  tft.println("K");</p><p>   //Rankine
    //T(°R) = (T(°C) + 273.15) × 9/5          
    //converted = temp + 273.15;
    //converted = (converted * 1.8);
  #ifdef SERIAL_DEBUG
    Serial.print("Rankin = ");
    Serial.print(ra);
    //Print degree symbol
    Serial.write(176);    
    Serial.println("R");
  #endif
  tft.setCursor(250,192+20);
  tft.print(ra);
  tft.print(" ");
  tft.print((char)247);
  tft.println("R");</p><p> //Humidity
 #ifdef SERIAL_DEBUG
    Serial.print("Humidity =");
    Serial.println(hum);
 #endif
    
  tft.setCursor(250,256+20);
  tft.print(hum);
  tft.print(" ");
  tft.println("%");
}

static word homePage()
{ long t = millis() / 1000; word h = t / 3600; byte m = (t / 60) % 60; byte s = t % 60; bfill = ether.tcpOffset(); bfill.emit_p(PSTR(

"HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n" "\r\n" "<meta http-equiv='refresh' content='1'/>"

"<title>DHT22 server</tile>"

"<h1> DHT22 Temperature / Humidity Server<br> </h1>"

"<h1><font color=blue> $D$D:$D$D:$D$D<br></h1>"

"<h1><font color=red>Celsius:$T°C<br>Fahrenheit:$T°C<br>Kelvin:$T<br>Rankine:$T°C<br></h1>"

"<h1><font color=green>Humidity:$T%<br></h1>",

h/10, h%10, m/10, m%10, s/10, s%10,temp,fa,ke,ra,hum);

return bfill.position();

}

Step 4: Conclusion

The project is successfully completed with Arduino UNO, ENC28J60 Ethernet module, 320x480 TFT LCD and DHT22 module.

The converted temperature can be viewed at Google chrome browser, TFD LCD screen and Serial Port screen as given below.