LoginSignup
0
1

More than 3 years have passed since last update.

プチロボ2PIC搭載ボード制御ソフトのシリアル通信用のダミーコードを作ってみた

Posted at

はじめに

共立プロダクツのプチロボ制御ソフトは、Windows版しか提供されていません。そこで、Linuxでも操作できるようにしてみたかったので、コントロールボードとPC間のシリアル通信をするための準備のためにC言語でのシリアル通信コードの学習もかねて簡単なソフトウェアを作ってみた。

コントロールボードについて

サーボモータを最大20個も操作できます。また、A/D入力にも対応しており、デジタル出力用のピンも出ています。サーボモータ用の操作には、I2C通信を使うケースが多く、シリアル通信での制御はあまり見かけません。せっかく手元にある玩具なので、もう少し深く楽しんでみたくなったのですが、はじめから準備されたWindowsソフトで遊ぶだけでは物足りません。

「WR-MSXX」の通信プロトコルは、共立電子の専用サイトからダウンロードが可能です。
https://drive.google.com/open?id=1lnpenY3FXI092F3Dacd8IQRRztPIJDvg

ZIPファイルをダウンロードして、解凍したフォルダのtutorial > pdffiles とたどると、ハードウェアマニュアルのPDFが無料で提供されています。(wr-xx_hardware2.pdf)更に、ハードウェアの回路図があります。PICが2個使われています。

・PIC16F687
・PIC16F886

PIC16F687がFT232RL経由でPCにつながります。2つのPIC間は、I2C通信設定のようです。以前から、Raspberry PiとPICとの組みあせには興味があったのですが、まさに、その実験にうってつけの製品だと思いました。

C言語でのシリアル通信コードについて

特に役に立ったのは、そのものズバリ、「The Linux Serial Programming HOWTO」(日本語版)です。
http://linuxjf.osdn.jp/JFdocs/Serial-Programming-HOWTO.html

ダミーコード・サンプル

いろいろとわからないことが多かったものの、結果的には簡単なコードになりましたので、全文を掲載します。結局、シリアル通信に使用するデバイスドライバファイルの扱いは、K&Rの「プログラミング言語C」の第8章2節の「低水準入出力ーーReadとWrite」の解説がとても役にたちましたが、それ以外は、「Cの絵本」を片手に学習したものです。

my_ttyUSB0.c
/***********************************************************************************************************
 * サンプルプログラム(Linux版 WR-XX返信ダミープログラム)無限ループ
 * Lian Ivvakanni (12-19-2020)
 * プログラムの内容
 *  ・Wonder Roid Motion Maker V343.1.1からのA/D入力取得コマンド(コマンド 5)を受信して
 *   WM:Wait data stack Memory状態「空」(=0)を送信する
 * WR-XX 通信プロトコルガイド(第2版)仕様
 * RS232C 通信設定(半二重通信)
 *  ・通信速度          :38400bps
 *  ・データ形式         :バイナリーモード出力
 *  ・データ           :8ビット
 *  ・ストップビット       :1
 *  ・パリティ          :無し
 *  ・ハンドシェイク(フロー制御):無し
 *  ・シリアルポート       :/dev/ttyUSB0
 * 
***********************************************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define MODEM_DEVICE "/dev/ttyUSB0"
#define BAUD_RATE   B38400
#define N 255

int main(int argc, char *argv[])
{
    int  fd, i, rlen, slen;
    struct termios tio;
    char s[8], rBuf[N] = {'\0'}, sBuf[N] = {'\0'};

    // WMデータ
    unsigned long mwData[] = {0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x00}; 
    // AD入力取得コマンド(コマンド 5)
    unsigned long cmd_five[] = {0xFD,0x04,0x05,0xFE};

    memset(&tio, 0, sizeof(tio));
    tio.c_cflag = BAUD_RATE | CS8 | CLOCAL | CREAD;
    tio.c_cc[VTIME] = 0; // キャラクタ間タイマは未使用
    tio.c_cc[VMIN] = 0;  // 文字受け取りブロックなし 

    // サーボ制御出力コマンド(ヘッダ)
    slen = sizeof(mwData) / sizeof(mwData[0]);
    sBuf[0] = 0xFD;
    sBuf[1] = slen + 4;
    sBuf[2] = 0x15; //
    sBuf[slen + 3] = 0xFE; 

    for (i = 3; i < slen; i++) {
        sBuf[i] = mwData[i-2];
    }
    /* 出力データのデバッグ
    for (i = 0; i < slen + 4; i++){
        printf("%02X ", sBuf[i]);
    } 
    printf("\n");
    */
    fd = open(MODEM_DEVICE, O_RDWR);
    if (fd < 0) {
        perror(MODEM_DEVICE);
        exit(-1);
    }
    tcflush(fd, TCIFLUSH);
    ioctl(fd, TCSETS, &tio);

    while(1){
        rlen = read(fd,rBuf, sizeof(rBuf));
        if(rlen < 0)
            printf("Device Read Error...\n");
        if(rlen == 0)
            continue;
        else if(rBuf[1] == cmd_five[1] && rBuf[2] == cmd_five[2]){
            // デバイスへ書き込み
            write(fd, sBuf, 15);
        } else {
            for(i = 0;i < rlen; i++){
                    sprintf(s,"%02X", rBuf[i]);
                    printf("%s ",s);
            }
            printf("\r\n");
        }
        rlen = 0;
    }
    close(fd);
    return 0;
}

おわりに

たったこれだけのことを理解するために、2週間ほどかかりました。やはり、独学というのは時間がかかって大変ですが、ある程度理解できたときの喜びもひとしおです。

これから、操作コマンドの送信用のプログラムはできていませんが、シリアル通信でサーボモータのコントロールは、結構大変そうです。UARTは、基本的な通信方式なので、ぜひとも基本的な仕組みは知っておきたかったので、もう少し学習をつづけておきたいと思います。

0
1
0

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
0
1