Raspberry Pi 4で スマスピ動作

(RaspbianOS 2020-02-05版では、Debian向けのAIYインストールを使って楽になったので、コメント4に投稿)

Raspberry Pi 4でAIY Voice Kit を動作させ、「ね~グーグル」の呼びかけができたので、
備忘録とする。RasPi3でも勿論動作する。
更に、14)のcheck_audio.pyを飛ばせば、AIY Voice Kit が無くても動作したので驚いた。Pulseaudioでマイク・スピーカーを切り替えることで自由に構築・運用ができる。
(下記原稿中、「–ダッシュ2個」の表現が全角文字置換されているので要注意)

【新規SDカードに書き込む場合】
1)MicroSDの初期化
  PCにてExplorerがすべて閉じた状態でディスク管理を開いて
  SDドライブのパーティションをすべてボリューム削除する
2)Win32DiskImager等でMicroSDに最新RaspbianOSを書き込む
  https://downloads.raspberrypi.org/raspbian_full_latest
  2019-09-26-raspbian-buster-full.img(Busterバージョン)
3)bootのconfig.txtに次の追記をする
  dtoverlay=googlevoicehat-soundcard
  また次をコメントアウトする
  #dtparam=audio=on
  なお、ミニLCDを使う場合は、次の追記も必要になることが多い。
  7Inch 1024×600だと、config.txtに次の追加を指示されている。
max_usb_current=1
hdmi_force_hotplug=1
config_hdmi_boost=7
hdmi_group=2
hdmi_mode=87
hdmi_cvt 1024 600 60 6 0 0 0
4)bootのトップにsshダミーファイルをおく

5)RasPiにMicroSDを入れ、電源をオンにして起動する
  (もしRasPi4だった場合は、まだgooglevoicehat-soundcardの
  ボードをドッキングさせずに電源を入れる)
6)RaspberryPiの設定誘導に対し、Password,Locale,Time zoneを適切に
  変更し、WiFiのPassKeyを設定する(スマホのGoogleツールで
  デバイス設定するとき、同一AP配下となる様に考慮)
  updateはここではskipする
7)PCからSSHツールにてraspberrypi.localに接続する
  SSHで時々の休止が気になるときは、次のコマンドで省エネを停止できる
  sudo iw dev wlan0 set power_save off
8)ダウンロードリストを拡張して、UPGRADEを実施する
  echo “deb https://dl.google.com/aiyprojects/deb stable main” | sudo tee /etc/apt/sources.list.d/aiyprojects.list
  wget -q -O – https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add –
  sudo apt-get update
  sudo apt-get -y upgrade
  sudo reboot する
  (RasPi4については、ここで画面出力を2Kに確定し、Shutdown
   してgooglevoicehat-soundcardのボードをドッキングさせる)

9)仮置きとしてAIY V2のインストールをする
  sudo apt install –fix-missing dkms
  sudo apt-get install -y aiy-voicebonnet-soundcard-dkms aiy-dkms
  処理中に–configureのエラーが発生するが、無視する:
   aiy-dkms
   aiy-voicebonnet-soundcard-dkms

10)AIYのadcとi2cの変更
  sudo cp /usr/src/aiy-1.1/aiy/iio/adc/aiy-adc.c /usr/src/aiy-1.1/aiy/iio/adc/aiy-adc.c.org
  sudo vi +138 /usr/src/aiy-1.1/aiy/iio/adc/aiy-adc.c
   該当1行の削除
  sudo cp /usr/src/aiy-1.1/aiy/mfd/aiy-io-i2c.c /usr/src/aiy-1.1/aiy/mfd/aiy-io-i2c.c.org
  sudo vi /usr/src/aiy-1.1/aiy/mfd/aiy-io-i2c.c
   2か所のi2c_lock_adapter(i2c->adapter);をi2c_lock_bus(i2c->adapter, I2C_LOCK_ROOT_ADAPTER);に変更
   2か所のi2c_unlock_adapter(i2c->adapter);をi2c_unlock_bus(i2c->adapter, I2C_LOCK_ROOT_ADAPTER);に変更
  インストールする
   sudo dkms install aiy/1.1
  sudo dkms remove aiy-voicebonnet-soundcard/1.0 –all
  sudo reboot する
11)Audioのインストール
  sudo apt-get update
  sudo apt-get install -y pulseaudio pavucontrol
  タイムアウトだったら、上手く行くまでinstallを再試行する。
  処理中のaiy-voicebonnet-soundcardに関するエラーは無視する。
   sudo mkdir /etc/pulse/daemon.conf.d/
  echo “default-sample-rate = 48000” | sudo tee /etc/pulse/daemon.conf.d/aiy.conf
  sudo apt-get install -y aiy-python-wheels
  処理中にlinux_armv6lと–configureのエラーが発生するが、無視する:
   aiy-python-wheels
   aiy-voicebonnet-soundcard-dkms

  また、VLCのHDMIからの音声出力を選択したいならば、
  #dtparam=audio=on
  のコメントを外し、カード番号を入れ替え、さらに次の
  定義を、/etc/asound.conf に追加する。
  <AIY VoiceKITのサウンドカードの人は、次のように設定>
options snd_rpi_googlevoicehat_soundcard index=0
pcm.softvol {
    type softvol
   slave.pcm dmix
        control {
        name Master
        card 0
    }
}
pcm.micboost {
    type route
    slave.pcm dsnoop
    ttable {
        0.0 30.0
        1.1 30.0
    }
}
pcm.!default {
    type asym
    playback.pcm “plug:softvol”
    capture.pcm “plug:micboost”
}
ctl.!default {
    type hw
    card 0
}
  <カード番号の入れ替え>/etc/modprobe.d/alsa-base.conf
  options snd slots=snd_rpi_googlevoicehat_soundcard,snd_bcm2835
  options snd_rpi_googlevoicehat_soundcard index=0
  options snd_bcm2835 index=1

12)protobufのインストール
  cd Downloads
  pip3 download protobuf
  pip3 install ./protobuf-3.11.2-py2.py3-none-any.whl
   (3.11.2の部分は、最新Vnoを使う)
  sudo vi +7 /var/lib/dpkg/info/aiy-python-wheels.postinst
   7-8行をコメントアウトする
  sudo dpkg –configure –force-overwrite –force-overwrite-dir -a
  処理中に–configureのエラーが発生するが、無視する:
   aiy-voicebonnet-soundcard-dkms
  sudo reboot する

13)実行準備
  git clone https://github.com/google/aiyprojects-raspbian.git AIY-projects-python
  sudo mv AIY-projects-python /opt/aiy/projects-python
  ln -s /opt/aiy/projects-python AIY-projects-python
  ln -s /home/pi/AIY-projects-python AIY-voice-kit-python
  sudo pip3 install -e AIY-projects-python

  THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE.
   このエラーが出たとしても無視する。

  sudo cp /opt/aiy/projects-python/src/aiy/assistant/auth_helpers.py \
                  /opt/aiy/projects-python/src/aiy/assistant/auth_helpers.py.org
  sudo vi +75 /opt/aiy/projects-python/src/aiy/assistant/auth_helpers.py
   この行末カッコ内の最後のパラメタ’,-1’を削除する
  pip3 install google-assistant-library==1.0.0
#  (Segmentation Fault防止のため、1.0.1を推奨するメッセージを
   無視して1.0.0をPre設置)
  pip3 install google-assistant-library
  pip3 install google-auth-oauthlib
  sudo pip3 install grpcio
  AIYプロジェクト内の日本語対応が不完全なところを修正する。
   vi +214 /home/pi/.local/lib/python3.7/site-packages/google/assistant/library/assistant.py
   の.encode(‘ASCII’) を.encode(‘utf-8’) にする。
  AIYボードの初期化のために、命令を追加する。
   vi +284 /home/pi/AIY-voice-kit-python/src/aiy/board.py
   に、GPIO.setwarnings(False) を行追加する。
14)次の確認を実施する
  amixer sset Master 50% で、音量を半分にしておく
  export PYTHONPATH=”/home/pi/AIY-voice-kit-python/src”
  /home/pi/AIY-voice-kit-python/checkpoints/check_audio.py

15)次のURLに基づき、アカウント登録をする
  https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00255/042600011/?P=4
  assistant.json ファイルを /home/piに置く
16)サンプルコードの実行
  export PYTHONPATH=”/home/pi/AIY-voice-kit-python/src”
$PYTHONPATH/examples/voice/assistant_library_with_button_demo.py
   初回のスクリプト実行時にURLが表示され、ブラウザでアクセスする
  ことで認証文字列が返される。
  それをスクリプト実行中の質問に貼り付ける。
17)デバイスの登録
  サンプルコードの実行でしばらく放置し、スマホのHomeアプリの設定・詳細設定の
  「アシスタント」に出現した新たなデバイス(Voice Kit)の言語を
  日本語に設定し、属性参照を許可する。

以下は、SmartTV(PX-W3U4,PX-Q3U4使用)に変身させるときの追加作業
18)TVチューナーサポートシステムのインストール
  curl –silent http://pmp-jp.com/test/TVget.sh | sh

19)N2TTS,youtube-dl,mojimojiのインストール
  このURLに従う:https://support.kddi-research.jp/n2/service.html
  (wget -O n2-linux-foc.tgz https://support.kddi-research.jp/n2/download.php?type=5)
  sudo -H pip install youtube-dl
  pip3 install mojimoji
  pip3 install –upgrade google-api-python-client

【RasPi4に対応させ、multiTV.shから aiyTV.shを用意】
  MPEG2に対するプレーヤーとして、OMXからVLCメディアプレーヤに
  切り替えるため、
  source ~/.biling
  if [ “$BILING” = “yes” ]; then
   MPG2 =`vcgencmd codec_enabled MPG2`
   if [ “$MPG2” = “MPG2 disabled” ]; then
   BILING=sel
   fi
  fi
  とし、
  elif [ “$BILING” = “sel” ]; then
   (recdvb –dev ${DEV} –b25 –strip –http 8080 ${LCH}; exit) &
   (sleep 2) &
   cvlc -f –no-video-title-show http://localhost:8080/${CH}/
  fi
  と、プレーヤーを取り換える。
  VLCはマルチスレッドではブロックノイズが出やすいため、スレッドを
  シングルに切り替える。
  <sayJ関数の追加>
  vi $PYTHONPATH/aiy/voice/tts.py
<pre>
def sayJ(text, asynch=0, lang=’ja-JP’, volume=60, pitch=130, speed=100, device=’sysdefault:CARD=ALSA’):

    logging.info(text)
    with tempfile.NamedTemporaryFile(suffix='.wav', dir=RUN_DIR) as f:
       cmd = 'n2tts -p VOLUME=%s -o %s "%s" && aplay -q -D %s %s' % \
             (volume, f.name, text, device, f.name)
       if asynch==0: subprocess.check_call(cmd, shell=True)
       else: subprocess.Popen(cmd, shell=True)
</pre>

以上

カテゴリー: RaspberryPi, お知らせ | 5件のコメント

コマンドプロンプトからファイル数


Windowsのコマンドプロンプトから、 フォルダ(ディレクトリ)配下の全ファイル数、全フォルダ数を取得するコマンドのメモ

——————–

ファイル数

dir /A-D /S /B | find /c /v “”

——————–

フォルダ数

dir /AD /S /B | find /c /v “”

——————–

dir /A-D は、ディレクトリ以外

dir /AD は、ディレクトリのみ

dir /S /B は、サブフォルダも含めて、配下のファイル名/フォルダ名のみ

出力

find /c /v “” は、行数を出力

カテゴリー: お知らせ | コメントする

2019年もよろしく

カテゴリー: お知らせ | コメントする

AIY Voice KIT にAlexaとGoogleAssistantを同居

3月26日のOSアップグレードで、少しインタフェースが変わったため、確実な同居方法を
メモした。また、04-13版のレベルダウンへも対応追記。

1.AIYプロジェクトのVoice Kit SD imageをダウンロード
 aiyprojects-2018-04-13.img.xz
 https://dl.google.com/dl/aiyprojects/aiyprojects-latest.img.xz
2.MicroSDに書き込み、インストール
 aiyprojects-2018-04-13.img.xzを解凍し、書き込みする
 参照:https://aiyprojects.withgoogle.com/voice/#assembly-guide-5-2–boot-the-device
2.1 Audio音量関数の修正
 2018-04-13.imgにはレベルダウンがあり、AIY-project*/src/aiy/audio.py を修正する。
 113行 db_range = -60.0 – (-60.0 * (volume / 100.0)) を
     db_range = -6.6 – (-6.6 * (volume / 100.0)) に書き換え。
3.AIYでの日本語動作確認
 PulseAudioの初期値が未設定なので、/etc/pulse/default.pa を編集します。
 バックエンドドライバーをロードする行を探してアンコメント(#削除)し、
 以下のように device パラメータを追加してください。
 さらに autodetect モジュールをロードする行をコメントアウトしてください。
 load-module module-alsa-sink device=dmix
 load-module module-alsa-source device=dsnoop
 # load-module module-udev-detect
 # load-module module-detect
 再起動
 amixer sset Master 50%  (初期音量を変更したい)
 参照:https://kureuetan.com/web/raspberrypi/4998/#OS
 ~/bin/AIY-projects-shell.sh
 src/examples/voice/assistant_grpc_demo.py
 この後、GoogleAssistantアプリで、デバイスVoiceKitの言語選択を日本語に設定してください。
4.RasPi用Snowboyのインストール
 参照:https://github.com/wanleg/snowboyPi
4.1 事前準備
 sudo apt update && sudo apt -y upgrade && sudo apt-get -y auto-remove && sudo reboot
 OSのバージョンは、3月末で、次のようになります。
  Linux raspberrypi 4.14.30-v7+ #1102 SMP Mon Mar 26 16:45:49 BST 2018 armv7l GNU/Linux
 sudo apt -y install python-pyaudio python3-pyaudio sox python3-pip python-pip libatlas-base-dev
 sudo pip3 install pyaudio
 sudo cp ~/.asoundrc /root/
4.2 Snowboyの準備
 wget https://s3-us-west-2.amazonaws.com/snowboy/snowboy-releases/rpi-arm-raspbian-8.0-1.1.1.tar.bz2
tar xvf rpi-arm-raspbian-8.0-1.1.1.tar.bz2
mv rpi-arm-raspbian-8.0-1.1.1 snowboy
4.3 サウンドテスト
  speaker-test -c 2
  arecord -d 3 test.wav
  aplay test.wav
4.4 Hotwordの作成
 pip install requests
 cd snowboy
 wget https://github.com/wanleg/snowboyPi/raw/master/training_service.py
https://snowboy.kitt.ai にログインし、Profile settings をクリック、
 作成された API token をコピーしてメモする。
 training_service.pyの次のパラメタを設定する
 ############# MODIFY THE FOLLOWING #############
 token = “コピーしてメモしたAPI token”
 hotword_name = “ホットワードの名前”
 language = “jp”
 age_group = “30_39”
 gender = “M”
 microphone = “usb microphone”
 ############### END OF MODIFY ##################

 rec -r 16000 -c 1 -b 16 -e signed-integer 1.wav
 rec -r 16000 -c 1 -b 16 -e signed-integer 2.wav
 rec -r 16000 -c 1 -b 16 -e signed-integer 3.wav
 python training_service.py 1.wav 2.wav 3.wav NeGoogle.pmdl
 cp NeGoogle.pmdl resources/NeGoogle.pmdl
4.5 Hotwordのテスト
 python3 demo.py ~/snowboy/resources/NeGoogle.pmdl

 startAlexa.sh,assistant_grpc_snow_demo.pyのダウンロードと走行確認
 wget -O startAlexa.sh http://pmp-jp.com/test/startAlexa.txt
 wget -O _snowboydetect.so http://pmp-jp.com/test/_snowboydetect.so
 wget -O assistant_grpc_snow_demo.py http://pmp-jp.com/test/snow_demo.txt
 python3 assistant_grpc_snow_demo.py

5. Alexaのインストール
 参照:https://github.com/alexa/avs-device-sdk/wiki/Raspberry-Pi-Quick-Start-Guide-with-Script

cd
    wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/setup.sh
    wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/config.txt
    wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/pi.sh
    vi setup.sh で次の変更を実施
       en-US を ja-JP
    vi config.txtで次の設定を実施
       Client ID, Client Secret, and Product IDの設定
   vi avs-device-sdk/build/BuildDefaults.cmake で include(KeywordDetector) をコメント化
  
   sudo bash setup.sh config.txt
    sudo bash startauth.sh の起動後、http://localhost:3000をアクセス
    sudo cp ~/.asoundrc /root/
  sudo bash startsample.sh を実行し、c、1、6と入力して日本語モードにする

6. AlexaとGoogleAssistantの同時実行
  cd ~/snowboy
  python3 assistant_grpc_snow_demo.py NeGoogle.pmdl
  この他、
  python3 assistant_grpc_snow_demo.py snowboy.umdl も試せます。

カテゴリー: RaspberryPi, お知らせ | 4件のコメント

岩手日報webnews、大幅改装で追随大変!

//      $body = mb_convert_encoding ($response['body'],"utf-8","Shift_JIS");
      $body = $response['body'];
    }
    $pos = 10000;
    $table = ""; // mb_substr($body,$pos,$pos2-$pos);
	$pos = mb_strpos($body,$from,$pos);
	 if ($pos === false) { return($table.$body); }
	$pos2 = mb_strpos($body,$to,$pos+30);
	 if ($pos2 === false) print "<br>strpos2がfalseを返しました。<br>";
	if (substr($ton,0,1)=="+") {
		$pos2 += mb_strlen($to);
		if (strlen($ton)>1) $pos2 += substr($ton,1);
	}
	else $pos2 += $ton;
    $body1 = mb_substr($body,$pos,$pos2-$pos);
    if ($url=="") return ($body1);
    return (div_cut($body1));
}
function div_cut($str) {
    global $time;
	if ($str=="") return "";
	$pos = strpos($str,'<article>',0);
	if ($pos === false) return "";
	$pos2 = strpos($str,'<div class="outer">',$pos);
	if ($pos2 === false) return $str;
	$pos3 = strpos($str,'</h1>',$pos2);
	$time1 = substr($str,$pos3+24,19);
	if (strcmp($time,$time1)<0) $time = $time1;
	return str_replace("<a href=","<a target='_NEW' href=",substr($str,$pos,$pos2-$pos))."&nbsp;".
        substr($str,$pos2+36,$pos3-$pos2-36)."</a></article>".div_cut(substr($str,$pos3));  
// <div class="outer"><dl><dt><div><h1>

カテゴリー: お知らせ | コメントする

スマートスピーカー自作に挑戦!

FaceBookに投稿を始めている。
Amazon Alexa もRasPiで実現!

カテゴリー: RaspberryPi, お知らせ | 3件のコメント

メールでの投稿について

このWordPressへの投稿は、電子メール(写メ)でできます。
まず、あなたのメールIDを管理者に申請しておいてください。
投稿は、次のURLの説明通りですが、発信宛先を、
hakua.bukatsu+47hakua@gmail.com
とします。
投稿方法

よろしくお願いします。

カテゴリー: HELP | 1件のコメント

同期・黄川田議員お疲れ様でした

カテゴリー: お知らせ | コメントする

Micro:bitがやって来た

Facebookでの投稿へのリンクを、散逸しないように固めておく。

マイクロビットとは
MINTIAケースに入れてみた
ここまで出来た!

カテゴリー: Micro:bit | コメントする

SPI使用9bit転送のOLED接続

手元にあったMARY-OBというOLEDボード(2011)を整備が進んできたSPIドライバー
経由で接続することにチャレンジしたので、まとめておく。

SPIドライバーは当初、GPIOが26ピンだったためSPIがバス1本のStandardSPIのみの
サポートで、基本的に8bit単位の転送しかできなかった。
40ピンの時代になってBCM2835が搭載され、拡張SPIへの本格的取組が行われてきた。
カーネルが4.4.13以降、何回かの錯誤を経て、SPIバス2本が使える形に仕上がって
来ている。
拡張されたauxiliary SPI側では、LoSSIやワードサイズの指定が(限定的に)できる。
詳細は、ここを参照するとよい。

【準備】

1.BCM2835が載ったRaspberryPiを用意する。
2.カーネル4.4.y(又は4.9.y)のRaspbianOSを
  インストールして起動する。
3.「 ls /dev/spi*」コマンドで、
  /dev/spidev0.0 /dev/spidev0.1 /dev/spidev1.0 /dev/spidev1.1
  の4ポートが出現するように設定する。そのためには、
 ・config.txtに
  dtoverlay=pi3-disable-bt
  dtoverlay=spi1-2cs
  を追加する。       (注意:/dev/ttyS0との共存はできない)
 ・/boot/cmdline.txtに
  console=ttyS0,115200
  があれば、この部分を削除する。
4.pigpioライブラリーをインストールする。
  http://abyz.co.uk/rpi/pigpio/download.html (ガイド付き)
  または、いつもの、
  sudo apt-get install pigpio python-pigpio python3-pigpio
5.環境をテストする(make -j4を実施した時)。
  sudo ./x_pigpio

【OLEDサンプルプログラム】
  OLEDユニット UG-2828GDEDF11 に使われているコントローラーは、
  SOLOMON SYSTECH社のSSD1351でした。

SPIのピンヘッダの利用は次の通り。
    

SPI Function Header Pin Broadcom Pin Name Broadcom Pin Function
MOSI P1-38 GPIO20 SPI1_MOSI
SCLK P1-40 GPIO21 SPI1_SCLK
CE0 P1-12 GPIO18 SPI1_CE0_N
CE1 P1-11 GPIO17 SPI1_CE1_N

GPIO16をVCC_POWER_ONに利用している。焼き付き防止に有効。
任意のOUTPUT端子で良いが、ここではGPIO23をモジュールのリセットに使う。
この他に、VCC5V、VDD3.3V、GNDの接続がそれぞれ必要である。

SPIバスのオープン
int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags);
spiChanでチップセレクトの出力先を、baudにはクロックスピードを設定する。
spiFlagsの意味
spiFlagsは下位22ビットが次のように定義されている。
21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m

    このサンプルでは、次のようにオープンしている。

static uint16_t mode = 0x160;

    Aをオンにし、auxSPIを使用する。
    u0,u1をオンにし、二つのポートCE0,1の制御をライブラリに委ねている。

static uint16_t bits = 9;

    bits of word は9ビットを指定

static uint32_t speed = 10000000;

    speedはPiZeroやPi3に合わせて要求した。P12は倍でもOK。実速度は異なる。

spiOpen(0, speed, bits<<16 | mode );

    /dev/spidev1.0 のオープン

ソースファイル

//=========================================================
// File Name : oledspi2.c
// Function  : OLED Control
//---------------------------------------------------------
//---------------------------------------------------------
// Copyright (C) 2010-2011 Munetomo Maruyama
//=========================================================
// ---- License Information -------------------------------
// Anyone can FREELY use this code fully or partially
// under conditions shown below.
// 1. You may use this code only for individual purpose,
//    and educational purpose.
//    Do not use this code for business even if partially.
// 2. You can copy, modify and distribute this code.
// 3. You should remain this header text in your codes
//   including Copyright credit and License Information.
// 4. Your codes should inherit this license information.
//=========================================================
// ---- Patent Notice -------------------------------------
// I have not cared whether this system (hw + sw) causes
// infringement on the patent, copyright, trademark,
// or trade secret rights of others. You have all
// responsibilities for determining if your designs
// and products infringe on the intellectual property
// rights of others, when you use technical information
// included in this system for your business.
//=========================================================
// ---- Disclaimers ---------------------------------------
// The function and reliability of this system are not
// guaranteed. They may cause any damages to loss of
// properties, data, money, profits, life, or business.
// By adopting this system even partially, you assume
// all responsibility for its use.
//=========================================================
#include <stdio.h>
#include <inttypes.h>
#include <pigpio.h>
#include "oled.h"
#include "font.h"

//=================
// Font Parameters
//=================
#define OLED_FONT_XSIZE 8
#define OLED_FONT_YSIZE 8

//======================
// Define OLED Commands
//======================
#define OLED_COMMAND 1
#define OLED_DATA    2
//
#define C_SET_COLUMN_ADDRESS 0x0215
#define C_SET_ROW_ADDRESS    0x0275
#define D_START_ADDRESS 2
#define D_END_ADDRESS   3
//
#define C_WRITE_RAM_COMMAND 0x005c
#define C_READ_RAM_COMMAND  0x005d
//
#define C_SET_REMAP_COLOR_DEPTH 0x01a0
#define D_SET_REMAP_COLOR_DEPTH 2
//
#define C_SET_DISPLAY_START_LINE 0x01a1
#define D_SET_DISPLAY_START_LINE 2
//
#define C_SET_DISPLAY_OFFSET 0x01a2
#define D_SET_DISPLAY_OFFSET 2
//
#define C_SET_DISPLAY_MODE_ALL_OFF 0x00a4
#define C_SET_DISPLAY_MODE_ALL_ON  0x00a5
#define C_SET_DISPLAY_MODE_RESET   0x00a6
#define C_SET_DISPLAY_MODE_INVERSE 0x00a7
//
#define C_FUNCTION_SELECTION 0x01ab
#define D_FUNCTION_SELECTION 2
//
#define C_SET_SLEEP_MODE_ON  0x00ae
#define C_SET_SLEEP_MODE_OFF 0x00af
//
#define C_SET_RESET_PRECHARGE_PERIOD 0x01b1
#define D_SET_RESET_PRECHARGE_PERIOD 2
//
#define C_ENHANCE_DRIVING_SCHEME_CAPABILITY 0x03b2
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_1 2
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_2 3
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_3 4
//
#define C_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY 0x01b3
#define D_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY 2
//
#define C_SET_SEGMENT_LOW_VOLTAGE 0x03b4
#define D_SET_SEGMENT_LOW_VOLTAGE_1 2 // 0xa0 or 0xa2
#define D_SET_SEGMENT_LOW_VOLTAGE_2 3 // 0xb5
#define D_SET_SEGMENT_LOW_VOLTAGE_3 4 // 0x55
//
#define C_SET_GPIO 0x01b5
#define D_SET_GPIO 2
//
#define C_SET_SECOND_PRECHARGE_PERIOD 0x01b6
#define D_SET_SECOND_PRECHARGE_PERIOD 2
//
#define C_LOOKUP_TABLE_FOR_GRAY_SCALE_PULSE_WIDTH 0x3fb8
static const uint8_t GAMMA_TABLE[63] =
{
    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
    //
    0x12, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f,
    0x21, 0x23, 0x25, 0x27, 0x2a, 0x2d, 0x30, 0x33,
    //
    0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4c,
    0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c,
    //
    0x70, 0x74, 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91,
    0x96, 0x9b, 0xa0, 0xa5, 0xaa, 0xaf, 0xb4
};
//
#define C_USE_BUILT_IN_LINEAR_LUT 0x00b9
//
#define C_SET_PRECHARGE_VOLTAGE 0x01bb
#define D_SET_PRECHARGE_VOLTAGE 2
//
#define C_SET_VCOMH_VOLTAGE 0x01be
#define D_SET_VCOMH_VOLTAGE 2
//
#define C_SET_CONTRAST_CURRENT_FOR_COLOR_ABC 0x03c1
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_A 2
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_B 3
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_C 4
//
#define C_MASTER_CONTRAST_CURRENT_CONTROL 0x01c7
#define D_MASTER_CONTRAST_CURRENT_CONTROL 2
//
#define C_SET_MUX_RATIO 0x01ca
#define D_SET_MUX_RATIO 2
//
#define C_SET_COMMAND_LOCK 0x01fd
#define D_SET_COMMAND_LOCK 2
//
#define C_HORIZONTAL_SCROLL 0x0596
#define D_HORIZONTAL_SCROLL_A 2
#define D_HORIZONTAL_SCROLL_B 3
#define D_HORIZONTAL_SCROLL_C 4
#define D_HORIZONTAL_SCROLL_D 5
#define D_HORIZONTAL_SCROLL_E 6
//
#define C_STOP_MOVING  0x009e
#define C_START_MOVING 0x009f

#define MAX_WORKBUF 64
uint8_t *xvsnprintf(uint8_t *str, int32_t length, const char *format)
{
    uint8_t *ptr;

    ptr = (uint8_t*) format;
    while(*ptr != '\0')
    {
            if (length > 0) {*str++ = *ptr; length--;}
            ptr++;
    }
    //
    if (str != NULL) *str = '\0';
    return str;
}

#
//=============
// Globals
//=============
volatile uint32_t gOLED_printf_Font   = OLED_FONT_SMALL;
volatile uint32_t gOLED_printf_ColorF = OLED_WHT;
volatile uint32_t gOLED_printf_ColorB = OLED_BLK;
volatile uint32_t gOLED_printf_PosX = 0;
volatile uint32_t gOLED_printf_PosY = 0;
//
volatile uint32_t gOELD_Orientation_Mode = OLED_TOP_N;

static uint16_t mode = 0x160;	/* SPI1,u1,u0 */
static uint16_t bits = 9;
static uint32_t speed = 10000000;
    uint32_t oled[65];
//======================
// Initialize OLED
//======================


/*
int gpioSetMode(unsigned gpio, unsigned mode);
int gpioGetMode(unsigned gpio);
int gpioSetPullUpDown(unsigned gpio, unsigned pud);
int gpioRead(unsigned gpio);
int gpioWrite(unsigned gpio, unsigned level);
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
int spiRead(unsigned handle, char *buf, unsigned count);
int spiWrite(unsigned handle, char *buf, unsigned count);
int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count);
*/
int Init_OLED(void)
{
    uint32_t i;

    // Display OFF

    oled[OLED_COMMAND] = C_SET_DISPLAY_MODE_ALL_OFF;
    OLED_Send_Command(oled);
    //
    // Initialization Sequence of OLED
    //
    oled[OLED_COMMAND] = C_SET_COMMAND_LOCK;
    oled[D_SET_COMMAND_LOCK] = 0x112; // unlock
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_COMMAND_LOCK;
    oled[D_SET_COMMAND_LOCK] = 0x1b1; // unlock
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SLEEP_MODE_ON;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY;
    oled[D_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY] = 0xf1;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_MUX_RATIO;
    oled[D_SET_MUX_RATIO] = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_OFFSET;
    oled[D_SET_DISPLAY_OFFSET] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_START_LINE;
    oled[D_SET_DISPLAY_START_LINE] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_REMAP_COLOR_DEPTH;
    oled[D_SET_REMAP_COLOR_DEPTH] = 0x174; // 64k colors
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_GPIO;
    oled[D_SET_GPIO] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_FUNCTION_SELECTION;
    oled[D_FUNCTION_SELECTION] = 0x101;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SEGMENT_LOW_VOLTAGE;
    oled[D_SET_SEGMENT_LOW_VOLTAGE_1] = 0x1a0; // use external VSL
    oled[D_SET_SEGMENT_LOW_VOLTAGE_2] = 0x1b5;
    oled[D_SET_SEGMENT_LOW_VOLTAGE_3] = 0x155;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_CONTRAST_CURRENT_FOR_COLOR_ABC;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_A] = 0x1c8;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_B] = 0x180;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_C] = 0x1c8;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_MASTER_CONTRAST_CURRENT_CONTROL;
    oled[D_MASTER_CONTRAST_CURRENT_CONTROL] = 0x10f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_LOOKUP_TABLE_FOR_GRAY_SCALE_PULSE_WIDTH;
    for (i = 2; i < 65; i++)
    {
        oled[i] = (uint32_t) GAMMA_TABLE[i - 2] | 0x100;
    }
    OLED_Send_Command(oled);
    //
  //oled[OLED_COMMAND] = C_USE_BUILT_IN_LINEAR_LUT;
  //OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_RESET_PRECHARGE_PERIOD;
    oled[D_SET_RESET_PRECHARGE_PERIOD] = 0x132;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_ENHANCE_DRIVING_SCHEME_CAPABILITY;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_1] = 0x1a4;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_2] = 0x100;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_3] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_PRECHARGE_VOLTAGE;
    oled[D_SET_PRECHARGE_VOLTAGE] = 0x117;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SECOND_PRECHARGE_PERIOD;
    oled[D_SET_SECOND_PRECHARGE_PERIOD] = 0x101;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_VCOMH_VOLTAGE;
    oled[D_SET_VCOMH_VOLTAGE] = 0x105;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_MODE_RESET;
    OLED_Send_Command(oled);
    //
    // Clear Screen
    oled[OLED_COMMAND] = C_SET_COLUMN_ADDRESS;
    oled[D_START_ADDRESS] = 0x100;
    oled[D_END_ADDRESS]   = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_ROW_ADDRESS;
    oled[D_START_ADDRESS] = 0x100;
    oled[D_END_ADDRESS]   = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
    OLED_Send_Command(oled);
    //
}

//==================================
// Initialize OLED with Orientation
//==================================
void Init_OLED_with_Orientation(uint32_t mode)
{
    uint8_t command;

    Init_OLED();
    gOELD_Orientation_Mode = mode;
    //
    command = (mode == OLED_TOP_W)? 0x25 :
              (mode == OLED_TOP_S)? 0x26 :
              (mode == OLED_TOP_E)? 0x37 : 0x34;
    oled[OLED_COMMAND] = C_SET_REMAP_COLOR_DEPTH;
    oled[D_SET_REMAP_COLOR_DEPTH] = command | 0x100;
    OLED_Send_Command(oled);
}

//=====================
// OLED Send Command
//=====================
void OLED_Send_Command(uint32_t *oled)
{
    uint32_t i;
    uint32_t count,countR;
    uint16_t bus;

    count = (oled[OLED_COMMAND] >> 8) & 0x0ff;

    bus = oled[OLED_COMMAND] & 0xFF;
    for (i=0;i<=count;i++) {
        countR = spiWrite( oled[0], (char *)&bus, 2);
        bus = oled[OLED_DATA+i] | 0x100;
    }	
    //
}

//=====================
// OLED Send Data
//=====================
void OLED_Send_Data(uint32_t *oled, int count)
{
    uint32_t i;
    uint16_t bus;

    for (i=0;i<count;i++) {
       bus = (oled[OLED_DATA+i] & 0xff) | 0x100;
       spiWrite( oled[0], (char *)&bus, 2);
    }	
}

//====================
// OLED Send a Pixel
//====================
void OLED_Send_Pixel(uint32_t color)
{
    oled[OLED_DATA+0] = (color >> 8) ;
    oled[OLED_DATA+1] = color;

    OLED_Send_Data(oled, 2);
}
//===================
// OLED Clear Screen
//===================
void OLED_Clear_Screen(uint32_t color)
{
    uint32_t i;
    uint32_t bus;

    oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
    OLED_Send_Command(oled);
    bus = (color & 0xff00)<<8  | (color & 0xff) | 0x01000100;
    for (i=0;i<128*128;i++) {
       spiWrite( oled[0], (char *)&bus, 4);
    }	
}

//=======================
// OLED Draw a Character
//=======================
// scale should be 0, 1 or 2
void OLED_Draw_Char(char ch, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b, uint32_t scale)
{
    uint32_t x0, y0;
    uint32_t xsize, ysize;
    uint32_t x, y;
    uint32_t xfont, yfont;
    uint32_t pixel;
    uint32_t color;
    //
    uint32_t col0, col1, row0, row1;

    ch = (ch < 0x20)? 0x20 : (ch > 0x7f)? 0x7f : ch;
    //
    x0 = posx * (OLED_FONT_XSIZE << scale);
    y0 = posy * (OLED_FONT_YSIZE << scale);
    //
    xsize = OLED_FONT_XSIZE * (1 << scale);
    ysize = OLED_FONT_YSIZE * (1 << scale);
    //
    if ((x0 <= (128 - xsize)) && (y0 <= (128 - ysize)))
    {
        col0 = (gOELD_Orientation_Mode == OLED_TOP_W)? y0       :
               (gOELD_Orientation_Mode == OLED_TOP_S)? x0 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? y0 : x0;
        col1 = (gOELD_Orientation_Mode == OLED_TOP_W)? y0 + ysize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? x0 + xsize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? y0 + ysize - 1 : x0 + xsize - 1;
        row0 = (gOELD_Orientation_Mode == OLED_TOP_W)? x0 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? y0 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? x0 : y0;
        row1 = (gOELD_Orientation_Mode == OLED_TOP_W)? x0 + xsize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? y0 + ysize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? x0 + xsize - 1 : y0 + ysize - 1;
        //
       
        oled[OLED_COMMAND] = C_SET_COLUMN_ADDRESS;
        oled[D_START_ADDRESS] = (col0 > 127)? 127 : col0;
        oled[D_END_ADDRESS]   = (col1 > 127)? 127 : col1;
        OLED_Send_Command(oled);
        //
        oled[OLED_COMMAND] = C_SET_ROW_ADDRESS;
        oled[D_START_ADDRESS] = (row0 > 127)? 127 : row0;
        oled[D_END_ADDRESS]   = (row1 > 127)? 127 : row1;
        OLED_Send_Command(oled);
        //
        oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
        OLED_Send_Command(oled);
        //
        for (y = 0; y < ysize; y++)
        {
            for (x = 0; x < xsize; x++)
            {
                xfont = x >> scale;
                yfont = y >> scale;
                pixel = FONT[((uint32_t) ch - 0x20) * 8 + yfont];
                pixel = (pixel >> (OLED_FONT_XSIZE - 1 - xfont)) & 0x01;
                color = (pixel == 1)? color_f : color_b;
                OLED_Send_Pixel(color);
            }
        }
    }
}

//====================
// OLED Make Color
//====================
//      RGB num
// BLK  000 0000-003f (< 64)
// BLU  001 0040-007f (<128)
// CYN  011 0080-00bf (<192)
// GRN  010 00c0-00ff (<256)
// YEL  110 0100-013f (<320)
// WHT  111 0140-017f (<384)
// MAG  101 0180-01bf (<448)
// RED  100 01c0-01ff (<512)
// BLK  000

//===========================
// OLED Set printf() Position
//===========================
void OLED_printf_Position(uint32_t posx, uint32_t posy)
{
    gOLED_printf_PosX = posx;
    gOLED_printf_PosY = posy;
}

//=====================
// OLED printf
//=====================
void OLED_printf(const char *format, ...)
{
    uint8_t buf[256];
    uint8_t *pStr;

    xvsnprintf(buf, 256, format);

    pStr = buf;
    while(*pStr != '\0')
    {
        if (*pStr == '\n')
        {
            gOLED_printf_PosX = 0;
            gOLED_printf_PosY++;
        }
        else
        {
            OLED_Draw_Char(*pStr, gOLED_printf_PosX, gOLED_printf_PosY,
                    gOLED_printf_ColorF, gOLED_printf_ColorB, gOLED_printf_Font);
            gOLED_printf_PosX++;
        }
        pStr++;
        //
        if (gOLED_printf_PosX >= (128 / (OLED_FONT_XSIZE << gOLED_printf_Font)))
        {
            gOLED_printf_PosX = 0;
            gOLED_printf_PosY++;
        }
        if (gOLED_printf_PosY >= (128 / (OLED_FONT_YSIZE << gOLED_printf_Font)))
        {
            gOLED_printf_PosY = 0;
        }
    }
}
//=====================
// Display BITMAP
//=====================
//-----------------------
// Main Routine
//-----------------------
#define BMP 1   // select which BMP you want to see.
#define BUD 30  // select which BUD part you want to see.


  #include "../bmp/lego8.bmp.plt.h"
  #include "../bmp/lego8.bmp.rgb.h"


  #include "../bmp/nana8.bmp.plt.h"
  #include "../bmp/nana8.bmp.rgb.h"


int main() {
    uint32_t x, y, i;
    uint8_t  index, orien;
    uint32_t palette;
    uint32_t red, blu, grn;
    uint32_t oled1, oled2, pixel;

   if (gpioInitialise() < 0) return -1;

    gpioSetMode(16,1);
    gpioSetMode(23,1);

    gpioWrite(16,1);    // OLED Vcc PowerON
    time_sleep( 0.1 );  // wait for 100ms
    // OLED Reset
    // OLED_/RES GPIO OUT
    gpioWrite(23,0);
    time_sleep( 0.1 );  // wait for 100ms
    gpioWrite(23,1);    // high (reset)
    time_sleep( 0.1 );  // wait for 100ms

    // Initialize Hardware
    oled1 = spiOpen(0, speed, bits<<16 | mode );
    oled2 = spiOpen(1, speed, bits<<16 | mode );
  for (orien=100; orien>0; orien--) {
    // Initialization
    //
    oled[0] = oled1;	
    Init_OLED_with_Orientation(orien & 3);
	OLED_Clear_Screen(OLED_BLK) ;   
    //
    // Send Bitmap Data1
    //
    i = 0;
    for (y = 0; y < 128; y++)
    {
        for (x = 0; x < 128; x++)
        {
            index = BMP_RGB[i++];
            palette = BMP_PLT[index];

            red = (palette >> (16 + 3)) & 0x01f;
            grn = (palette >> ( 8 + 2)) & 0x03f;
            blu = (palette >> ( 0 + 3)) & 0x01f;
            pixel = (red << 11) + (grn << 5) + (blu << 0);
            OLED_Send_Pixel(pixel);
        }
    }
    // Display ON
    oled[OLED_COMMAND] = C_SET_SLEEP_MODE_OFF;
    OLED_Send_Command(oled);
    // Dummy Print (to make correct link)
    OLED_printf_Position(0, 0);
    OLED_printf("RaspberryPi");
    //
    // Send Bitmap Data2
    //
    time_sleep( 1 );  // wait for 1s
  }
   gpioWrite(16,0);    // OLED Vcc PowerOFF
   spiClose(oled1);
   spiClose(oled2);
   gpioTerminate();

}
//=========================================================
// End of Program
//=========================================================

oled.h

ifndef __OLED_H__
#define __OLED_H__

//===============
// Define Colors
//===============
#define OLED_RED_MAX 0x1f
#define OLED_GRN_MAX 0x3f
#define OLED_BLU_MAX 0x1f
#define OLED_RED_MIN 0x00
#define OLED_GRN_MIN 0x00
#define OLED_BLU_MIN 0x00
#define OLED_RED_MID 0x10
#define OLED_GRN_MID 0x20
#define OLED_BLU_MID 0x10
//
#define OLED_RED ((OLED_RED_MAX << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MIN << 0))
#define OLED_GRN ((OLED_RED_MIN << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MIN << 0))
#define OLED_BLU ((OLED_RED_MIN << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MAX << 0))
#define OLED_BLK ((OLED_RED_MIN << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MIN << 0))
#define OLED_WHT ((OLED_RED_MAX << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MAX << 0))
#define OLED_YEL ((OLED_RED_MAX << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MIN << 0))
#define OLED_CYN ((OLED_RED_MIN << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MAX << 0))
#define OLED_MAG ((OLED_RED_MAX << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MAX << 0))
#define OLED_GRY ((OLED_RED_MID << 11) + (OLED_GRN_MID << 5) + (OLED_BLU_MID << 0))

//=================
// Font Parameters
//=================
#define OLED_FONT_SMALL  0
#define OLED_FONT_MEDIUM 1
#define OLED_FONT_LARGE  2

//=================
// Orientation Mode
//=================
enum OELD_ORIENTATION_MODE {OLED_TOP_N, OLED_TOP_W, OLED_TOP_S, OLED_TOP_E};

//==============
// Prototypes
//==============
int  Init_OLED(void);
void Init_OLED_with_Orientation(uint32_t mode);
void OLED_Send_Command(uint32_t *oled);
void OLED_Send_Pixel(uint32_t color);
uint32_t OLED_Draw_Text_Small(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Draw_Text_Medium(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Draw_Text_Large(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
void OLED_Draw_Char(char ch, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b, uint32_t scale);
void OLED_Draw_Dot(int32_t x, int32_t y, int32_t size, uint32_t color);
void OLED_Clear_Screen(uint32_t color);
void OLED_Fill_Rect(int32_t x0, int32_t y0, int32_t xsize, int32_t ysize, uint32_t color);
char OLED_Num4_to_Char(uint32_t num4);
uint32_t OLED_Draw_Hex(uint32_t bitlen, uint32_t hex, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Make_Color(uint32_t num);
//
void OLED_printf_Font(uint32_t font);
void OLED_printf_Color(uint32_t color_f, uint32_t color_b); // corrected 2011.03.20 MM
void OLED_printf_Position(uint32_t posx, uint32_t posy);
void OLED_printf(const char *format, ...);

#endif // __OLED_H__
カテゴリー: RaspberryPi | コメントする