Help us understand the problem. What is going on with this article?

Wio-LTE で現在時刻を取得する

More than 1 year has passed since last update.

結局 Wio-LTE には時計が二つ入っている。一つは EC21-J のモデムに、もう一つは STM32F4 の SoC 上にある。基本的には電源が切れると、両方とも時刻を忘れる。

時刻の同期元となるものは、携帯網自体か、あるいはNTPによるものか、GPSによるものか、と種類がある。

SoC の時計から時刻を取得する

これは単純に Date() で取得できる。

>console.log(new Date().toString());
Tue Apr 3 2018 02:10:16 GMT+0000
=undefined
>console.log(getTime()); // get in unix epoch seconds
1522721416.42934918403
=undefined

時刻合わせをするときには setTime() で行う。CPU の時刻を使うメリットは、モデムとの通信を待たないでいいことで、他の通信を妨げないのが最大のメリット。モデムの時計をコピーして時刻をセットしておくと便利だろう。あるいはあえて時刻をセットせず、カレンダーとしてではなく、単純に起動時からの経過時間として使うという手もある。

>setTime(1522721463)
=undefined
>console.log(new Date().toString());
Tue Apr 3 2018 02:11:06 GMT+0000
=undefined

E.setTimeZone() で CPU のタイムゾーンを設定すると new Date().toString() の出力を現地時刻に変更できる。

>E.setTimeZone(9)
=undefined
>console.log(new Date().toString());
Tue Apr 3 2018 11:13:39 GMT+0900
=undefined

モデムの時計から時刻を取得する

EC21-J は LTE モデムなので、ネットワークに接続できると、携帯網の機能を使って自動的に時刻が設定される。

モデムの時計からは AT+CCLK コマンドで取得できる。

function clockNow(board){
  var pad2 = function(n){ return ("00" + n).slice(-2); };
  var normalize_datetime = function(s){
    return s.replace("/","-").replace("/","-").replace(",","T");
  };
  return new Promise((resolve,reject)=>{
    board.at.cmd("AT+CCLK?\r\n", 1000, L=>{
      if(L===undefined){
        reject("timeout");
      }else if(parseInt(L[8]) >= 7){ // 1970
        reject("uninitialized");
      }else{
        var dt = normalize_datetime("20" + L.slice(8, 25));
        var offset = parseInt(L.slice(26, 28));
        dt += L[25] + pad2(offset/4) + pad2((offset%4) * 15);
        resolve(new Date(dt));
      }
    });
  });
}

// ここから下はボードの起動手順。後の例では省略。
var board;
function onConnect(err){
  if(err){
    board = require("wiolte").connect(onConnect);
  }else{
    clockNow(board).then(T=>{
      console.log("clockNow", T);
    });
  }
}

function onInit(){
  board = require("wiolte").connect(onConnect);
}

onInit();

携帯網の時刻を取得する

モデムの時計からではなく、網から明示的に取得する方法。

function networkNow(board, utc){
  var pad2 = function(n){ return ("00" + n).slice(-2); }
  var normalize_datetime = function(s){
    return s.replace("/","-").replace("/","-").replace(",","T");
  }
  var cmd = "AT+QLTS=2\r\n";
  if(utc){
    cmd = "AT+QLTS=1\r\n";
  }
  return new Promise((resolve,reject)=>{
    board.at.cmd(cmd, 1000, L=>{
      if(L===undefined){
        reject("timeout");
      }else{
        // +QLTS: "2018/04/02,17:31:55+36,0"
        var dt = normalize_datetime(L.slice(8, 27));
        // Espruino Date accepts 2018-04-02T17:31:55Z
        if(utc){
          resolve(new Date(dt + "Z"));
        }else{
          var offset = parseInt(L.slice(28, 30));
          dt += L[27] + pad2(offset/4) + pad2((offset%4) * 15);
          resolve(new Date(dt));
        }
      }
    });
  });
}

NTP で時刻を取得する

NTPで現在時刻を取得する。ネットワークパケットを使う。このコマンドはモデムの AT コマンドを使うのだが、取得と同時にモデムの時計をセットすることもできる。

function ntpNow(board, server){
  var pad2 = function(n){ return ("00" + n).slice(-2); };
  var normalize_datetime = function(s){
    return s.replace("/","-").replace("/","-").replace(",","T");
  };
  return new Promise((resolve,reject)=>{
    var handler = function(L){
      if(L===undefined){
        reject("QNTP timeout");
      }else if(L=="OK"){
        return handler;
      }else if(L.slice(0,9)=="+QNTP: 0,"){
        // +QNTP: 0,"2018/04/03,02:52:26"
        var offset = parseInt(L.slice(30,32));
        var dt = normalize_datetime(L.slice(10,29));
        dt += L[29] + pad2(offset/4) + pad2((offset%4) * 15);
        // Espruino Date accepts 2018-04-02T17:31:55Z
        resolve(new Date(dt));
      }else{
        reject(L);
      }
    };
    board.at.cmd("AT+QNTP=1,\""+server+"\"\r\n", 10000, handler);
  });
}

GPS

実は Wio-LTE の JP バージョンでのみ GPS が削除されているということに、今気が付きました。日本版だけ劣化してる……。それならそれで soracom のキットを最初から買えばよかった。残念。

kwi
iij
日本のインターネットを支えてきたIIJ。現在もその先もイニシアティブをとり続けます。
https://www.iij.ad.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした