Shuichi Machida's Weblog

« [Sun SPOT(23)] Sun... | メイン | [Sun SPOT API Tips(1... »

http://blogs.sun.com/machida/date/20080428 2008年 4月 28日 月曜日

[Sun SPOT Demo(6)] OLED Display (μOLED-96-G1) を使ってみる。

 ストロベリー・リナックスで超小型のフルカラーOLED(有機EL)ディスプレイモジュールを見つけたので、Sun SPOTのeDemoボードに取り付けてみました。

# OLEDモジュール。かなり小さいです!

# 裏。microSDカードも使えます。

 以前 LCDをつないだ時にも書きましたが、Sun SPOTの eDemoボード上の汎用I/Oピン D0, D1を使うと簡単に非同期シリアル通信(UART)ができます (最大 baud rate は 38400, data 8bits, no parity, 1or2 stop bits)。

# UART で使用するI/Oピン

今回のOLEDモジュールもシリアル接続できるので、Sun SPOTで制御できそうです。ただ、OLEDモジュールは TTLレベル(0-3.3V)とのことで、そのまま Sun SPOTのRx と OLEDモジュールの Tx をつなぐとD0ピンの許容最大電圧 3.0Vを超えてしまいます。このような場合、レベルシフトバッファなどを使って電圧を調整するそうなのですが、抵抗で分圧しても良いみたいですので、今回は抵抗を使います。

# 1KΩと100Ωの抵抗で分圧。電圧計で実際に測ったところ 2.8V程度でしたが、ロジックレベル 'H' として十分認識される範囲なのでOKでしょうか。。

 

早速電子回路の作成です。 OLEDモジュールは最大で100mA以上消費するので、Sun SPOTの5Vでは危なそうなので外部電源を使います。

 # ちょっと拡大。相変わらず半田付けがてきとうです。目が悪すぎて手元が良く見えないせいということにしておきます ;-)

 作成した回路基板がSun SPOTにマウントできるように、裏にはピンヘッダを取り付けています。

 装着。

# 横から見るとこんな感じです。ArshanがUSから持ってきていたディスプレイボードとは違い、不恰好です orz

# まぁ、eProto ボードが手元にないのでしょうがないのですが。。

 。。。

ハードウェアは完成です!ここまでくれば、後は パパッと Javaでプログラムを作成してインストールするだけです。

。。。

電源を入れてみました。

# OLEDのロゴに続いて、、、 

# お約束の?メッセージが表示されました ;-) それにしても、このディスプレイ結構表示が綺麗です。

プログラムはこんな感じです。

#  メイン部分のプログラム(MIDlet)

package org.sunspotworld;

import com.sun.spot.peripheral.ISleepManager;
import com.sun.spot.peripheral.Spot;
import com.sun.spot.util.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class StartApplication extends MIDlet implements MicroOLEDConstants {
    private IOled oled;  // OLED
    
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();
        
        // USBケーブルでPCにつないでいない状態で電源が切れないように、
        // 自動電源管理によるdeep sleepをオフにする
        ISleepManager sleepManager = Spot.getInstance().getSleepManager();
        sleepManager.disableDeepSleep();
        
        // uOLED-96-G1 にアクセスするためのクラスのインスタンスを生成
        oled = new MicroOLED96G1();

        
        // OLED にメッセージを表示
        try {
            oled.clear();
            oled.drawString("Hi!", 0, 0, FONT_8x12, RED);
            oled.drawString("This is", 0, 2, FONT_8x12, GREEN);
            oled.drawString("a Sun SPOT!!", 0, 3, FONT_8x12, BLUE);
        } catch (Exception ex) {
            ex.printStackTrace();
            Utils.sleep(2000L);
        }

        
        while (true) {
            // TODO: ここに処理を追加
            Utils.sleep(2000L);
        }
    }
    
    protected void pauseApp() {
    }
    
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

IOledは、OLEDモジュールにアクセスするためのインタフェースを定義します。

package org.sunspotworld;

public interface IOled {
    /** OLEDの画面をクリア */
    void clear() throws CommandExecutionException;
    /** column, row で指定された位置に引数で指定された文字列を表示する */
    void drawString(String text, int column, int row, int font, byte[] color) throws CommandExecutionException;
}

package org.sunspotworld;

public interface MicroOLEDConstants {
    // コマンド
    // ここでは、今回実際に使用するもののみ定義
    public static final byte ACK = (byte)0x06;
    public static final byte NAK = (byte)0x15;
    
    public static final byte COMMAND_INIT = (byte)'U';
    public static final byte COMMAND_CLS = (byte)'E';
    public static final byte COMMAND_DRAW_STRING = (byte)'s';
    
    // フォント関連
    public static final byte FONT_5x7 = (byte)0x00;
    public static final byte FONT_8x8 = (byte)0x01;
    public static final byte FONT_8x12 = (byte)0x02;
    
    // 文字列関連
    public static final byte STRING_TERMINATOR = (byte)0x00;

    // 色関連
    public static final byte[] BLACK = {(byte)0x00, (byte)0x00};
    public static final byte[] RED = {(byte)0xF8, (byte)0x00};
    public static final byte[] GREEN = {(byte)0x07, (byte)0xE0};    
    public static final byte[] BLUE = {(byte)0x00, (byte)0x1F};    
    public static final byte[] WHITE = {(byte)0xFF, (byte)0xFF};    
}

 

package org.sunspotworld;

public class CommandExecutionException extends java.lang.Exception {
    public CommandExecutionException() {
    }

    public CommandExecutionException(String message) {
        super(message);
    }
}

MicroOLED96G1 は IOled インタフェースの実装クラスで、OLEDにアクセスするための機能を実装します。なおここでは最小限の機能のみ実装しています(実際、このデバイスはかなり高機能です)。

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.util.Utils;
import java.io.IOException;

public class MicroOLED96G1 implements IOled, MicroOLEDConstants {
    private EDemoBoard demo;

    public MicroOLED96G1() {
        demo = EDemoBoard.getInstance();
        // baud: 38400bps, 8bits, no parity, 1 stop bit
        demo.initUART(EDemoBoard.SERIAL_SPEED_9600, false);
        initialize();
    }
   
    private void initialize() {
        send(COMMAND_INIT);
        try {
            receiveAck();
        } catch (CommandExecutionException ex) {
            ex.printStackTrace();
        }
    }

    public void clear() throws CommandExecutionException {
        send(COMMAND_CLS);
        receiveAck();
    }

   
    public void drawString(String text, int column, int row, int font, byte[] color) throws CommandExecutionException {
        byte[] data = text.getBytes();
        if (data.length > 255)
            throw new IllegalArgumentException("text length out of range: " + data.length);
       
        send(COMMAND_DRAW_STRING);
        send((byte)column);
        send((byte)row);
        send((byte)font);
        for (int i = 0; i < color.length; i++) {
            send(color[i]);
        }
        for (int i = 0; i < data.length; i++) {
            send(data[i]);
        }
        send(STRING_TERMINATOR);
       
        receiveAck();
    }

   
    private void send(final byte data) {
        demo.sendUART(data);
    }

    private byte receive(final long timeout) throws IOException {
        long startTime = System.currentTimeMillis();
        while (true) {
            try {
                byte data = demo.receiveUART();
                return data;
            } catch (IOException ex) {
                if ((timeout > 0) & (System.currentTimeMillis() - startTime) > timeout) {
                    throw ex;
                }
            }
            Utils.sleep(10L);
        }
    }

    private byte receiveAck() throws CommandExecutionException {
        int retry = 0;
        while (retry < 3) {
            Utils.sleep(20L);
            try {
                byte status = demo.receiveUART();
                if (!(status == ACK)) {
                    throw new CommandExecutionException("response -> " + Integer.toHexString(status));
                }
                return status;
            } catch (IOException ex) {
                System.out.println("Error in receiveAck: " + ex);
                retry++;
            }
        }
        throw new CommandExecutionException("No response" );
    }
}

とりあえず動かすことはできましたが、まだこのデバイスの持つ機能をほとんど使っていないので、時間があるときにもう少しいじってみようと思います。


投稿されたコメント:

当初 uOLED の Rx をプルアップしなかったところ通信できずに動作しなかったようで焦りました(10k でプルアップし動作しました).
あと SunSPOT にピッタリはまるコネクタがあるといいですね.

Posted by toshi on 5月月 11日, 2008年 at 07:44 午後 JST #

メインボードとつなぐためのHiroseの30pinコネクタがもうすぐ以下のサイトでオンライン購入できるようになるようですね:-)
http://www.digikey.com/
# と、Blog SPOT Blog( http://blogs.sun.com/davidgs ) では言っていました。

何個単位なのか気になりますが。。

Posted by machida on 5月月 13日, 2008年 at 12:07 午前 JST #

Hello! I need of the offer to OLED-96-G1 (12 pieces) with charges and transportation to São Paulo in Brazil.
Please inform the cost total (with charges and transportation) for 12 items.
Please send me the offer to viviane.chicano @ saint-gobain.com

Posted by viviane on 10月月 24日, 2008年 at 02:47 午前 JST #

コメント
  • HTML文法 不許可

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.