Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
有機LED(OLED)ディスプレイ

概要

4D Systemsが製造しているμOLED-128-G2(uOLED-128-G2)という有機LEDグラフィックディスプレイを使った実験です。有機ELキャラクタディスプレイの実験はこちらから。

注意:この実験ではArduinoから電源を供給しています。今回はこのグラフィックディスプレイだけしか接続していないので問題がないかもしれませんが、他のデバイスを同時に接続する場合などは注意してください。

まだ実験中なので、今後追加していきます。

目的

uOLED-128-G2という有機LEDグラフィックディスプレイをArduinoから制御できるようにしていきます。このグラフィックディスプレイはシリアル通信を使ってコマンドを送信することができます。

データシート

uOLED-128-G2のデータシートを参照して、どのようななものかを調べました。

このグラフィックディスプレイは、シリアル通信を利用してコマンドを送信することが可能です。シリアル通信に関するデータシートはを読んでいくと、Arduino用のライブラリがあることが判明しました。メーカー純正のライブラリはこちらを参照してください。これをそのまま使ってもいいのですが、プログラムの練習も兼ねて独自のライブラリを作成することにしました。

概要

uOLED-128-G2の仕様の概要は以下の通りです。

項目 値など
入力電圧 4.0V~5.5V。標準は5.0V
消費電流 20mA~200mA。標準は60mA。利用状況によって変動する。
コントローラ GOLDELOXグラフィックプロセッサ

以下は背面の写真です。ピンが10本出ています。また、マイクロSDカードのスロットもついています。

ピンは10本あります。意味と今回の実験のときに使ったArduinoのピン番号は以下の通りです。電源(+5V/GND)とシリアル通信(TX/RX)の4ピンを使いました。IO1/IO2を使うと様々なことができるようです。

OLEDグラフィックディスプレイのピン 意味 Arduinoのピン
1 +5V +5V
2 5V OUT 未使用
3 TX 0(RX)
4 IO2 未使用
5 RX 1(TX)
6 IO1 未使用
7 GND GND
8 GND 未使用
9 RESET 未使用
10 3.3V 未使用

また、マイクロSDカード用のスロットもついていて、マイクロSDカードに格納した画像やビデオを表示できるようです。マイクロSDカードにデータを書き込むには、専用のツールが必要です。この専用のツールは、4D Systemsのページから無料でダウンロードできます。Windows専用のようです。このページの真ん中よりやや下のDOWNLOADSというセクションの右側にリンクがあります。

スケッチを書きこむ際に、Arduinoの0番ピンと1番ピンには何も接続しないでください。スケッチの書き込みが失敗する可能性があります。

シリアル通信

シリアル通信を使ったコマンドは69個提供されています。Arduinoからコマンドを送信すると結果が返ってくるという、当たり前の動作です。ArduinoのSerialライブラリを使って問題なく通信できました。通信速度はデフォルトでは9600bpsのようです。

コマンド(シリアル通信)

GOLDELOXグラフィックプロセッサには、シリアル通信で利用できるコマンドが69個用意されています。コマンドは以下のように分類されます。

分類 説明 コマンド数
文字と文字列コマンド ディスプレイに文字や文字列を表示するためのコマンド 19
グラフィックコマンド ディスプレイにグラフィックを表示するためのコマンド 25
メディアコマンド SD/SDHCメモリカードを操作するためのコマンド 11
メモリアクセスコマンド グラフィックプロセッサのメモリの読み書きを行うためのコマンド 4
GPIOコマンド IO1に接続したジョイスティックの状態を取得するためのコマンド 1
サウンドコマンド IO2にビープを出すためのコマンド 1
シリアル通信コマンド シリアル通信の通信速度を設定するためのコマンド 1
イメージ制御コマンド ブロックイメージ転送を行い画面にイメージを表示するためのコマンド 1
システムコマンド バージョン情報の取得やスクリーンセーバの設定を行うためのコマンド 6

実験

マイクロSDカード上のイメージやビデオを表示する

マイクロSDカード上のイメージやビデオを表示するには、以下の手順が必要です。

  1. マイクロSDカードにイメージやビデオを保存する
  2. マイクロSDカード上のイメージやビデオを表示するプログラムを動作させる

マイクロSDカードにイメージやビデオをを保存する。

マイクロSDカード上のイメージやビデオをグラフィックディスプレイに表示するには、マイクロSDカードにデータを書き込んでおく必要があります。データのマイクロSDカードへの書き込みには、前述の専用ツールを利用する必要があります。このツールをインストールすると、いくつかのツールがインストールされます。今回利用するのは、「Graphics Composer」というツールです。

【注意】GOLDELOXグラフィックプロセッサでは、マイクロSDカードはRAW形式で利用します。このため、このツールでマイクロSDカードにデータを書き込むとフォーマットされていない状態になります。フォーマットした状態で保存してあるデータは使えなくなるので注意してください。

このツールを起動すると、Windows7では「次の不明な発行元からのプログラムにこのコンピューターへの変更を許可しますか?」と聞かれるので、「はい」を選択します(何かあっても責任はとれませんが)。

簡単な使い方は以下の通りです。画面を行ったり来たりするので少しわかりづらいかもしれません。

  1. スクリーンサイズを選択します。
    • 製品と同じサイズを選びます。
    • 画像を追加した状態ではサイズを変更できないようなので、最初に操作します。
  2. 表示する画像(イメージ・ビデオ)を追加します。【Addボタンを押下】
    • 追加した画像のファイル名が、「Entries」に表示されます。複数の画像を追加することもできます。
    • イメージやビデオを選択することができます。
    • 画像を削除するときは、画像を選択してDeleteキーを押します。
  3. 表示する画像を編集します。【Editボタンを押下】
    • 新しいウインドウが表示されます。
  4. 表示する領域を指定します。
    • ウインドウの左側が元の画像、右側がグラフィックディスプレイに表示する画像です。
    • 画像上の赤い点線をマウスで動かす(移動・大きさ変更)することもできます。
  5. 出力するサイズを指定します。
    • グラフィックディスプレイに表示する際のサイズを指定します。
    • グラフィックディスプレイと同じサイズにするか、もとの画像の縦横比を保存したうえで、長いほうの辺をグラフィックディスプレイと同じサイズにするのがいいのではと思います。
  6. データをPC上にセーブします。【Saveボタンを押下】
    • 編集内容を記録したファイルをPC上に保存します。
  7. データをマイクロSDカードにセーブします。【Buildボタンを押下】
    • マイクロSDカードに情報を保存するためのウインドウが表示されます。
  8. uSD RAWを選択します。
    • uOLED-128-G2では、ファイルシステムではなくRAWを利用します。
  9. マイクロSDカードが接続されているドライブを選択します。
    • マイクロSDカードを選択した後、OKを押すとマイクロSDカードに情報が書き込まれます。
    • マイクロSDカードはRAW形式なので、Windowsからはどういう状態になっているのかは確認できません(たぶん)。
  10. 画像の開始位置を確認する。【View most recent .GC Fileボタンを押下】
    • 画像がマイクロSDカードに記録された位置は、プログラムで利用します。
    • ここで確認を忘れても、セーブしたファイルの中に同一の情報が記録されています。
    • 複数の画像を追加している場合は、複数のエントリが記録されています。

起動直後の状態です。

表示する画像を追加した後の状態です。画像は複数追加することができます。

Editボタンを押した後の状態です。

Buildボタンを押した後の状態です。

View most recent .GC Fileボタンを押した後の状態です。

上記の場合は、開始位置は、0x00000000です。プログラムの中では、2バイトずつ指定します。画像を複数指定した場合は、指定した数分だけの情報が出力されます。画像によってセクターアドレスが異なります。

マイクロSDカード上のイメージやビデオを表示するプログラムを動作させる

マイクロSDカードに保存した画像をグラフィックディスプレイに表示させるためには、以下の手順が必要です。

  1. マイクロSDカードを利用するための初期化
  2. 表示したい画像が格納されているアドレスの設定
  3. 画像の表示

上記のそれぞれに対応したシリアルコマンドが用意されています。また、画像が格納されているアドレスは前のステップの最後で確認した画像の開始位置です。

Arduinoの画像を表示した例です。ディスプレイ保護用のフィルムをつけた状態です。

GOLDELOXグラフィックプロセッサのシリアルコマンドは、2バイトのコマンドとコマンドによって異なるnバイトのパラメータから構成されます。コマンドの送信後、グラフィックプロセッサからは、結果コードとコマンドによってはnバイトの戻り値が返却されます。

ディルプレイに画像を表示するためのコマンドは、以下の通りです。メソッド名は、私が作成したライブラリのメソッド名です。ほとんど、データシートに合わせてあります。

処理 コマンド パラメータ 結果コード 戻り値 メソッド名
初期化 0xffb1 なし。 0x06(成功のとき) 2バイトの戻り値。0が戻ってきたときは初期化に失敗。その他とときは成功。 mediaInit()
アドレス(セクター)設定 0xffb8 セクタアドレス(4バイト)。.GCファイルに出力されたアドレス。 0x06(成功のとき) なし setSectorAddress()
画像の表示 0xffb3 x(2バイト)、y(2バイト)。画像を表示する左上の座標。 0x06(成功のとき) なし displayImageRaw()

例えば、画像の表示は、以下のようにシリアル通信を行えばいいことになります(ライブラリのメソッドではなく、Arduino標準のAPIだけを利用した場合の例です)。

// 初期化コマンド
Serial.write(0xff);
Serial.write(0xb1);
ret = Serial.read(); // 結果コード
ret = Serial.read(); // 戻り値(1バイト目)
ret = Serial.read(); // 戻り値(2バイト目)

// アドレス(セクター)設定コマンド
Serial.write(0xff);
Serial.write(0xb8);
Serial.write(0x00); // セクターアドレス
Serial.write(0x00);
Serial.write(0x00);
Serial.write(0x00);
ret = Serial.read(); // 結果コード

// 画像の表示コマンド(2バイト)
Serial.write(0xff);
Serial.write(0xb3);
Serial.write(0x00); // x座標(2バイト)
Serial.write(0x00);
Serial.write(0x00); // y座標(2バイト)
Serial.write(0x00);
ret = Serial.read(); // 結果コード(1バイト)

ビデオを表示することもできます。この場合は、0xffb3のかわりに、0xffbbを送信します。

文字を表示する

ディスプレイに文字を表示するには、表示位置を設定するコマンドを実行した後、文字や文字列を表示するコマンドを実行するだけです。文字の色や背景の色を指定することもできます。また、ボールド体やイタリック体をにしたり、下線を引いたりすることもできます。

どのような文字が表示可能かを試してみたところ、ASCIIコードの0x20から0x7fまでのコードが表示できるようです。ただし、0x7fは全ドット塗りつぶしです。

図形を表示する

線や三角、四角、ポリゴンを表示するコマンドも用意されています。詳細はプログラムを眺めてください。

以下は、円をランダムな色で表示するプログラムを実行した例です。

マンデルブロ集合を表示するプログラムを動かしてみました。

色の指定

色は、16ビットの値で指定します。明確な説明を見つけることはできませんでしたが、ウェブ上の情報から判断すると、赤5ビット、緑6ビット、青5ビットを連結したデータ構造のようです。

例えば、赤色は上位5ビットを1にした0xf800、緑は中間の6ビットを1にした0x07e0、青は下位5ビットを1にした0x1fとなります。実際試してみたところ、そのようになりました。

プログラム

このグラフィックプロセッサを制御するためのライブラリを作成しました。まだきちんとライブラリ化はできていませんが。GitHubのリポジトリはこちら

戻り値はすべてintです。成功したらtrueを、失敗したらfalseを返します。メソッドによっては、グラフィックプロセッサから値を取得するものもあります。その場合も、戻り値はメソッドの成功・失敗であり、取得した情報はメソッドの引数を使って返却します。引数がポインタ型になっているもののほとんどはそのような使い方をしています。

display_image.ino

イメージを表示するプログラム例です。

#include "goldelox.h"

GOLDELOX oled(&Serial);

void setup() {
  // put your setup code here, to run once:
  uint16_t result;
  
  Serial.begin(9600);
  oled.begin();
  oled.screenSaverTimeout(0);   // Disable Screen Saver
  oled.clearScreen();           // Clear Screen
  
  oled.mediaInit(&result);      // Initialize Media
  
  if (result) {
    oled.setSectorAddress(0);   // Set Sector Address
    oled.displayImageRaw(0, 0); // Display Image
  }
}

void loop() {
  // put your main code here, to run repeatedly: 
}

text.ino

文字を表示するプログラム例です。

#include "GOLDELOX.h"

GOLDELOX oled(&Serial);

char *string = "Hello World !!";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  oled.begin();
  oled.screenSaverTimeout(0);
  oled.clearScreen();
  
  oled.textForegroundColor(0xffff);
  oled.moveCursor(0, 0);
  oled.putString(string);
  
  oled.textForegroundColor(0xf800);
  oled.textBold(true);
  oled.moveCursor(0, 1);
  oled.putString(string);
  
  oled.textForegroundColor(0x07e0);
  oled.textItalic(true);
  oled.moveCursor(0, 2);
  oled.putString(string);
  
  oled.textForegroundColor(0x001f);
  oled.textUnderline(true);
  oled.moveCursor(0, 3);
  oled.putString(string);
  
  oled.textForegroundColor(0xffe0);
  oled.textItalic(true);
  oled.textBold(true);
  oled.moveCursor(0, 4);
  oled.putString(string);
  
  oled.textForegroundColor(0x0000);
  oled.textBackgroundColor(0xffff);
  oled.moveCursor(0, 5);
  oled.putString(string);
  
  oled.textForegroundColor(0xffff);
  oled.textBackgroundColor(0x0000);
  for (int i = 0; i < 16; i++) {
    for (int j = 0; j < 16; j++) {
      oled.moveCursor(j, i + 6);
      oled.putCharacter((char)i * 16 + j);
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly: 
  
}

random_circles.ino

円を表示するプログラム例です。

#include "GOLDELOX.h"

GOLDELOX oled(&Serial);

void setup() {
  // put your setup code here, to run once:
  uint16_t result;
  
  randomSeed(analogRead(0));
  Serial.begin(9600);
  oled.begin();
  oled.screenSaverTimeout(0);   // Disable Screen Saver
  oled.clearScreen();           // Clear Screen
  oled.backgroundColor(0);      // Set Background Color Black
}

void loop() {
  // put your main code here, to run repeatedly: 
  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      oled.drawCircle(x * 16 + 7, y * 16 + 7, 7, random(65536));
    }
  }
}

goldelox.h

#ifndef GOLDELOX_H
#define GOLDELOX_H

#include <stdint.h>
class Stream;

#define GOLDELOX_CMD_MOVE_CURSOR                0xffe4
#define GOLDELOX_CMD_PUT_CHARACTER              0xfffe
#define GOLDELOX_CMD_PUT_STRING                 0x0006
#define GOLDELOX_CMD_CHARACTER_WIDTH            0x0002
#define GOLDELOX_CMD_CHARACTER_HEIGHT           0x0001
#define GOLDELOX_CMD_TEXT_FOREGROUND_COLOR      0xff7f
#define GOLDELOX_CMD_TEXT_BACKGROUND_COLOR      0xff7e
#define GOLDELOX_CMD_SET_FONT                   0xff7d
#define GOLDELOX_CMD_TEXT_WIDTH                 0xff7c
#define GOLDELOX_CMD_TEXT_HEIGHT                0xff7b
#define GOLDELOX_CMD_TEXT_X_GAP                 0xff7a
#define GOLDELOX_CMD_TEXT_Y_GAP                 0xff79
#define GOLDELOX_CMD_TEXT_BOLD                  0xff76
#define GOLDELOX_CMD_TEXT_INVERSE               0xff74
#define GOLDELOX_CMD_TEXT_ITALIC                0xff75
#define GOLDELOX_CMD_TEXT_OPACITY               0xff77
#define GOLDELOX_CMD_TEXT_UNDERLINE             0xff73
#define GOLDELOX_CMD_TEXT_ATTRIBUTES            0xff72
#define GOLDELOC_CMD_SET_TEXT_PARAMETERS        0xffe3

#define GOLDELOX_CMD_CLEAR_SCREEN               0xffd7
#define GOLDELOX_CMD_CHANGE_COLOR               0xffbe
#define GOLDELOX_CMD_DRAW_CIRCLE                0xffcd
#define GOLDELOX_CMD_DRAW_FILLED_CIRCLE         0xffcc
#define GOLDELOX_CMD_DRAW_LINE                  0xffd2
#define GOLDELOX_CMD_DRAW_RECTANGLE             0xffcf
#define GOLDELOX_CMD_DRAW_FILLED_RECTANGLE      0xffce
#define GOLDELOX_CMD_DRAW_POLYLINE              0x0005
#define GOLDELOX_CMD_DRAW_POLYGON               0x0004
#define GOLDELOX_CMD_DRAW_TRIANGLE              0xffc9
#define GOLDELOX_CMD_CALCULATE_ORBIT            0x0003
#define GOLDELOX_CMD_PUT_PIXEL                  0xffcb
#define GOLDELOX_CMD_READ_PIXEL                 0xffca
#define GOLDELOX_CMD_MOVE_ORIGIN                0xffd6
#define GOLDELOX_CMD_DRAW_LINE_AND_MOVE_ORIGIN  0xffd4
#define GOLDELOX_CMD_CLIPPING                   0xff6c
#define GOLDELOX_CMD_SET_CLIP_WINDOW            0xffbf
#define GOLDELOX_CMD_EXTEND_CLIP_REGION         0xffbc
#define GOLDELOX_CMD_BACKGROUND_COLOR           0xff6e
#define GOLDELOX_CMD_OUTLINE_COLOR              0xff67
#define GOLDELOX_CMD_CONTRAST                   0xff66
#define GOLDELOX_CMD_FRAME_DELAY                0xff69
#define GOLDELOX_CMD_LINE_PATTERN               0xff65
#define GOLDELOX_CMD_SCREEN_MODE                0xff68
#define GOLDELOX_CMD_SET_GRAPHICS_PARAMETERS    0xffd8

#define GOLDELOX_CMD_MEDIA_INIT                 0xffb1
#define GOLDELOX_CMD_SET_BYTE_ADDRESS           0xffb9
#define GOLDELOX_CMD_SET_SECTOR_ADDRESS         0xffb8
#define GOLDELOX_CMD_READ_BYTE                  0xffb7
#define GOLDELOX_CMD_READ_WORD                  0xffb6
#define GOLDELOX_CMD_WRITE_BYTE                 0xffb5
#define GOLDELOX_CMD_WRITE_WORD                 0xffb4
#define GOLDELOX_CMD_FLUSH_MEDIA                0xffb2
#define GOLDELOX_CMD_DISPLAY_IMAGE_RAW          0xffb3
#define GOLDELOX_CMD_DISPLAY_VIDEO_RAW          0xffbb
#define GOLDELOX_CMD_DISPLAY_VIDEO_FRAME_RAW    0xffba

#define GOLDELOX_CMD_BEEP                       0xffda

#define GOLDELOX_CMD_GET_DISPLAY_MODEL          0x0007
#define GOLDELOX_CMD_SCREEN_SAVER_TIMEOUT       0x000c
#define GOLDELOX_CMD_SCREEN_SAVER_SPEED         0x000d

#define GOLDELOX_RESPONSE_ACK                   0x06

#define GOLDELOX_SYSTEM_FONT                    0x00
#define GOLDELOX_MEDIA_FONT                     0x07

#define GOLDELOX_TEXT_BOLD                      0x10
#define GOLDELOX_TEXT_ITALIC                    0x20
#define GOLDELOX_TEXT_INVERSE                   0x40
#define GOLDELOX_TEXT_UNDERLINED                0x80

#define GOLDELOX_TEXT_PRINT_DELAY               0x07

#define GOLDELOX_CLIPPING_DISABLED              0x00
#define GOLDELOX_CLIPPING_ENABLED               0x01

#define GOLDELOX_LANDSCAPE                      0x01
#define GOLDELOX_LANDSCAPE_REVERSE              0x02
#define GOLDELOX_PORTRAIT                       0x03
#define GOLDELOX_PORTRAIT_REVERSE               0x04

#define GOLDELOX_PEN_SIZE                       0x00
#define GOLDELOX_SOLID                          0x00
#define GOLDELOX_OUTLINE                        0x01

#define GOLDELOX_OBJECT_COLOR                   0x02

class GOLDELOX {
public:
/*
 * Constructor
 */
  GOLDELOX(Stream  *port);

  char displayModel[20];

/*
 *  Public methods
 */
  void begin();
 
/*
 * Text Commands
 */
  int moveCursor(uint16_t x, uint16_t y);
  int putCharacter(char character);
  int putString(char *string);
  int characterWidth(char character, uint16_t *width);
  int characterHeight(char character, uint16_t *height);
  int textForegroundColor(uint16_t color);
  int textBackgroundColor(uint16_t color);
  int textWidth(uint16_t multiplier);
  int textHeight(uint16_t multiplier);
  int textXGap(uint16_t pixelcount);
  int textYGap(uint16_t pixelcount);
  int textBold(uint16_t mode);
  int textInverse(uint16_t mode);
  int textItalic(uint16_t mode);
  int textOpacity(uint16_t mode);
  int textUnderline(uint16_t mode);
  int textAttributes(uint16_t value);
  int setTextParameters(uint16_t function, uint16_t value);
 
/*
 * Graphics Commands
 */
  int clearScreen();
  int changeColor(uint16_t oldColor, uint16_t newColor); 
  int drawCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color);
  int drawFilledCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color);
  int drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
  int drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
  int drawFilledRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
  int drawPolyline(uint16_t n, uint16_t *xArray, uint16_t *yArray, uint16_t color);
  int drawPolygon(uint16_t n, uint16_t *xArray, uint16_t *yArray, uint16_t color);
  int drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color);
  int calculateOrbit(uint16_t angle, uint16_t distance, uint16_t *dist);
  int putPixel(uint16_t x, uint16_t y, uint16_t color);
  int readPixel(uint16_t x, uint16_t y, uint16_t *color);
  int moveOrigin(uint16_t xpos, uint16_t ypos);
  int drawLineAndMoveOrigin(uint16_t xpos, uint16_t ypos);
  int clipping(uint16_t value);
  int setClipWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
  int extendClipRegion();
  int backgroundColor(uint16_t color);
  int outlineColor(uint16_t color);
  int contrast(uint16_t contrast);
  int frameDelay(uint16_t msec);
  int linePattern(uint16_t pattern);
  int screenMode(uint16_t mode);
  int setGraphicsParameters(uint16_t function, uint16_t value);
  
/*
 * Media Commands(SD/SDHC Memory Cards)
 */
  int mediaInit(uint16_t *value);
  int setByteAddress(uint32_t address);
  int setSectorAddress(uint32_t address);
  int readByte(uint8_t *value);
  int readWord(uint16_t *value);
  int writeByte(uint8_t value, uint16_t *status);
  int writeWord(uint16_t value, uint16_t *status);
  int flushMedia(uint16_t *status);
  int displayImageRaw(uint16_t x, uint16_t y);
  int displayVideoRaw(uint16_t x, uint16_t y);
  int displayVideoFrameRaw(uint16_t x, uint16_t y, uint16_t frameNumber);

/*
 * Sound and Tune Commands
 */
  int beep(uint16_t note, uint16_t duration);
  
/*
 * System Commands
 */
  int getDisplayModel(char *string);
  int screenSaverTimeout(uint16_t timeout);
  int screenSaverSpeed(uint16_t speed);

/*
 * Utility Commands
 */

int rgbToColor(uint8_t red, uint8_t green, uint8_t blue);
  
private:
  Stream *serialPort;
/*
 *  Private methods
 */
  int getResponse(uint8_t response);
  int getResponseByte(uint8_t response, uint8_t *value);
  int getResponseWord(uint8_t response, uint16_t *value);
  int getResponseWords(uint8_t response, uint16_t n, uint16_t *value);
  int getResponseString(uint8_t response, char *string);
  int sendByte(uint8_t command);
  int sendWord(uint16_t command);
  int setDisplayModel();
};

#endif /* GOLDELOX_H */

godelox.cpp

#include "Arduino.h"
#include "goldelox.h"

/*
 * Constructor
 */
GOLDELOX::GOLDELOX(Stream *port) {
  serialPort = port;
}

/*
 *  Public methods
 */
void GOLDELOX::begin() {
  setDisplayModel();
}

/*
 * Text Commands
 */
int GOLDELOX::moveCursor(uint16_t x, uint16_t y) {
  sendWord(GOLDELOX_CMD_MOVE_CURSOR);
  sendWord(y);
  sendWord(x);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::putCharacter(char character) {
  sendWord(GOLDELOX_CMD_PUT_CHARACTER);
  sendWord(character);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::putString(char *string) {
  int length = strlen(string);
  
  sendWord(GOLDELOX_CMD_PUT_STRING);
  for (int i = 0; i < length; i++) {
    sendByte(string[i]);
  }
  sendByte(NULL);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::characterWidth(char character, uint16_t *width) {
  int result;

  sendWord(GOLDELOX_CMD_CHARACTER_WIDTH);
  sendByte(character);
  
  return(getResponseWord(GOLDELOX_RESPONSE_ACK, width));
}

int GOLDELOX::characterHeight(char character, uint16_t *height) {
  int result;

  sendWord(GOLDELOX_CMD_CHARACTER_HEIGHT);
  sendByte(character);
  
  return(getResponseWord(GOLDELOX_RESPONSE_ACK, height));
}

int GOLDELOX::textForegroundColor(uint16_t color) {
  sendWord(GOLDELOX_CMD_TEXT_FOREGROUND_COLOR);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textBackgroundColor(uint16_t color) {
  sendWord(GOLDELOX_CMD_TEXT_BACKGROUND_COLOR);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textWidth(uint16_t multiplier) {
  sendWord(GOLDELOX_CMD_TEXT_WIDTH);
  sendWord(multiplier);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textHeight(uint16_t multiplier) {
  sendWord(GOLDELOX_CMD_TEXT_HEIGHT);
  sendWord(multiplier);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textXGap(uint16_t pixelcount) {
  sendWord(GOLDELOX_CMD_TEXT_X_GAP);
  sendWord(pixelcount);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textYGap(uint16_t pixelcount) {
  sendWord(GOLDELOX_CMD_TEXT_Y_GAP);
  sendWord(pixelcount);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textBold(uint16_t mode) {
  sendWord(GOLDELOX_CMD_TEXT_BOLD);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textInverse(uint16_t mode) {
  sendWord(GOLDELOX_CMD_TEXT_INVERSE);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textItalic(uint16_t mode) {
  sendWord(GOLDELOX_CMD_TEXT_ITALIC);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textOpacity(uint16_t mode) {
  sendWord(GOLDELOX_CMD_TEXT_OPACITY);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textUnderline(uint16_t mode) {
  sendWord(GOLDELOX_CMD_TEXT_UNDERLINE);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::textAttributes(uint16_t value) {
  sendWord(GOLDELOX_CMD_TEXT_ATTRIBUTES);
  sendWord(value);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::setTextParameters(uint16_t function, uint16_t value) {
  sendWord(GOLDELOC_CMD_SET_TEXT_PARAMETERS);
  sendWord(function);
  sendWord(value);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

/*
 * Graphics Commands
 */
int GOLDELOX::clearScreen() {
  sendWord(GOLDELOX_CMD_CLEAR_SCREEN);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::changeColor(uint16_t oldColor, uint16_t newColor) {
  sendWord(GOLDELOX_CMD_CHANGE_COLOR);
  sendWord(oldColor);
  sendWord(newColor);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_CIRCLE);
  sendWord(x);
  sendWord(y);
  sendWord(rad);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawFilledCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_FILLED_CIRCLE);
  sendWord(x);
  sendWord(y);
  sendWord(rad);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_LINE);
  sendWord(x1);
  sendWord(y1);
  sendWord(x2);
  sendWord(y2);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_RECTANGLE);
  sendWord(x1);
  sendWord(y1);
  sendWord(x2);
  sendWord(y2);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawFilledRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_FILLED_RECTANGLE);
  sendWord(x1);
  sendWord(y1);
  sendWord(x2);
  sendWord(y2);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawPolyline(uint16_t n, uint16_t *xArray, uint16_t *yArray, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_POLYLINE);
  sendWord(n);
  
  for (int i = 0; i < n; i++) {
    sendWord(xArray[i]);
  }

  for (int i = 0; i < n; i++) {
    sendWord(yArray[i]);
  }
  
  sendWord(color);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawPolygon(uint16_t n, uint16_t *xArray, uint16_t *yArray, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_POLYGON);
  sendWord(n);
  
  for (int i = 0; i < n; i++) {
    sendWord(xArray[i]);
  }

  for (int i = 0; i < n; i++) {
    sendWord(yArray[i]);
  }
  
  sendWord(color);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) {
  sendWord(GOLDELOX_CMD_DRAW_TRIANGLE);
  sendWord(x1);
  sendWord(y1);
  sendWord(x2);
  sendWord(y2);
  sendWord(x3);
  sendWord(y3);
  sendWord(color);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::calculateOrbit(uint16_t angle, uint16_t distance, uint16_t *dist) {
  sendWord(GOLDELOX_CMD_CALCULATE_ORBIT);
  sendWord(angle);
  sendWord(distance);
  
  return getResponseWords(GOLDELOX_RESPONSE_ACK, 2, dist);
}

int GOLDELOX::putPixel(uint16_t x, uint16_t y, uint16_t color) {
  sendWord(GOLDELOX_CMD_PUT_PIXEL);
  sendWord(x);
  sendWord(y);
  sendWord(color);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::readPixel(uint16_t x, uint16_t y, uint16_t *color) {
  sendWord(GOLDELOX_CMD_READ_PIXEL);
  sendWord(x);
  sendWord(y);
  
  getResponseWord(GOLDELOX_RESPONSE_ACK, color);
}

int GOLDELOX::moveOrigin(uint16_t xpos, uint16_t ypos) {
  sendWord(GOLDELOX_CMD_MOVE_ORIGIN);
  sendWord(xpos);
  sendWord(ypos);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::drawLineAndMoveOrigin(uint16_t xpos, uint16_t ypos) {
  sendWord(GOLDELOX_CMD_DRAW_LINE_AND_MOVE_ORIGIN);
  sendWord(xpos);
  sendWord(ypos);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::clipping(uint16_t value) {
  sendWord(GOLDELOX_CMD_CLIPPING);
  sendWord(value);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::setClipWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
  sendWord(GOLDELOX_CMD_SET_CLIP_WINDOW);
  sendWord(x1);
  sendWord(y1);
  sendWord(x2);
  sendWord(y2);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::extendClipRegion() {
  sendWord(GOLDELOX_CMD_EXTEND_CLIP_REGION);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::backgroundColor(uint16_t color) {
  sendWord(GOLDELOX_CMD_BACKGROUND_COLOR);
  sendWord(color);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::outlineColor(uint16_t color) {
  sendWord(GOLDELOX_CMD_OUTLINE_COLOR);
  sendWord(color);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}
  
int GOLDELOX::contrast(uint16_t contrast) {
  sendWord(GOLDELOX_CMD_CONTRAST);
  sendWord(contrast);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::frameDelay(uint16_t msec) {
  sendWord(GOLDELOX_CMD_FRAME_DELAY);
  sendWord(msec);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::linePattern(uint16_t pattern) {
  sendWord(GOLDELOX_CMD_LINE_PATTERN);
  sendWord(pattern);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::screenMode(uint16_t mode) {
  sendWord(GOLDELOX_CMD_SCREEN_MODE);
  sendWord(mode);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::setGraphicsParameters(uint16_t function, uint16_t value) {
  sendWord(GOLDELOX_CMD_SET_GRAPHICS_PARAMETERS);
  sendWord(function);
  sendWord(value);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}
  
/*
 * Media Commands(SD/SDHC Memory Cards)
 */
int GOLDELOX::mediaInit(uint16_t *value) {
  sendWord(GOLDELOX_CMD_MEDIA_INIT);
  
  return(getResponseWord(GOLDELOX_RESPONSE_ACK, value));
}

int GOLDELOX::setByteAddress(uint32_t address) {
  sendWord(GOLDELOX_CMD_SET_BYTE_ADDRESS);
  sendWord(address >> 16);
  sendWord(address & 0xffff);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::setSectorAddress(uint32_t address) {
  sendWord(GOLDELOX_CMD_SET_SECTOR_ADDRESS);
  sendWord(address >> 16);
  sendWord(address & 0xffff);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::readByte(uint8_t *value) {
  sendWord(GOLDELOX_CMD_READ_BYTE);
  
  return(getResponseByte(GOLDELOX_RESPONSE_ACK, value));
}

int GOLDELOX::readWord(uint16_t *value) {
  sendWord(GOLDELOX_CMD_READ_WORD);
  
  return(getResponseWord(GOLDELOX_RESPONSE_ACK, value));
}

int GOLDELOX::writeByte(uint8_t value, uint16_t *status) {
  sendWord(GOLDELOX_CMD_WRITE_BYTE);
  sendByte(0x00);
  sendByte(value);

  return(getResponseWord(GOLDELOX_RESPONSE_ACK, status));
}

int GOLDELOX::writeWord(uint16_t value, uint16_t *status) {
  sendWord(GOLDELOX_CMD_WRITE_BYTE);
  sendWord(value);

  return(getResponseWord(GOLDELOX_RESPONSE_ACK, status));
}

int GOLDELOX::flushMedia(uint16_t *status) {
  sendWord(GOLDELOX_CMD_FLUSH_MEDIA);
  
  return(getResponseWord(GOLDELOX_RESPONSE_ACK, status));
}

int GOLDELOX::displayImageRaw(uint16_t x, uint16_t y) {
  sendWord(GOLDELOX_CMD_DISPLAY_IMAGE_RAW);
  sendWord(x);
  sendWord(y);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::displayVideoRaw(uint16_t x, uint16_t y) {
  sendWord(GOLDELOX_CMD_DISPLAY_VIDEO_RAW);
  sendWord(x);
  sendWord(y);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::displayVideoFrameRaw(uint16_t x, uint16_t y, uint16_t frameNumber) {
  sendWord(GOLDELOX_CMD_DISPLAY_VIDEO_RAW);
  sendWord(x);
  sendWord(y);
  sendWord(frameNumber);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

/*
 * Sound and Tune Commands
 */
int GOLDELOX::beep(uint16_t note, uint16_t duration) {
  sendWord(GOLDELOX_CMD_BEEP);
  sendWord(note);
  sendWord(duration);
  
  return getResponse(GOLDELOX_RESPONSE_ACK);
}

/*
 * System Commands
 */
int GOLDELOX::getDisplayModel(char *string) {
  sendWord(GOLDELOX_CMD_GET_DISPLAY_MODEL);

  return getResponseString(GOLDELOX_RESPONSE_ACK, string);
}

int GOLDELOX::screenSaverTimeout(uint16_t timeout) {
  sendWord(GOLDELOX_CMD_SCREEN_SAVER_TIMEOUT);
  sendWord(timeout);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

int GOLDELOX::screenSaverSpeed(uint16_t speed) {
  sendWord(GOLDELOX_CMD_SCREEN_SAVER_SPEED);
  sendWord(speed);

  return getResponse(GOLDELOX_RESPONSE_ACK);
}

/*
 * Utility commands
 */

int GOLDELOX::rgbToColor(uint8_t red, uint8_t green, uint8_t blue) {
  return (((red & 0b11111000) << 8) | ((green & 0b11111100) << 3) | (blue >> 3));
}
 
/*
 *  Private methods
 */
int GOLDELOX::sendByte(uint8_t command) {
  serialPort->write((command));
}

int GOLDELOX::sendWord(uint16_t command) {
  serialPort->write((command >> 8));
  serialPort->write((command & 0xff));
}

int GOLDELOX::getResponse(uint8_t response) {
  while(serialPort->available() <= 0) {
    delay(2);
  }
  
  return (response == serialPort->read()) ? true : false;
}

int GOLDELOX::getResponseByte(uint8_t response, uint8_t *value) {
  union {
    char buffer[2];
    uint16_t value;
  } buffer;
  int result;
  
  if (result = getResponse(response)) {
    while (serialPort->available() < 2) {
      delay(2);
    }
    buffer.buffer[1] = serialPort->read();
    buffer.buffer[0] = serialPort->read();
  }
  *value = buffer.value & 0x0f;
  
  return result;
}

int GOLDELOX::getResponseWord(uint8_t response, uint16_t *value) {
  union {
    char buffer[2];
    uint16_t value;
  } buffer;
  int result;
  
  if (result = getResponse(response)) {
    while (serialPort->available() < 2) {
      delay(2);
    }
    buffer.buffer[1] = serialPort->read();
    buffer.buffer[0] = serialPort->read();
  }
  *value = buffer.value;
  
  return result;
}

int GOLDELOX::getResponseWords(uint8_t response, uint16_t n, uint16_t *value) {
  union {
    char buffer[2];
    uint16_t value;
  } buffer;
  int result;
  int nbytes = 2 * n;
  
  if (result = getResponse(response)) {
    while (serialPort->available() < nbytes) {
      delay(2);
    }
    
    for (int i = 0; i < nbytes; i++) {
      buffer.buffer[1] = serialPort->read();
      buffer.buffer[0] = serialPort->read();
    
      value[i] = buffer.value;
    }
  }  
  
  return result;
}

int GOLDELOX::getResponseString(uint8_t response, char *string) {
  uint16_t value;
  int result;
  
  if (result = getResponseWord(response, &value)) {
    serialPort->readBytes(string, value);
    string[value] = '\0';
  }
  
  return result;
}

int GOLDELOX::setDisplayModel() {
  int result = getDisplayModel(displayModel);

  return result;
}

バージョン

Arduino 1.5.5/Arduino Uno



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2013 garretlab all rights reserved.
inserted by FC2 system