Skip to content

Instantly share code, notes, and snippets.

@DerekErb
Last active October 2, 2019 17:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DerekErb/4525631 to your computer and use it in GitHub Desktop.
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…
/*
* 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