All I want for xmas is a time and date stamp in my sketch... My GOD HOW CAN THIS BE SO PAINFULLY DIFFICULT. No, I dont want a RTC or Ethernet shield (>$50 really???). I only want to get the time from the host (RPi2) over serial and print it in the serial monitor of the Arduino. From their I can customize my sketch to include this aspect.
This should be one of the most common and basic tasks for an Arduino yet it is painfully, stupidly difficult to do in practice. Im not the sharpest knife in the drawer (obviously) but I can get around pretty easily with most microcontrollers Ive played with over the years.
Ive got the latest Time library from Git but the docs are either incomplete (most always this way in this Arduino world) or it just doesnt work or its purposefully difficult.
I used terminal to send the message instead of SyncASrduinoClock.
date +T%s\n > /dev/ttyACM0
Here is the TimeSerial code I used.
/*
* TimeSerial.pde
* example code illustrating Time library set through serial port messages.
*
* Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
* you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013
T1357041600
*
* A Processing example sketch to automatically send the messages is inclided in the download
* On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone)
*/
#include <Time.h>
#define TIME_HEADER "T" // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message
void setup() {
Serial.begin(9600);
while (!Serial) ; // Needed for Leonardo only
pinMode(13, OUTPUT);
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
}
void loop(){
if (Serial.available()) {
processSyncMessage();
}
if (timeStatus()!= timeNotSet) {
digitalClockDisplay();
}
if (timeStatus() == timeSet) {
digitalWrite(13, HIGH); // LED on if synced
} else {
digitalWrite(13, LOW); // LED off if needs refresh
}
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void processSyncMessage() {
unsigned long pctime;
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
if(Serial.find(TIME_HEADER)) {
pctime = Serial.parseInt();
if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
setTime(pctime); // Sync Arduino clock to the time received on the serial port
}
}
}
time_t requestSync()
{
Serial.write(TIME_REQUEST);
return 0; // the time will be sent later in response to serial mesg
}
Here is the SyncArduinoClock code: It fails saying index is incorrect. I tried /dev/ttyACM0 and ACM0 instead of the 0 default but no luck). I use terminal to send the message instead but TimeSerial just stops at the "Waiting for sync message" and LED 13 shows off awaiting refresh.
/**
* SyncArduinoClock.
*
* portIndex must be set to the port connected to the Arduino
*
* The current time is sent in response to request message from Arduino
* or by clicking the display window
*
* The time message is 11 ASCII text characters; a header (the letter 'T')
* followed by the ten digit system time (unix time)
*/
import processing.serial.*;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public static final short portIndex = 0; // select the com port, 0 is the first port
public static final String TIME_HEADER = "T"; //header for arduino serial time message
public static final char TIME_REQUEST = 7; // ASCII bell character
public static final char LF = 10; // ASCII linefeed
public static final char CR = 13; // ASCII linefeed
Serial myPort; // Create object from Serial class
void setup() {
size(200, 200);
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this,Serial.list()[portIndex], 9600);
println(getTimeNow());
}
void draw()
{
textSize(20);
textAlign(CENTER);
fill(0);
text("Click to send\nTime Sync", 0, 75, 200, 175);
if ( myPort.available() > 0) { // If data is available,
char val = char(myPort.read()); // read it and store it in val
if(val == TIME_REQUEST){
long t = getTimeNow();
sendTimeMessage(TIME_HEADER, t);
}
else
{
if(val == LF)
; //igonore
else if(val == CR)
println();
else
print(val); // echo everying but time request
}
}
}
void mousePressed() {
sendTimeMessage( TIME_HEADER, getTimeNow());
}
void sendTimeMessage(String header, long time) {
String timeStr = String.valueOf(time);
myPort.write(header); // send header and time to arduino
myPort.write(timeStr);
myPort.write('\n');
}
long getTimeNow(){
// java time is in ms, we want secs
Date d = new Date();
Calendar cal = new GregorianCalendar();
long current = d.getTime()/1000;
long timezone = cal.get(cal.ZONE_OFFSET)/1000;
long daylight = cal.get(cal.DST_OFFSET)/1000;
return current + timezone + daylight;
}
Can anyone help me get a timedate stamp in a sketch.