LoginSignup
2
3

More than 5 years have passed since last update.

【ev3dev】LCD(画面)制御の仕組みを理解しよう

Last updated at Posted at 2017-02-25

はじめに

この記事は、EV3にev3devをインストールし、SSH接続できている状態であることを前提にしています。環境構築ができていない方はこちらの記事を参考にしてください。

mindstorm-EV3をLinuxで制御しよう! ev3dev OSのインストールとSSH接続

概要

ev3devではEV3のLCDをどのように制御できるのか、サンプルコードを図を用いて解説します。
python製ライブラリのev3dev-lang-pythonにはLCDを簡単に制御できるAPIが提供されていますが、今回はそれらのライブラリを使わずにLCD制御の仕組みを理解することが目的です

LCDの仕組み

EV3のLCDは178 x 128ピクセルのモノクロ画面になっています。
ビデオドライバーはLinuxのframebufferインターフェースによって提供されていて、デバイスファイル/dev/fb0にデータを書き込むことでLCDを制御できます。
framebufferの情報をfbset -iコマンドを実行して確かめてみましょう。

robot@ev3dev:~$ fbset -i

mode "178x128"
    geometry 178 128 178 128 1
    timings 0 0 0 0 0 0 0
    rgba 1/0,1/0,1/0,0/0
endmode

Frame buffer device information:
    Name        : ST7586
    Address     : 0xc39f9000
    Size        : 3072
    Type        : PACKED PIXELS
    Visual      : MONO01
    XPanStep    : 0
    YPanStep    : 0
    YWrapStep   : 0
    LineLength  : 24
    Accelerator : No

LCDが178 x 128ピクセルで構成されること、水平方向一列のピクセル情報が24byteで表させることが分かります。
(下図)

スクリーンショット 2017-02-18 17.20.36.png

LCDはモノクロ(カラーではない)なので、それぞれの最小ピクセルは0か1のバイナリーデータとなります。
1byte=8bitなので、178pxを表現するには178/8=22.25(byte)あれば足ります。しかし実際には、水平方向一列のピクセル情報は24byteで表現されます。つまり24byteのデータ全てが画面上に表示されるわけではないということです。

サンプルコード

LCDを制御するには24byte x 128(rows) = 3072byteのデータをデバイスファイルに書き込む必要があります。
以下の図形を表示させるサンプルコードは以下のようになります。

9.png

#!/usr/bin/env python

# Hard coding these values is not a good idea because the values could
# change. But, since this is an example, we want to keep it short.
SCREEN_WIDTH = 178 # pixels
SCREEN_HEIGHT = 128 # pixels
LINE_LENGTH = 24 # bytes
SIZE = 3072 # bytes

import os
import array


def main():
    # 要素数3072の配列を定義
    buf = [0] * SIZE

    # 100カラム目に縦線を引く
    for row in range(0, SCREEN_HEIGHT):
        buf[row * LINE_LENGTH + int(100 / 8)] = 1 << (100 % 8)

    # 64列目に水平線を引く
    for col in range(0, LINE_LENGTH):
        buf[64 * LINE_LENGTH + col] = 0xff


    import math
    # 中心点 (40,40), 半径 20の円を描く
    for x in range(0, 20):
        y = math.sqrt(20 * 20 - x * x)
        buf[(40 + int(y)) * LINE_LENGTH + int((40 + x) / 8)] = 1 << ((40 + x) % 8)
        buf[(40 - int(y)) * LINE_LENGTH + int((40 + x) / 8)] = 1 << ((40 + x) % 8)
        buf[(40 + int(y)) * LINE_LENGTH + int((40 - x) / 8)] = 1 << ((40 - x) % 8)
        buf[(40 - int(y)) * LINE_LENGTH + int((40 - x) / 8)] = 1 << ((40 - x) % 8)

    # デバイスファイルへの書き込み
    f = os.open('/dev/fb0', os.O_RDWR)
    s = array.array('B', buf).tostring()
    os.write(f, s)
    os.close(f)

if __name__ == '__main__':
    main()

コードを保存させ実行するとLCD画面に図形が表示されます。
ライブラリに定義されていないような複雑なLCD制御をしたい場合、参考になると思います。

参考

Using the EV3 LCD

画面キャプチャ
【ev3dev】pythonを使ってLCD(画面)をキャプチャーするプログラムを作る

2
3
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
2
3