SSブログ

OLED 0.91インチディスプレイを買ってみた [DIY電気]

電子工作で小型の表示器が必要になりAmazonでOLED表示器を買ってみました。
「DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ」という商品で表示面積がかなり小さなものとなっています。届いた商品を開けると本体と接続ケーブルが2セット、広告っぽいチラシ一枚です。
DSC_0980.jpg

ひとつ手にとってます。
赤いのは保護シートを剥がす端っこです。
DSC_0981.jpg

それぞれの表裏です。
DSC_0982.jpg

Arduinoのu8glibライブラリを使えと書いてあるだけです。私は、PICマイコンで使用するつもりなのでArduinoと言われてもピンと来ないのです。勉強不足でついて行けません。
もう少し調べると、一番重要なキャラクターROMが入ってないということが判明したのであります。やられました!
まあ、購入前からキャラクターROMが入ってないというのは薄々わかっていましたが、案の定そうだったわけです。
文字フォントはマイコン側に持たせてI2C通信によりビット情報を流し込んでドットで書け!というものです。
今回の工作では主に時刻情報を表示させたいので、一歩譲って最悪数字とコロンと+αがあればいいということにします。
チラシにはメインチップがSSD1306だと書かれていますので、早速ネットで仕様書をダウンロードして入手。
コントローラであるSSD1306は128*64の解像度のOLEDを制御するとのこと。縦の64ドットは8ブロックに分かれ、ページと呼んでいます。1ページの縦は8ドットです。全面を全て書くには、8ビットを128回書くのを8回繰り返すということです。
それは理解できたんですけど、今回購入した表示器は128*32なので仕様書に書かれている縦のドット数が半分なのです。
あたって砕けろ!ということでブレッドボードでテストしてみました。
PICマイコンは16F88です。
DSC_0985.jpg

回路図です。
OLED TEST.gif

データを流し込んだら、わ~綺麗な水色表示!
でも、なんか変んな表示!どういうこと?砕けかけそうです。
それからそれから、あれこれ遊んでいるうちに発見しました。
奇数ビットだけ表示しているようなんです。
おいおい、偶数ビットは無視かよ。
仕様書に舞い戻り、「Set COM Pins Hardware Configuration (DAh)」という項目に目が止まりました。
0xDAコマンドの次の1バイトデータで設定できるようです。
今回初期値でテストしていましたので、0xDAに続いて0x02を設定することにより表示に成功しました。
左は猫のシルエットを4文字分で表示されています。
数字は、自作の7セグメント風フォントです。
DSC_0998.jpg

ビットマップフォントは1文字12*16にしています。横12ドットだと10文字で120ドットなので水平方向は8ドット余る計算。
縦はフルで32ドットなので、その半分の16ドットにしました。表示できる文字数は10*2ということになります。
DSC_1001.jpg

その後、テストを繰り返しているうちに別の場所のACコンセントにさすと、OLED画面の初期化に失敗しているようで、画面が反転モードだったり、砂の嵐だったり、一部が横線だったり、勝手にスクロールしたりなんです。
数分完全放電させると正常になったりするので、動作モードが予期せぬモードにラッチしているような感じです。ラッチが抜けにくいというか。
SSD1306仕様書の最後にApp Noteというのがあり、P5/6に「Software Configuration」の項目があり初期化のフローが書いてありました。12ステップですが、仕様書どおりに初期化ルーチンを書いて様子見しましたが改善せず。
結果的には商品が不良っぽいです。
2つのうちもうひとつは安定動作することがわかりました。

ここからCCSC用のテストプログラム(C言語ソースコード)です
/**********************************************
  OLED TEST PROGRAM
  DSD TECH OLED 0.91inch Display
  CCSC PIC COMPILER
  DATE 2019 JULY
***********************************************/

#include <16f88.h>
#use delay(clock=20000000)
#FUSES  HS,NOWDT,NOPROTECT,PUT,MCLR,NOBROWNOUT,NOLVP
#ignore_warnings 203
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>

#use i2c(master,sda=PIN_B1,scl=PIN_B4,FAST)

// Bitmap Font Data
//
// [14][24]で一つの配列にしたかったがコンパイラエラーとなるため分けた
// font1[14][12], font2[14][12]の2つにした
byte const font1[14][12] =
{
{0x00,0xFC,0x7A,0x06,0x06,0x06,0x06,0x06,0x06,0x7A,0xFC,0x00},//0
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xFE,0x00},//1
{0x00,0x00,0x82,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//2
{0x00,0x02,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//3
{0x00,0xFE,0x7C,0x80,0x80,0x80,0x80,0x80,0x80,0x7C,0xFE,0x00},//4
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x02,0x00,0x00},//5
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x82,0x00,0x00},//6
{0x00,0xFC,0x7A,0x06,0x06,0x06,0x06,0x06,0x06,0x7A,0xFC,0x00},//7
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//8
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//9
{0xFF,0xFC,0xB8,0xF8,0xF8,0xB8,0xFE,0x00,0x00,0x00,0x00,0x00},//CAT LTOP
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//CAT RTOP
{0x00,0x01,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//CAT LBTM
{0xFF,0xFF,0xFF,0xFF,0xFC,0xC0,0x00,0x07,0x1F,0xF8,0xE0,0x00},//CAT RBTM
};

byte const font2[14][12] =
{
{0x00,0x3F,0x5E,0x60,0x60,0x60,0x60,0x60,0x60,0x5E,0x3F,0x00},//0
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7F,0x00},//1
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x41,0x00,0x00},//2
{0x00,0x40,0x60,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//3
{0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x3E,0x7F,0x00},//4
{0x00,0x00,0x41,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//5
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//6
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7F,0x00},//7
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//8
{0x00,0x00,0x40,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//9
{0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF8,0xF0,0xF0,0xE0},//CAT LTOP
{0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0xE0,0xF0,0x38,0x38,0x18},//CAT RTOP
{0x20,0x60,0x78,0xFF,0xFF,0x7F,0x1F,0x7F,0x7F,0xFF,0xFF,0xFF},//CAT LBTM
{0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x38,0x38,0x1C,0x0F,0x03,0x00},//CAT RBTM
};

// AポートのI/Oビット配置
struct porta_pin_map {      // This structure is overlayed
    BOOLEAN reserved1;
    BOOLEAN reserved2;
    BOOLEAN reserved3;
    BOOLEAN reserved4;
    BOOLEAN pl;      //pilot lamp
} PORTA;
#byte PORTA = 0x05
#byte PORTB = 0x06

void oled_init(void);
void oled_clr(int);
void char1216( int font_code, int cx, int cy );
/*---------------------------------------------
   main module
---------------------------------------------*/
void main( void ){
    setup_adc_ports(NO_ANALOGS);
    setup_ccp1(CCP_OFF);
    set_tris_a( 0x00 );     // ALL OUT
    set_tris_b( 0x12 );     // SDA, SCL is INPUT
    PORTA.pl = 0;           //PL OFF
    delay_ms(100);
    oled_init();
    delay_ms(100);
    oled_clr(0x00);


    char1216(10,0,0);  //猫シルエット左上
    char1216(11,1,0);  //右上
    char1216(12,0,1);  //左下
    char1216(13,1,1);  //右下

    char1216(0,2,0);  // Font0 を x=2 y=0に出力
    char1216(1,3,0);
    char1216(2,4,0);
    char1216(3,5,0);
    char1216(4,6,0);
    char1216(5,7,0);
    char1216(6,8,0);
    char1216(7,9,0);

    char1216(8,2,1);
    char1216(9,3,1);
    char1216(0,4,1);
    char1216(1,5,1);
    char1216(2,6,1);
    char1216(3,7,1);
    char1216(4,8,1);
    char1216(5,9,1);
    while(1);
}

/* ----------------------------------------------------------------
    OLEDの初期化
---------------------------------------------------------------- */
void oled_init(void)
{
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0xa8); //SET MUX RATIO
   i2c_write(0x3f);
   i2c_write(0xd3); //SET DISPLAY OFFSET
   i2c_write(0x00);
   i2c_write(0x40); //SET DISPLAY START LINE
#if 0 //画面上下設定
   i2c_write(0xa0); //SET SEGMENT RE-MAP
   i2c_write(0xc0); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x02);
#else //画面上下逆
   i2c_write(0xa1); //SET SEGMENT RE-MAP
   i2c_write(0xc8); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x22);
#endif
   i2c_write(0x81); //SET CONTRAST CONTROL
   i2c_write(0x7f);
   i2c_write(0xa4); //DISABLE ENTRE DISPLAY ON
   i2c_write(0xa6); //SET NORMAL DISPLAY
   i2c_write(0xd5); //SET OSC FREQUENCY
   i2c_write(0x80);
   i2c_write(0x8d); //ENSBLE CHSRGE PUMP REGULATOR
   i2c_write(0x14);
   i2c_write(0xaf); //DISPLAY ON
   i2c_stop();
}
/* ----------------------------------------------------------------
    OLEDの画面クリア

      data : 埋めるデータ
---------------------------------------------------------------- */
void oled_clr(int data) // OLED 画面消去
{
   int32 i;
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0x20); // Set memory addressing mode
   i2c_write(0x00); // Horizontal addressing mode
   i2c_write(0x21); // Set column address
   i2c_write(0x00); // Column start address 0
   i2c_write(0x7F); // Column end address 127d
   i2c_write(0x22); // Set page address
   i2c_write(0x00); // Page start address 0
   i2c_write(0x03); // Page end address 7d ->3d
   i2c_stop();
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x40);
   for(i=0; i<512; i++){ // 128COL * 4page
     i2c_write(data); // Out data
   }
   i2c_stop();
}

/* ----------------------------------------------------------------
     OLEDに一文字出力
       font_code:
          配列を指定(0~)
       cx:
          出力水平位置(0~9)
       cy:
          出力垂直位置(0~1)
---------------------------------------------------------------- */
void char1216( int font_code, int cx, int cy ) // 12x16dot FONT
{
    int x;
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x00); // Control byte Co=0, D/C#=0
    i2c_write(0x20); // Set memory addressing mode
    i2c_write(0x00); // Horizontal addressing mode
    i2c_write(0x22); // Set Page Address
    i2c_write(cy*2); // Page Start
    i2c_write(cy*2+1); // Page End
    i2c_write(0x21);  // Set Column Address
    i2c_write(cx*12);  // Start Address(0-9)
    i2c_write(cx*12+11);  // End Address
    i2c_stop();
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x40);
    for( x=0 ; x<12 ; ++x ){
      i2c_write(font1[font_code][x]);
    }
    for( x=0 ; x<12 ; ++x ){
      i2c_write(font2[font_code][x]);
    }
   i2c_stop();
}


このデバイスを使った電子工作が完成したら記事にしたいと思います。


DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ

DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ

  • 出版社/メーカー: DSD TECH
  • メディア: エレクトロニクス




人気ブログランキング
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

TK-85が出てきた [DIY電気]

若いころこNECのTK-85というマイコンボードを買ってきてマイコンのプログラミングトレーニングをしました。トレーニングじゃなく半分遊び道具だったかもしれません。
そのTK-85が蔵から出てきました。
こんな汚い箱に入って。
DSC_0967.jpg

箱から出てきたのは、本体のみでマニュアルがありませんでした。
非常に残念。
DSC_0964.jpg

テンキーみたいなキーボード
DSC_0965.jpg

改造した痕跡。
DSC_0966.jpg

たしか、1982年頃に買ったのではないかと思います。
プログラミングの方法は、アセンブラ言語をノートにコーディングして、その右に、命令に対する16進数を書いてという具合に。ジャンプ命令は、特にやっかいなもんでした。命令を増やしたりすると番地が変わるのでその都度ジャンプ命令の部分も書き換えが必要だったのです。
 注)相対ジャンプ命令は例外
アセンブラ学習中は7セグメントLEDを光らせたりするぐらいのことしか学習課題がなく、時計の秒のような数字の変化を見ては少し喜び、他人が見てたら変人と思うはずです。
そうこうしているとYAMAHAからシンセサイザDX-7が発売になると知ったのです。
音楽的に興味があったわではなく、MIDIという信号を入れてあげると音が鳴るということに興味を惹かれました。独身貴族だった私はすぐさま秋葉原のラオックスでDX-7ゲット(20ン万円)。
TK-85とDX-7をつなぐインターフェイス回路(パラシリ変換)を作ってプログラミングに臨んだわけです。DX-7は16音が同時に発音できる仕様ですので、プログラムも16チャンネル出力できるようにしました。
全てのプログラムは残っていませんでしたが、サブルーチンだけが古いノートの一部に残っていました。
TK85_PRG_1.jpg

DX-7と接続するための改造が写真の手配線です。
プログラミングが終わってからは、ひたすら譜面を16進数に落とし、自動演奏を完成させることができました。
TK85_PRG_2.jpg

自動演奏に酔いしれ感心したもんです。
ビバルディの春を20小節ぐらいかな、とても全部はメモリ不足で入りません。
ビバルディの春の次は、ギターの譜面でディアハンターをデータ化して演奏させた記憶があります。
当時はインターネットも、Nifty-Serveもなく、シェアして他の方にお披露目させることもなかったです。
今思えばオーディオテープにでも取っておけばよかったと後悔しています。


人気ブログランキング
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

LINEのスタンプ作成手順 [PC]

写真を利用したLINEスタンプをフリーウェア FileAlpacaを使って作成したので忘れないように覚書。

FileAlpaca ver2.1.19

(1)FileAlpacaを起動して新規作成を始める
[ファイル][新規作成]
用紙サイズ[LINEスタンプ×1]

(2)写真素材を取り込む
[ファイル][画像をレイヤーとして開く]
写真素材を選択して[開く]

(3)用紙サイズに対して写真が大きいので表示している写真が写真の左上部を拡大したものになっている。
[Ctrl][T]を押す
左上のアンカーを右下にドラッグを繰り返して写真サイズを小さくし、希望の大きさで用紙サイズ内に適切に配置できたら、下部の[OK]を押す

(4)取り込んだ写真素材の不要な部分を消す作業を始める
作業レイヤーが今取り込んだ写真のレイヤーを選択しているか確認
左に並んでいる「選択」ボタン□形のボタンを押す→上部の「矩形」の設定を「多角形」に変更
マウスをクリックしながら削除したい形をなぞり最後にダブルクリック。
消したい部分を多角形で囲むということ
「Delete」キーで多角形で囲んだ部分が消える。
多角形でおおまかに消したら、次に[消しゴム]や[自動選択]を駆使して不要部を消していく。
[消しゴム]はマウスを使って根気よく消しゴムのように消していく
[自動選択]は上の[許容値]の数値を(20前後)に設定し「アンチエイリアス」はオンにする。
消したい中心付近をクリックすると自動選択されるので問題なければ、[Delete]キーで画像を消していく。
[Ctrl][D]を押して選択解除しながら作業する。

(5)綺麗に消したかの確認
[表示][透明背景]のチェックを外して、[表示][背景色の指定]で色付きの背景にして背景色を変えたりしながら、不要部がきれいに消えているか確認する。

(6)画像を見栄え良くする
画像が暗い場合は、[フィルタ][トーンカーブ]斜めの線をドラッグして画像を調整する。

(7)画像に付けるセリフを入れる作業。
右側にある、新規レイヤーボタンで新規レイヤーを作る。
[ツール][テキスト]写真の真ん中をクリック
[HG丸ゴシックM-PRO][太字][色-黒]文字入力する
[レイヤー][変換][カラーレイヤーに変換]
レイヤを複製する
複製したレイヤーを白の文字縁取りにするので、そのレイヤーを選択して、
[選択範囲][レイヤーを元に作成/不透明度]
[選択範囲][拡張][3]
色を[白]選択
[Ins]キー押す

(8)画像はキャンバスの最外周から10Px程度の余白が必要なので余白を作る
写真が置かれているレイヤーを選択
[選択範囲][全て選択]
[選択範囲][収縮]
10[OK]
[選択範囲][反転]
[Delte]キー押す

(9)完成したら
[表示][透明背景]のチェックをオンにする
[ファイル][書き出し][PNG(透過PNG)]→[OK]

スタンプ画像は、370×320(最大)ですが、メイン画像は240×240、タブ画像は96×74なので、メイン画像やタブ画像は用紙サイズを変更して作成。

2022/1/6
不要な部分を消す手順を更新

FileAlpaca1.jpg


人気ブログランキング
nice!(0)  コメント(0) 
共通テーマ:日記・雑感