It is quite common to want your Arduino to keep actual time allowing you to timestamp data in a way that humans can understand. These dates and times can easily be interpreted by tools like Microsoft Excel and Matlab where they can be used for more in-depth analysis.
This example shows how you can use MegunoLinks MessageLibrary and MLPUIMessageProcessor controls inside an interface panel to detect and respond to a time sync message sent by the Arduino.
Time is kept using a library written by Michael Margolis and Paul Stoffregen. This time library can be downloaded from here. Install the library as you would any other Arduino library. As well as the time library we are also using our CommandHandler and ArduinoTimer libraries for receiving the time and triggering the synchronization.
The MegunoLink Interface
The first step is to configure MegunoLink (or download my example interface to set the Arduino time). Once you have MegunoLink open create a basic project with connection manager, monitor, and interface panel. The interface panel handles the command processing and time synchronizing.
Go into the interface panel designer by clicking the designer button (circled in red). The image below shows the designer. From the Toolbox on the left add a MessageLibrary and then a MLPUIMessageProcessor. The order is important so make sure the MessageLibrary is added first.
MLPUIMessageProcessor responds to serial commands it receives and the MessageLibrary object provides a way to design responses which can be executed whenever the target command is received.
In this example, we will stick with the default names and we will not specify a channel for the MLPUIMessageProcessor.
Now we need to add the command to the MessageLibrary1 object. To do that click on MessageLibrary1 and in the properties box click on the Messages property.
The Messages property box will appear. Here you enter the name of the message, this name is what the Arduino will use in its serial message to trigger the command. In this case, I called it “TimeMessage”. Then simply add the command you want to execute, the result of which will be sent back over the serial channel. In this example I want to send the time in seconds since the 1/1/1970 (Unix time).
1 |
!SetTime [Math.Round(DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0)).TotalSeconds)]\r\n |
Close the message library once your message has been added.
Now we need to connect the MessageLibrary1 object to the MLPUIMessageProcessor1 object. Click on MLPUIMessageProcessor1 and in the properties section, you will see a library option. Click on that and select MessageLibrary1.
Once that connection is made you can click apply (top left) in the designer so that the interface is transferred to MegunoLink. Now you can close the designer and its a good idea save your MegunoLink project.
Now whenever the Arduino sends this {UI|CMD|TimeMessage} over the serial connection the MLPUIMessageProcessor1 object will trigger and respond to the Arduino with the Unix time. The Arduino program will process this message and synchronise its clock to that time.
The Arduino Program
The below code block shows the Arduino program. The program is fairly simple, your Arduino should attempt to sync its time every 10 seconds and it will print the time to the monitor every second.
Program your Arduino with this and then connect it to MegunoLink using the connection manager.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/* * Example showing how to sync Michael Margolis' time keeping library using MegunoLink. * * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970) */ /* * Example showing how to sync Michael Margolis' time keeping library using MegunoLink. * * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970) */ #include "TimeLib.h" #include "CommandHandler.h" #include "ArduinoTimer.h" CommandHandler<> SerialCommandHandler; ArduinoTimer SyncTimeTimer; ArduinoTimer PrintTimeTimer; void Cmd_SetTime(CommandParameter &Parameters) { unsigned long ReceivedTime = Parameters.NextParameterAsUnsignedLong(); setTime(ReceivedTime); Serial.print("Time Synced:"); DigitalClockDisplay(); } void setup() { Serial.begin(9600); while (!Serial); // Needed for Leonardo only SerialCommandHandler.AddCommand(F("SetTime"), Cmd_SetTime); RequestSync(); Serial.println("Setup Complete"); } void loop() { SerialCommandHandler.Process(); if (PrintTimeTimer.TimePassed_Milliseconds(1000)) { DigitalClockDisplay(); } if (SyncTimeTimer.TimePassed_Seconds(10)) { RequestSync(); } } 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 RequestSync() { Serial.println("{UI|CMD|TimeMessage}"); } |
What you should see in MegunoLink
Once your Arduino is programmed connect it to MegunoLink and look at the monitor to see what messages are going back and forth. The screenshot below shows an example of what should occur. At startup and every 10 seconds, the Arduino sends MegunoLink a request for the time ({UI|CMD|TimeMessage}). This message is processed and the time sync message is sent back to the Arduino (!SetTime 1491919844\r\n). The Arduino used this message to sync up its clock and then it prints the time every second which you can also see in the monitor window.
Summary
This example demonstrates that MegunoLink can be used as a time synchronization service when coupled with a time-keeping library and our command handling and timer libraries.
Being able to provide your own timestamp is useful when wanting to log and plot data with your own timestamps rather than relying on MegunoLinks internal timestamping.
If you enjoyed this article give us a like on Facebook.
And don’t forget to subscribe if you’d like to hear about more snazzy Arduino projects.
Is it possible to set the time by Meguno and by Xbee for a RTC_DS1307 shield on an arduino uno ?
Don’t see why not. The same approach should work.