W5500などのEthenetr IC用のCライブラリ、
WIZnet ioLibraryの中でNTPの不具合の対処方法を紹介します。
ネットワークから時刻を取得して同期する機能として
NTPがあります。クライアント側のみに対応したSNTPの関数が
WIZnet ioLibraryの中に用意されています。
ArduinoではC++サンプルコードがあり、
NTPの不具合は受けません。
不具合としては
NTPで時刻を取得できない現象です。
原因としてはリトライカウントが増えず、
リクエストの再送信が行われませんでした。
1回目の時刻取得のリクエスト以降、
再送されず、ずっと返答待ち状態になってしまいます。
特に接続直後のネットワークが確立していない状態で
NTPで時刻取得のリクエストすると
1回目のリクエストを落としてしまう可能性が非常に高く、
リクエストの再送信が重要となります。
Cライブラリで用意されているSNTP関数の中に
int8_t SNTP_run(datetime *time)があり、
リトライカウントに応じた処理をしています。
【修正前】
〜〜〜〜〜〜〜〜〜〜
if(ntp_retry_cnt<0xFFFF)
{
if(ntp_retry_cnt==0)//first send request, no need to wait
{
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
ntp_retry_cnt++;
}
else // send request again? it should wait for a while
{
{
if(ntp_retry_cnt==0)//first send request, no need to wait
{
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
ntp_retry_cnt++;
}
else // send request again? it should wait for a while
{
if((ntp_retry_cnt % 0xFFF) == 0) //wait time
〜〜〜〜〜〜〜〜〜〜
【修正後】
〜〜〜〜〜〜〜〜〜〜
if(ntp_retry_cnt<0xFFFF)
{
if(ntp_retry_cnt==0)//first send request, no need to wait
{
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
ntp_retry_cnt++;
}
else // send request again? it should wait for a while
{
{
if(ntp_retry_cnt==0)//first send request, no need to wait
{
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
ntp_retry_cnt++;
}
else // send request again? it should wait for a while
{
ntp_retry_cnt++;//追加
if((ntp_retry_cnt % 0xFFF) == 0) //wait time
〜〜〜〜〜〜〜〜〜〜
上記の修正である間隔でリクエストの再送信が行われるようになります。