Systemzeit mit Werten aus Konsole setzen

Wenn der konstante Zeitaufwand eliminiert ist, sollte es denke ich praktisch kein Problem sein einen Bereich von +/- 10ms zu treffen. Je nachdem wie kritisch deine Anwendung jedoch ist, solltest du dir bewusst sein, dass du in einem nicht echtzeitfähigem System keine Garantien zu irgendwelchen Ausführungszeiten bekommst. Du weißt eigentlich nur sicher, dass dein Programm irgendwann ausgeführt wird.
 
Jop! Und ich denke, das ein Computer, der NUR diese zwei kleinen Programme ausführt keine Probleme haben sollte nah an einem echtzeitfähigen System zu sein. Aber damit muss ich leben und hoffe, dass meine Anforderungen erfüllt werden. Mal sehen was die ersten Tests so sagen. Wie gesagt, mit +- 10 ms wäre ich schon sehr zufrieden.
 
Es gibt leider doch noch ein letztes Problem. Die Daten des GPS kommen mit 50 Hz, also recht schnell. Ich möchte die Systemzeit aber ungerne 50 mal die Sekunde setzen, was glaube ich auch nicht wirklich umsetzbar ist. Ich habe mit sleep() versucht die Zeit nur alle paar Sekunden zu setzen. Allerdings zerstört sleep in diesem Fall das Ergebnis. Die Sekundenstelle wird nur jede Minute um eine Sekunde nach oben gezählt...iwas stimmt da also nicht.
Hat jemand eine Idee woran es liegen könnte?
 
Du kannst das Event doch einfach ignorieren und nur ab und zu bearbeiten. Ungefähr so:

Code:
counter = (counter+1) % 50;
if (!counter) {
    //dein Code hier
}

Das wäre bei 50Hz dann einmal pro Sekunde.
 
Hi,

ich muss den Thread leider doch noch ein weiteres mal zum Leben erwecken. Und zwar hat sich ein weiterer Fehler bzw. eine Veränderung ergeben.
Ich habe mein Programm noch etwas umgebaut, um zu sehen inwiefern sich die Systemzeit nach einer Weile von der GPS-Zeit unterscheidet. Dazu hole ich mir die GPS-Zeit und setze diese als neue Systemzeit, wie zuvor auch schon. Allerdings wird die Ausgabe nun direkt in eine Textdatei umgeleitet, damit ich eine Art Log habe.
Nun zum Problem: Ich schreibe jede Sekunde einen Wert für GPS-Zeit und Systemzeit. Die GPS-Zeit wird korrekt geschrieben, die Systemzeit (die ja aus der GPS-Zeit resultiert), hingegen scheint nicht korrekt zu sein. Sie befindet sich zu weit von der GPS-Zeit entfernt. Sekundenanzahl stimmt, die Millisekunden jedoch nicht. Das Ergebnis sieht wie folgt aus:

Code:
GPS time:    1391394769.460000
System time: 1391394769.49682
GPS time:    1391394769.960000
System time: 1391394769.50171
GPS time:    1391394770.460000
System time: 1391394770.50575
GPS time:    1391394770.960000
System time: 1391394770.51074
GPS time:    1391394771.460000
System time: 1391394771.51574
GPS time:    1391394771.960000

Eigentlich sollte die Systemzeit ja sher nah hinter der GPS-Zeit liegen. Also wenn die GPS-Zeit auf .860000 endet, sollte die Systemzeit irgendwo bei .860000 - .870000 sein, das trifft allerdings nicht zu. Hier könnte ich mir vorstellen, das ich beim Schreiben der Systemzeit etwas falsch gemacht habe (Zeile 114-134). Kann aber nicht sagen was und ob ich mit meiner Vermutung richtig liege.

Ein weiteres Problem ist, das die Systemzeit "wandert". Normalerweise sollte sie ja immer um eine Sekunde nach hinten verschoben sein, also die gleichen Werte nach dem Punkt haben. Diesen Fehler könnte ich durch die Zeit erklären, die das Programm benötigt, um den Zeit zu schreiben, auszulesen und in das txt-file zu schreiben. Leider ist dieser Wert nicht konstant, so dass ich ihn einfach abziehen oder drauf rechnen könnte.
Oder meint ihr, der Fehler liegt hier woanders?

Hier nochmal der Code:

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>

#include <iostream>
#include <fstream>

using namespace std;

// defines the socket used by the GPS
#define PORT 3000 

/****************************/
 int CreateSocket(int port)
/****************************/
{
    // Create an UDP-socket
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
	
    // Check if UDP-socket was created
    if(sock==-1)
    {
       fprintf(stderr, "CreateSocket: socket failed\n");
       return -1;
    }

    // Bind it to the local IP-address
    struct sockaddr_in address;
	
    // Pointer to the block of memory to fill with address data
    memset(&address, 0, sizeof(address));

    address.sin_family      = AF_INET;             // Address family for IP-address 
    address.sin_addr.s_addr = htonl(INADDR_ANY);   // converts the unsigned integer hostlong from host byte order to network byte order 
    address.sin_port        = htons(port);         // converts the unsigned short integer hostshort from host byte order to network byte order
	
    // Check if IP-address is correct, if not Socket failed. Otherwise it returns the socket
    if(bind(sock, (struct sockaddr *) &address, sizeof(address))==-1)
    {
       fprintf(stderr, "CreateSocket: bind failed\n");
       close(sock);
       return -1;
    }
    return sock;
}


/**********************************/
 int main(int argc, char *argv[])
/**********************************/
{
   int channel;
   long GPS_min;
   double sec_offset;
   double min2sec;
   double sec_total;
   double ms;	
   double sec_p_ms;
   int newtime;	
   struct timeval systime;
   char * text_time;
   int counter;

int sock = CreateSocket(PORT);

   if(sock==-1)
   {
      fprintf(stderr, "Can't create the UDP socket\n");
      return 1;
   }

   // defines a 80 byte long buffer to receive the 72 byte long NCOM packet
   unsigned char buffer[80]; 



   // creates an infinite loop
   while(1)
   {
		 
struct sockaddr_in addr;
      socklen_t  addrlen = sizeof(addr);

	  // defines an integer len with the length of the NCOM packet
      int len = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *) &addr, &addrlen);

	  // checks the length of the packet. if it is 72 or more byte long, packet extraction starts
      if(len>=72)
      {
		 ms = (buffer[2] << 8) | buffer [1];     // reads byte 1 and 2, who are containing the milliseconds into the minute
		 channel = buffer[62];                   // defines variable channel on byte 62
		 if(channel==0)                          // checks if byte 62 is 0
		 {
            GPS_min = (buffer[66] <<24) | (buffer[65] <<16) | (buffer[64] <<8) | buffer [63]; // reads the minutes since 06.01.1980 from byte 63-66
		 }
		 }

		 // calculates seconds since 01.01.1970
		 sec_offset  = 315964800.0;                 // difference in seconds between 01.01.1970 and 06.01.1980
		 min2sec = (GPS_min*60)+sec_offset;         // calculates total seconds since 01.01.1970
         //printf("Min: %f\n", min2sec);
         sec_p_ms = ms/1000;                        // calculates the milliseconds
		 sec_total = min2sec+sec_p_ms;              // adds the milliseconds
         //printf("Zeit: %f\n", sec_total);
        
         // timer to slow the process below down to 1 Hz	
         counter = (counter+1) % 25;
         if (!counter) {
		 // sets the system time (accuracy: seconds)
		 systime.tv_sec = sec_total;
		 
		 // sets the system time (accuracy: milliseconds)
		 systime.tv_usec = ms;
         
		 // converts seconds.milliseconds in a date with millisecond accuracy as system time
		 newtime = settimeofday(&systime, 0);

		 // routine to check, if the system time was set correctly (only for test runs)
		 if (newtime==0){ //test for errors
			printf("settimeofday() successful.\n");
			}
			else{
				printf("settimeofday() failed, "
					   "errno = %s\n",strerror(errno));
				return -1;
				}
		 
            // defines variable "t" containing the actual system time		 
            gettimeofday(&systime, 0);
            cout << systime.tv_sec << ':' << systime.tv_usec << endl;
		
            // creates an output file with the GPS-seconds and the system time 			
			FILE* myfile;
			myfile=fopen ("Timetest.txt","a+");
			fprintf(myfile,"GPS time:    %f\n", sec_total);
            fprintf(myfile,"System time: %ld", systime.tv_sec);
            fprintf(myfile,".%ld\n", systime.tv_usec);
			fclose(myfile);
			}
		}

   return 0 ;
}

edit: Habe gerade noch bemerkt, dass die Systemzeit unterschiedlich stark wandert. Je nachdem wie groß ich den counter in Zeile 115 wähle. Im Moment steht er bei 25, also jede halbe Sekunde ein Wert. Dabei ergibt sich ein "Wanderwert" von 5 ms. Schreibe ich jede Sekunde einen Wert, ergibt sich ein Wert von 10 ms, bie alle 2 Sekunden ergeben sich 20 ms als "Wanderwert".
Ergänzung ()

Okay, also das "Wandern" der Zeit habe ich im Griff bzw. war es vorher eigentlich auch schon okay, habe das nur nicht bemerkt. :)

Aber anscheinend wird immer noch die Systemzeit mit .tv_usec, also Mikrosekundenbereich, nicht richtig gesetzt. Sekunden stimmen, Mikro- bzw. Millisekundenanteil jedoch nicht. :confused_alt:
 
Zuletzt bearbeitet:
Ich setze Millisekunden, aber auch wenn ich in tv_usec einfach einen festen Wert für Mikrosekunden einsetze, wird dieser nicht geschrieben.
 
Ja, aber dennoch sollte ein Zusammenhang zwischen dem Wert den ich zum setzen benutze und dem gesetzten Wert vorhanden sein. Soll heißen, wenn ich die Zeit mit 133s und 123456 Mikrosekunden setze, sollte der gesetzte ausgelesene Wert zumindest dahinter liegen und nicht wie bei mir davor mit z.b. 133s und 012589 Mikrosekunden.

Aber deinen Kommentaren entnehme ich, dass meine Syntax an sich nicht falsch ist und es so eigentlich funktionieren sollte?
Ergänzung ()

Habe es hinbekommen! es hat dann wie du vermutet hast doch daran gelegen, dass ich nur 3 Stellen anstatt 6 Stellen übergeben habe. Komisch ist nur, dass es bei meinen Tests mit statischen Mikrosekunden (6 Stellen) trotzdem nicht funktioniert hat.

Danke nochmal!
 
Zuletzt bearbeitet:
Zurück
Oben