BBBでシリアル通信

概要

BeagleBoneBlack(BBB)のシリアルポートUART4(P9 11:RXD,13:TXD)を使えるようにする。

背景

ある探査ロボットのモータ制御をRS485で行う必要があり、RS232でしゃべれるBBBを利用した。
その際に、手始めに、BBBでシリアル制御を行ったのでその備忘録。
この後、pythonからシリアル制御を行ったのでそれも近日中に記載予定。
RS232C<-->RS485コンバータの製作についても記載するかも。

手順

設定

以下の設定を行いreboot。UART4の部分は設定を行いたいものに読み替え。

$ diff -u /boot/uboot/uEnv.txt~ /boot/uboot/uEnv.txt
--- /boot/uboot/uEnv.txt~	2014-05-15 23:58:50.000000000 +0000
+++ /boot/uboot/uEnv.txt	2014-06-20 01:28:44.000000000 +0000
@@ -17,7 +17,7 @@
 ##BeagleBone Black:
 ##Disable HDMI/eMMC
 #optargs=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN,BB-BONE-EMMC-2G
-
+optargs=quiet drm.debug=7 capemgr.enable_partno=BB-UART4
 console=ttyO0,115200n8
 
 mmcroot=UUID=526efd31-8f31-4dc6-8b5d-ac3a2b3736e2 ro

reboot後、/dev/ttyO4が見えるようになる。ちなみに、ttyO0は、オンボードデバッグ用シリアルピン。
シリアル通信の設定を行う。

$ sudo stty -F /dev/ttyO4 raw
$ sudo stty -F /dev/ttyO4 9600

P9 11,13をシリアルで別の端末に接続。写真のような感じで。
端子同士の配線は以下。


動作確認

TeraTermなどでシリアルを9600bpsで開いた状態で、BBBから以下を実行。

$ sudo su -
# echo "Hello,nihohi" >/dev/ttyO4

無事表示されました。
BBB側も、ttO4をcatして、TeraTerm側からも文字を送ると受信にも成功。

# cat /dev/ttyO4 
moge^C hello,nihohi!

※2014/09/28追記。
もし2つのデバイスを有効化する場合(例えばttyO2とttyO4)、前述の/boot/uboot/uEnv.txtで、以下のようにカンマ区切りでデバイスを設定すればOK。

 capemgr.enable_partno=BB-UART2,BB-UART4

今後の更新予定/備忘

  • (自分向け。見たときに思い出せるように)

決意/方針

  • ドタバタしてていろいろ放置気味だったので、完璧に仕上がらなくても一部でも知見を共有できるように徐々に更新して行こう...。
    • 「あっ、と気付いたこと」、「心に引っ掛かったこと」、「これ知ってると便利なのに」、や、「面白い/愉快と感じたこと」を中心に。
    • 無理に分野に分けるより、上記分類でタグ付けた方が自分の中ではわかりやすいかも。
    • あと、これらの一見異なるものがすべてリンクしているというのも表明できると面白いかも。
公開方法/内容について
  • githubとも連携していくかな。
  • 月面ローバー開発の話とかとpythonの話も盛り込めるといいな
    • pycon行く余裕あればネタに出来るかしら)
  • プログラム以外の方向も少し織り込む? 炎上しやすそう...

ソフトウェア技術ネタ

今後ぼちぼちアップして行こう

  • Qt5つかってみた
  • ZMQつかってみた
  • 802.11acドライバ構築まとめ on BBB --> github
  • BBBでシリアル通信(2014/06/03 済)
  • AndroidGPSで距離計測アプリつくってみた/.11acの到達距離計測ロガー --> github/google playにも置く?
  • 3D mapping / SfM
  • ステレオマッチング/OpenCV
  • MEMS LRF
  • インターフェースデザインの在り方
  • 設計のはなし

実験ネタ

  • .11ac距離計測
  • 月面探査ローバー開発の話
  • 鉱山跡探訪
  • 砂鉄が良く取れるところ
  • 自宅製鉄実験

社会ネタ? 生活ネタ? 考え方?

  • 資本主義について
  • 科学と宗教、哲学
  • 心理の話、心の動きの話
  • 興味のある本/著者の紹介(文・理・芸術問わず)
  • コンサート(クラシック)、美術館、博物館情報
  • 知財の話
  • 合気道の話
  • カーリング部の話
  • ハクトの話
  • 問題解決の心構えの話/debug含む
  • 問題解決と課題設定の違いの話
  • レイヤー的考え方/OSIなど通信プロトコル含む
  • 要求と仕様と設計の違いについて/いっしょくたにされることが多い。分析と構築の話でもいいかも。
  • 分析的アプローチとは異なる方法の課題抽出、問題特定、及び課題・問題解決アプローチについて
  • 自己複製について/物理的個体・物理的集団の自己複製、考え方・文化・振る舞いの自己複製

シリアル通信(RS232C/422A/485)の特徴まとめ

概要

  • Beagle Bone Black(以下BBB)/Ubuntu 12.04でのシリアル通信利用方法(RS232C/485)とその際に利用したRS232C-485コンバータのまとめ。(動作実績品ということで)

背景

  • BBBでモータードライバとシリアル通信する際にRS232Cだけでなく、RS485も使うことになったので、シリアル通信の整理と、サンプルコード、その際に利用したコンバータの情報などを整理しておきたいと思ったため。

環境

// 書く

RS232C/422A/485の特徴

  • RS485はRS422Aの上位互換があるらしい。(RS485が改良版)
規格 最大伝送速度 最大ケーブル長 接続形式
RS232C 20kbps 15m 1:1
RS422A 10Mbps 1200m 1:N (Nmax:10)
RS485 10Mbps 1200m N:N (Nmax:32)

コンバータ

// RS232C<->RS485のコンバータ。BBBで動作実績あり。写真も。

コード

// 書く

cythonでpythonの計算時間を100倍に 〜(1)cythonのcdefを使う〜

概要

ある単純な足し算の計算速度向上をcythonの2つの機能を使うことで試みた。

(1)cdefを使う
純粋なpythonを使った場合と、cythonを使った場合で計算時間を比較を行った。
その結果、cythonで、cdef利用した場合には(ある条件下では)50倍程度高速化された。
(後述の環境では、5.7[sec]かかっていたものが、100[msec]程となった。)

(2)nogilを使う
cythonのwith nogilを使うことで、GIL(Global Interpreter Lock)の制限解除を行うことが出来る。
(<--pythonAPIは一切使えない、thread切り替えのoverheadがあるなど、注意点もあるとのことだが)
GIL解除+multithreadingで、複数コア環境で更に倍速にすることを試みた。

"(2)"は近日中記載予定。
以下では、"(1)"について記載する。

背景

PyCon2013(2013/09/14-15@新宿/工学院大学)で、cythonを使うと、高速化できるという話を伺ったので、遊んでみようと簡単な例を試してみたという次第。
聴講したセッションは、以下。
「Cythonによる拡張モジュール開発」(Atsuo Ishimoto氏)
http://apac-2013.pycon.jp/zh/program/sessions.html#session-14-1630-rooma0765-ja2-en
資料:http://www.slideshare.net/atsuoishimoto/introduction-to-cython
動画:http://www.youtube.com/watch?v=eo6YcwQZV8k
# 48'06"あたりから、自分の質問も残っていたりw

環境

OS:(仮想系内)Ubuntu10.04
CPU:(仮想系内)Intel(R) Core(TM) i7-2670QM CPU @ 2.20GHz * 2
Mem:(仮想系内)4GB

コード

C,python,cython+pythonのコードを用意し、単純な足し算での速度比較を行ってみた。

C言語

simple_add_pure_c.c

#include <stdio.h>
int main(){
	long long a=0;
	long long i=0;
	for(i=0; i<100000000; i++){
		a += i;
	}
        printf("%lld\n",a);
	return 0;
}
python

simple_add.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

def simple_add():
    a = 0
    for i in range(100000000):
        a += i
    return a
if __name__ == "__main__":
    print simple_add()
python+cython(cdefなし)

simple_add2.pyx

def simple_add():
    a = 0
    for i in range(100000000):
        a += i
    return a

simple_add2_cython.py(cythonモジュールを呼ぶ人)

#! /usr/bin/env python
# -*- coding: utf-8 -*-

if __name__ == "__main__":
    import simple_add2
    print simple_add2.simple_add()
python+cython(cdefあり)

simple_add2_cdef.pyx

def simple_add():
    cdef int i,a
    a = 0
    for i in range(100000000):
        a += i
    return a

simple_add2_cython.py(cythonモジュールを呼ぶ人)

#! /usr/bin/env python
# -*- coding: utf-8 -*-

if __name__ == "__main__":
    import simple_add2_cdef
    print simple_add2_cdef.simple_add()

実行(ビルド/時間測定)

cのコード --> 2[msec]ほど

$ gcc -O2 simple_add_pure_c.c -o simple_add_pure_c
$ time ./simple_add_pure_c

real	0m0.002s
user	0m0.010s
sys	0m0.000s

python --> 8[sec]ほど

$ time ./simple_add.py

real	0m8.138s
user	0m6.660s
sys	0m1.470s

cython(cdefなし) --> 5[sec]ほど

$ cython simple_add2.pyx
$ export PYTHON_H_DIR=/usr/include/python2.6
$ gcc -c -O2 -fPIC -I$PYTHON_H_DIR simple_add2.c -o simple_add2.o
※最適化オプション(-O2)つけないと、あまり速くならなかった。(あたりまえといえばあたりまえ)
$ gcc -shared -o simple_add2.so simple_add2.o
$ time ./simple_add2_cython.py

real	0m5.516s
user	0m4.290s
sys	0m1.220s

cython(cdefあり) --> 100[msec]ほど

$ cython simple_add.pyx
$ export PYTHON_H_DIR=/usr/include/python2.6
$ gcc -c -O2 -fPIC -I$PYTHON_H_DIR simple_add2_cdef.c -o simple_add2_cdef.o
$ gcc -shared -o simple_add2_cdef.so simple_add2_cdef.o

real	0m0.100s
user	0m0.090s
sys	0m0.020s

参考

Pythonを高速化するCythonを使ってみた
http://kesin.hatenablog.com/entry/20120306/1331043675

追記

2013/09/18 Mi.

"実行"の"最適化オプション"について補足

2013/10/18 Fr.

社内勉強会で発表。指摘事項を反映。
int -> long longに変更(overflowしていたorz)
結果も確認出来るように、print文を追加。
aの初期化漏れ対応。a=0を追加。

celeryでclassのmethodを利用する方法

概要

django+celeryを利用して、あるクラスの処理を非同期に処理しようとした際に、メソッドを利用するところで、「takes exactly 2 arguments (1 given)」と怒られた。
(selfが渡っていないときなどによく見るエラー)
調べてみると、celeryから、classのmethodを利用する際には、それに応じた手続きが必要なようであったので、以下その方法を記載しておく。

背景

あるクラス(Converterというクラス)に含まれるメソッド"convert()"を利用した際に、「raised exception: TypeError('convert() takes exactly 2 arguments (1 given)',)」と怒られた。

本家のドキュメント(celery.contrib.methods)にあったので、それを参考に、後述の様に書き換えたところ動いた。

上記サイトによれば、taskのベースクラスが新しくなったそうで、これまでのような古い書き方は推奨されないらしい。

The task must use the new Task base class (celery.Task), and the old base class using classmethods (celery.task.Task, celery.task.base.Task).

This means that you have to use the task decorator from a Celery app instance, and not the old-API:

from celery import task # BAD
from celery.task import task # ALSO BAD
(略)

ということで、以下自分の使ったクラス(Conveterクラス)を例に、手順を示す。
元々のConverterクラスはこんな感じ。

from celery import task
class Converter(object):
     def __init__(self, converter="xxx", file_format="yyy"):
         pass
         # いろいろ処理

     @task()
     def convert(self, in_file):
     pass
         # いろいろ処理

以下の様に書き換えた。(from celery ... --> from celery.contrib.methods ...)

from celery.contrib.methods import task
class Converter(object):
     def __init__(self, converter="xxx", file_format="yyy"):
         pass
         # いろいろ処理

     @task()
     def convert(self, in_file):
     pass
         # いろいろ処理

あとは、普通に、非同期実行でOK。

$ python
Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23) 
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from xxx.converter import Converter
>>> c = Converter()
>>> c.convert.delay("xxx/aaa.bbb")
<AsyncResult: 43c72c43-f535-45f0-b6a2-2ed60897c352>
>>>

celery側のログ

[2012-12-02 03:32:37,116: INFO/MainProcess] Task xxx.converter.convert[50e07a93-6eef-48f8-84f8-249d03354089] succeeded in 0.123465061188s: 'xxx/aaa.bbb'