フォト
2020年2月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
無料ブログはココログ

表示器制御関連

2020年2月 4日 (火)

M5Stackで日本語表示(2)

M5Stackでの日本語表示の続きです。
前回とは別の自作ライブラリをM5Stack対応の修正を行いました。

利用ライブラリ
 ・Arduino-KanjiFont-Library-SD
    Arduino用のマルチサイズ漢字フォントを利用するためのライブラリ(SDカード版)
    https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD

ライブラリを使って、「吾輩は猫である」の文書を表示してみました。

    01_20200204162501 

動いている様子
    

8ドットから24ドットのフォントサイズを変えて繰り返し表示しています。

動画を見れば分かると思いますが、表示はあまり速くないです。
逐次、SDカードから読んでいるためかと思われます。
まあ、とりあえずは良しとします。

スケッチ


表示の高速化のため、M5Stackで利用されている液晶パネルILI9341Windows機能を利用してフォントの表示を行っています。
drawPixel()を使うよりもコマンド送信数が少なくて済むので多少は速くなると思います。
ただし、SDカードアクセスが遅いためあまり効果としては現れませんね。

ちょっとハマった..

今回はテキストをスクロールさせるつもりでscrollUp()関数を作成したのですが、
期待通りに動きませんでした。
プログラム的には、指定座標のピクセル色を読んで、1文字分上に表示でスクロールさせようとしたのですが..

「何故だろう..?」と調べると、
なんとMISO(LCDからデータを読む)が使われていません。

02_20200204164501
(回路図は公式サイトより入手し引用)

これでは、物理的にデータの取得は出来ないですね。
ですので用意されている readPixel()readRect() は正常に動きません。
ためしてみると、ピクセルの色は常に 65535の値が返されます。

もう一点、ウィンドウ設定でsetAddrWindow()を使っているのですが、
setWindow()だと正しく表示出来ませんでした。
setAddrWindow()は、内部的にsetWindow()を読んでいるのですが、
SPIの設定を行ってからsetWindow()が呼び出されています。
SPIがSDカードのアクセスと共用のため、SPIの設定が必要だったのだと思われます。

とりあえずは、ウィンドウ設定の関数が用意されているのが分かったのは収穫でした。

追記
  MOSIを双方向にてデータを読む方法があるようです。

  関連情報
   ・M5Stackで画面キャプチャーを取得する
      https://qiita.com/fukuebiz/items/8aff6cad2f6048f02f12

   ・Bodmer/TFT_eSPI
      Arduino and PlatformIO IDE compatible TFT library optimised for the STM32,
      ESP8266 and ESP32 that supports different driver chips
      https://github.com/Bodmer/TFT_eSPI

  M5Stackのライブラリ=v0.2.9)のTFT_eSPIが古いため、現時点で readPixel()readRect() が使えないようです。
  まあ、いずれ、TFT_eSPIの最新版を取り込んで利用可能になると思います。

2020年1月18日 (土)

M5stackで日本語表示

Arduino Uno用に作成したフォントライブラリをM5Stackで試してみました。

ライブラリ
  ・Arduino用 美咲フォントライブラリ 教育漢字・内部フラッシュメモリ乗せ版
    https://github.com/Tamakichi/Arduino-misakiUTF16

とりあえず、LCDにライブラリ無修正で利用出来ました。
Dscn2468
ノーマルのサイズでは、文字が小さすぎて読めません。

3倍角にして表示してみました。
Dscn2477

まあ、8ドットフォントなのでこんなもんでしょう。

動いている様子


コントラストの関係で動画が綺麗に取れないため、背景色を青に変更しました。
8ドットフォントを1~4倍にして繰り返し表示しています。

スケッチ

スケッチは、OLED(SSD1306)で美咲フォントを使った漢字表示 のものを修正して作成しました。

フォント表示については、他の自作ライブラリの動作も検証したいと思います。



2020年1月 9日 (木)

NeoPixel(WS2812B)の制御 その4

ArduinoによるNeoPixel(WS2812B)の制御の続きです。質問があり、折角なので
以前作成した、8x8ドットマトリックスタイプのNeoPixelを制御するスケッチを汎用化(任意のサイズ対応)しました。
とりあえず手持ちの16x16ドットモジュールで試してみました。

動いている様子


利用したモジュールは、Aliexpressにて入手しまた。

1 pcs/lot DC5V 16x16 Pixel WS2812B LED Digital Flexible Individually addressable Panel light
04_20200109194301

このモジュールのNeoPixelの並びは次のようになっています。
05_20200109195701

接続
    Arduino:D11   -  NeoPixel:DIN
    Arduino:5V     -  NeoPixel:5V
    Arduino:GND  -  NeoPixel:GND

スケッチ


スケッチは、16x16ドットマトリックスに対応するように作成していますが、
下記の横ピクセル数、縦ピクセル数を変更することで、横8x縦8ドット、横32x縦8ドットにも対応出来ると思います。
  #define PXCEL_W  16    // 横ピクセル数
  #define PXCEL_H   16    // 縦ピクセル数

また、メッセージ表示の縦位置は NeoMsg()関数の最後の引数で指定出来ます。
スケッチは、Githubのgistにて公開しています。スケッチ表示の下部の帯のリンクから参照出来ます。
スケッチのコンパイルには、別途下記のライブラリが必要です。

   ライブラリ
   ・Arduino用 美咲フォントライブラリ 教育漢字・内部フラッシュメモリ乗せ版
     https://github.com/Tamakichi/Arduino-misakiUTF16

関連記事
 NeoPixel(WS2812B)の制御 その4(2020.01.09)  ・・・ 16x16マトリックスの制御(この記事です)  
 
NeoPixel(WS2812B)の制御 その3(2018.05.30)  ・・・ 8x8マトリックスの制御
 NeoPixel(WS2812B)の制御 その2(2018.05.22)   ・・・ SPIを使った制御
 NeoPixel(WS2812B)の制御(2018.05.20)            ・・・ GPIOを使った制御

2019年12月10日 (火)

IchigoJamのファームウェア 1.4.1が正式に公開されました

IchigoJamのファームウェア 1.4.1が正式に公開されました。
早速、ファームウェアをアップデートしました。

関連記事
  ・こどものプログラミング教育ツール『IchigoJam BASIC』ver 1.4リリース
  ・IchigoJam ダウンロード
  ・documents of IchigoJam
  ・IchigoJam BASIC リファレンス ver 1.4
  ・IchigoJam BASIC 1.4 コマンド一覧
  ・IchigoJam BASIC 1.4 コマンド一覧(印刷用)
   
追加された機能の中で、クリスマスが近いということで、
NeoPixel(WS2812B)の制御を行うコマンド WS.LED の動作を試して見ました。
このコマンドは、表示する色のパターンを配列([0]~)に定義し、そのパターンを繰り返して表示します。
下記に仕様をまとめました。


WS.LED
---------------------------------------------------------------------------------------------
【概要】
    NeoPixel(WS2812B)の制御を行う  

【書式】
    WS.LED 色パターン定義数 {,繰り返し数}

【結線】
    IchigoJam側          NeoPixel(WS2812B)
     LEDピン                  DIN
     GND                       GND
     5V                         VCC(5V)

【引数】
  色パターン定義数:  配列に定義(緑、赤、青の3つで1セット)のする色パターン数
  繰り返し数        :  色パターン繰り返し回数

【解説】
    配列の先頭([0]~)から緑、赤、青の順に設定された連続する3つの値(0~255)でLEDピンに接続された
    NeoPixel(WS2812B)を1つ分、光らせます。
    緑、赤、青の値は複数定義可能で、複数のNeoPixelを光らせることができます。
    繰り返し回数を指定することで、緑、赤、青の値のパータンでの光らせます。
    
    データ送信の際、割込みを中断するためNTSCビデオ出力の画面表示が一瞬止まります。
---------------------------------------------------------------------------------------------

実際に、NeoPixel(WS2812B)30個接続のリボンタイプのモジュールを制御してみました。

    02_20191210094401

まずは、全30個のLEDを次のコマンドで赤(最大輝度 255)で表示してみます。 
   LET [0],0,255,0:WS.LED 1,30

    Dscn2305

あらかじめ配列に1つ分のLEDの色パターン 緑:0、赤:255、青:0を格納します。
次にWS.LEDコマンドにて、パターン数=1、繰り返し数=30回を指定して実行します。
これだけで、30個のLED全点が赤になりました。

次に緑、赤、青のパターンを10回繰り返す表示をやってみます。
   LET [0],255,0,0,0,255,0,0,0,0,255:WS.LED 3,10

    Dscn2306

  配列に3個分のパターン 
      緑:255、赤:0、   青:0
      緑:0、   赤:255、青:0
      緑:0、  赤:0、    青:255
  を格納します。
  次にWS.LEDコマンドにて、パターン数=3、繰り返し数=10回を指定して実行します。

今度は、プログラムを組んで動きのある表示をやってみます。
  10 LET [0],255,0,0,0,255,0,0,0,255:WS.LED 3,10:WAIT 30
  20 LET [0],0,255,0,0,0,255,255,0,0:WS.LED 3,10:WAIT 30
  30 LET [0],0,0,255,255,0,0,0,255,0:WS.LED 3,10:WAIT 30
  40 GOTO 10

    Dscn2307

  0.5秒間隔でLEDの表示がシフトして表示されます。

  なかなか遊べるコマンドですね。
  

 

2019年8月 2日 (金)

SSD1322搭載3.12インチ OLEDの動作確認

AliexpressでコントローラSSD1322搭載 3.12インチ OLEDディスプレイを入手しました。

入手サイト
TZT Real OLED Display 3.12" 256*64 Dots Graphic LCD Module Display Screen LCM Screen SSD1322 Controller Support SPI
01_20190802090601

$20.70と少々お高いですが、以前に比べるとお手頃な価格になってきました。

実際の製品

届いた製品です。0.96インチ(上)と比較するとやはり大きいです。
Dscn1942

マニュアル類の付属がないため、製品販売ページの情報をもとに使い方は調べる必要があります。
購入先の業者に問い合わせても良いと思います。


製品仕様について

てっきりモノクロ(単色)だと思っていたのですが、
SSD1322の仕様を調べると、1ドット当たり4ビットの16階調表示でした。
256x64ドット、1ドットあたり4ビットのためバッファを使う方式でのプログラム実装では
バッファサイズは8kバイト必要となります。

2x16のピンヘッダでの接続となります。
インタフェースとしては、SPIの他にパラレル接続も可能です。
Photo_20190802094501
デフォルトではパラレル接続モードになっています。
裏のシルク印刷の設定をみてSPI(4SPI)接続に変更しました(R6の抵抗を取ってR5につける)。
Dscn1976

SPI(4SPI)で利用する場合、モジュールのピンヘッダのうち、下記のピンを利用します。
(Reset、CS、DCはArduinoの任意のピンでOK)
02_20190802094201
Arduinoでの動作確認

利用ライブラリ

ググって探して、次のライブラリを試してみました。
1) U8glib V2 library for Arduino
    https://github.com/olikraus/U8g2_Arduino
2) Arduino library for 256x64 OLED ER-OLED032-1 (SSD1322 driver)
    https://github.com/cvonk/arduino-SSD1322

接続はこんな感じです。
Dscn1977
結論を先に述べると、1)のU8glibの利用がお勧めです。
16階調表示には対応していないですが、フレームバッファ使わない方式にも対応しています。
下記の画像はU8glibを使った動作です。

Dscn1961
Dscn1965
Dscn1966
表示がとても綺麗です。文字の表示にも、もちょうど良いサイズです。

U8glibのサンプルスケッチをコンパイルする使う場合、コメントアウトされている下記を有効にします。
   U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h

U8glibでも、フルサイズのバッファを使う場合、バッファサイズとして2kバイトが必要です。
Arduino Unoでは利用出来ません。Arduino MEGA2560で利用出来ました。

SPI接続では、OLEDモジュールからの表示内容の読み出しが出来ないため
表示している内容に追記するような場合は、Arduino側でバッファが必要となります。
バッファを使いない場合、グラフィック描画時に制約が発生します。

2)のライブラリはAdafruit_SSD1306がベースのライブラリなのですが、
古いAdafruit_GFXを使っているためか、Adafruit_GFXのメンバ変数参照でコンパイルエラーが
発生し、ライブラリソースの修正が必要でした(このあたりの対応は省略します)。

さらにバッファとして最低2kバイト(単色利用時)が必要です。Arduino Unoでは利用出来ません。
Arduino MEGA2560ではとりあえず動きました。

Dscn1970

16階調での利用は、バッファサイズ8kバイトが必要なため、Arduino MEGA2560でも利用出来ませんでした。


まとめ

このSSD1322搭載の本製品、ドットサイズが256x64、16階調、表示が綺麗で見やすいのです。
文字を表示にも適したサイズです。
ただし、16階調(1ドット4ビット)は、メモリ消費が多くなり、ちょっと使いにくいです。

16階調の表示の評価として、何か写真っぽいのを表示を試して見たいと思います。

2019年7月 8日 (月)

4連8x8ドットLEDマトリックスを試してみる 続編(2)

以前書いた記事「4連8x8ドットLEDマトリックスを試してみる 続編」に関して
スクロール表示ではなく、固定メッセージを表示したいとの質問があり、ちょっとやってみました。

ハードウェア構成は、前回のSDカードモジュールを使わず、SDカードシールドを使っています。
この方が結線が楽ちんですね。SDカードシールドは意外と安いです。

Dscn1883

動作している様子



スケッチ: ダウンロード - max7219_test3a.zip

  別途自作ライブラリ sdfonts を利用しています。
   ・sdfonts : Arduino用漢字フォントライブラリ SDカード版
     https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD


スケッチを直接貼り付けて掲載したかったのですが、
ArduinoのHTML形式コピーのスケッチを貼るとココログの編集画面が100%暴走するようになり、
掲載出来なくなってしまいました。
まだまだ、リニューアルの後遺症が残っているようです。

代わりに、GitHub(gist)を使って掲載します。


追記

このスケッチで利用している、ビットマップ操作を行う処理、
機能強化&ライブラリ化してGitHubに登録していたことをすっかり忘れていました。
しかも、マニュアルを作成せず、登録しただけ...

 ・Arduino ビットマップ操作ライブラリ
    https://github.com/Tamakichi/libBitmap

暇をみて、ドキュメントを追記しますです。

2019年7月 7日 (日)

豊四季タイニーBASIC for Arduino機能拡張版の修正中(4)

豊四季タイニーBASIC for Arduino機能拡張版(+ VFD MW25616L対応)の修正、
前回から、美咲フォントの漢字選定の変更やらダイエットやらを行いましした。
(コード見直しで500バイトくらいダイエット出来たのですが、機能追加で差し引き0です)

・Tamakichi/ttbasic_MW25616L
   ブランチ(随時更新) https://github.com/Tamakichi/ttbasic_MW25616L/tree/update_to_v007

   2019/10/22 追記
   ブランチ版をメインストリーム(V007) にマージして正式版として公開しました。※ブランチは削除しました。
   メインストリーム(仕様確定版)   https://github.com/Tamakichi/ttbasic_MW25616L



見た目的には、前回とあまり変わらないのですが、修正で"埼玉"が表示出来るようになりました。

動いている様子



プログラム


10 NINIT ARRAY,64
20 NBRIGHT 1
30 FOR N=1 TO 5
40 C=RND(255)
50 FOR I=0 TO 3
60 NCLS 0
70 NLINE I,I,7-I,7-I,C,1
80 WAIT 150
90 NEXT
100 NEXT
110 NMSG 80,RGB(7,0,0),"こんにちは、埼玉♪"
120 NMSG 80,RGB(0,0,3),"今日は、7月7日です。"
130 GOTO 30


色々と悩んだ挙句、次のフォントを選定しました。
年号、季節、時刻、天気、方向、単位、地形、色を強化しました。

01_20190707203001

フォントは約5kバイト容量を喰うため、他の機能をOFFにする必要があります。
オプション指定で、フォントの利用を無効にすることも出来ます。

また、英数記号・カタカナ・ひらがな 288文字のみ利用可能とするオプション指定も
用意しました。この場合は3kバイト程度の消費となります。

NeoPixel制御はこれくらいにして、次はタイマー割り込み機能に着手します。


2019年6月27日 (木)

豊四季タイニーBASIC for Arduino機能拡張版の修正中(3)

豊四季タイニーBASIC for Arduino機能拡張版(+ VFD MW25616L対応)の修正中です。
前回から、さらにNeoPixcelを制御するコマンドを追加しました。

・Tamakichi/ttbasic_MW25616L
   ブランチ(随時更新) https://github.com/Tamakichi/ttbasic_MW25616L/tree/update_to_v007

   2019/10/22 追記
   ブランチ版をメインストリーム(V007) にマージして正式版として公開しました。※ブランチは削除しました。
   メインストリーム(仕様確定版)   https://github.com/Tamakichi/ttbasic_MW25616L

02_20190627200601

NeoPixel的には1個のLEDあたり、24ビット色なのですが、今回は、メモリ制約等を考慮して、8ビット色としました。
また制御できるLEDは最大で64個までとしました。

NeoPixelのリボン・スティック形状(ストレート)、リング形状、8x8ドットマトリックス形状に対応しました。

追加コマンド(×は未実装、いずれ対応する予定)
 補足: コマンドの更新flgは、デフォルト値が1、0を指定した場合はバッファへの書き込みのみで、表示に反映しません。
         NUPDATEで、バッファ内容を表示に反映出来ます。

■ 初期設定
   NINIT バッファアドレス,ピクセル数
   バッファアドレスには、仮想アドレスを指定します。1ピクセルあたり1バイト必要です。

■ 輝度設定
   NBRIGHT 輝度
   輝度は0(低)~5(高)の範囲で指定します。

■ 表示クリア
   NCLS [更新flg]

■ 指定LEDの色設定
   NSET 番号,色[,更新flg]
   番号はLEDのピクセル番号(0~)、色は0~255(RGB関数を使うと便利)

■ 8x8マトリックスの指定位置にピクセル設定
   NPSET X,Y,色[,更新flg]

■ 8x8マトリックスにメッセージ文表示
   NMSG 色,速度,メッセージ文
   速度はスクロール時のウェイト時間(ミリ秒単位)

■ 8x8マトリックスを指定方向に1ピクセルスクロール
   NSCROLL 方向[,更新flg]

■ 8x8マトリックス ライン描画
   NLINE X1,Y1,X2,Y2,色[,モード] [,更新flg]
   モードは、0:直線(デフォルト)、1:矩形、2:矩形塗りつぶし

■ バッファ表示反映
  NUPDATE

■ LEDの表示をシフト
   NSHIFT 方向[,更新flg]
   LEDの表示を1つずらします。
   先頭のLEDの色は最後尾のLEDに設定されます。ループとなります。

■ 8ビット色コード取得
  RGB(赤,青,緑)

■ 8x8マトリックス 指定座標色コード取得
  NPOINT(X,Y)

結線


NeoPixel


Arduino


1 VDD


5V


2 DOUT


(未接続)


3 VSS(GND)


GND


4 DIN


MOSI(11ピン)



NeoPixelを制御するプログラムの例

01_20190627201201

動いている様子

色々とメッセージを表示してみたのですが、
やはり、文字が足りません。漢字はもう少し選定を見直す必要があります。

まだまだ、色々とと見直し中です。
う~ん、メモリが足りず中々厄介です。


追記 2019/06/28

1メートル 30個LED搭載テープ(リボン)を制御してみました。

Dscn1862

プログラムで2点(赤と青)を往復運動させています。



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


10 NINIT MEM,30
20 NBRIGHT 5
30 NCLS
40 NSET 0,RGB(0,0,3)
50 NSET 1,RGB(7,0,0)
60 N=0:D=0
70 NSHIFT D
80 N=N+1
90 IF N=28 N=0:IF D=0 D=1 ELSE D=0
100 WAIT 30
110 GOTO 70

10行で、NeoPixel用のメモリ領域として、仮想アドレスMEMから30個分30バイトを確保しています。
20行で、輝度を最大の5にしています。
30行で、念のためすべての表示をクリア
40行、50行で0番目、1番目のLEDに青、赤の色を設定して表示しています。
60行のNはNSHIFTコマンドの実行回数のカウント用、DはNSHIFTの方向引数です。
70行のNSHIFT Dは、LEDの表示を前または後ろに1つ分移動します。
80行で移動数をカウント、
90行で方向転換するための判定と、方向Dの値を逆方向に設定しています。
100行はウェイト
110行は70行にジャンプして繰り返し表示

プログラム次第で色々と面白い動き、表示が出来ると思います。

追記 2019/06/29 

1メートル 30個LED搭載テープ(リボン)制御のその2です。
全LEDを一括更新する例として、全LEDを0.5秒間隔で赤、緑、青と変化させています。

Dscn1864

動いている様子



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


10 NINIT MEM,30:NBRIGHT 3
20 NCLS
30 @(0)=RGB(7,0,0),RGB(0,7,0),RGB(0,0,3)
40 C=0
50 FOR I=0 TO 29
60 NSET I,@(C),0
70 NEXT I
80 NUPDATE
90 C=C+1:IF C=3 C=0
100 WAIT 500
110 GOTO 50

50行~70行で全LEDの色を設定しています。
60行のNSET I,@(C),0 で各LEDの色の設定をしているのですが、
3番目の引数の0を指定することで、バッファのみの書き込みとなります。
80行のNUPDATEで一括してバッファの内容をNeoPixelに反映させています。

60行は、次の処理と等価です。
 POKE MEM+I,@(C)
10行のNINITで指定したアドレスのデータに直接値を設定して、
NUPDATEで表示に反映させることも出来ます。


上記に、輝度制御を追加したバージョン



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


10 NINIT MEM,30:NBRIGHT 0
20 NCLS
30 @(0)=RGB(7,0,0),RGB(0,7,0),RGB(0,0,3)
40 C=0
50 FOR I=0 TO 29
60 NSET I,@(C),0
70 NEXT I
80 NUPDATE
90 C=C+1:IF C=3 C=0
100 WAIT 200
110 FOR I=1 TO 5:NBRIGHT I:NUPDATE:WAIT 200:NEXT I
120 NBRIGHT 0:NUPDATE
130 GOTO 50

110行~120行で輝度を変化させる処理を行っています。
NBRIGHTコマンドで輝度を指定します。表示への反映はNUPDATEの実行します。

NBRIGHTコマンドはちょっと見直そうと思います。
 ・NUPDATEを呼び出さずに、表示に反映
 ・輝度を-3 ~ 5 として、マイナス値で減光出来るようにする

2019年6月 1日 (土)

Arduino STM32でキャラクタ液晶ディスプレイを使う

現在ちびちびと Arduino STM32 リファレンス 日本語版 を整備しているにですが、
今回、標準ライブラリの LiquidCrystalライブラリの部分を追記しました。

このライブラリはHD44780コントローラ(互換品含む)を使った
キャラクタ液晶ディスプレイ用のライブラリです。

動作確認として、実際にBluePillボードで制御してみました。

02_5  

利用したキャラクタ液晶ディスプレイ
1602A-V2aitendoでも販売されています)
   表示文字数 16桁×2行 、バックライト付きSTN液晶ディスプレイ
   Aliexpressでは、2ドル以下で購入出来ます。

久しぶりに、パラレル接続のキャラクタ液晶ディスプレイを使いました。
色々と忘れていて、コントラスト調整に戸惑ってしまいました。

今回はとりあえず、4ビットモードで利用しました。
動作電源が5Vのため、BluePillボードの5Vで利用可能なピンを利用しました。
下記がその結線です。

結線表

1602A-V2端子 接続先 備考
VSS BluePill - GND  
VDD BluePill - 5V  
V0 20kΩ半固定抵抗(GND接続) コントラスト調整用
RS BluePill - PA8 5Vトレラントピン利用
RW BluePill - GND LOW(GND)でWモード固定
E BluePill - PA9 5Vトレラントピン利用
D0 (未接続)  
D1 (未接続)  
D2 (未接続)  
D3 (未接続)  
D4 BluePill - PB6 5Vトレラントピン利用
D5 BluePill - PB7 5Vトレラントピン利用
D6 BluePill - PB8 5Vトレラントピン利用
D7 BluePill - PB9 5Vトレラントピン利用
A BluePill - 5V バックライトLED用
K BluePill - GND バックライトLED用


動作確認に利用したスケッチ

#include <LiquidCrystal.h>
#define LCD_RS  PA8
#define LCD_E   PA9
#define LCD_D4  PB6
#define LCD_D5  PB7
#define LCD_D6  PB8
#define LCD_D7  PB9
uint8_t font[]= {
  0b00001010,
  0b00001110,
  0b00011111,
  0b00010101,
  0b00011111,
  0b00011111,
  0b00001110,
 0b00000000,
};
LiquidCrystal lcd(LCD_RS,LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
void setup() {
  lcd.begin(16, 2);
  lcd.createChar(1,font);
  lcd.clear();
  lcd.cursor();
  lcd.blink();
  lcd.setCursor(0, 0);
  lcd.print("Hello, world!");
  lcd.setCursor(0, 1);
  lcd.print("\xc8\xba\x20\xc6\x20\xba\xdd\xca\xde\xdd\xdc\x01");
}
void loop() { }

スケッチは、LiquidCrystalクラスのインスタンス lcd をピン割り付けを指定して生成し、
begin()にて利用開始します。

4ビットモードだと結線数も少なく、割と簡単に制御出来ます。

LiquidCrystalライブラリ は、Printクラスの派生クラスのため、
Serialオブジェクトのような感じで、print()関数が利用出来ます。
数値等の出力も簡単に出来ます。

写真の 「ネコ ニ ホンバンワ」の半角カタカナ表示の部分は、
Arduino IDE環境の文字コードUTF-8コードのため、文字列をそのまま記述することはできません。
UTF-8で半角カタカナ1文字は、3バイトに置き換えられてしまい文字化けします。
ですので、文字コードを16進数表記で記述しています。

また、猫っぽいアイコンは、CGRAM領域にフォントデータを登録して表示しています。
CGRAM領域には、最大8文字(5x8ドット)登録することが出来ます。
lcd.createChar(1,font)にてその登録を行っています。
登録した文字は文字コード0~7にて指定出来ます。
(ただし、文字コード0は文字列終端子と被るのでwrite()で書く必要あり)

登録するフォントデータは8バイトですが、横5ドットは下位5ビットにて定義します。
縦は実際は7ドットのため、最後の8列目は0を設定します。

参考文献
 ・Adafruit Explore & Learn - Wiring a Character LCD
 ・HD44780U (LCD-II)

2019年3月21日 (木)

BluePillボードで4桁7セグLEDの制御

先日のArduino STM32用タイマー割り込みライブラリを使って、
BluePillボードを使って、4桁7セグLEDをダイナミック点灯にて制御してみました。

Dscn9818

動いている様子



以前、秋月電子で入手して放置していた 4桁7セグLEDはOSL40562-IG を利用しました。
このOSL40562-IGアノードコモンでVFが3.3Vと高く 少々使いにくです。

  ダイナミック接続4桁高輝度緑色7セグメントLED表示器 アノードコモン アノード共通接続 OSL40562-IG

  01


03

とりあえず、次のような回路で駆動させてみました。

02

BluePillボードの5Vトレラント対応のピンを使って駆動させます。
各LEDに流れる電流は5mA程度にしています。
I = (5[V] - Vf[V] ) / 330[Ω]  = (5 - 3.3) /330 = 0.00515[A] ≒ 5[mA]

各桁セグメントDIG1 ~ DIG4は、LED8個分の40mAが流れます。 
BluePillボードでは20mAまでしか流せないため、PNPトランジスタ 2SA1015を使って
駆動させるようにしました。

スケッチ
//
// 4桁高輝度緑色7セグメントLED表示器(アノードコモン) OSL40562-IG の制御
// 2019/03/17 たま吉さん 
// 利用パーツ
//  BluePillボード
//  4桁7セグメントLED  OSL40562-IG x 1
//  桁制御用トランジスタ    2SA1015L-GR x 4
//  LED電流制御用抵抗       330Ω x 8
//  トランジスタベース抵抗  10kΩ x 4
//

#include "TimerEvent.h"

// タイマー割り込み管理
TimerEvent ticker;     
#define REFTIME 4

// デジタルピンの定義
#define DIG1  PB12
#define DIG2  PB13
#define DIG3  PB14
#define DIG4  PB15
#define SEGA  PB3
#define SEGB  PB4
#define SEGC  PB6
#define SEGD  PB7
#define SEGE  PB8
#define SEGF  PB9
#define SEGG  PB10
#define SEGP  PB11

// 桁表示ON・OFF
#define DIG_ON   0
#define DIG_OFF  1

// セグメント表示ON・OFF
#define SEG_ON   0
#define SEG_OFF  1

// セグメントビット定義
#define BIT_A 0b10000000
#define BIT_B 0b01000000
#define BIT_C 0b00100000
#define BIT_D 0b00010000
#define BIT_E 0b00001000
#define BIT_F 0b00000100
#define BIT_G 0b00000010
#define BIT_P 0b00000001

// フォントの定義
const uint8_t font[12] = {
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_E|BIT_F,       // 0
  BIT_B|BIT_C,                               // 1
  BIT_A|BIT_B|BIT_G|BIT_E|BIT_D,             // 2
  BIT_A|BIT_B|BIT_G|BIT_C|BIT_D,             // 3
  BIT_F|BIT_B|BIT_G|BIT_C,                   // 4
  BIT_A|BIT_F|BIT_G|BIT_C|BIT_D,             // 5
  BIT_A|BIT_F|BIT_E|BIT_D|BIT_C|BIT_G,       // 6
  BIT_A|BIT_B|BIT_C,                         // 7
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_E|BIT_F|BIT_G, // 8
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_F|BIT_G,       // 9
  0,                                         // ブランク
  BIT_G,                                     // -
};

// 桁制御ピン
const uint8_t pin_dig[4] = {
  DIG1, DIG2, DIG3, DIG4,
};

// セグメント制御ピン
const uint8_t pin_seg[8] = {
  SEGA, SEGB, SEGC, SEGD, SEGE, SEGF, SEGG, SEGP,
};

// 表示用データ
volatile uint8_t digit[4];

// タイマー割り込み呼び出し関数
void dinamic_update() {
  static uint8_t cnt = 0;
  for (uint8_t i = 0; i < 4; i++)
    digitalWrite(pin_dig[i], DIG_OFF); 
  for (uint8_t i = 0; i < 8; i++)  
     digitalWrite(pin_seg[i], digit[cnt] & (0x80>>i) ? SEG_ON:SEG_OFF);
  digitalWrite(pin_dig[cnt], DIG_ON); 
  cnt++; if (cnt == 4) cnt = 0;
}

// データのクリア
void cls() {
  digit[0] = 0; digit[1] = 0; digit[2] = 0; digit[3] = 0;
}

// 数値の設定
void setNumber(uint16_t n, uint8_t dt = 0) {
  if (n>9999)
    return;

  cls();
  uint8_t dec = 0;
  // 4桁目
  if (n >= 1000) {
    digit[0] =font[ n / 1000]; n = n % 1000; dec = 1;
  }
  // 3桁目
  if (n >= 100) {
    digit[1] = font[n / 100]; n = n % 100; dec = 1;
  } else if (dec) {
    digit[1] = font[0];
  }
  // 2桁目
  if (n >= 10) {
    digit[2] = font[n / 10]; n = n % 10; dec = 1;
  } else if(dec) {
    digit[2] = font[0];
  }
  // 1桁目
  digit[3] = font[n];

  // 小数点
  if(dt && dt <=4) {
    digit[4-dt] |= BIT_P;
  }
}

void setup() { 
  //  桁ピンの初期化
  for (uint8_t i = 0; i < 4; i++) {
    pinMode(pin_dig[i], OUTPUT_OPEN_DRAIN);
    digitalWrite(pin_dig[i], DIG_OFF);
  }

  //  セグメントピンの初期化
  for (uint8_t i = 0; i < 8; i++) {
    pinMode(pin_seg[i], OUTPUT_OPEN_DRAIN);
    digitalWrite(pin_seg[i], SEG_OFF);
  }

  // 表示データの初期化
  for (uint8_t i = 0; i < 4; i++) {
    digit[i] = 0;
  }

  // LEDダイナミック点灯用割り込み設定
  ticker.set(REFTIME, dinamic_update);  // REFTIME間隔で dinamic_update()を呼び出す
  ticker.start();                       // タイマー割り込み実行開始
}

void loop() {
  static uint16_t n = 0;
  setNumber (n,millis()%1000>500?1:0);
  delay(100);
  n++; if (n>9999) n = 0;
}

タイマー割り込みは4m秒間隔で実行させています。
一回の割り込みで4桁のうちの1つを表示させています。
全桁更新周期は 4m秒 x 4 = 16m秒 ≒ 1/60秒 です。
これは、人間の目がちらつきを感じない周期です。
これ以上遅くすると、ちらついて見えます。

電圧を5Vではなく、3.3Vにしても問題なく点灯出来ました。
VF 3.3Vとありますが、実際はもっと低い値のようです。

より以前の記事一覧