フォト
2017年12月
          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 30
31            
無料ブログはココログ

表示器制御関連

2017年11月19日 (日)

Arduino STM32で漢字表示

以前、Arduino用でやってみた「Arduino - TV出力(TVoutLibrary使用)で漢字表示」を
Arduino STM32でやってみました。

マイコンボードは、STM32F103C8T6搭載のBlack Pillボードを利用しています。
Blue Pillボードでも動きます)

自作フォントライブラリを利用しています。
  Arduino用漢字フォントライブラリ SPIフラッシュメモリ版
  https://github.com/Tamakichi/Arduino_exfonts


01

動いている様子



結線

02



スケッチ

//
// TTVOutでマルチフォント表示 by たま吉さん 2017/11/18
//  

#include <SPI.h>
#include <W25Q64.h>
#include <exfonts.h>
#include <TTVout.h>

TTVout TV;
exfonts ft;  // フォント管理オブジェクト

// 指定位置に1文字表示
void mputc(uint16_t x, uint16_t y, uint16_t code) {
  byte buf[MAXFONTLEN]; 
  ft.getFontData(buf,code); // フォントデータの取得  
  TV.bitmap(x,y, buf ,0,ft.getWidth(), ft.getHeight());
}

// 指定位置に文字列表示
void mprint(uint16_t x, uint16_t y, char* str) {
  uint16_t wstr[1024];
  int16_t   len;
  
  len = exfonts::Utf8ToUtf16(wstr, str);  // UTF8からUTF16に変換する
  for (uint16_t i=0; i <len; i++) {
    mputc(x, y, wstr[i]);
    if (x + ft.getWidth()*2 < TV.hres()) {
      x += ft.getWidth();  
    } else {  
      x = 0;
      if (y+ft.getHeight()*2 < TV.vres()) {
        y+=ft.getHeight();
      } else {  
        break;
      }
    }
  }      
}

void setup () {
  static const char* text=
   "吾輩わがはいは猫である。名前はまだ無い。"
   "どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。"
   "吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪どうあくな種族であったそうだ。"
   "というのは時々我々を捕つかまえて煮にて食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。"
   "ただ彼の掌てのひらに載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。"
   "掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始みはじめであろう。";
   
  TV.begin(SC_448x216,2); // 第2引数でSPI 1,2を指定(デフォルト 1))
  TV.adjust(2);           // 垂直同期信号補正(デフォルト 0)
  ft.init(PA4);           // フォント管理の初期化
      
  //7種類のフォントサイズで文字列表示
  while(1)
    for (uint8_t i =0 ; i <7; i++) {
      TV.fill(0);
      ft.setFontSize(i);
      mprint(0,0,(char*)text);
      delay(1000*3);
    }
}

void loop () {

}

Arduinoと比べると、SRAMが20kバイトあるため画面解像度448x216ドットを確保出来ました。 表示も速いです。

2017年8月15日 (火)

OLED(SSD1309)ディスプレイモジュールを試して見る

大き目のOLEDディスプレイをAliExpressで見つけ、ポチりました。
2.42" 12864 OLED Display Module IIC I2C SPI Serial FOR C51 STM32 WHITE SSD1309

Aliexpress

$22.99はちょっとお高いかなぁと思いつつ、製品が到着。
0.96インチのOLEDと比較すると、以外と大きい...値段に納得。

Dscn6854

早速動作確認しました。
下記の情報を参考にしました。参考記事の製品は私の物と全く同じようです。
Arduino Forum >  Using Arduino >  Displays >  2.42" OLED SSD1309 with U8GLIB

SPI接続で利用します。
ライブラリはu8glibではなく、u8g2を使いました。
ライブラリはここから入手しました。

Dscn6842

流石OLED、表示が綺麗です。
画面のサイズも思っていたよりも大きいです。これなら$22.99で十分お得かも..

Dscn6841

参考にした記事ではVCC 5Vで稼働させていますが、3.3Vでも動作しました。
このモジュール、SPI利用の場合のピンの利用がちょっと分かりにくですが、
参考記事にて使い方が判明しました。

Dscn6846

SSD1309はSSD1306と互換性があるようです。u8glibではデバイスとしてSSD1306を
指定しても動作しました。

AdafruitのSSD1306ライブラリも試して見ました。

Dscn6853

問題なく動いていると思いきや、スクロールのデモでスクロールせず..

Dscn6850

ハードウェアスクロールが動かないです。SSD1309は完全互換では無いみたいですね。

次の調査として、Blue Pillボードでも使えるかやってみます。

追記

Blue Pillボードでもu8glib(u8g2)ライブラリを使った表示制御が出来ました。
豊四季Tiny BASICから利用出来るよう、ちょっとやってみます。

Dscn6863


2017年8月 7日 (月)

豊四季 Tiny BASIC for Arduino STM32でOLED(SSD1306)の制御

豊四季 Tiny BASIC for Arduino STM32をつかった
OLED(SSD1306)ディスプレイの制御です。I2Cにて接続しています。
以前V0.83用に作成したものを、V0.84でも問題なく動くかの動作確認を行いました。


このOLED、横向きに文字を表示するにはフォント回転が必要です。
その回転もBASICでは苦しいかと思ましたが、問題なくリアルタイム表示出来ました。

プログラムソースは、ちょっと長めです。
https://gist.github.com/Tamakichi/36896640d6e8ac94e618f78f9a5bddd8

1 'SSD1306_2(PB6=SCL,PB7=SDA)
10 M=MEM:A=$3C:CLS
20 GOSUB "@INIT":GOSUB "@CLS"
30 X=0:Y=0:C=ASC("A"):GOSUB "@OUT(X,Y,C)"
40 X=1:Y=1:C=ASC("B"):GOSUB "@OUT(X,Y,C)"
50 X=2:Y=2:C=ASC("C"):GOSUB "@OUT(X,Y,C)"
60 X=0:Y=5:S="Hello Tiny BASIC":GOSUB "@PRN(X,Y,S)"
70 'WAIT 2000
80 'GOSUB "@CLS"
90 GETTIME E,F,G
100 LOCATE 0,0:?#-2,E;":";F;":";G
110 X=0:Y=7
120 FOR b=0 TO 7
130 C=VPEEK(X,0)
140 GOSUB "@OUT(X,Y,C)"
150 X=X+1
160 NEXT b
170 WAIT 1000
180 GOTO 90
190 END
5000 "@INIT"
5010 POKE M,$00,$B0,$21,$00,$7F,$40,$80
5020 POKE M+7,$AE,$A8,$3F,$D3,$00,$40,$A1,$C8
5030 POKE M+15,$DA,$12,$81,$FF,$A4,$A6,$D5,$80
5040 POKE M+23,$2E,$20,$10,$21,$00,$7F,$22,$00
5050 POKE M+31,$07,$8D,$14,$AF
5060 FOR I=0 TO 27:R=I2CW(A,M,1,M+7+I,1):NEXT I
5070 RETURN
5080 "@OUT(X,Y,C)"
5090 POKE M+3,X*8:POKE M+1,Y|$B0
5100 GOSUB "@ROTATE(C)"
5110 R=I2CW(A,M,1,M+1,4)
5120 R=I2CW(A,M+5,1,M+50,8)
5130 RETURN
5140 "@CLS"
5150 POKE M+3,0:POKE M+1,0|$B0
5160 R=I2CW(A,M,1,M+1,4)
5170 FOR I=0 TO 127
5180 R=I2CW(A,M+5,1,FNT,8)
5190 NEXT I
5200 RETURN
5210 "@PRN(X,Y,S)"
5220 L=LEN(S)
5230 FOR I=1 TO L
5240 C=ASC(S,I)
5250 GOSUB "@OUT(X,Y,C)"
5260 X=X+1:IF X>15 X=0:Y=Y+1
5270 NEXT I
5280 RETURN
5290 "@ROTATE(C)"
5300 F=FNT+C*8
5310 FOR J=0 TO 7
5320 D=0
5330 FOR K=7 TO 0 STEP -1
5340 D=D+((PEEK(F+K)>>(7-J))&1)<<K
5350 NEXT K
5360 POKE (M+50+J),D
5370 NEXT J
5380 RETURN

5000~5380行はサブルーチンです。
ラベル指定呼び出しで5つのサブルーチンを定義しています。
・"@INIT"
  OLEDモジュールの初期設定を行うサブルーチンです。
・"@CLS"
  OLEDの画面の表示を全消去します。
・"@OUT(X,Y,C)"
   指定した座標に文字を表示します。
   変数Xに横座標、Yに縦座標、Cに文字コードを指定します。
・"@PRN(X,Y,C)"
   指定した座標に文字列を表示します。
   変数Xに横座標、Yに縦座標、Sに文字列を指定します。
・"@ROTATE(C)"
  "@OUT(X,Y,C)"から利用されるサブルーチンです。
  指定した文字コードのフォントデータを回転してメモリに格納します。

10~190行がメインルーチンです。
サブルーチンを利用して文字、文字列、時刻の表示を行っています。

プログラムがちょと長いですねぇ
長いとNTSCのビデオ出力画面でのプログラム作成は辛いです。
テキストエディタで作成して転送になっちゃいますね。

そこで、 V0.84(現在動作確認中)では長いプログラムを作成しやすくするために、
次の機能を盛り込みました。

  1)プログラム編集機能の改善
    ・ターミナル上で最大横128文字x縦50行のスクリーン編集をサポート
    ・プログラムソースの上下スクリール表示

  2)プログラムソースの部分保存・読み込み
    例:上記ソース5000行~5380行(サブルーチン部)だけを保存・読み込みする

  3)RENUMコマンドで範囲指定の番号振り直し対応
   例; 上記ソースの10行~190行だけを行番号の振り直しする

  4)利用可能変数の追加
    A~Zではちょと足りないので、A0、A1のように数字を付けた変数名もOK


色々と長いプログラム作成の改善方法を模索したのですが、
幾つか長いプログラムを作成してみると、
「行番号付けるのうざい、行番号要らなくねぇ?」
と、感じる今日この頃です。

  行番号廃止
これが一番の改善策と思えてきました。
行番号が無ければ、番号の振り直しとか不要ですし...
行番号の付け間違えで、行が消えたり等弊害もあります。

たしか、BASICの親戚(親?)のFORTRANは必要な時だけ(GOTOの飛び先)、
行番号を付けていたはずです。

行番号ではなく、単に行(先頭からの行の連番)だけでもイケないだろうか模索中です。
何れは、号番号廃止したいなぁと思っています。

また、引数を伴うサブルーチン呼び出しも
  CALL "@PRN", X,Y,S
みたいな呼び出しと
  SUB "@PRN" X0,Y0,S0
    ・・・
  RETURN

みたいなサブールーチンの定義にしたいです。

2016年8月 7日 (日)

Arduinoで8x8LEDマトリックスを直接(直結)で制御する

以前、IchigoDotSが電流制御抵抗なしにマイコンでLEDマトリックスを制御しており、
「どういう制御しているのだろう?」と疑問に思い、調査がてらArduinoでやってみました。

※注意 真似するとArduinoが破損する場合があります。

動作の様子



LEDマトリックスは秋月電子で購入した MNA20SR092G を利用しました。

組み立て
D7、D8ピンは隙間が空いているのですが、LEDマトリックスのピンを広げて装着させました。

Dscn5520

反対側のピンは、ジャンパワイヤー(メス・オス)で結線しました。

Dscn5515


回路図(結線図)

02


     接続ピンの対応表
        2つの表は同じものです(左がLED PIN順 、右がMATRIX割り付け機能順)。
        表のLEDピンは上図のPIN1~PIN16に対応します。
        MATRIXはPINに割り当てられている機能を示しています。       

                     LED PIN順                          MATRIX 割り付け順
      01_2

      アナログピンA0~A3もデジタル入出力として利用しています。
      A0~A3はデジタルピンとして使う場合ピン番号14~17として利用出来ます。

スケッチ
  ダウンロード matrix4.zip (22.8K)

メイン処理部のみ掲載しました。

#include <avr/interrupt.h>
#include <TimerOne.h>
#include "misakiUTF16.h"

//*************************************
//   出力ピンの定義(MNA20SR092G接続用)
//*************************************
// 横
#define COL1  10
#define COL2  7
#define COL3  6
#define COL4  16
#define COL5  4
#define COL6  15
#define COL7  12
#define COL8  13

// 縦
#define ROW1  17
#define ROW2  11
#define ROW3  2
#define ROW4  14
#define ROW5  9
#define ROW6  3
#define ROW7  8
#define ROW8  5

#define UARTBPS 9600
#define TIMERTIK 100

//*****************************
// グローバル変数
//*****************************
// COL,ROWのピン割り付けテーブル
uint8_t col[8] = {COL1,COL2,COL3,COL4,COL5,COL6,COL7,COL8};
uint8_t row[8] = {ROW1,ROW2,ROW3,ROW4,ROW5,ROW6,ROW7,ROW8};

// 表示用バッファ(8x8ドット分)
uint8_t pdata[8];
uint8_t line, colno;

//*********************************
// ドットマトリックス表示用関数
//*********************************

//
// digitalWrite高速化版
//
void new_digitalWrite(uint8_t pin, uint8_t val) {
  uint8_t bit = digitalPinToBitMask(pin);
  volatile uint8_t *out = portOutputRegister(digitalPinToPort(pin));
  if (val == LOW)
    *out &= ~bit;
  else
    *out |= bit;  
}

// 点灯する行の選択
// y: 行(0〜7)
void selectRow(uint8_t y) {
  for(uint8_t i=0; i <8; i++)
    new_digitalWrite(row[i], HIGH);   
  new_digitalWrite(row[y], LOW);
}

// 1行分データの出力
void setData(uint8_t d) {
  uint8_t msk = B10000000;
  for (uint8_t i = 0; i<8; i++) {
    if (msk & d) { 
      new_digitalWrite(col[i], HIGH);
    } else {
      new_digitalWrite(col[i], LOW);
    }
    msk>>=1;
  }  
}

// ドット単位のダイナミック駆動
void update_dot() {
  setData(0);
  selectRow(line);
  setData(pdata[line] & (B10000000>>colno));
  colno++;
  if (colno == 8) {
    colno =0;
    line++;
    if (line==8) 
      line = 0;  
  }
}

// ドットマトリックスの表示OFF
void matrix_off() {
  for (uint8_t i = 0; i < 8; i++)
       new_digitalWrite(row[i], HIGH);
}

// バッファクリア
void clrar_buf() {
  for (uint8_t i=0; i <8; i++) 
     pdata[i]=0;
}

// バッファへの書き込み
// 8x8フォントパターンを表示用バッファに書き込む
void write_buf(uint8_t* dat) {
  for (uint8_t i=0; i<8; i++)
     pdata[i]= dat[i];
}

// 指定座標にフォントパターンをセット
void write_bufat(uint8_t* fptr, uint8_t x, uint8_t y) {
  uint8_t w;
  
  if (x>7 || y >7)
    return;     
  for (byte j=y,i=0; j < 8; j++,i++)
    pdata[j] = (pdata[j]>>(8-x))<<(8-x) | fptr[i]>>x;
}

// バッファーデータのスクロール
// h_mode : 0 なし,1 左 ,2 右 
// v_mode : 0 なし,1 上, 2 下      
void scroll(uint8_t h_mode, uint8_t v_mode) {
  if (h_mode ==1) 
    for (byte i = 0; i < 8; i++) 
      pdata[i] = pdata[i]<<1;
  if (h_mode ==2)
    for (byte i = 0; i < 8; i++)
      pdata[i] = pdata[i]>>1;
  if (v_mode ==1) {
    for (byte i = 0; i < 7; i++)
     pdata[i]= pdata[i+1];
    pdata[15]=0;
  }
  if (v_mode == 2) {
    for (byte i = 7; i >0; i--)
     pdata[i]= pdata[i-1];
    pdata[0] = 0;    
  }
}

// スクロールしながらパターンを表示
void scrollout(uint8_t* fptr, uint16_t dly) {
  for (byte i=0; i<8; i++) {
    scroll(1, 0);
    write_bufat(fptr, 7-i, 0) ;
    delay(dly);
  }
}  

char buf[129];
bool lfgMsg;

//*********************************
// メッセージ受信チェック
//*********************************
void chekMessage() {
  // シリアルデータ受信
  uint8_t n=0;
  while (Serial.available() > 0) {
    buf[n] = Serial.read();
    n++;
    if (n>128) {
      break;  
    }
  }

  buf[n] = 0;
  lfgMsg = true;
  Serial.println("OK");
  Serial.flush();  
}

//*********************************
// メイン処理
//*********************************
void setup() {
  for (uint8_t i=0; i <8; i++) {
    // ピンモードの設定
    pinMode(col[i], OUTPUT);
    pinMode(row[i], OUTPUT);
  }
  Serial.begin(UARTBPS);
  clrar_buf();
  line = 0;
  colno = 0;
  lfgMsg = false;
   
  Timer1.initialize(TIMERTIK); 
  Timer1.attachInterrupt(update_dot);  
  //setfull();
}

char *str="こんにちは さいたま県♪ 今、さいたまがアツい!";
uint8_t fnt[FONT_LEN];
char *pUTF8;

void setfull() {
  for (uint8_t i=0; i <8;i++) 
    pdata[i] = 0xff;
}

void loop() { 
  if (lfgMsg) {
    pUTF8 = buf;
    lfgMsg = false;
  } else {
    pUTF8 = str;  
  }
  while(*pUTF8) {
    pUTF8 = getFontData(fnt, pUTF8,true);     // フォントデータの取得
    scrollout(fnt, 70);                      // スクロールしながら文字を表示
    if (Serial.available() > 0 && !lfgMsg) 
      chekMessage();      
  }
  delay(1000);
}

解説

1)LEDの駆動
電流制御抵抗なしでも、LEDにかける電圧のディューティー比 とパルス幅を調整すると
定格内でLEDの駆動が行えます。
(専門家ではないので、間違えているかもしれませんが..)

まずは、利用したLEDマトリックス MNA20SR092Gのデータシートに下記の記載があります。

  03

    IPF 100mA が注目する数値です。
    ディューティー比 1/10サイクル パルス幅 0.1ms内なら100mAまで可能です。

    これを守れば、通常の30mA(IAF)を超えてもOKです。
    これがまず可能にする理由の第一点
    ((パルス幅 0.1msはちょっと短すぎです。別製品 OSL641501-ARAだと1ms)

LEDに関しては問題なしです。

参考にしたサイト
   ikkei blog -  Arduino UNO にLEDを直結して電流を測ってみた


2)Arduino
Arduinoの出力ポートの出力抵抗(インピータンス)が30Ω程度あります。

LEDのVfが2.0Vなので、
ソース(HIGH)→ LED → シンク (LOW)で点灯させた場合に流れる電流は
  (5.0 - 2.0) / (30+30) = 0.0645 = 50mA
となります(自信はないので断言は出来ません)。

arduino的には最大定格40mAを超えていますね。

一方別の記載で1ピンで推奨の20mA超えても
ソースで他ピンを含めた合計で100mA厳守、同シンクで150mA厳守の記載があります。
インターネット上で調べると定格以上でも70mA位流せるようです。
ただし、動作保証範囲外の利用となります。

ここは、趣味で利用する範囲で許容範囲としましょう。


実際にオシロスコープで測定でしてみて、
3.3V稼働時に28mA、5V稼働で48mA流れていることを確認しましった。

スケッチの実装について

Arduin IDE 1.6.9にて実装しています。

ハードウエア的制約を考慮して実装しました。
ダイナミック駆動は1ドット単位で制御するようにしました。
(瞬間的には常に最大で1点しか点灯していないことになります)
ボタン電池による駆動を視野にいれ省電力化に貢献すると思います。

パルス幅 0.1ms内を考慮し、0.1ms間隔のタイマー割り込みを利用し、
1回の割り込みで1ドットの制御、64回の割り込みで1画面分64ドットの制御を
行うようにしました。ディューティー比 1/64 となります。
    
6.4msで1画面の更新となります。
人間の目で1/60秒以内ならチラついて見えないのでこの更新なら十分でしょう。

この周期でタイマ割り込みで行うにおいてOneTimerライブラリを使いました。
更に0.1ms内でのLED制御を考慮してdigitalWrite()を高速版に置き換えました。

実際にオシロスコープで測定すると、0.1ms幅のパスルは出ていなくて0.04msでした。
パルス周波数は156.2Hzであるため正確な間隔で割り込みが発生しています。
(周期 0.1ms x 64 = 6.4 ms   1/6.4ms = 156.25Hz)

日本語表示は、美咲フォントを利用しています。

機能的には、固定文字列 "こんにちはさいたま県.."を表示しています。

さらに、シリアル通信にて受信した文字列を表示出来るようにしました。
(まだ作りが甘いです。たまにおかしくなります) 

実際の実装は、3Vボタン電池稼働でやろうと思っています。
電流制御抵抗使用しないのも省電力につながると思います。
ほとんどIchigoDotのマネですが..
Atmega328(中身はArduino) 3V 内部RCクロック 8MHzにて動作しました。

Dscn5511



2016年7月23日 (土)

アクティブマトリクス蛍光表示管の実験用表示モジュールの試用

Facebookのお友達からお借りしました、「アクティブマトリクス蛍光表示管(CL-VFD)
MW25616L 実験用表示モジュール」を調査中です。

16x256ドットのグラフィック表示が可能なモジュールです。

Dscn5467

制御用にAtmega328pが使われており、Arduino IDE環境にてプログラム開発が出来ます。
いくつか、自由に使えるGPIOピンが開放されており、I2Cやシリアル通信も使えそうです。

日本語フォントROM GT20L16J1Y16を搭載していており、日本語表示も可能です。

Dscn5465

背面にICSP端子があり、この端子経由でSPI接続でSDカードなんかが使えそうですね。

Arduinoと同じようにUSB経由での書込みと電源供給が出来ます。
非常にお手軽に使えるモジュールです。

Dscn5453

プログラムを書きこんで表示で表示してみた様子
公開かさているサンプルスケッチを書きこんで動かしてみました。

Dscn5456_2

輝度が強く、私のデジカメでは綺麗に映すことがが出来ません。光が広がってフォントが
つぶれた映像となってしまいます。動画も撮影したのですが、ダメダメでした。
(何枚も撮って一番よさそうなのを掲載しました)
実際には表示は非常にきれいです。文字が左にスクロール表示します。
日本語のメッセージが表示出来ます。

ただし、日本語フォントROM GT20L16J1Yは私も使ったことがあるのですが、
ひらがな、カタカナ、漢字、全角英数、半角英数そのれぞれのバランスが微妙です。

制御方法について

表示のための制御は比較的簡単のようです。
表示パターンは2バイト16ビットが縦1列に対応しています。そのデータが
横256ドット分、合計512バイト分シーケンシャルに並んでいる構造です。

シフトレジスタを使う要領で4つのSI、CLK、LAT、ENを使ってデータを転送します。
16x256ドット分の4096ビット分のレジスタがあり、4096ビット単位でラッチして
表示データを確定出来ます。

表示機器にはこの形式多く、過去に手掛けて蓄積したノウハウが役立てそうです。

02

03

この構造の場合、表示中の画像に線を書いたり、追記描画するのは苦手です。
追記しようにも、データを送るとシフトされて左に画像全体が移動します。

通常、このような構造で自由に描画するにはフレームバッファ(ワークメモリ)を用います。
一旦、フレームバッファに描画してそのデータを一括送信して表示更新する方法です。

次のような感じです。

04

この方式では一括転送に要する時間が早いほど映像が素早く更新出来ます。
動きのある表示や、リアルタイム更新表示を行う場合は早い方が良いです。

(ちょっと前にやった「4連8x8ドットLEDマトリックス」なんかも同じ方式でやっています)

実際に、フレームバッファを使って1点描画するごとに表示更新を行う処理を
ArduinoのShiftOut()関数を使って行ったところ、目視で5画面/秒程度がやっとな感じでした。

ShiftOut()は無駄に遅いことで有名で、同じ処理を直接I/Oレジスタを操作して
転送を行うとかなり改善します。ShiftOut()とdigitalWrite()と次のような感じで
実装して置き換えるだけで、転送速度は8倍ぐらいに改善しました。

void new_shiftOut(uint8_t dataPin,uint8_t clockPin,uint8_t bitOrder,byte val) {
  uint8_t i;
  uint8_t bit_data = digitalPinToBitMask(dataPin);
  uint8_t bit_clock = digitalPinToBitMask(clockPin);
  volatile uint8_t *out_data = portOutputRegister(digitalPinToPort(dataPin));
  volatile uint8_t *out_clock = portOutputRegister(digitalPinToPort(clockPin));

  for (i = 0; i < 8; i++)  {
    if (bitOrder == LSBFIRST) {
      if(val & (1 << i)) {
        *out_data |= bit_data;
      } else {
        *out_data &= ~bit_data;
      }
    } else {
      if(val & (1 << (7 - i))) {
        *out_data |= bit_data;
      } else {
        *out_data &= ~bit_data;
      }
    }
    *out_clock |= bit_clock;
    *out_clock &= ~bit_clock;
  }
}

inline void new_digitalWrite(uint8_t pin, uint8_t val) {
  uint8_t bit = digitalPinToBitMask(pin);
  volatile uint8_t *out = portOutputRegister(digitalPinToPort(pin));
  if (val == LOW)
    *out &= ~bit;
  else
    *out |= bit;  
}

ShiftOut()なら本来、SPIを使った高速通信に置き換えるのが容易なのですが、
SPIピンとは別ピンに接続されているのがちょっと残念です。
それでも、上記修正で秒20画面位は更新できそうです。

現状、表示する文字列はシフトJIS指定でプログラムに埋め込み、表示画像も
プログラムに埋め込みでちょっと使い勝手が良くないです。

05

この当たり、自作のマルチフォントライブラリ、ビットマップ画像ローダを使って
自由度のあるコンテンツ表示をやりたいなぁと思います。

2016/12/20~  随時追記中

裏の端子にアクセスしやすいように専用の脱着式の基板を作成しました。

Dscn6226

SPI接続にてSDカードを接続。自作のマルチサイズフォントライブラリが動くようになりました(ただし、調整中)。

Dscn6268

SDカードが3.3V駆動にため、電圧レベルの調整をしています。

Photo

動作の様子


8ドット漢字も意外と読めますね。

表示は前述のフレームバッファに一旦書きこんでから、VDFに一括転送しています。
表示するメッセージの指定はUTF-8文字列です。

void demo02() {

  uint8_t font[MAXFONTLEN];   uint16_t x = 0;   uint8_t sz[] = {16,14,12,10,8};   mw_claerbuf();   SDfonts.open(); // フォントのオープン   for (uint8_t i = 0; i < 5; i++) {     char* pUTF8 = "SDカード漢字フォント利用テスト";     SDfonts.setFontSize(sz[i]); // フォントサイズの設定     x = 0;     while ( pUTF8 = SDfonts.getFontData(font, pUTF8) ) { // フォントの取得       mw_drawFont(x, font);       x+=SDfonts.getWidth();     }     mw_update();     delay(1500);     mw_claerbuf();      }   SDfonts.close();  // フォントのクローズ   delay(2000); }

次はメッセージの縦スクロール、SDカードに青空文庫の小説(テキストファイル)入れて
表示出来るようにしてみます。

(つづく)


2016年7月16日 (土)

IchigoJamで有機ELキャラクタディスプレイモジュールを制御

IchigoJamで秋月電子で販売されている有機ELキャラクタディスプレイモジュール
制御してみました(型番はSO1602AWWB-UC-WB-Uという製品)。
IchigoJamのファームウェアは1.2.1を使っています。

IchigoJamからはI2C接続にて制御しています。

Dscn5417

さすが有機EL、表示が綺麗ですね。

この有機ELキャラクタディスプレイモジュール(以後長いのでOLEDと略)の使い方は
製品ページリンクのデータシートよりも、製品についてる説明書(日本語)の方が分かり
易いです。

結線
製品についてる説明書の「マイコンとの接続例」に従って結線するだけです。

プログラムソース

1 'OLED Character Display DEMO
10 CLV
20 GSB @ショキカ
30 [0]="IchigoJam World"
40 [1]="ネ・コ・ニ・コ・ン・バ・ン・ワ"
50 X=0:Y=0:S=[0]:GSB @ヒョウジ
60 X=0:Y=1:S=[1]:GSB @ヒョウジ
70 END
500 @ショキカ
510 POKE #700,0,1,2,#C,1,#40
520 FOR M=#701 TO #704
530 R=I2CW(#3C,#700,1,M,1)
540 NEXT
550 RTN
600 @ヒョウジ
610 L=LEN(S)
620 POKE#706,#80+Y*32+X
630 R=I2CW(#3C,#700,1,#706,1)
640 FOR I=0 TO L-1
650 R=I2CW(#3C,#705,1,S+I,1)
660 NEXT
670 RTN

プログラムはわりと短めですね。使いやすいモジュールです。
GSBGOSUBの省略形、RTNRETURNの省略形です)

簡単な解説

OLEDの利用のために2つのサブルーチン(GOSUBで呼び出し)を定義しています。
初期化処理(500行 @ショキカ)と、表示処理(600行 @ヒョウジ)です。

・初期化処理(500行 @ショキカ)
  OLED対する命令は2バイト構成(コマンドコード+データ)です。
  510行でそのコマンドとデータをメモリ上に定義しています。
  520行~540行でそのデータをI2Cアドレス#3CのOLEDに送っています。

  具体的には
    #00, #01 : Clear Display (表示部をクリア)
    #00, #02 : Return Home (カーソル位置を先頭に移動)
    #00, #0C : Send Display on command (表示ON、カーソル表示なし)
    #00, #01 : Clear Display (表示部をクリア、取りあえず説明書通りにもう一度クリア) 
  という4つの命令を送っています。

・表示処理(600行 @ヒョウジ)
  引数(値を渡す変数)としてSXYを使用しています。

     表示する文字列  S(文字列)
     表示位置横        X(0~15)
     表示位置縦        Y(0~1)
 
  610行が表示する文字列の長さを変数Lに設定、
  620行が表示位置アドレス (OLEDの内部アドレス)をメモリアドレス#706に設定
  しています。630行でその表示位置をOLEDに送信しています。
  具体的には次の2バイトを送信しています。
    #80, 表示位置アドレス : Set DDRAM Address
  表示アドレスは1行目が#00~#0F(左→右)、2行目が#20~#2F(左→右)となります。
  640行~660行が変数Sから1文字づつ文字を取り出して、OLEDに送信して
  表示を行っています。

これらのサブルーチンを10行から70行で利用しています。




2016年7月 5日 (火)

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

前回の続きです。

4連8x8ドットLEDマトリックス2つを連結して32x16ドット表示にしてみました。
スケッチは前回からの少々の改造で実装出来ました。

01

1つめの出力を2つめの入力に接続しいます。増やしても5線のみので制御できます。

16x16ドットの日本語文を表示するため、自作フォントライブラリを利用しました。
フォントをmicroSDカードから読むため3.3V稼働させています。
(Arduino Unoも3.3V稼働出来るものを利用)

MAX7219としては3.3Vは動作保証外ですが問題なく動作しました。
3.3VでもOKなので、ARMやESP-WROOM-02でも利用出来ますね。

動作の様子


下段のモジュールのLEDが不良のため1点だけ点灯しませんが
動作としては期待以上に動いてくれました。

ただ、Arduino標準のshiftOut()関数によるシリアルデータの送り出しが遅いようです。
早いスクロール表示が出来ませんでした。そのため高速版のshiftOut()に置き換えました。

8個もLEDマトリックスを使用しているので消費電流が気になり、計ってみました。

Dscn5391

表示部(Arduino Unoを除く)は、最大35.1mAでした。まあ、こんなもんですかね。
バッテリー駆動も可能なレベルですかね。

このモジュールなかなか使いやすですね。用途に応じて、連結して利用出来ます。
更に、4連基板をカットして利用することも出来るみたいです。

基板の裏はこんな感じ

Dscn5380

今回作成したスケッチ(プログラム)  ダウンロード max7219_test3.zip (6.2K)

いくつかのファイルに別れますが、取りあえずメイン部はこんな感じです。

// max7219_test3.ino
// MAX7179ドライバーライブラリ動作チェック 32x16ドットバージョン
// 2016/07/05 たま吉さん

#include <string.h>
#include <sdfonts.h>

#include "MAX7219_matrix.h"
#include "libmatrix.h"

// MAX7219接続
#define MAX7219_DIN   2 // DIN
#define MAX7219_CLK   4 // CLK
#define MAX7219_LOAD  3 // LOAD

// SDカード接続
#define MOSI_SD   11    // SDカードのMOISへ接続
#define MISO_SD   12    // SDカードのMISOへ接続
#define CLK_SD    13    // SDカードのCLKへ接続
#define CS_SD     10    // SDカードモジュールCSへ接続

#define  SCREENS   8    // MAX7219カスケード接続数
#define  BRT       0    // LEDの輝度(0~7)
#define  SC_WIDTH  32   // マトリック表示横ドット数
#define  SC_HIGHT  16   // マトリック表示縦ドット数

uint8_t fbuf[SC_WIDTH*SC_HIGHT/8];  // 表示用バッファ

// 表示用バッファを表示
// (フレームバッファ32x16ドットをMAX7219用バッファ64x8にマッピング)
void update_screen() {
  uint8_t* ptr = MAX7219_getBuffer();
  for (uint8_t i=0; i < 8; i++) {
    memcpy(&ptr[i*8],&fbuf[i*4+32], 4);
    memcpy(&ptr[i*8+4],&fbuf[i*4], 4);
  }
  MAX7219_update();  
}

// デモ
void demo() {
  uint8_t font[MAXFONTLEN];
  SDfonts.open();            // フォントのオープン
  SDfonts.setFontSize(16);    // フォントサイズの設定

  char* str = "こんにちは埼玉県!熱いぞ!埼玉県!";

  MAX7219_clear();
  while(1) {
    str = SDfonts.getFontData(font, str);  // フォントデータの取得
    if (!str)
      break;
    scrollInFont(fbuf, font, 30);
  }
  SDfonts.close(); 
}

// 1文字分スクロール挿入表示
void scrollInFont(uint8_t*ptr, uint8_t *fnt, uint16_t dt) {
  for (int8_t t = 0; t < 16; t++) {
    scrollBitmap(ptr, SC_WIDTH, SC_HIGHT, B0001); // 左スクロール
    clearBitmapAt(ptr, SC_WIDTH, SC_HIGHT, SC_WIDTH-t-1, 0, SC_HIGHT, SC_HIGHT);
    setBitmapAt(ptr, SC_WIDTH, SC_HIGHT, SC_WIDTH-t-1, 0, fnt, SC_HIGHT, SC_HIGHT);
    update_screen();
    delay(dt);
  }  
}

void setup() {
  //Serial.begin(115200);
  SDfonts.init(10);     // フォント管理の初期化
  
  // マトリック表示ドライバの初期化
  MAX7219_init(MAX7219_DIN, MAX7219_CLK, MAX7219_LOAD, SCREENS, BRT);
}

void loop() {
  MAX7219_clear();
  demo();
  delay(1000);
}

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

今まで、LEDドットマトリックスを色々やってきましたが、このモジュールの利用で
落ち着きそうです。

2016年7月 4日 (月)

4連8x8ドットLEDマトリックスを試してみる

Aliexpressで4連の8x8ドットLEDマトリックが格安で売っていたので入手しました。
ドライバーにMAX7219を4つ使った製品です。

なんか、ドットマトリックスばっかりやってる感がありますが、表示器の制御は
面白いです。

MAX7219 Dot Matrix Module For Arduino Microcontroller 4 In One Display with 5P Line

01

到着した製品はこんな感じです。

Matrix

早速、Arduinoにて動作確認してみました。
輝度が強く、眩しいので輝度設定を最小にしました。LEDマトリック自体は明るい製品みたいです。

Dscn5373

Arduinoとの接続は5線(VCC、GND、DIN、CLK、LOAD)のみです。シフトレジスタを
使うような感じでデータを送ります。

購入した2つのうち1つは1ドット点灯しない不具合を発見。
入れ替ると点灯するので基板ではなく、8x8ドットLEDマトリックス1個が不良のようです。
まあ、これは諦めましょう。

本製品で使われている8x8ドットLEDマトリックスは5個で$3で売っているのでそちらを
買って差し換えるつもりです。

Dscn5377

動いている様子


4文字表示できると時刻や気温の表示なんかにも使えそうです。


スケッチ(プログラムソース)
ダウンロード max7219_test.zip (5.6K)

4連結の制御にちょっとはまりましたが、取りあえず出来ました。
下記のライブラリを参考にさせて頂き、制御部分を作成しました。
  https://github.com/lstoll/arduino-libraries/tree/master/Matrix

日本語フォント表示は美咲フォントを使わせて頂きて、自作ライブラリにて
行っています。コンパイルには上記スケッチとは別に下記が必要となります。

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

さて、2つあるので繋げてなんとか32x16ドット表示を実装したいですね。
その後は、ESP-WROOM-02に繋げてインターネットから取得した情報を表示なんてのを
やってみたいです。

2016年6月28日 (火)

ESP-WROOM-02を始めました(3) SPIFFSの利用

2016/07/02 追記更新

前回はSDカードに漢字フォントとビットマップファイルをを載せていたのですが、
そのデータを標準搭載のフラッシュメモリ上に置けることが分かりました。

ということで、実際にフラッシュメモリ上に漢字フォントをおいて動かしてみました。
取りあえず、動作しました。

03

だだし若干、表示にチラつきが出ます。
フラッシュメモリにアクセスする時にダイナミック駆動に利用しているタイマー割り込みが
中断させられるのかもしれません。

今後、WiFi通信等の利用も考えると、1msecの割り込みのダイナミック駆動はちょっと
負担が大きそうです。

フラッシュメモリの具体的な利用方法

ESP-WROOM-02には4MバイトのSPI接続フラッシュメモリが搭載されており、
そのうち、1M or 3Mバイトをデータ用のファイルシステムとして利用出来ます。

この領域は、専用に確保されておりスケッチを書き換えても影響を受けません。

  Flash layout

  ※公式サイトのリファレンスマニュアル ESP8266 Arduino Core /  File System /  より引用
    http://esp8266.github.io/Arduino/versions/2.3.0/doc/filesystem.html

ファイルシステムに利用する領域はArduino IDEにて選択が出来ます。

フラッシュサイズが4MバイトのESP-WROOM-02は1M or 3Mバイトが選択出来ます。

Arduino IDEから任意のファイルを配置出来る

やり方は、公式サイトのリファレンスマニュアル
  ESP8266 Arduino Core /  File System / Uploading files to file system
     http://esp8266.github.io/Arduino/versions/2.3.0/doc/filesystem.html#uploading-files-to-file-system
に記載されています。

ブラグインをダウンロードして、Arduino IDEに組み込み、Arduino IDEを再起動、
これで、ツールメニューに「EPS8266 Sketch data upload」というメニューが追加されます。

現在開いているスケッチが置いてあるフォルダにフォルダ data を作成してその中に
データファイルを置いておきます。

そんでもって、メニュー 「EPS8266 Sketch data upload」 をクリックしてアップロードします。

実際に漢字フォントとビットマップファイルの約1.75Mバイトをアップロードしてみると
数分かかりましたが、エラーなく完了出来ました。

プログラムからのファイルアクセス

ヘッダーファイル fs.h をインクルドします。これにより、File system object (SPIFFS)が
利用出来ます。

ファイルシステムの操作はSPIFFSオブジェクトを使って行います。
SDライブラリのSDオブジェクトとほとんど同じ感覚で利用出来ます。

SDオブジェクトからSPIFFSオブジェクトへの移行は関数がほぼ1対1でかつ、
パラメタも類似しているためすんなりと行えました。

ただ、どうもSDライブラリとの相性が悪いのかSD.hも別途インクルドするFileクラス関連の
コンパイルエラーが発生しました(これは要調査です)。
まあ、今回は、併用しないのでSD.hのインクルドを止めました。

プログラム(スケッチ)

現時点のバージョンを置いておきます。
     ダウンロード sample5v2_esp.zip (14.1K)   

ココログでは、1Mバイト以上のファイルを置けないので、フォントデータは下記より
ダウンロードして下さい。
     https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD/archive/master.zip

フォントの著作権は私ではなくフォント作成者にあります。
解凍し、README.TXTのライセンス等に関する記載内容を確認の上お使い下さい。

解凍したフォルダのfontbin内のFONT.BINが利用するフォントデータとなります。
このフォントデータをスケッチ配置フォルダ下のdataフォルダに入れて、ESP-WROOM-02
にアップロードして利用します。

最後に

最終的にはESP-WROOM-02用の漢字フォントライブラリを整備したいと思います。

2016/07/02 追記

ライブラリ化し、下記にて公開しました。
  ・ESP8266用漢字フォントライブラリ SPIFFS版 ESP8266-KanjiFont-Library-SPIFFS
    https://github.com/Tamakichi/ESP8266-KanjiFont-Library-SPIFFS

2016年6月26日 (日)

ESP-WROOM-02を始めました(2)

前回からの続きです。
ESP8266搭載のESP-WROOM-02の調査中です。

Arduinoとしてどれくらい利用可能かを確認するため、
Arduino UNO(Atmega328)用のaitendo 16x16LEDマトリックス制御プログラムを移植
してみました。

Dscn5336

動作の様子



意外とライブラリの互換性レベルが高く、
I/Oピンの割り付け変更とタイマー割り込みの設定の変更程度で動きました。
(直接レジスタをいじっている高速版digitalWrite()、shiftOut()はさすがに動かないので、
正規版に戻しました)。

行儀のよいArduino UNO用スケッチなら少々の修正で利用出来ると思います。
実際に自作のビットマップファイルロードライブラリ、フォントライブラリが利用出来ました。
(この動作確認にて、自作のフォントライブラリの不具合を見つけました)

SPI、SDライブラリは割り付けピンを変えるだけで利用出来ました。

プログラム領域にデータを置いて参照利用するpgm_read_byte()利用出来ました。

タイマー割り込みに使っていたMsTimer2ライブラリは動かないので、ESP8266用に
用意されているTickerを利用しました。利用はとても簡単です。

ヘッダーファイル Ticker.hをインクルードして、グローバル変数を宣言して、
  #include <Ticker.h>
  Ticker ticker ;


タイマー割り込み設定の
  MsTimer2::set(1, fontout);
  MsTimer2::start();
  ticker.attach_ms(1, fontout);
と変更するだけです。

「いろは歌」はSDカード上のフォントを利用して表示しています。
「ねこにこんばんわ」はビットマップファイルを読み込んで表示していま。

タイマ割り込みTickerは、MsTimer2に比べると若干、精度が悪い感じです。
ダイナミック駆動のLED表示に若干ムラが生じます。

ピン割り付けがちょっと悩みましたが、下記のサイトの情報が大変参考になりました。

・Qiita - ESP-WROOM-02 Arduino互換ボードのGPIOはこうやって使う
   http://qiita.com/umi_kappa/items/ac3d37db44a2dcfe71fd

スケッチ  ダウンロード sample5_esp.zip (4.6K)

  ※コンパイルには下記のライブラリが別途必要です。
   sdfonts   : Arduino用漢字フォントライブラリ SDカード版
   sdbitmap : Arduino用Bitmap画像ロードライブラリ

// sample5_esp.ino
// aitendo 16x16LEDドットマトリックスの制御サンプル 漢字フォントライブラリ利用バージョン
// 2016/06/16 ESP-WROOM-02(ESP8266)用に移植 by たま吉さん
// 2016/06/29 コメント追記、定数の定義追加 by たま吉さん
//

#include <sdfonts.h>
#include <string.h>
#include <sdbitmap.h>
#include <Ticker.h>

// ビットマップ操作関数宣言
void scrollBitmap(uint8_t *bmp, uint16_t w, uint16_t h, uint8_t mode);
void clearBitmapAt(uint8_t* bmp, uint16_t w, uint16_t h, int16_t x, int16_t y, uint8_t cw, uint8_t ch);
void setBitmapAt(uint8_t *dstbmp, uint16_t dstw, uint16_t dsth, int16_t dstx, int16_t dsty,uint8_t *srcbmp, uint16_t srcw, uint16_t srch);

//ESP-WROOM-02 接続ピン設定
#define DATAPIN   (5)     // TB62706のSERIAL-INへ接続
#define LATCHPIN  (2)     // TB62706のLATCHへ接続
#define CLOCKPIN  (4)     // TB62706のCLOCKへ接続
#define ENABLEPIN (16)    // TB62706のENABLEへ接続

#define MOSI_SD   (13)    // SDカードのMOISへ接続
#define MISO_SD   (12)    // SDカードのMISOへ接続
#define CLK_SD    (14)    // SDカードのCLKへ接続
#define CS_SD     (15)    // SDカードモジュールCSへ接続

//LEDドットマトリックス用定義
#define FBUFSIZE     32   // ドットマトリックスフレームバッファサイズ
#define MWIDTH       16   // ドットマトリックス幅
#define MHIGTHT      16   // ドットマトリックス高さ

// タイマー割り込み
Ticker ticker;

// 表示用バッファ
uint8_t fbuf[FBUFSIZE];   // 表示パターンバッファデータ
uint8_t buf[MAXFONTLEN];  // フォントデータ格納アドレス(最大24x24/8 = 72バイト)

// バッファ内データを表示する(1ライン分割表示)
void fontout() {
  static uint8_t _line = 0;      // 表示対象行
  // 点灯LEDが移動するパターン
  digitalWrite(ENABLEPIN,LOW);   // OUTを有効にする
  digitalWrite(LATCHPIN, LOW);   //送信開始        
 
  // 表示対象行選択
  uint16_t val = _BV(15-_line);
  shiftOut(DATAPIN, CLOCKPIN, LSBFIRST, val);
  shiftOut(DATAPIN, CLOCKPIN, LSBFIRST, val>>8);       
     
  // 表示対象行のフォントパターン送信
  shiftOut(DATAPIN, CLOCKPIN, LSBFIRST, fbuf[(_line<<1)+1]);
  shiftOut(DATAPIN, CLOCKPIN, LSBFIRST, fbuf[_line<<1]);

  digitalWrite(LATCHPIN, HIGH);  //送信終了

  // 表示対象行を次行に設定
  _line++;
  if (_line == MHIGTHT )
    _line = 0;
}

// バッファクリア
void clearBuf() {
   memset(fbuf, 0, FBUFSIZE);
}

// いろは歌デモ
void test_iroha() {
  char* str="色はにほへど散りぬるを我が世たれぞ常ならむ有為の奥山今日越えて浅き夢見じ酔ひもせず";
  uint8_t fn;
  uint8_t tmpbuf[FBUFSIZE];        // 表示パターン2次バッファデータ
  memset(tmpbuf,0,FBUFSIZE);       // 2次バッファクリア
  SDfonts.open();                 // フォントのオープン

  // 表示文字数分ループ処理
  while(1) {
    fn = rand() % (EXFONT24+1);            // 表示フォントサイズランダム決定
    SDfonts.setFontSizeAsIndex(fn);       // フォントサイズの指定
    str = SDfonts.getFontData(buf, str);  // フォントデータの取得
    if (!str)
      break;                               // 文末なら抜ける

    // 1文字分スクロール表示
    for (int8_t t = 0; t < SDfonts.getWidth(); t++) {
      scrollBitmap(tmpbuf, MWIDTH, MHIGTHT, B0001); // 左スクロール
      clearBitmapAt(tmpbuf, MWIDTH, MHIGTHT, MWIDTH-t-1, MHIGTHT-t-1, SDfonts.getWidth(), SDfonts.getHeight());
      setBitmapAt(tmpbuf, MWIDTH, MHIGTHT, MWIDTH-t-1, MHIGTHT-t-1, buf, SDfonts.getWidth(), SDfonts.getHeight());
      memcpy(fbuf,tmpbuf,FBUFSIZE);
      delay(30);
    }
  }
  SDfonts.close(); // フォントのクローズ
}

// ビットマップパターン表示
void test_bitmap() {
  uint8_t tmpbuf[FBUFSIZE]; // 表示パターンバッファデータ
  uint8_t rc;
  uint8_t w,h;

  memset(tmpbuf,0,FBUFSIZE);
  sdbitmap bitmap;
  bitmap.setFilename("IMG2.BMP");

  // ビットマップデータオープン
  rc = bitmap.open();
  w  = bitmap.getWidth();
  h  = bitmap.getHeight();
  
  for (uint8_t i=0; i <= w-MWIDTH; i++) {  
    // データの取得
    bitmap.getBitmapEx(tmpbuf, i, 0, MWIDTH, MHIGTHT, 1);
    memcpy(fbuf,tmpbuf,FBUFSIZE);
    delay(30);
  }
  delay(2000);
  bitmap.close();
}

// セットアップ
void setup() {
  // LEDマトリックス用制御ピンのモード設定
  pinMode(ENABLEPIN,OUTPUT);
  pinMode(DATAPIN, OUTPUT);
  pinMode(LATCHPIN, OUTPUT);
  pinMode(CLOCKPIN, OUTPUT);

  // 制御ピンの初期化
  digitalWrite(ENABLEPIN,HIGH);
  digitalWrite(CLOCKPIN, LOW);
  digitalWrite(LATCHPIN, HIGH);

  // SDカード利用フォントライブラリの初期化
  SDfonts.init(CS_SD);         // フォント管理の初期化

  // 1msec間隔タイマー割り込み設定
  ticker.attach_ms(1, fontout); 
}

// デモループ
void loop(){
  test_bitmap();  // ビットマップデータロードテスト
  test_iroha();   // いろは歌デモ表示
  //clearBuf();   // 表示用バッファ初期化
  delay(1000);
}

今回の動作確認でデジタル出力、SPI通信普通に使えることが分かりました。
次はI2Cを調べてみます。

より以前の記事一覧