Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save john212/ca30f6746488e8a32f116cab60c9df00 to your computer and use it in GitHub Desktop.
Save john212/ca30f6746488e8a32f116cab60c9df00 to your computer and use it in GitHub Desktop.
Arduino With Ethernet Shield Controlling LED via Telent and Displaying Temp., Humidity, LDR Readings via Telnet and on 16x2 Display
/**************************************************
Udemy Arduino Step-by-Step Course
Section 6 Lecture 60 Ethernet Shield Telnet Control
With 16x2 LCD Text Display and DHT11 Temperature/Humidity Sensor
Quiz - Just For Fun - No Grade
by J. Cantlin
July 8, 2016
***************************************************/
/**************************************************
Description of Program
In this demonstration, a W5100 based Ethernet Shield with
an Arduino Uno is used to show how remote control, in this
case via telnet, can be used to read the analog output of
an LDR (light dependent resistor). read the temperature
and humidity from an HT22 sensor, and turn an LED on
or off.
Upon connection to the remote PC, a 16x2 LCD
will display the IP address used for the network connection.
A remote telnet command will display secected data via
Telnet, the serial monitor and the 16x2 display at the same time.
The W5100 Ethernet Shield communicates via SPI.
The 16x2 LCD Display communicates via I2C.
A 1k ohm resistor is used to limit the current through the LED,
and another 1k ohm resistor is used as a voltage divider
with the LDR to provide a good range of voltages between
the LDR and the 1k ohm resistor.
***************************************************/
/**************************************************
BIG TIP! THIS PROGRAM USES A LOT OF Serial.print("some string") lines.
EACH "some string" IS STORED IN PRECIOUS VOLATILE SDRAM AND NOT
IN THE NON-VOLATILE PROGRAM MEMORY ON THE UNO. THE UNO HAS ONLY
2K OF SDRAM AND 32K OF PROGRAM MEMORY. THERE IS AN EASY BUT SOMEWHAT
OBSCURE WAY TO TELL THE ARDUINO COMPILER NOT TO PUT "some string"
INTO SDRAM BUT TO PUT IT IN PROGRAM MEMORY. IT IS CALLED "F() MACRO"
AND YOU WILL WANT TO USE IT OR YOUR PROGRAM WILL NOT RUN!
F() Macro is easy to use, just change each string (mostly in the
Serial.print() functions as follows:
Change: Serial.print("some string")
To: Serial.print(F("some string"))
This program stopped working (at midnight of course)after I had added
so many strings in the Serial.print() lines that I was using 82%
of the 2k SDRAM. The compiler gave me a "low SDRAM warning"
otherwise this problem would have been, at least for me, unsolvable.
After adding F() around all of the Serial.print() strings the
SDRAM usage dropped to 42% and the program ran fine.
More information about "F() Macro" is here:
http://playground.arduino.cc/Learning/Memory
https://www.baldengineer.com/arduino-f-macro.html
***************************************************/
/**************************************************
Description of W5100 Ethernet Shield
The Wiznet 5100 based ethernet shield includes a micro
SD card for data storage. The W5100 controller has a
hardwired RJ-45 Ethernet controller and supports the following
communication protocols TCP, UDP, ICMP, IPv4, ARP, IGMP,
PPPoE, and the physcial Ethernet layer. It can use DHCP
to dynamically pull an IP address from your router.
The Arduino communicates with both the W5100 and SD card using the
SPI bus (through the ICSP header). This is on digital
pins 10, 11, 12, and 13 on the Uno. Pin 10 is used to for the SPI
"SS" (slave select) to select the W5100 on the SPI bus
and pin 4 is SS for the for the micro SD card so these pins cannot
be used for general I/O when using the ethernet shield.
The Wiznet W5100 needs more power than the Arduino can supply.
The Arduino and shield are powered via USB and 9VDC. A
separate breadboad 5vdc is used to power the display and DH22
sensor to limit the electrical load on the Arduino.
The shield also has numerous status LEDs and a reset button.
***************************************************/
/**************************************************
Telnet
Telnet is a protocol that allows you to connect to remote computers
(called hosts) over a TCP/IP network (such as the Internet).
Using telnet client software on your computer, you can make a
connection to a telnet server (i.e., the remote host). Once your
telnet client establishes a connection to the remote host,
your client becomes a virtual terminal, allowing you to communicate
with the remote host. A login may be required but is not in this case.
A Telnet client (or even server) is built in to most operatiing systems.
The latest versions of Windows have it deactivated by default. Below is a
link to a good reference for activating it:
http://www.sysprobs.com/install-and-enable-telnet-in-windows-8-use-as-telnet-client
Putty is a free SSH and Telnet Client I recommend. Download it here:
http://www.chiark.greenend.org.uk/~sgtatham/putty/
***************************************************/
/**************************************************
Ethernet Library
The build-in Ethernet Library allows an Arduino board to connect
to the internet. It can serve as either a server accepting
incoming connections or a client making outgoing ones.
The library supports up to four concurrent connection
(incoming or outgoing or a combination).
***************************************************/
#include <SPI.h> //the ethernet shild uses SPI to communicate
#include <Ethernet.h> //the ethernet library
EthernetServer server(23); //start new server object, Telnet port is 23
/**************************************************
16x2 LCD Display Libraries
Since the display uses I2C, the display's unique I2C address must be used.
For information on how to determine (via a sketch) any devices' I2C address:
http://todbot.com/blog/2009/11/29/i2cscanner-pde-arduino-as-i2c-bus-scanner/
The NewLiquidCrystal.h Library needed for the 16x2 display using I2C is on
BitBucket at:
https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
To use the I2C sublibraries, replace "include LiquidCrystal.h", with
"include LiquidCrystal_I2C.h" and "include LCD.h". Also call
"include Wire.h" for I2C functions.
Common display I2C addresses: Probably 0x27 or 0x3F Use an I2C scanning program
to find the device's address and be sure.
Constructor with backlight control:
(lcd_Addr, Enable, ReadWrite, ReSet, d4, d5, d6, d7, backlightPin, backlighPolarity)
The 8 pins from PCF8574T serial board connect to the LCD display as follows:
LCD======>>>pcf8574T CHIP (use these pins in the constructor definitions)
RS(pin4) pin 0
RW(pin5) pin 1
EN(pin6) pin 2
V0-BL(pin3) pin 3
D4(pin11) pin 4
D5(pin12) pin 5
D6(pin13) pin 6
D7(pin14) pin 7
************************************************ */
#include <Wire.h> //native I2C library
#include <LCD.h> //sub library of LiquidCrystal library
#include <LiquidCrystal_I2C.h> //sub library of LiquidCrystal library
#define I2C_ADDR 0x3F //16x2 I2C address, found using I2C Scanner sketch
#define BackLt_pin 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
//start a new lcd class
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,BackLt_pin,POSITIVE);
/**************************************************
DHT Temperature-Humidity Sensor Library
Uses library DHT.h, must define DHT sensor type, DHT11, DHT21, DHT22.
Call the library using DHT dht(pin_used,dht_sensor_type).
The DHT sensor needs a 6.6k ohm pullup resistor, connect it between the
5v power and the signal line. The Arduino has internal pull-ups
which could be used, but their exact value in unknown and is low in any case.
So use a known 6.6k ohm external pull up resistor instead. A 100nF
capacitor may be added between Vcc and Ground for "wave filtering". (not used)
Using high quality shielded wire the signal wire may be up to 20 m (~65 ft)!
Only one digital pin is needed to connect the capacitive type DHT22 to the
Arduino. A burst of digital pulses whose width determines 1 or 0 is converted
by the software library into a temperature reading. The digital pulse encodes
a 40 bit signal in one burst. Sort of like high speed Morse code :-). Cool.
A bare DHT sensor has 4 pins. Looking at the latticed front of the sensor
(the mounting hole is through the back), the 4 pins from left to right are:
1 = 3.3 to 6vdc (use 5vdc)
2 = output digital signal (to Arduino digital pin)
3 = not used
4 = Ground
***************************************************/
#include "DHT.h" //dht library
#define DHTPIN 7 //digital pin DHT sensor uses
#define DHTTYPE DHT11 //dht model (type) of sensor
DHT dht(DHTPIN, DHTTYPE); //start a new dht class
/**************************************************/
/**************************************************
SD Library
The SD library allows for reading from and writing to SD cards.
The library supports FAT16 and FAT32 file systems on standard
SD cards and SDHC cards. It uses short 8.3 names for files.
The file names passed to the SD library functions can include
paths separated by forward-slashes, /, e.g. "directory/filename.txt".
Because the working directory is always the root of the SD card,
a name refers to the same file whether or not it includes a leading
slash (e.g. "/file.txt" is equivalent to "file.txt").
***************************************************/
// #include <SD.h> //SD is not used in this sketch
/**************************************************
Summary of Arduino Uno Analog Pins Used:
A0 = LDR (light dependent resistor) signal
A1 =
A2 =
A3 =
A4 = I2C SDA (serial data) for 16x2 Display
A5 = I2C SCL (serial clock) for 16x2 Display
***************************************************/
/**************************************************
Summary of Arduino Uno Digital Pins Used:
00 =
01 =
02 = Optional Interrupt for W5100 (set with jumper)-not used
03 = LED 5vdc supply (on or off)
04 = SPI SS (slave select) for SD card - hardwired in ethernet shield
05 =
06 =
07 = DHT11 Temperature-Humidity Sensor
08 =
09 =
10 = SPI SS (slave select) for W5100 - hardwired in ethernet shield
11 = SPI MOSI (master out slave in) for ethernet and SD card
12 = SPI MISO (master in slave out) for ethernet and SD card
13 = SPI SCK (serial clock)
***************************************************/
// Store a MAC address and IP address for the Ethernet Shield.
// The MAC address is, in this case, made up.
// The IP address is on the local network and is normally issued by the router via DHCP.
// The gateway and subnet are optional.
// The subnet used, 255.255.255.0, is for a Class C subnet which is the "small"
// class used for most residential networks, IP's = 192.0.0.0 to 223.0.0.0
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,110);
IPAddress myDNS(192,168,1, 1);
IPAddress gateway(192,168,1, 1);
IPAddress subnet(255, 255, 255, 0);
// Initialize Variables
boolean alreadyConnected = false; //client connected previously flag
String commandString; //variable to hold the user typed Telnet command
#define orangeLED 3 // assign digital pin to an LED, #define only uses 1 byte
void setup()
{//****start setup function****
//Call "Begin" Functions At The Beginning of Setup
Serial.begin(9600); // Open serial communications at 9600b baud
lcd.begin(16, 2); //start LCD with 16 colums 2 rows
dht.begin(); //start dht function for measuring temp/hum.
Ethernet.begin(mac, ip, myDNS, gateway, subnet); // start ethernet without using DHCP
//setup LEDs
pinMode(orangeLED, OUTPUT); //declare LED pins as output.
digitalWrite(orangeLED, LOW); //start with orange LED off
// start listening for clients
//Note: by enclosing Serial.print("strings") in the "F() Macro"
//that is, Serial.print(F("strings")) the string is stored in
//Flash Ram instead of the scarce SRAM -- who knew?
// print to the serial monitor
Serial.print(F("Assigned gateway address: "));
Serial.println(gateway);
Serial.print(F("Assigned DNS server address: "));
Serial.println(myDNS);
Serial.print("Assigned Class C subnet address: ");
Serial.println(subnet);
Serial.print(F("Assigned IP Address: "));
Serial.println(ip);
Serial.print(F("Actual Chat server address from Ethernet.localIP(): "));
Serial.println(Ethernet.localIP());
Serial.print(F("LDR sensor reading: "));
Serial.println(analogRead(A0));
//print to the 16x2 LCD
// Switch on the backlight
lcd.setBacklightPin(BackLt_pin,POSITIVE);
lcd.setBacklight(HIGH); //turns backlight on, use LOW for off
lcd.clear();
lcd.home(); // go home
lcd.print("IP Address");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(Ethernet.localIP());
delay(3000);
}//****endof setup function****
void loop()
{//****start infinite loop****
/*********************************************************/
// Ethernet Connection
/*********************************************************/
// wait for a new client:
EthernetClient client = server.available();
// when the client sends the first byte, say hello:
if (client)
{
if (!alreadyConnected)
{
// clear out the input buffer:
client.flush();
commandString = ""; //clear the commandString variable
server.println("--> Please type your command and hit Return...");
alreadyConnected = true;
}
while (client.available())
{
// read the bytes incoming from the client:
char newChar = client.read();
if (newChar == 0x0D) //If a 0x0D is received, a Carriage Return, then evaluate the command
{
server.print("Received this command: ");
server.println(commandString);
processCommand(commandString);
}
else
{
Serial.println(newChar);
commandString += newChar;
}
}
}
/*********************************************************/
// DHT22 Temperature and Humidy Data
/*********************************************************/
// Wait between measurements.
delay(1000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (sensor is slow)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
/*********************************************************/
// LDR - Light Dependent Resistor DatA
/*********************************************************/
float ldr = analogRead(A0); //1023 = sun, 0 dark
//print data to the serial monitor
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F(" %\t"));
Serial.print(F("Temperature: "));
Serial.print(t);
Serial.print(F(" *C "));
Serial.print(f);
Serial.println(F(" *F\t"));
Serial.print(F("LDR 1023 = sun, 0 = Dark: "));
Serial.println(ldr);
//print data to the 16x2 LCD
// Switch on the backlight
lcd.setBacklightPin(BackLt_pin,POSITIVE);
lcd.setBacklight(HIGH); //turns backlight on, use LOW for off
lcd.clear();
lcd.home(); // go home
lcd.print(F("Temp-Deg. F"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(f,1);
delay(2000);
lcd.clear();
lcd.home(); // go home
lcd.print(F("Rel. Humidity-%"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(h,1);
delay(2000);
lcd.clear();
lcd.home(); // go home
lcd.print(F("LDR-1023max sun"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(ldr);
delay(2000);
}//****endof infinite loop****
/********************************************************************
// start of subroutines i.e. supporting functions
*******************************************************************/
//option: use Telnet command to display serial data on LCD, e.g. LDR, DHT22
//ref.: https://www.arduino.cc/en/Tutorial/LiquidCrystalSerialDisplay
void processCommand(String command)
{//****start processCommand function****
server.print(F("Processing command "));
server.println(command);
if (command.indexOf("ldr") > -1){
Serial.println(F("Photo command received"));
server.print(F("Reading from photoresistor: " ));
server.println(analogRead(A0)); //Print the integer returned by analogRead to the server object
commandString = "";
return;
}
if (command.indexOf("ledon") > -1){
server.println(F("LED On command received"));
digitalWrite(orangeLED, HIGH); // sets the LED on
server.println(F("LED was turned on"));
commandString = "";
return;
}
if (command.indexOf("ledoff") > -1){
Serial.println(F("LED Off command received"));
digitalWrite(orangeLED, LOW); // sets the LED off
server.println(F("LED was turned off"));
commandString = "";
return;
}
if (command.indexOf("tempc") > -1){
Serial.println(F("tempc command received"));
server.print(F("Temperature - Deg. C: " ));
server.println(dht.readTemperature()); //Print the temp.
commandString = "";
//print data to the 16x2 LCD
// Switch on the backlight
lcd.setBacklightPin(BackLt_pin,POSITIVE);
lcd.setBacklight(HIGH); //turns backlight on, use LOW for off
lcd.clear();
lcd.home(); // go home
lcd.print(F("Temp-Deg. C"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(dht.readTemperature(),1);
delay(10000);
return;
}
if (command.indexOf("tempf") > -1){
Serial.println(F("tempc command received"));
server.print(F("Temperature - Deg. F: " ));
server.println(1.8*dht.readTemperature()+32); //Print the temp.
commandString = "";
//print data to the 16x2 LCD
// Switch on the backlight
lcd.setBacklightPin(BackLt_pin,POSITIVE);
lcd.setBacklight(HIGH); //turns backlight on, use LOW for off
lcd.clear();
lcd.home(); // go home
lcd.print(F("Temp-Deg. F"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(1.8*dht.readTemperature()+32,1);
delay(10000);
return;
}
if (command.indexOf("rh") > -1){
Serial.println(F("rh command received"));
server.print(F("Rel. Humidity - %: " ));
server.println(dht.readHumidity()); //Print the rel. humidity.
commandString = "";
//print data to the 16x2 LCD
// Switch on the backlight
lcd.setBacklightPin(BackLt_pin,POSITIVE);
lcd.setBacklight(HIGH); //turns backlight on, use LOW for off
lcd.clear();
lcd.home(); // go home
lcd.print(F("Rel. Humidity-%"));
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(dht.readHumidity(),1);
delay(10000);
return;
}
commandString = "";
instructions();
}//****endof processCommand function****
/********************************************************************/
void instructions()
{//****start instructions function****
server.println(F("I don't understand"));
server.println(F("Please use one of these commands:"));
server.println(F("* ldr, to get a reading from the light dependent resistor"));
server.println(F("* ledon, to turn on the LED"));
server.println(F("* ledoff, to turn off the LED"));
server.println(F("* tempc, to read temperature, deg. C"));
server.println(F("* tempf, to read temperature, deg. F"));
server.println(F("* rh, to read rel. humidity, %"));
}//****endof instructions function****
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment