LoginSignup
5
6

More than 5 years have passed since last update.

Raspberry Pi > C > ローカルタイムのmsec(ミリ秒)まで取得して標準出力 > gettimeofday()使用版とclock_gettime()使用版

Last updated at Posted at 2018-08-01
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
gcc (Raspbian 4.9.2-10) 4.9.2

概要

  • ローカルタイムのmsecまでを取得して標準出力する

参考

情報感謝です。

実装 (一部) > gettimeofday()使用

RPi_i2c_comm_CLKSTR_180712.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
...
static void printTime(bool addLF)
{
    struct timeval tvToday; // for msec
    struct tm *ptm; // for date and time

    gettimeofday(&tvToday, NULL); // Today
    ptm = localtime(&tvToday.tv_sec);

    // date and time
    printf("%04d/%02d/%02d,%02d:%02d:%02d,",
        ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
        ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    // msec
    printf("%03d,", (uint16_t)(tvToday.tv_usec / 1000));

    if (addLF) {
        printf("\n");
    }
}

実行例

$sudo ./RPi_i2c_comm_CLKSTR_180712
2018/08/01,11:03:17,700,C,767.066284,T,31.790649,RH,32.881165
2018/08/01,11:03:19,760,C,749.454285,T,31.817352,RH,33.106995
2018/08/01,11:03:21,803,C,760.685913,T,31.817352,RH,33.123779
2018/08/01,11:03:23,861,C,776.762817,T,31.804001,RH,33.029175
2018/08/01,11:03:25,920,C,782.709595,T,31.774628,RH,33.102417

上記のCの左側までがprintTime(false)での実装。

他環境の実装

メモ

確認しているセンサーは、2秒インターバルの動作が、実際には2秒50ミリ秒程度のインターバルになっている。
(DataReadyになってからの読込み時間も含む)。

教えていただいた事項

(追記 2018/08/01)

@tenmyo 様のコメントにてオーバーヘッドのこととclock_gettimeについて教えていただきました。

情報感謝です。

clock_gettimeに関して下記を見つけました。

実装 > clock_gettime()使用

(追記 2018/08/01)

clock_gettime()を使用してみました。

CLOCK_REALTIME_COARSE (Linux 2.6.32 以降; Linux 特有)
高速だが精度が低い CLOCK_REALTIME。速度が非常に必要で、かつ高精度のタイムスタンプが不要な場合に使用するとよい。
...
CLOCK_MONOTONIC_COARSE (Linux 2.6.32 以降; Linux 特有)
高速だが精度が低い CLOCK_MONOTONIC。速度が非常に必要で、かつ高精度のタイムスタンプが不要な場合に使用するとよい。

printTime_180801.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>

static void printTime_clock_gettime(clockid_t clk_id, bool addLF)
{
    struct timespec tvToday; // for msec
    struct tm *ptm; // for date and time

    clock_gettime(clk_id, &tvToday);
    ptm = localtime(&tvToday.tv_sec);

    // date and time
    printf("%04d/%02d/%02d,%02d:%02d:%02d,",
        ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
        ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    // msec
    printf("%03d,", (uint16_t)(tvToday.tv_nsec / 1000000));

    if (addLF) {
        printf("\n");
    }
}

int main(void)
{
    int loop;

    for(loop=0; loop<5; loop++) {
        printTime_clock_gettime(CLOCK_MONOTONIC_COARSE, /*addLF=*/true);
    }
    for(loop=0; loop<5; loop++) {
        printTime_clock_gettime(CLOCK_REALTIME_COARSE, /*addLF=*/true);
    }
}
run
$ gcc printTime_180801.c
$ ./a.out 
1970/01/01,15:37:29,515,
1970/01/01,15:37:29,525,
1970/01/01,15:37:29,525,
1970/01/01,15:37:29,525,
1970/01/01,15:37:29,525,
2018/08/01,16:59:39,362,
2018/08/01,16:59:39,362,
2018/08/01,16:59:39,362,
2018/08/01,16:59:39,362,
2018/08/01,16:59:39,362,

実時刻を得るにはCLOCK_REALTIME_XXXの方がを使うことになりそうですね。

5
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6