LED-Matrix-Panelの駆動(2)



 Excel VBAでアイコンを作成し、LED-Matrix-Panelに表示しました。

P4LED MATRIX PANEL 64×32 用のアイコンを作成し表示



 Excel VBAを使ってアイコン用のカラーデータを作成しました。
出来上がったアイコンデータをP4LED MATRIX PANEL 64×32 に表示させてみました。



  完成動画


 クリスマス用にアイコンを作成し、それをLEDパネルに表示させた動画です。
明るすぎてカメラが反応できなく見にくい画像になっています。
 最初に「Merry Christmats」と、作成したアイコンを表示した後、「Merry Christmas to you!」とスクロールしています。






  Excel VBAのカラー設定とビット変換


Excel VBAを使用するにあたって、VBAのカラー設定を確認しました。

1.Excel VBAで使用するカラーは、Color-Index が 1~56 まであります。
 そのカラーについて、RGB、16進数コード、10進数コードを表示し、そのデータをArduino用の 16bitカラーデータに変換しました。

(1) Excelの16進数カラーコードは、その仕様のため RGBの順序でなく、BGRの順になっています。
 例えば、赤色はRGB(255,0,0) ですが、Excelでは、16進数カラーコードは &H0000FF となっています。
通常の場合と区別するため先頭に"&H"を付けています。
 したがって、10進数コード表示は、
   RED + GREEN*256 + BLUE*256*256 = 255 + 0*256 + 0*256*256 = 255
となっています。

(2)通常の場合、RGB(255,0,0)は、16進数表示で0xFF0000 と表され、10進数コード表示は、
   RED*256*256 + GREEN*256 + BLUE = 255*256*256 + 0*255 + 0 = 16711680
となります。

(3)以下の図が、Excel VBAで使用するカラーとそのカラーコードの出来上がった表です。
 最初にIndexの列に1~56を入力して、「カラー表示」ボタンをクリックすると列Aにカラーが表示されます。
 次に「code変換」ボタンをクリックすると Excel VBA 用のカラーコードが表示され、最後に、「bit変換」ボタンを クリックすると、通常の場合の10進数、24bit、16bitのコードが表示されます。



(4)Excel VBAのプログラムを次に表記しておきますが、急ごしらえで参考にならないと思います。

	
Option Base 1
Dim i As Integer
Dim CNo, Red, Green, Blue As Long

Private Sub code変換_Click()
    Dim Exhex As String
    Dim Exlen24 As Integer
    
    Workbooks("color_bit変換.xlsm").Activate
    Worksheets("color_sheet").Activate
        
    For i = 1 To 56
        CNo = Range("A" & i + 3).Interior.color
        Range("E" & i + 3) = CNo
        
        Red = CNo Mod 256
        Green = Int(CNo / 256) Mod 256
        Blue = Int(CNo / 256 / 256)
        
        Range("C" & i + 3) = "RGB(" & Red & "," & Green & "," & Blue & ")"
        Exhex = Hex(Range("E" & i + 3))
        Exlen24 = 6 - Len(Exhex)
        Range("D" & i + 3) = "&H" + Left("000000", Exlen24) + Exhex
        Range("F" & i + 3) = Red * 256 * 256 + Green * 256 + Blue
    Next
End Sub
------------------------------------------------------------------------------------------------------
Private Sub bit変換_Click()

    Dim hexd24 As String
    Dim hexd16 As String
    Dim dlen24 As Integer
    Dim dlen16 As Integer
    Dim shift8 As Long
    Dim shift5 As Long
    Dim shift3 As Long

    Workbooks("color_bit変換.xlsm").Activate
    Worksheets("color_sheet").Activate
    
    Range("G4:H59").NumberFormatLocal = "@"
    
    For i = 1 To 56
        hexd24 = Hex(Range("F" & i + 3))
        dlen24 = 6 - Len(hexd24)
        Range("G" & i + 3) = "0x" + Left("000000", dlen24) + hexd24
        
        shift8 = (Range("F" & i + 3) \ (2 ^ 8)) And 63488
        shift5 = (Range("F" & i + 3) \ (2 ^ 5)) And 2016
        shift3 = (Range("F" & i + 3) \ (2 ^ 3)) And 31
        hexd16 = Hex(shift8 Or shift5 Or shift3)
                
        dlen16 = 4 - Len(hexd16)
        Range("H" & i + 3) = "0x" + Left("0000", dlen16) + hexd16
    Next

End Sub
------------------------------------------------------------------------------------------------------
Private Sub Color表示_Click()

    Workbooks("color_bit変換.xlsm").Activate
    Worksheets("color_sheet").Activate

    For i = 1 To 56
        If Range("B" & i + 3) = "" Or Range("B" & i + 3) = Null Then
            MsgBox "Color Index が空欄になっています。入力して下さい。"
            Exit For
        End If
        Range("A" & i + 3).Interior.ColorIndex = Range("B" & i + 3)
    Next
    
End Sub
								
						




  アイコンのデータ作成


 Excel VBAを使って、LEDパネルの縦16×横16の範囲内でアイコンを作成するようにしました。
LEDパネルなので多くのカラーは必要ないと思い、9色のカラーを使ってアイコンを作るようにしました。
 別のカラーが必要なときは、上図のカラーコード表から16bitデータを探してアイコンのデータを後で修正します。

1.Excel VBAのアイコンデータ作成画面
 下図が、Excel VBAで作成した画面です。



2.操作方法
(1)アイコンの大きさとして、画面左上の行と列の黄色枠に2~16の数値を入力し中央に格子枠を作ります。

(2)次に「格子作成」ボタンをクリックします。
 図の場合は、行に16列に16を入力した場合の格子枠が太枠の中に表示されます。

(3)この格子枠に左のカラーをコピーして貼り付けて、アイコンを作成します。
 雪だるまを作成するつもりでカラーを貼り付けたものが下図になります。

(4)次に、画面右上の「color_bit」ボタンをクリックすると、ボタンの右下に各格子の色の16bitカラーコードが 表示されます。

(5)最後に、画面下の「データ作成」ボタンをクリックすると、上記データのデータ間にコンマ","が入った アイコンデータが作成されます。これをArduino IDEのプログラムに使用します。

(6)雪だるまのアイコンを行=16,列=16で作成してみました。




3.他の例
 雪のアイコンを行=10,列=10で作成してみました。
(1)「格子作成」ボタンをクリックすると下図のようになります。




(2)カラーをコピーして格子に貼り付けたのが次の図(雪の結晶?)になります。
右下にデータが作成されています。




4.参考になりませんが、Excel VBAのプログラムを次に表記しておきます。

Option Base 1
Dim i As Integer
Dim j As Integer
Dim ind As Integer
Dim gyou As Integer
Dim retu As Integer

Private Sub 格子作成_Click()

    Workbooks("icon_data.xlsm").Activate
    Worksheets("icon").Activate

    gyou = Range("B2")
    retu = Range("D2")
    Range("F6:V22").Clear
    Range("F6:V22").ClearFormats
    
    If gyou < 2 Or gyou > 16 Then
        MsgBox "行・列の値は、2~16の数値を入力して下さい。"
        Exit Sub
    End If
    
    If retu < 2 Or retu > 16 Then
        MsgBox "行・列の値は、2~16の数値を入力して下さい。"
        Exit Sub
    End If
    
    For i = 1 To retu
        Cells(i + 6, 6) = i
    Next
    
    For i = 1 To gyou
        Cells(6, i + 6) = i
    Next
    
    Range(Cells(7, 7), Cells(gyou + 6, retu + 6)).Borders.LineStyle = True
    Range("Y7:AN22").Clear
    Range("Y25:Y40").Clear

End Sub
---------------------------------------------------------------------------------

Private Sub color_bit_Click()

    Dim ind As Integer
    
    Workbooks("icon_data.xlsm").Activate
    Worksheets("icon").Activate
    
    For j = 1 To gyou
        For i = 1 To retu
            ind = Cells(j + 6, i + 6).Interior.ColorIndex
            Select Case ind
                Case 1
                    Cells(j + 6, i + 24) = Range("C7")
                Case 2
                    Cells(j + 6, i + 24) = Range("C8")
                Case 3
                    Cells(j + 6, i + 24) = Range("C9")
                Case 4
                    Cells(j + 6, i + 24) = Range("C10")
                Case 5
                    Cells(j + 6, i + 24) = Range("C11")
                Case 6
                    Cells(j + 6, i + 24) = Range("C12")
                Case 7
                    Cells(j + 6, i + 24) = Range("C13")
                Case 8
                    Cells(j + 6, i + 24) = Range("C14")
                Case 46
                    Cells(j + 6, i + 24) = Range("C15")
            End Select
        Next
    Next
    
End Sub
---------------------------------------------------------------------------------

Private Sub データ作成_Click()

    Dim arrange As String
    Dim arrset As String
    
    Workbooks("icon_data.xlsm").Activate
    Worksheets("icon").Activate
        
    For j = 1 To gyou
        arrset = ""
        For i = 1 To retu
            arrange = Cells(j + 6, i + 24) + ","
            arrset = arrset + arrange
        Next
        Range("Y" & j + 24) = arrset
    Next

End Sub
						




  アイコンをLEDパネルに表示


1.上記作成したアイコンを使って、クリスマス用にP4LED MATRIX PANEL 64×32に表示しました。



前作のページ「LED-Matrix-Panelの駆動(1)」と同様にプログラムを作成しました。
 その起動が冒頭の動画です。

2.下記がそのプログラムです。

#include <PxMatrix.h>

// Pins for LED MATRIX
#define P_LAT 22
#define P_A 19
#define P_B 23
#define P_C 18
#define P_D 5
#define P_OE 2

hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

#define matrix_width 64
#define matrix_height 32

uint8_t display_draw_time=70; //30-70 is usually fine

//PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
//PxMATRIX display(64,64,P_LAT, P_OE,P_A,P_B,P_C,P_D,P_E);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

uint16_t myCOLORS[8]={myRED,myGREEN,myBLUE,myWHITE,myYELLOW,myCYAN,myMAGENTA,myBLACK};

uint16_t static snow_icons[10][10]={
{0x0020,0x0000,0x0000,0x0000,0x07FF,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0020,0x0020,0x07FF,0x07FF,0x07FF,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x07FF,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x07FD,0x0000,0x07FF,0x07FF,0x07FF,0x0000,0x07FF,0x0000,0x0000},
{0x07FF,0x07FF,0x07FF,0x07FF,0xFFFF,0x07FF,0x07FF,0x07DF,0x07FF,0x0000},
{0x0000,0x07DF,0x0000,0x07FF,0x07FF,0x07DF,0x0000,0x07FF,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x07FF,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0020,0x0000,0x07FF,0x07FF,0x07FF,0x0020,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x07FF,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}
};

uint16_t static snowman_icons[16][16]={
{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,0xffff,0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xf800,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000},
{0x0000,0xfc00,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000},
{0xfc00,0xfc00,0x0000,0x0000,0xffff,0xf800,0xf800,0xf800,0xf800,0xf800,0xffff,0x0000,0xfc00,0x0000,0x0000,0x0000},
{0x0000,0x0000,0xfc00,0xffff,0xffff,0xffff,0xffff,0xffff,0xf800,0xf800,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf800,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000},
{0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x001f,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000},
{0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0x001f,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}
};

void IRAM_ATTR display_updater(){
  portENTER_CRITICAL_ISR(&timerMux);
  display.display(display_draw_time);
  portEXIT_CRITICAL_ISR(&timerMux);
}

void display_update_enable(bool is_enable)
{
  if (is_enable)
  {
    timer = timerBegin(0, 80, true);
    timerAttachInterrupt(timer, &display_updater, true);
    timerAlarmWrite(timer, 4000, true);
    timerAlarmEnable(timer);
  }
  else
  {
    timerDetachInterrupt(timer);
    timerAlarmDisable(timer);
  }
}

void setup() {

  Serial.begin(9600);
  display.begin(16);
  
  display.clearDisplay();
  display_update_enable(true);
  delay(100);
}

void draw_snow_icon (uint8_t xxpos,uint8_t yypos){
  for (int yy=0; yy<10;yy++){
    for (int xx=0; xx<10;xx++){
      uint16_t snow_pos_color = snow_icons[yy][xx];
      display.drawPixel(xxpos+xx,yypos+yy,snow_pos_color);
    }
  }
}

void draw_snowman_icon (uint8_t xxpos,uint8_t yypos){
  for (int yy=0; yy<17;yy++){
    for (int xx=0; xx<17;xx++){
      uint16_t snow_pos_color = snowman_icons[yy][xx];
      display.drawPixel(xxpos+xx,yypos+yy,snow_pos_color);
    }
  }
}

void scroll_text(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB)
{
    uint16_t text_length = text.length();
    display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
    display.setTextSize(1);
    display.setRotation(0);
    display.setTextColor(display.color565(colorR,colorG,colorB));

    for (int xpos=matrix_width; xpos>-(matrix_width+text_length*5); xpos--)
    {
      display.setTextColor(display.color565(colorR,colorG,colorB));
      display.clearDisplay();
      display.setCursor(xpos,ypos);
      display.println(text);
      delay(scroll_delay);
      yield();
    }
}

void loop() {
  display.clearDisplay();
  display.setTextColor(myCYAN);
  display.setCursor(2,0);
  display.print("Merry");
  display.setTextColor(myMAGENTA);
  display.setCursor(8,8);
  display.print("Christmas"); 
    
  draw_snow_icon (8,20);
  draw_snow_icon (50,16);
  draw_snowman_icon(26,16);
  delay(6000);
  display.clearDisplay();
  scroll_text(1,50,"A Merry Christmas to you!",0,255,0);
  
}