秋月電子などで販売されているSHARP製HR-TFTモノクロメモリ液晶を、直接駆動するためのライブラリです。 図形、文字列の描画が可能です。 日本語のフォントも内包していますが、FlashサイズやRAMサイズが小さいものだと扱いきれないかもしれません。 既存のライブラリとは違い、貴重なSPIポートを占拠しません。DigitalOut端子3本でSPIモドキを実現しています。 結線方法については、デモプログラムのページをご参照ください。

Dependents:   SHARP_MEMORYLCD_WJ

内部画素記憶配列に関する注意

このライブラリでは、ライブラリを通して描かれた全画素の情報ををchar型の一次元配列として記憶します。
故に、小さなRAMしか搭載していないものではOutOfMemoryになり、うまく動作しません

init関数で固まる場合は、memset(R, -1, siz); で配列が初期化できずに止まっている可能性があります。

内部画素記憶配列のサイズは、((表示幅[px] / 8) * 表示高さ[px])[byte]です。
表示幅400px、表示高さ240pxの場合は 12Kbyte(12,000byte) の領域を要します。

シャープ製メモリ液晶直接駆動用ライブラリ

秋月電子などで販売されている、シャープ製のモノクロメモリ液晶を
直接駆動させるためのライブラリとデモプログラムです。

図形や文字列を比較的簡単に表示させることが可能です。
また、メモリに余裕があれば日本語(全角文字)も描画可能です。

文字描画のアルゴリズムは、こちらのページで公開されていた
日本語ビットマップフォント表示アルゴリズムを改変して使用しています。
松浦光洋様、素晴らしいアルゴリズムを公開していただきありがとうございます。
現在ソースコードの公開は停止されている模様です。

また、ビットマプフォントにはM+ BITMAP FONTSで公開されている
Mplus-gothic-medium-R-normal 12pxを使用しています。


使用できる液晶製品

LS027B7DH01Aと同一の駆動方式であれば駆動可能です。

対応済みと思われる製品(テストはLS027B7DH01Aで行っています)

LS012B7DD01とLS013B7DH06は駆動方式が異なるため使用できません。

直接結線して駆動することを前提としてコードを書いているので、
間にSRAMやEEPROMなどを挟んだり、4線式SPIの使用を前提としたものでは動作しません。


デモプログラムのページ(結線方法など)

mbed LPC1768用デモプログラム


描画方式と内部画素記憶配列について

メモリ液晶の描画方式は

  1. ゲートラインアドレス(1から始まる行番号)を選択
  2. 1行あたりの画素数を8画素ごとに区切って連続転送する(幅 / 8の数だけ) というものです。

つまり2値(白黒)の8画素なので、char型(1byte)の配列で画素をコントロールすることが可能です。

一見単純に見えますが、行ごとの更新では更新したくない画素も更新対象に入ってしまいます。
例えば、このような行がある場合、

11111011 11111111

13番目の画素に黒点を打つために「11111111 11110111」のデータを送ると・・・

11111111 11110111 ←6番目の画素も上書きされてしまう

更新したくない画素も更新されてしまいます。

これでは意図した描画が簡単に行えませんので、このライブラリでは現在の画素情報を
char型の1次元配列で保管し(サイズは 幅 / 8 * 高さ)、この記憶情報を更新してから、液晶に
送ることによって図形などの描画を実現しています。
例えば、

11111011 11111111

13番目の画素に黒点を打つために「11111111 11110111」のデータを表示したい・・・

.......11111011 11111111 ←もともと表示されていたデータ
AND)...11111111 11110111 ←表示したいデータと論理積をとる
++++++++++++++++++++++++
.......11111011 11110111 ←液晶に書き込むべき値がでてくる

これで更新すべき値を算出して、液晶に流し込んでいます。

また、この液晶は1が白0が黒です。
これもわかりにくいので、このライブラリ内では1を黒0を白として扱っています。


即時描画(immidiate)について

関数の最後の引数にbool型のimmidiateというものがありますが、これは即時描画を行うかどうかのフラグです。

例えばpixel関数で1個打点したあと、immidiatetrueであればすぐに液晶に反映されます。
immidiatefalseの場合、内部画素記憶配列のみを更新し、液晶には反映しません。

1行だけの反映であれば大した時間はかかりませんが、反映する行が増えれば増えるほど
処理の時間がかかってしまいますので、書きたい情報を全部内部画素記憶配列に書き込んでから
一気にドバっと反映するほうが効率的で処理時間の短縮が見込めます。

なので、文字や四角形や格子模様などを複数行広範囲にわたって書き込む場合はimmidiatefalseにして
すべての描画処理が完了したあとにwriteArrayN関数やwriteArrayA関数を使用して
ドバっと更新するほうがお得です。

ちなみに、各関数のimmidiateのデフォルト値はtrueです。
引数を省略した場合は即時描画されてしまいますのでご注意ください。


COM反転信号

COM反転は、液晶の寿命を延ばすために(焼き付き防止?)人間に見えない速度で液晶を明滅させる仕組みです。
COM反転信号はCOM反転を行うタイミングを液晶に伝達するもので、外部信号と内部信号の2種類があります。
このライブラリでは呼ばれたコンストラクタによって処理を変えており、
引数が3つのコンストラクタで呼ばれたらCOM反転は内部信号を使用します。
引数が5つのコンストラクタで呼ばれたらCOM反転は外部信号を使用します。
(ただし、引数が5つでもDigitalOutができないピンであれば内部信号に切り替わる)

引数が3つのコンストラクタを呼ぶ場合は、EXTCOMの端子VSS(GND)に接続し 引数が5つのコンストラクタを呼ぶ場合は、EXTCOMの端子VDD(3.3-5V)に接続してください。

COM反転信号はTickerを使って自動的に送出される仕組みになっていますが
init関数を呼ぶまではタイマーは作動しません。ユーザーがderegTimer関数でタイマーを解除した場合も、
regTimer関数で再度タイマーを開始するまでは止まったままになります。

また、int main()が終了した場合もSH_MLCD_Jクラスのインスタンスそのものが削除されて
COM反転信号が止まりますので、プログラムの終了を意図的に遅延させるか、プログラム終了後は
速やかに液晶を取り外してください。

SH_MLCD_J.h

Committer:
Yajirushi
Date:
2015-12-11
Revision:
0:8512c64be557

File content as of revision 0:8512c64be557:

/* Sharp MemoryLCD Graphic Library (with Japanese Font)
 * Copyright (c) 2015 Yajirushi(Cursor)
 *
 * Released under the MIT license
 * http://opensource.org/licenses/mit-license.php
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * -----------------------------------------------------------------
 * M+ BITMAP FONTS
 * http://mplus-fonts.osdn.jp/mplus-bitmap-fonts/index.html
 *
 * LICENSE
 *
 * These fonts are free software.
 * Unlimited permission is granted to use, copy,
 * and distribute it, with or without modification,
 * either commercially and noncommercially.
 *
 * THESE FONTS ARE PROVIDED "AS IS" WITHOUT WARRANTY.
 */
#include "mbed.h"

#ifndef SH_MLCD_J
#define SH_MLCD_J

//SPIモドキの持ち時間
#define SHMLCD_J_SPIWAIT 1

//MLCDの命令
#define SHMLCD_J_WRITE 0x80
#define SHMLCD_J_COM 0x40
#define SHMLCD_J_CLEAR 0x20
#define SHMLCD_J_DUMMY 0x00

//ピクセルモード
#define SHMLCD_J_BLACK 0
#define SHMLCD_J_ERASE 1
#define SHMLCD_J_INVERT -1

/** シャープ製メモリ液晶用直接駆動ライブラリ
 *
 * 秋月電子通商などで販売されている、シャープ製メモリ液晶を直接駆動させるためのライブラリです。
 * 「みんなのラボ」から販売されている、SRAMを介すもの(メモリ液晶ブレークアウト基板)では動作しません。
 *
 * 2015年時点で販売されている、同じ駆動方式のLCD一覧:(このライブラリで駆動可能)
 * LS010B7DH01, LS013B7DH05, LS013B7DH03, LS027B7DH01A, LS044Q7DH01
 * (LS012B7DD01, LS013B7DH06は駆動方式が異なるため使用できません)
 *
 * Example:
 * @code
 * //メモリ液晶に様々な図形や文字を表示する
 *
 * #include "mbed.h"
 * #include "SH_MLCD_J.h"
 *
 * SHMLCD_J mlcd(p26, p25, p24);
 *
 * int main(){
 *
 *    wait(20.0); //結線完了までの待ち時間(不要であれば削除)
 *
 *    //初期化(引数にはデータシートに書いてある表示横幅と表示高さを指定する)
 *    mlcd.init(400, 240);
 *
 *    //四角形(即時描画)
 *    mlcd.drawRect(15, 15, 20, 20, SHMLCD_J_BLACK, true);
 *    mlcd.drawRect2(45, 15, 65, 35, SHMLCD_J_BLACK, true);
 *    mlcd.fillRect(75, 15, 20, 20, SHMLCD_J_BLACK, true);
 *    mlcd.fill2Point(105, 15, 125, 35, SHMLCD_J_BLACK, true);
 *
 *    //円(あとで描画):第5引数がfalseだと即時描画しない
 *    mlcd.drawCircle(25, 55, 10, SHMLCD_J_BLACK, false);
 *    mlcd.fillCircle(55, 55, 10, SHMLCD_J_BLACK, false);
 *
 *    //小さい文字(あとで描画):第5引数がfalseだと即時描画しない
 *    char str1[] = "small text! 小さい文字は余裕。\n改行も有効です。タブは無理。";
 *    mlcd.ws(str1, 10, 80, SHMLCD_J_BLACK, false);
 *
 *    //大きい文字(即時描画):第4引数にズーム倍率(整数)で倍角可能
 *    char str2[] = "Large Text! 2倍角も余裕。";
 *    mlcd.ws(str2, 10, 160, 2, SHMLCD_J_BLACK, true);
 *
 *    wait(3.0);
 *
 *    //表示画素全部更新(ここで円と小さい文字が描画されます)
 *    mlcd.writeArrayA();
 *
 *    wait(3.0);
 *
 *    //設定された表示幅と高さを取得
 *    int width_size = mlcd.getWidth();
 *    int height_size = mlcd.getHeight();
 *
 *    //グリッドを表示
 *    //垂直線を等間隔にXOR表示(描画はあとで):第4引数は描画モード
 *    //描画モード(fillCircleはSHMLCD_J_INVERTが使えません):
 *    // SHMLCD_J_BLACK (0): 黒で描画します
 *    // SHMLCD_J_ERASE (1): 白で描画します
 *    // SHMLCD_J_INVERT (-1): 画素を反転(XOR)させます(白なら黒、黒なら白)
 *    for(int x=10; x<width_size; x+=20){
 *        mlcd.drawLine(x, 0, x, height_size-1, SHMLCD_J_INVERT, false);
 *    }
 *    //水平線を等間隔にXOR表示(描画はあとで):第4引数は描画モード
 *    for(int y=10; y<height_size; y+=20){
 *        mlcd.drawLine(0, y, width_size-1, y, SHMLCD_J_INVERT, false);
 *    }
 *
 *    //表示画素特定部分だけ更新:ライン80からライン160まで更新
 *    mlcd.writeArrayN(80, 160);
 *
 *    wait(3.0);
 *
 *    //表示画素全部更新
 *    mlcd.writeArrayA();
 *
 * }
 * @endcode
 */
class SHMLCD_J{
public:
    /** コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します
     *
     *  @param vSCK メモリ液晶のSCK端子に出力するピンを指定
     *  @param vSI メモリ液晶のSI端子に出力するピンを指定
     *  @param vCS メモリ液晶のSCS端子に出力するピンを指定
     *  @param vCOM メモリ液晶のCOM端子に出力するピンを指定
     *  @param vDISP メモリ液晶のDISP端子に出力するピンを指定
     */
    SHMLCD_J(PinName vSCK, PinName vSI, PinName vCS, PinName vCOM, PinName vDISP);

    /** コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します
     *
     *  @param vSCK メモリ液晶のSCK端子に出力するピンを管理するDigitalOutポインタを指定
     *  @param vSI メモリ液晶のSI端子に出力するピンをを管理するDigitalOutポインタを指定
     *  @param vCS メモリ液晶のSCS端子に出力するピンをを管理するDigitalOutポインタを指定
     *  @param vCOM メモリ液晶のCOM端子に出力するピンをを管理するDigitalOutポインタを指定
     *  @param vDISP メモリ液晶のDISP端子に出力するピンをを管理するDigitalOutポインタを指定
     *
     * Example:
     * @code
     * #include "mbed.h"
     * #include "SH_MLCD_J.h"
     *
     * DigitalOut i_sck(p26);
     * DigitalOut i_si(p25);
     * DigitalOut i_cs(p24);
     * DigitalOut i_com(p23);
     * DigitalOut i_disp(p22);
     *
     * int main(){
     *     SHMLCD_J mlcd(&i_sck, &i_si, &i_cs, &i_com, &i_disp); //<- 先に宣言したものを&(アドレス)で渡す
     *     mlcd.init(400, 240);
     *     mlcd.pixel(50, 50);
     * }
     * @endcode
     */
    SHMLCD_J(DigitalOut *vSCK, DigitalOut *vSI, DigitalOut *vCS, DigitalOut *vCOM, DigitalOut *vDISP);

    /** コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します(COM端子とDISP端子は使用しません)
     *
     *  @param vSCK メモリ液晶のSCK端子に出力するピンを指定
     *  @param vSI メモリ液晶のSI端子に出力するピンを指定
     *  @param vCS メモリ液晶のSCS端子に出力するピンを指定
     */
    SHMLCD_J(PinName vSCK, PinName vSI, PinName vCS);

    /** コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します(COM端子とDISP端子は使用しません)
     *
     *  @param vSCK メモリ液晶のSCK端子に出力するピンを管理するDigitalOutポインタを指定
     *  @param vSI メモリ液晶のSI端子に出力するピンをを管理するDigitalOutポインタを指定
     *  @param vCS メモリ液晶のSCS端子に出力するピンをを管理するDigitalOutポインタを指定
     *
     * Example:
     * @code
     * #include "mbed.h"
     * #include "SH_MLCD_J.h"
     *
     * DigitalOut sck(p26);
     * DigitalOut si(p25);
     * DigitalOut cs(p24);
     *
     * int main(){
     *     SHMLCD_J mlcd(&sck, &si, &cs); //<- 先に宣言したものを&(アドレス)で渡す
     *     mlcd.init(400, 240);
     *     mlcd.pixel(50, 50);
     * }
     * @endcode
     */
    SHMLCD_J(DigitalOut *vSCK, DigitalOut *vSI, DigitalOut *vCS);

    /** デストラクタ:内部配列と使用した変数を削除します(ユーザーが呼ぶ必要はありません)
     */
    ~SHMLCD_J();

private:
    //ディスプレイの幅、高さ
    unsigned short _width, _height;

    //一行のデータ量(_width / 8)
    unsigned char _bytes;

    //画素状態記憶用配列
    //最大12KByte(400 / 8 * 240 = 12,000)
    char *R;

    //通信に使用するピン(SPIモドキ)
    DigitalOut *pinSCK, *pinSI, *pinSCS;

    //外部信号用ピン
    DigitalOut *pinCOM, *pinDISP;
    bool useEcom, useEdisp;

    //COM信号状態
    bool comFlag;

    //COM信号用タイマー
    Ticker comT;

    //命令送信フラグ
    bool busySPI;

    //SPIモドキのコマンド送出
    void send_mode(unsigned char val);
    void send_addr(unsigned char val);
    void send_data(unsigned char val);

public:
    /** 初期化:使用する配列や端子の状態を初期化します
     *  @warning インスタンス1つにつき1回しか呼ばないこと
     *
     *  @param dispWidth メモリ液晶の表示幅をピクセルで指定する
     *  @param dispHeight メモリ液晶の表示高さをピクセル指定する
     *
     *  @retval true 初期化に成功した
     *  @retval false 初期化に失敗した(表示幅や高さが間違っている等)
     */
    bool init(unsigned short dispWidth, unsigned short dispHeight);

    /** 初期化時に指定した表示ピクセル幅を返す
     *
     *  @returns 初期化時に指定した表示ピクセル幅
     */
    unsigned short getWidth();

    /** 初期化時に指定した表示ピクセル高さを返す
     *
     *  @returns 初期化時に指定した表示ピクセル高さ
     */
    unsigned short getHeight();

    /** 液晶の表示をクリアする:内部画素記憶配列はクリアされない
     */
    void clear();

    /** 液晶の表示をクリアする:内部画素記憶配列はクリアされない(clear()のエイリアス)
     */
    void cls();

    /** 内部画素記憶配列をクリアする:表示はクリアされない
     */
    void clearArray();

    /** 内部画素記憶配列をクリアする:表示はクリアされない(clearArray()のエイリアス)
     */
    void cla();

    /** DISP端子をONにする:外部DISP信号を使用しない場合は何も起きない
     */
    void dispON();

    /** DISP端子をOFFにする:外部DISP信号を使用しない場合は何も起きない
     */
    void dispOFF();

    /** 液晶寿命を延ばすためにCOM信号を反転させる
     *
     * initの中で自動的にタイマーに登録されるので、ほとんどの場合は呼ぶ必要がない
     */
    void invertCOM();

    /** 液晶寿命を延ばすためのCOM信号反転をタイマーに登録して自動的に行う
     *
     * initの中で自動的に呼ばれるので、ほとんどの場合は呼ぶ必要がない
     *
     * @param tickTime COM信号反転間隔(秒)
     */
    void regCOMTimer(float tickTime=0.25);

    /** 液晶寿命を延ばすためのCOM信号反転のタイマーを解除する
     */
    void deregCOMTimer();

    /** 内部画素記憶配列の特定の行にデータを上書きする
     *
     *  @param ln 上書きする行(0 から 高さ-1 まで)
     *  @param data 上書きするデータ
     */
    void updateArray1(unsigned char ln, const char *data);

    /** 内部画素記憶配列の特定の範囲にデータを上書きする
     *
     *  @param sn 上書きを開始する行(0 から 高さ-1 まで)
     *  @param en 上書きが終了する行(0 から 高さ-1 まで)
     *  @param data 上書きするデータ
     */
    void updateArrayN(unsigned char sn, unsigned char en, const char *data);

    /** 内部画素記憶配列を全て上書きする
     *
     *  @param data 上書きするデータ
     */
    void updateArrayA(const char *data);

    /** 内部画素記憶配列の特定の行をメモリ液晶に表示する
     *
     *  @param ln 表示する行(0 から 高さ-1 まで)
     */
    void writeArray1(unsigned char ln);

    /** 内部画素記憶配列の特定の範囲をメモリ液晶に表示する
     *
     *  @param sn 表示したい範囲の開始行(0 から 高さ-1 まで)
     *  @param sn 表示したい範囲の終了行(0 から 高さ-1 まで)
     */
    void writeArrayN(unsigned char sn, unsigned char en);

    /** 内部画素記憶配列を全てメモリ液晶に表示する
     */
    void writeArrayA();

    /** データをメモリ液晶の特定行に表示する(内部画素記憶配列を介さない)
     *
     *  @param ln 表示する行(0 から 高さ-1 まで)
     *  @param data 表示するデータ
     */
    void write1(unsigned char ln, const char *data);

    /** データをメモリ液晶の特定の範囲に表示する(内部画素記憶配列を介さない)
     *
     *  @param sn 表示したい範囲の開始行(0 から 高さ-1 まで)
     *  @param en 表示したい範囲の終了行(0 から 高さ-1 まで)
     *  @param data 表示するデータ
     */
    void writeN(unsigned char sn, unsigned char en, const char *data);

    /** データをメモリ液晶全域に表示する(内部画素記憶配列を介さない)
     *
     *  @param data 表示するデータ
     */
    void writeA(const char *data);

    /** メモリ液晶の特定の座標に1ピクセルのドットを表示する
     *
     *  @param x X座標(0 から 幅-1 まで)
     *  @param y Y座標(0 から 高さ-1 まで)
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void pixel(unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に線を表示する
     *
     *  @param fromX 始点のX座標(0 から 幅-1 まで)
     *  @param fromY 始点のY座標(0 から 高さ-1 まで)
     *  @param toX 終点のX座標(0 から 幅-1 まで)
     *  @param toY 終点のY座標(0 から 高さ-1 まで)
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void drawLine(unsigned short fromX, unsigned short fromY, unsigned short toX, unsigned short toY, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に四角形を表示する
     *
     *  @param left 画面左端からの距離(0 から 幅-1 まで)
     *  @param top 画面上端からの距離(0 から 高さ-1 まで)
     *  @param width 四角形の幅
     *  @param height 四角形の高さ
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void drawRect(unsigned short left, unsigned short top, unsigned short width, unsigned short height, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に四角形を表示する(対角点指定)
     *
     *  @param x1 四角形の左上の点のX座標(0 から 幅-1 まで)
     *  @param y1 四角形の左上の点のY座標(0 から 高さ-1 まで)
     *  @param x2 四角形の右下の点のX座標(0 から 幅-1 まで)
     *  @param y2 四角形の右下の点のY座標(0 から 高さ-1 まで)
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void drawRect2(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に塗りつぶされた四角形を表示する
     *
     *  @param left 画面左端からの距離(0 から 幅-1 まで)
     *  @param top 画面上端からの距離(0 から 高さ-1 まで)
     *  @param width 四角形の幅
     *  @param height 四角形の高さ
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void fillRect(unsigned short left, unsigned short top, unsigned short width, unsigned short height, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に塗りつぶされた四角形を表示する(対角点指定)
     *
     *  @param x1 四角形の左上の点のX座標(0 から 幅-1 まで)
     *  @param y1 四角形の左上の点のY座標(0 から 高さ-1 まで)
     *  @param x2 四角形の右下の点のX座標(0 から 幅-1 まで)
     *  @param y2 四角形の右下の点のY座標(0 から 高さ-1 まで)
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void fill2Point(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に円を表示する
     *
     *  @param centerX 円の中心のX座標(0 から 幅-1 まで)
     *  @param centerY 円の中心のY座標(0 から 高さ-1 まで)
     *  @param r 円の半径
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     */
    void drawCircle(unsigned short centerX, unsigned short centerY, unsigned short r, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に塗りつぶされた円を表示する
     *
     *  @param centerX 円の中心のX座標(0 から 幅-1 まで)
     *  @param centerY 円の中心のY座標(0 から 高さ-1 まで)
     *  @param r 円の半径
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): fillCircleは描画方法が特殊なためうまく描画できません
     *
     *  @param immidiate 即時描画させる
     */
    void fillCircle(unsigned short centerX, unsigned short centerY, unsigned short r, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に文字を表示する
     *
     *  @param s 表示する文字
     *  @param x テキストを囲う四角形の左上のX座標
     *  @param y テキストを囲う四角形の左上のY座標
     *  @param zoom 拡大倍率
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     *
     *  @retval -1 表示できなかった
     *  @retval 0以上 文字のバイトサイズ
     */
    signed char drawChar(const char *s, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に文字列を表示する
     *
     *  @param str 表示する文字列
     *  @param x テキストを囲う四角形の左上のX座標
     *  @param y テキストを囲う四角形の左上のY座標
     *  @param zoom 拡大倍率
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     *
     *  @retval -1 表示できなかった
     *  @retval 1 表示できた
     */
    signed char writeString(const char *str, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に文字列を表示する
     *
     *  @param str 表示する文字列
     *  @param x テキストを囲う四角形の左上のX座標
     *  @param y テキストを囲う四角形の左上のY座標
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     *
     *  @retval -1 表示できなかった
     *  @retval 1 表示できた
     */
    signed char writeString(const char *str, unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に文字列を表示する(writeStringのエイリアス)
     *
     *  @param str 表示する文字列
     *  @param x テキストを囲う四角形の左上のX座標
     *  @param y テキストを囲う四角形の左上のY座標
     *  @param zoom 拡大倍率
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     *
     *  @retval -1 表示できなかった
     *  @retval 1 表示できた
     */
    signed char ws(const char *str, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);

    /** メモリ液晶に文字列を表示する(writeStringのエイリアス)
     *
     *  @param str 表示する文字列
     *  @param x テキストを囲う四角形の左上のX座標
     *  @param y テキストを囲う四角形の左上のY座標
     *  @param mode 表示モード
     *
     *  @note modeの一覧:
     *   SHMLCD_J_BLACK (0): 黒く表示する
     *   SHMLCD_J_ERASE (1): 白く表示する
     *   SHMLCD_J_INVERT (-1): 画素を逆転させる(黒なら白、白なら黒)
     *
     *  @param immidiate 即時描画させる
     *
     *  @retval -1 表示できなかった
     *  @retval 1 表示できた
     */
    signed char ws(const char *str, unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true);
};

#endif