Raspberry Piでのシリアル通信

Raspberry Pi

第31回ロボット学会に出展中のYukiです。
2週にわたって原稿を落とすのは悲しいので、遅れてでも書いている最中です。

さて、Raspberry Piですが、シリアル通信をするにはおまじないとでもいうか、設定が必要です。
今回は、GPIOポートからシリアル通信をしてみます。
とはいえ、Raspberry Piは、3.3V仕様で、双葉のサーボは5V仕様の通信のため、何らかの工夫が必要です。(実際には動きますけど、いずれどっちかが電気的な問題が起きる可能性があるのでレベルコンバータをかませます。)

出張中は写真がままならないため、今回も写真なしで。

【Raspberry piをシリアル通信できるようにする】

シリアル通信モードにする設定は次のとおりです。デフォルトでは、システムコンソールになっているため、そのままではシリアル通信で使えません。この作業は、必ずオンボードか、有線LANでやってください。(Yukiは無線LANでやってて、無線が途中できれて、編集途中の設定ファイルのせいで2度と起動しなくなりました。)

1. /boot/cmdline.txt を下記のように変更します。

dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

なぜか行を分けて書いたら、起動しなくなりました。1行で書かないとだめなのかな。ここは要注意です。

2. /etc/initabを編集
Raspberry piを最新にしている人は、たぶん、一番最後の行になっていると思います。

ここをコメントアウトしたものがこれ
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

この後、rebootしてください。
これで、シリアル通信ができるはずです。

さて、準備ができました。
回路は次週にでも公開しましょう。
それではいそいそと、Linuxにおけるシリアル通信の基礎をやっていきましょう。

そんなにシリアル通信好きか?と思われるほどシリアル通信をこのブログでやっているような気がしますが、通信手段を書けるのはいろいろ便利ですよね。w
(ちなみにマイコンを使った回路で早いシリアル通信をしようとすると水晶発信器の周波数をきちんと計算して選定しないとCPUの通信速度の受け入れ可能誤差範囲に発生させるクロックがついてこないことがあるので要注意です。)

LinuxのCでは、シリアル通信は、べたにシステムを触ることになるのでioctlを多用します。
手順としては次のとおりです。

1. includeファイルを指定
2. 使用するポートを決める
3. シリアル通信ポートを開く
4. ボーレートやその他通信のプロトコルを設定する
5. 使用準備完了

今日は、使用準備完了までにしましょう。

指定するinclude は次のとおりです。あとから操作するために必要なstdなんちゃら.hとシリアル通信に必要なsys/なんちゃら以降のものとがあります。意外と多いです。

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

これらを指定しておきます。
次に、使用するポートを設定します。

/* Raspberry Pでのシリアルインターフェースに対応するデバイスファイル */
#define SERIAL_PORT “/dev/ttyAMA0”
#define BAUDRATE B115200 //ボーレートの設定(Futabaデフォルト)

これを定義しておきます。
それでは、通信ポートを開いてみましょう。
こんな感じです。(まだ閉じるところまで書いてないからこのままやってもシリアルポートが開いただけで何もしません。)

int main(int argc, char *argv[])
{
	int fd; /* シリアル通信ファイルディスクリプタ */
	char *com;
	struct termios newtio, oldtio;    /* シリアル通信設定 */
	    
	if(!(fd = open(SERIAL_PORT, O_RDWR))) return -1; /* デバイスをオープンする */
	ioctl(fd, TCGETS, &oldtio);       /* 現在のシリアルポートの設定を待避 */

	bzero(&newtio, sizeof(newtio));
	newtio = oldtio;                  /* ポートの設定をコピー */
	newtio.c_cflag = (BAUDRATE | CS8 | CLOCAL | CREAD);

	newtio.c_iflag = (IGNPAR);
	newtio.c_oflag = 0;
	newtio.c_lflag = ICANON; /* カノニカルモード */

    ioctl(fd, TCSETS, &newtio);       /* ポートの設定を有効にする */
}

次週は、写真がとれたら写真を出します。w
では~

タイトルとURLをコピーしました