<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>2014/05/28 on Yano&#39;s digital garage</title>
    <link>https://www.bravotouring.com/~yano/archives/2014/05/28/</link>
    <description>Recent content in 2014/05/28 on Yano&#39;s digital garage</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 28 May 2014 23:37:57 +0900</lastBuildDate>
    <atom:link href="https://www.bravotouring.com/~yano/archives/2014/05/28/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>fplug_for_linux</title>
      <link>https://www.bravotouring.com/~yano/diary/it/20140528fplug4linux.htm</link>
      <pubDate>Wed, 28 May 2014 23:37:57 +0900</pubDate>
      <guid>https://www.bravotouring.com/~yano/diary/it/20140528fplug4linux.htm</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.bravotouring.com/~yano/diary/it/20140523fplug4linux.htm&#34;&gt;先日導入&lt;/a&gt;した&lt;a href=&#34;https://github.com/goto2048/fplug_for_linux&#34;&gt;goto2048/fplug_for_linux&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;table align=&#34;right&#34; class=&#34;Landscape&#34;&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;img alt=&#34;F-PLUG&#34; src=&#34;https://www.bravotouring.com/~yano/images/2014/20140521fplug.jpg&#34;/&gt;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td class=&#34;PhotoMemo&#34;&gt;F-PLUG&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;span class=&#34;Warning&#34;&gt;温度(Temperature)の応答メッセージが1バイト短い問題&lt;/span&gt;は、ひとまずデータの最後から2バイトに注目するように改修したのだが、やはり「1バイト短い」だけではなく別種別の応答が返ってくる事例もあって&lt;a href=&#34;https://www.bravotouring.com/~yano/diary/it/20140526sensors.htm&#34;&gt;ゴミデータっぽい&lt;/a&gt;値となっている事がわかった。&lt;/p&gt;&#xA;&lt;p&gt;そういうわけで定石通り「SEOJクラスコード」が期待と違ったらリトライするようにしようかと思ったのだが、そこで&lt;span class=&#34;Warning&#34;&gt;温度(Temperature)の応答メッセージで「SEOJクラスコード」が漏れる問題&lt;/span&gt;に再び行く手を阻まれた。&lt;/p&gt;&#xA;&lt;p&gt;もしかして、TIDが使われていない(常時ゼロ)のが問題なのではないか？というのも気になったので、カウントアップするTIDを載せてみたものの結果は変わらず。しかし、「SEOJクラスコード」が無くても「TIDがある」事で各情報の要求と応答メッセージが紐付けできるようになるので、&lt;span class=&#34;Software&#34;&gt;fpstatus&lt;/span&gt;を下のように改修してみた。&#xA;&lt;blockquote class=&#34;Log&#34;&gt;&#xA;#include &lt;stdint.h&gt;&lt;br/&gt;&#xA;#include &lt;errno.h&gt;&lt;br/&gt;&#xA;#include &lt;stdio.h&gt;&lt;br/&gt;&#xA;#include &lt;sys/types.h&gt;&lt;br/&gt;&#xA;#include &lt;sys/stat.h&gt;&lt;br/&gt;&#xA;#include &lt;sys/ioctl.h&gt;&lt;br/&gt;&#xA;#include &lt;fcntl.h&gt;&lt;br/&gt;&#xA;#include &lt;termios.h&gt;&lt;br/&gt;&#xA;#include &lt;unistd.h&gt;&lt;br/&gt;&#xA;#include &lt;time.h&gt;&lt;br/&gt;&#xA;#include &lt;string.h&gt;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;#include &#34;fplug.h&#34;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;#undef  DEBUG&lt;br/&gt;&#xA;#define ENOTCONN_RETRY_MAX      10&lt;br/&gt;&#xA;#define MSG_RETRY_MAX           5&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;#define FPLUG_EXEC(fd,msg,buf)  fplug_exec((fd),(msg),sizeof((msg)),(buf),sizeof((buf)))&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;typedef unsigned char uchar;&lt;br/&gt;&#xA;static uint16_t tid = 0x0001;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;void hunt_tid(uchar *buf)&lt;br/&gt;&#xA;{&lt;br/&gt;&#xA;    *(uint16_t *)&amp;buf[2] = tid++;&lt;br/&gt;&#xA;}&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;typedef uchar uchar;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;static void dump_message( char *mes, uchar *buf, int size  )&lt;br/&gt;&#xA;{&lt;br/&gt;&#xA;#ifdef DEBUG&lt;br/&gt;&#xA;    int cnt;&lt;br/&gt;&#xA;    printf( &#34;%s&#34;, mes );&lt;br/&gt;&#xA;    for ( cnt=0; cnt&lt;size; cnt++ ) {&lt;br/&gt;&#xA;        printf( &#34;%02X,&#34;, buf[cnt] );&lt;br/&gt;&#xA;    }&lt;br/&gt;&#xA;    printf( &#34;\n&#34; );&lt;br/&gt;&#xA;#endif&lt;br/&gt;&#xA;    return;&lt;br/&gt;&#xA;}&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;int fplug_exec(int fd, uchar *req_msg, size_t req_len, uchar *res_buf, size_t bufsiz)&lt;br/&gt;&#xA;{&lt;br/&gt;&#xA;    struct timespec tmspec = { 0, 1000 * 1000 };&lt;br/&gt;&#xA;    int ret, i, j;&lt;br/&gt;&#xA;    uchar req_buf[BUFSIZ];&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    memcpy(req_buf, req_msg, req_len);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    for (i = 0;i &lt; MSG_RETRY_MAX; i++ ) {&lt;br/&gt;&#xA;        hunt_tid(req_buf);&lt;br/&gt;&#xA;        dump_message( &#34;Command:&#34;, req_buf, req_len);&lt;br/&gt;&#xA;        for (ret = j = 0;j &lt; ENOTCONN_RETRY_MAX; j++ ) {&lt;br/&gt;&#xA;            ret = write(fd, req_buf, req_len);&lt;br/&gt;&#xA;            if ( ret == req_len )&lt;br/&gt;&#xA;                break;&lt;br/&gt;&#xA;#ifdef DEBUG&lt;br/&gt;&#xA;printf(&#34;write()=%d,errno=%d\n&#34;, ret, errno);&lt;br/&gt;&#xA;#endif&lt;br/&gt;&#xA;            switch ( errno ){&lt;br/&gt;&#xA;            case ENOTCONN :&lt;br/&gt;&#xA;                tmspec.tv_nsec = 500 * 1000 * 1000;&lt;br/&gt;&#xA;                nanosleep(&amp;tmspec, NULL);&lt;br/&gt;&#xA;                break;&lt;br/&gt;&#xA;            }&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;        if ( ret &lt;= 0 )&lt;br/&gt;&#xA;            break;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;        tmspec.tv_sec = 0;&lt;br/&gt;&#xA;        tmspec.tv_nsec = 250 * 1000 * 1000;&lt;br/&gt;&#xA;        nanosleep(&amp;tmspec, NULL);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;        ret = read(fd, res_buf, bufsiz);&lt;br/&gt;&#xA;        if ( ret &lt;= 0 )&lt;br/&gt;&#xA;            continue;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;        dump_message( &#34;read:&#34;, res_buf, ret );&lt;br/&gt;&#xA;        if (4 &lt; ret &amp;&amp; !memcmp(req_buf, res_buf, 4)){   // TID match&lt;br/&gt;&#xA;#ifdef DEBUG&lt;br/&gt;&#xA;printf(&#34;read()=%d,errno=%d\n&#34;, ret, errno);&lt;br/&gt;&#xA;#endif&lt;br/&gt;&#xA;            return ret;&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;    }&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    return -1;&lt;br/&gt;&#xA;}&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;int fplug_main( int fd, int mode )&lt;br/&gt;&#xA;{&lt;br/&gt;&#xA;    int cmd;&lt;br/&gt;&#xA;    int cnt;&lt;br/&gt;&#xA;    int ret;&lt;br/&gt;&#xA;    int i=0;&lt;br/&gt;&#xA;    uchar buf[BUFSIZ];&lt;br/&gt;&#xA;    uchar *szMode, szResult[BUFSIZ];&lt;br/&gt;&#xA;    time_t timer;&lt;br/&gt;&#xA;    struct tm *t;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    strcpy(szResult, &#34;--&#34;);&lt;br/&gt;&#xA;    szMode = szResult;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    switch(mode) {&lt;br/&gt;&#xA;    case &#39;h&#39;:&lt;br/&gt;&#xA;        szMode = &#34;FP_HUMID&#34;;&lt;br/&gt;&#xA;        for ( i = 0; i &lt; MSG_RETRY_MAX &amp;&amp; 0 &lt; (ret = FPLUG_EXEC(fd, Humid, buf)); i++ ){&lt;br/&gt;&#xA;            uint16_t a = *(uint16_t *)&amp;buf[ret-2];&lt;br/&gt;&#xA;            if ( 100 &lt; a )&lt;br/&gt;&#xA;                continue;&lt;br/&gt;&#xA;            sprintf(szResult, &#34;%d&#34;, a );&lt;br/&gt;&#xA;            break;&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;        break;&lt;br/&gt;&#xA;    case &#39;i&#39;:&lt;br/&gt;&#xA;        szMode = &#34;FP_ILLUM&#34;;&lt;br/&gt;&#xA;        for ( i = 0; i &lt; MSG_RETRY_MAX &amp;&amp; 0 &lt; (ret = FPLUG_EXEC(fd, Illum, buf)); i++ ){&lt;br/&gt;&#xA;            uint16_t a = *(uint16_t *)&amp;buf[ret-2];&lt;br/&gt;&#xA;            if ( 0xFFFD &lt; a )&lt;br/&gt;&#xA;                continue;&lt;br/&gt;&#xA;            sprintf(szResult, &#34;%d&#34;, a );&lt;br/&gt;&#xA;            break;&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;        break;&lt;br/&gt;&#xA;    case &#39;t&#39;:&lt;br/&gt;&#xA;        szMode = &#34;FP_TEMP&#34;;&lt;br/&gt;&#xA;        for ( i = 0; i &lt; MSG_RETRY_MAX &amp;&amp; 0 &lt; (ret = FPLUG_EXEC(fd, Temp, buf)); i++ ){&lt;br/&gt;&#xA;            int16_t a = *(int16_t *)&amp;buf[ret-2];&lt;br/&gt;&#xA;            if ( a &lt; -100 || 500 &lt; a )&lt;br/&gt;&#xA;                continue;&lt;br/&gt;&#xA;            sprintf(szResult, &#34;%.1f&#34;, (float)a / 10);&lt;br/&gt;&#xA;            break;&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;        break;&lt;br/&gt;&#xA;    case &#39;w&#39;:&lt;br/&gt;&#xA;        szMode = &#34;FP_WATT&#34;;&lt;br/&gt;&#xA;        for ( i = 0; i &lt; MSG_RETRY_MAX &amp;&amp; 0 &lt; (ret = FPLUG_EXEC(fd, RWatt, buf)); i++ ){&lt;br/&gt;&#xA;            int16_t a = *(int16_t *)&amp;buf[ret-2];&lt;br/&gt;&#xA;            if ( 2000 &lt; a )&lt;br/&gt;&#xA;                continue;&lt;br/&gt;&#xA;            sprintf(szResult, &#34;%.1f&#34;, (float)a / 10);&lt;br/&gt;&#xA;            break;&lt;br/&gt;&#xA;        }&lt;br/&gt;&#xA;        break;&lt;br/&gt;&#xA;    default:&lt;br/&gt;&#xA;        szMode = &#34;FP_unknown&#34;;&lt;br/&gt;&#xA;        break;&lt;br/&gt;&#xA;    }&lt;br/&gt;&#xA;    printf( &#34;%s=%s;&#34;, szMode, szResult);&lt;br/&gt;&#xA;}&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;int main(int argc, char *argv[])&lt;br/&gt;&#xA;{&lt;br/&gt;&#xA;    int fd;&lt;br/&gt;&#xA;    struct termios oldtio, newtio;&lt;br/&gt;&#xA;    char *cmd;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    if ( argc == 1 ) {&lt;br/&gt;&#xA;        printf(&#34;Usage: fpstatus &lt;option&gt;\n&#34;);&lt;br/&gt;&#xA;        return(0);&lt;br/&gt;&#xA;    }&lt;br/&gt;&#xA;    if ( *argv[1] == &#39;-&#39; ) argv[1]++;&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    fd = open(SERIAL_PORT, O_RDWR);&lt;br/&gt;&#xA;    if ( fd &lt; 0 ){&lt;br/&gt;&#xA;        perror(&#34;open(/dev/rfcomm0)&#34;);&lt;br/&gt;&#xA;        return 0;&lt;br/&gt;&#xA;    }&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    tcgetattr( fd, &amp;oldtio );&lt;br/&gt;&#xA;    newtio = oldtio;&lt;br/&gt;&#xA;    newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;&lt;br/&gt;&#xA;    tcsetattr(fd, TCSANOW, &amp;newtio);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    for ( cmd = argv[1]; cmd &amp;&amp; *cmd; cmd++ )&lt;br/&gt;&#xA;        fplug_main(fd, *cmd);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    printf( &#34;\n&#34;);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    tcsetattr(fd, TCSANOW, &amp;oldtio);&lt;br/&gt;&#xA;    close(fd);&lt;br/&gt;&#xA;&lt;br/&gt;&#xA;    return 0;&lt;br/&gt;&#xA;}&lt;br/&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;iframe align=&#34;right&#34; frameborder=&#34;0&#34; marginheight=&#34;0&#34; marginwidth=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;https://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=yanosdigitalg-22&amp;o=9&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=ss_til&amp;asins=B00AFQZRZM&#34; style=&#34;width:120px;height:240px;&#34;/&gt;&#xA;&lt;iframe align=&#34;right&#34; frameborder=&#34;0&#34; marginheight=&#34;0&#34; marginwidth=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;https://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=yanosdigitalg-22&amp;o=9&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=ss_til&amp;asins=B00436F14W&#34; style=&#34;width:120px;height:240px;&#34;/&gt;&#xA;受信メッセージが期待する種別の応答でない場合は新しいTIDをアサインして要求からリトライする。5回送信しても期待する種別の応答が得られなかった場合、取得値は&#34;--&#34;となる。&#xA;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
