Last active
October 2, 2019 17:39
-
-
Save DerekErb/4525631 to your computer and use it in GitHub Desktop.
Arduino - Ethernet Shield
Connect the Ethernet shield to the network, and Internet, with a fixed IP address
Get the current date & time from an NTP server and apply time zone adjustment
Create some files on the SD card with default and fixed datetime stamps
Create a file on the SD card, write some lines to it, set the datetime stamps on the file…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Ethernet Shield * | |
Fixed IP Address | |
Get Time from NTP with TZ adjustment | |
SD Card create CSV file | |
Set file date & time | |
Read remaining free space on SD card | |
Ethernet functions | |
Based on Ethernet shield code | |
created 18 Dec 2009 | |
modified 9 Apr 2012 | |
by David A. Mellis | |
SD functions | |
Based on Example Code | |
from Timstamp sketch in SdFat library | |
Current Code | |
Created by Derek Erb 13/01/2013 | |
Last Modified : 13/01/13 | |
by Derek Erb | |
Requirement : Arduino w/ Ethernet Shield and a FAT formatted SD card installed | |
*/ | |
#include <SPI.h> | |
#include <Ethernet.h> | |
#include <EthernetUdp.h> | |
#include <Time.h> | |
#include <SdFat.h> | |
// Version number | |
const float fVerNum = 0.1; | |
// Local port to listen for UDP packets | |
unsigned int uiLocalPort = 8888; | |
// Time Server fixed IP address (nist1-ny.ustiming.org) | |
IPAddress ipTimeServer(64, 90, 182, 55); | |
// NTP time stamp from first 48 bytes of the message | |
const int iNTP_PACKET_SIZE = 48; | |
// Buffer to hold incoming / outgoing packets | |
byte byPacketBuffer[ iNTP_PACKET_SIZE]; | |
// Time Zone (Difference from GMT in seconds) | |
const long lTZ = 3600; | |
// UPD instance | |
EthernetUDP Udp; | |
// Arduino Ethernet Shield = pin 4 | |
const int iSDPin = 4; | |
// Global card and file variables | |
SdFat sd; | |
SdFile file; | |
char strFname[] = "WRITETST.CSV"; // File name | |
int i = 1; // Global counter | |
// Global time variable | |
time_t t; | |
//////////////////////////////////////////////////////// | |
// | |
// sendNTPpacket | |
// | |
// Send an NTP request to the NTP time server at the IP address | |
// | |
// | |
unsigned long sendNTPpacket(IPAddress& address) { | |
// set all bytes in the buffer to 0 | |
memset(byPacketBuffer, 0, iNTP_PACKET_SIZE); | |
// Initialize values needed to form NTP request | |
// (see URL above for details on the packets) | |
byPacketBuffer[0] = 0b11100011; // LI, Version, Mode | |
byPacketBuffer[1] = 0; // Stratum, or type of clock | |
byPacketBuffer[2] = 6; // Polling Interval | |
byPacketBuffer[3] = 0xEC; // Peer Clock Precision | |
// 8 bytes of zero for Root Delay & Root Dispersion | |
byPacketBuffer[12] = 49; | |
byPacketBuffer[13] = 0x4E; | |
byPacketBuffer[14] = 49; | |
byPacketBuffer[15] = 52; | |
// all NTP fields have been given values, now | |
// you can send a packet requesting a timestamp: | |
Udp.beginPacket(address, 123); //NTP requests are to port 123 | |
Udp.write(byPacketBuffer, iNTP_PACKET_SIZE); | |
Udp.endPacket(); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// PrintIP | |
// | |
// Serial Print IP address | |
// | |
void PrintIP(byte byArr[]) { | |
Serial.print(byArr[0]); | |
Serial.print(F(".")); | |
Serial.print(byArr[1]); | |
Serial.print(F(".")); | |
Serial.print(byArr[2]); | |
Serial.print(F(".")); | |
Serial.print(byArr[3]); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// PrintTime | |
// | |
// Serial Print time (HH:MM:SS - Day, DD/MM/YYYY | |
// | |
void PrintTime(time_t t) { | |
char* strDays[] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; | |
lzPrint(hour(t)); | |
Serial.print(F(":")); | |
lzPrint(minute(t)); | |
Serial.print(F(":")); | |
lzPrint(second(t)); | |
Serial.print(F(" - ")); | |
Serial.print(strDays[weekday(t)]); | |
Serial.print(F(", ")); | |
lzPrint(day(t)); | |
Serial.print(F("/")); | |
lzPrint(month(t)); | |
Serial.print(F("/")); | |
lzPrint(year(t)); | |
Serial.println(); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// lzPrint | |
// | |
// Serial Print iVal with a leading zero | |
// | |
void lzPrint(int iVal) { | |
if (iVal < 10) | |
Serial.print('0'); | |
Serial.print(iVal); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// PrintTimestamps | |
// | |
// Serial print all of file's datetime stamps | |
// | |
void PrintTimestamps(SdFile& f) { | |
dir_t d; | |
if (!f.dirEntry(&d)) | |
Serial.println(F("ERROR : f.dirEntry failed")); | |
Serial.print(F("Created :\t")); | |
f.printFatDate(d.creationDate); | |
Serial.print(F(" ")); | |
f.printFatTime(d.creationTime); | |
Serial.println(F("\t(yyyy-mm-dd hh:mm:ss)")); | |
Serial.print(F("Modified :\t")); | |
f.printFatDate(d.lastWriteDate); | |
Serial.print(F(" ")); | |
f.printFatTime(d.lastWriteTime); | |
Serial.println(F("\t(yyyy-mm-dd hh:mm:ss)")); | |
Serial.print(F("Accessed :\t")); | |
f.printFatDate(d.lastAccessDate); | |
Serial.println(F("\t\t(yyyy-mm-dd)")); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// ShowFreeSpace | |
// | |
// Serial print space available on SD card | |
// | |
void ShowFreeSpace() { | |
// Calculate free space (volume free clusters * blocks per clusters / 2) | |
long lFreeKB = sd.vol()->freeClusterCount(); | |
lFreeKB *= sd.vol()->blocksPerCluster()/2; | |
// Display free space | |
Serial.print(F("Free space: ")); | |
Serial.print(lFreeKB); | |
Serial.println(F(" KB")); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// GetSetTime | |
// | |
// Get the time via NTP, adjust for Time Zone and set time variable | |
// | |
void GetSetTime() { | |
// Set an NTP packet to the NTP time server | |
Serial.println(F("\nSending NTP Packet...")); | |
sendNTPpacket(ipTimeServer); | |
// wait to see if a reply is available | |
Serial.println(F("\nWaiting for reply...")); | |
delay(1000); | |
if (Udp.parsePacket()) { | |
// We've received a packet, read the data from it | |
Serial.println(F("Reading received packed...")); | |
Udp.read(byPacketBuffer, iNTP_PACKET_SIZE); | |
//the timestamp starts at byte 40 of the received packet and is four bytes, | |
// or two words, long. First, esxtract the two words: | |
unsigned long highWord = word(byPacketBuffer[40], byPacketBuffer[41]); | |
unsigned long lowWord = word(byPacketBuffer[42], byPacketBuffer[43]); | |
// combine the four bytes (two words) into a long integer | |
// this is NTP time (seconds since Jan 1 1900): | |
unsigned long secsSince1900 = highWord << 16 | lowWord; | |
Serial.print(F("Seconds since Jan 1, 1900 = ")); | |
Serial.println(secsSince1900); | |
// now convert NTP time into everyday time: | |
Serial.print(F("Unix time = ")); | |
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800: | |
const unsigned long seventyYears = 2208988800UL; | |
// subtract seventy years: | |
unsigned long epoch = secsSince1900 - seventyYears; | |
// print Unix time: | |
Serial.println(epoch); | |
Serial.println(F("Setting time var to UNIX time...")); | |
t = epoch; | |
Serial.print(F("The current UTC time is ")); | |
PrintTime(t); | |
Serial.println(F("Adjusting for local time zone...")); | |
t = epoch + lTZ; | |
Serial.print(F("The current local time is ")); | |
PrintTime(t); | |
} | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// SETUP | |
// | |
void setup(void) { | |
// Ethernet Shield MAC | |
byte byMAC[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xA3, 0x39 }; | |
// Fixed IP address config | |
byte byDNS[] = { 8, 8, 8, 8 }; | |
byte byGateway[] = { 192, 168, 0, 1 }; | |
byte bySubnet[] = { 255, 255, 255, 0 }; | |
// Ethernet Shield Fixed IP address | |
IPAddress ipA(192,168,0,51); | |
// Setup serial monitor | |
Serial.begin(9600); | |
// Wait 3 seconds | |
delay(3000); | |
// Some declaring text | |
Serial.println(F("\nArduino Ethernet Shield")); | |
Serial.println(F("Fixed IP & NTP & Time Zone &")); | |
Serial.println(F("SD Card File & date-time stamp &")); | |
Serial.println(F("File Size & Free Space")); | |
Serial.print(F("Version : ")); | |
Serial.println(fVerNum); | |
Serial.println(F("Arduino - Derek Erb\n")); | |
// Initialise Ethernet network connection | |
Ethernet.begin(byMAC, ipA, byDNS, byGateway, bySubnet); | |
// give the Ethernet shield a second to initialise : | |
delay(1000); | |
Serial.println(F("Connecting to Ethernet network and Internet...\n")); | |
// Local IP address | |
Serial.println(F("Local IP info : ")); | |
Serial.print(F("IP address : ")); | |
Serial.print(Ethernet.localIP()); | |
Serial.print(F("\nSubnet : ")); | |
PrintIP(bySubnet); | |
Serial.print(F("\nGateway : ")); | |
PrintIP(byGateway); | |
Serial.print(F("\nDNS : ")); | |
PrintIP(byDNS); | |
Serial.print(F("\n")); | |
// Initialise UDP connection | |
Serial.println(F("\nInitialising UDP connection...")); | |
Udp.begin(uiLocalPort); | |
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | |
// breadboards. use SPI_FULL_SPEED for better performance. | |
if (!sd.begin(iSDPin, SPI_HALF_SPEED)) | |
sd.initErrorHalt(); | |
// remove files if they exist | |
sd.remove("DEFAULT.TXT"); | |
sd.remove("STAMP.TXT"); | |
sd.remove(strFname); | |
// create a new file with default datetimestamps | |
if (!file.open("DEFAULT.TXT", O_CREAT | O_WRITE)) { | |
Serial.println(F("ERROR : open DEFAULT.TXT failed.")); | |
} | |
Serial.println(F("DEFAULT.TXT created with default date/time stamps:")); | |
PrintTimestamps(file); | |
// close file | |
file.close(); | |
Serial.print(F("\n")); | |
// create a new file with set datetimestamps | |
if (!file.open("STAMP.TXT", O_CREAT | O_WRITE)) { | |
Serial.println(F("ERROR : open STAMP.TXT failed")); | |
} | |
Serial.println(F("STAMP.TXT created with default date/time stamps:")); | |
PrintTimestamps(file); | |
// set creation date time 2012-01-01 22:27:00 | |
if (!file.timestamp(T_CREATE, 2012, 1, 1, 22, 27, 00)) { | |
Serial.println(F("ERROR : set create time failed")); | |
} | |
// set write/modification date time 2012-12-31 04:42:24 | |
if (!file.timestamp(T_WRITE, 2012, 12, 31, 4, 42, 24)) { | |
Serial.println(F("ERROR : set write time failed")); | |
} | |
// set access date 2013-01-08 16:49:49 | |
if (!file.timestamp(T_ACCESS, 2013, 1, 8, 16, 49, 49)) { | |
Serial.println(F("ERRROR : set access time failed")); | |
} | |
Serial.println(F("STAMP.TXT modified with set date/time stamps:")); | |
PrintTimestamps(file); | |
file.close(); | |
// Get and set time | |
GetSetTime(); | |
// create a new file with current datetimestamps | |
if (!file.open(strFname, O_CREAT | O_WRITE)) { | |
Serial.print(F("ERROR : open ")); | |
Serial.print(strFname); | |
Serial.print(F(" failed")); | |
} | |
Serial.print(F("\n")); | |
Serial.print(strFname); | |
Serial.println(F(" created with current date/time stamps:")); | |
PrintTimestamps(file); | |
// set creation date time to now | |
if (!file.timestamp(T_CREATE, year(t), month(t), day(t), hour(t), minute(t), second(t))) { | |
Serial.println(F("ERROR : set create time failed")); | |
} | |
// set write/modification date time to now | |
if (!file.timestamp(T_WRITE, year(t), month(t), day(t), hour(t), minute(t), second(t))) { | |
Serial.println(F("ERROR : set write time failed")); | |
} | |
// set access date to now | |
if (!file.timestamp(T_ACCESS, year(t), month(t), day(t), hour(t), minute(t), second(t))) { | |
Serial.println(F("ERRROR : set access time failed")); | |
} | |
Serial.print(strFname); | |
Serial.println(F(" created with current date/time stamps:")); | |
PrintTimestamps(file); | |
file.close(); | |
Serial.println(F("\nSetup() Done.")); | |
} | |
//////////////////////////////////////////////////////// | |
// | |
// LOOP | |
// | |
void loop(void){ | |
Serial.println(F("\nReading free space...")); | |
ShowFreeSpace(); | |
// Open file for writing (appending) | |
if (!file.open(strFname, O_CREAT | O_WRITE | O_AT_END)) { | |
Serial.print(F("ERROR : open ")); | |
Serial.print(strFname); | |
Serial.print(F(" failed")); | |
} | |
// Write to file | |
Serial.print(F("\nWriting to the file...\tIteration : ")); | |
Serial.println(i); | |
for (int j = 0; j < 10; j++) { | |
file.print("\"FILE WRITE TEST\",1234"); | |
file.print(j + ((i-1)*10)); | |
file.println(",\"LINE WRITTEN\",\"ARDUINO FILE TIMESTAMP TESTING\""); | |
} | |
i++; | |
// set write/modification date time to now | |
if (!file.timestamp(T_WRITE, year(t), month(t), day(t), hour(t), minute(t), second(t))) { | |
Serial.println(F("ERROR : set write time failed")); | |
} | |
// set access date time to now | |
if (!file.timestamp(T_ACCESS, year(t), month(t), day(t), hour(t), minute(t), second(t))) { | |
Serial.println(F("ERRROR : set access time failed")); | |
} | |
Serial.print(strFname); | |
Serial.println(F(" modified with current date/time stamps:")); | |
PrintTimestamps(file); | |
file.close(); | |
Serial.print(F("Current File Size :\t")); | |
Serial.print(file.fileSize()); | |
Serial.println(F(" b")); | |
// Wait 30 seconds | |
Serial.println(F("Waiting 30 seconds...")); | |
delay(30000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment