Go Down

Topic: [SOLVED]Setting Yun's Date/Time (Read 13131 times) previous topic - next topic

theDuke540

Mar 13, 2014, 03:55 am Last Edit: Mar 20, 2014, 09:27 pm by theDuke540 Reason: 1
I have looked high and low for any information on how to properly set the Linino Date/Time. So far, I've tried:
Code: [Select]
date +%F -s "20140312"
(returns=2016-08-14)
Code: [Select]
date +%D -s "03122014"
(returns=03/12/16)
and even  
Code: [Select]
date +%Y -s "2014"
(returns=2016). Can someone please tell me exactly what I'm doing wrong?

Edit:
I'm trying to figure out how to do this so that I can run a Process to update system time from gps every 5 minutes or so. If there is a easier way, please let me know! Also, I can't use NTP time. This yun will be outdoors far away from networks...

sonnyyu

#1
Mar 13, 2014, 07:13 am Last Edit: Mar 13, 2014, 07:15 am by sonnyyu Reason: 1
Stop and disable NTP server:

Code: [Select]
/etc/init.d/sysntpd stop
/etc/init.d/sysntpd disable


Change Yun back to UTC time zone.

Read UTC time from GPS:

Code: [Select]
$GPRMC,020545.600,A,3157.8299,N,03551.5057,E,18.18,37.45,130314,,,A*6C

020545.600:  hhmmss.sss
130314:     ddmmyy

Set date and time:
Code: [Select]
date --set "2014-03-13 02:05:45"


theDuke540

Thanks for the reply! I was successful in stopping, disabling and initially setting the time. My question now is, what is the best way to parse NMEA sentences and set linux time with that? I prefer TinyGPS so I was thinking of maybe declaring a variable for hour:minute:second and another for mm:dd:Y and then calling a process to set the date using those variables. Would this be a viable solution? Thanks again.

Chagrin

The TinyGPS examples include a print_date() function that outputs a string in a format that would work fine with the linux date command.

I don't see any other shortcuts you could do. The date command will take a wide variety of formats but chokes on ambiguous strings of numbers so some reformatting will always be necessary.

sonnyyu

#4
Mar 13, 2014, 03:39 pm Last Edit: Mar 13, 2014, 03:51 pm by sonnyyu Reason: 1
http://forum.arduino.cc/index.php?topic=208117.msg1532061#msg1532061

I prefer hook up GPS directly to linino side(no GPS shield), once it is at linux parse data is a piece of cake.
We could use Arduino to switch on/off GPS power supply for energy saver.

Biggest problem Yun did not break out any GPIO pin (total of 29).  We can't directly connect GPS module to AR9331.

theDuke540

#5
Mar 13, 2014, 05:40 pm Last Edit: Mar 13, 2014, 05:44 pm by theDuke540 Reason: 1
So i tried modifying the "simple_test" sketch from TinyGPS examples. Here is the code:
Code: [Select]
#include <SoftwareSerial.h>
#include <Bridge.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
  It requires the use of SoftwareSerial, and assumes that you have a
  4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(9, 8);

void setup()
{
 Serial.begin(115200);
 ss.begin(9600);
 Bridge.begin();
 
 Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
 Serial.println("by Mikal Hart");
 Serial.println();
}

void loop()
{
 bool newData = false;
 unsigned long chars;
 unsigned short sentences, failed;

 // For one second we parse GPS data and report some key values
 for (unsigned long start = millis(); millis() - start < 1000;)
 {
   while (ss.available())
   {
     char c = ss.read();
     // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
     if (gps.encode(c)) // Did a new valid sentence come in?
       newData = true;
   }
 }

 if (newData)
 {
   float flat, flon;
   unsigned long age;
   gps.f_get_position(&flat, &flon, &age);
   Serial.print("LAT=");
   Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
   Serial.print(" LON=");
   Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
   Serial.print(" SAT=");
   Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
   Serial.print(" PREC=");
   Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
   Serial.print(" ");
   int year;
   byte month, day, hour, minute, second, hundredths;
   gps.crack_datetime(&year, &month, &day, &hour, &minute, &second);
//    Serial.print(" ");
//    Serial.print(month, DEC); Serial.print("/");
//    Serial.print(day, DEC); Serial.print("/"); Serial.print(year);
//    Serial.print(" ");
//    Serial.print(hour, DEC); Serial.print(":");
//    Serial.print(minute, DEC); Serial.print(":"); Serial.println(second, DEC);
   SetTime();
 }
 
//  gps.stats(&chars, &sentences, &failed);
//  Serial.print(" CHARS=");
//  Serial.print(chars);
//  Serial.print(" SENTENCES=");
//  Serial.print(sentences);
//  Serial.print(" CSUM ERR=");
//  Serial.println(failed);
//  if (chars == 0)
//    Serial.println("** No characters received from GPS: check wiring **");
}
void SetTime()
{
 int year;
 byte month, day, hour, minute, second, hundredths;
 gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
 char sz[32];
 sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d  ",
 month, day, year, hour, minute, second);
 Serial.println(sz);
 Process Set;
 Set.begin("date --set");
 Set.addParameter("year-month-day hour:minute:second");
 Set.run();  
}

No luck though. This is seriously frustrating. When I SSH into the Linino side, the "date" command returns a date from like Aug 2013. BTW, the modified part is in the function SetTime(). I'm still able to manually set the date though.

bjarne

I don't have a lot of experience with addParameter, but I think you are sending the string "year-month-day hour:minute:second" rather than the variables.  Have you tried
Set.addParameter(sz); instead?

Also I seem to have much more luck with runShellCommand rather than run.

theDuke540

I hadn't thought of that. I'll try it now.

Quote
Also I seem to have much more luck with runShellCommand rather than run.

Can you explain or show an example for me please?

bjarne

Here is a code snippet from my sketch
Code: [Select]

void sendSMS(String message) {
  Process smsSend;
  String command;
 
  command = "/mnt/sd/data/sms.py 1408XXXXXXX '" + message + "'";
  smsSend.runShellCommand(command);
}


Obviously, in my code 1408XXXXXXX is a real phone number (my cell phone).

theDuke540

Ok i tried the runShellCommand and no joy. Here is what i tried based off of bjarne's example:
Quote
#include <SoftwareSerial.h>
#include <Bridge.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(9, 8);

void setup()
{
  Serial.begin(115200);
  ss.begin(9600);
  Bridge.begin();
 
  Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
    Serial.print(" ");
    int year;
    byte month, day, hour, minute, second, hundredths;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second);
//    Serial.print(" ");
//    Serial.print(month, DEC); Serial.print("/");
//    Serial.print(day, DEC); Serial.print("/"); Serial.print(year);
//    Serial.print(" ");
//    Serial.print(hour, DEC); Serial.print(":");
//    Serial.print(minute, DEC); Serial.print(":"); Serial.println(second, DEC);
    SetTime();
  }
 
//  gps.stats(&chars, &sentences, &failed);
//  Serial.print(" CHARS=");
//  Serial.print(chars);
//  Serial.print(" SENTENCES=");
//  Serial.print(sentences);
//  Serial.print(" CSUM ERR=");
//  Serial.println(failed);
//  if (chars == 0)
//    Serial.println("** No characters received from GPS: check wiring **");
}
void SetTime()
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
  char sz[32];
  sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d  ",
  month, day, year, hour, minute, second);
  Serial.println(sz);
  [font=Verdana]Process Set;
  command = "date --set 'year-month-day hour:minute:second'";
  Set.runShellCommand(command);[/font]

}


I'm at my wits end with this one. If my time isn't able to be set, this project is over.

bjarne

Again I think you are send the string   'year-month-day hour:minute:second' instead of the values.
Maybe try
 command = "date --set '" + year  + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second + "'";
I know pretty long, but try.  And I am in a hurry so there might be typos.


theDuke540

OK thank you. I will try this and let everyone know the results.

theDuke540


Again I think you are send the string   'year-month-day hour:minute:second' instead of the values.
Maybe try
 command = "date --set '" + year  + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second + "'";
I know pretty long, but try.  And I am in a hurry so there might be typos.




OK i've tried this and here is the error I get:
Quote
simple_test.ino: In function 'void SetTime()':
simple_test:89: error: invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+'

Chagrin

I'm also quite poor with the String type myself; you'd assuredly get a better answer in the Programming forum as this isn't specifically Yun-related. But I think what you're after is:

Code: [Select]
void SetTime()
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
  char sz[32];
  sprintf(sz, "date --set '%02d/%02d/%02d %02d:%02d:%02d'", month, day, year, hour, minute, second);
  Serial.println(sz);
  Process Set;
  Set.runShellCommand(sz);
}

bjarne

You are right, I am getting the same when I try your code.  Not exactly sure why, but I created the command the long way, and at least it compiles.
Code: [Select]

   command = "date --set '";
   command += year;
   command += "-";
   command += month;
   command += "-";
   command += day;
   command += " ";
   command += hour;
   command += ":";
   command += minute;
   command += ":";
   command += second;
   command += "'";
   Set.runShellCommand(command);


If this works we can always figure out what was wrong with the first way and create a little more elegant syntax.

Go Up