M5Stack ATOM Matrixで2桁の数字を同時表示

M5Stack

 M5Stack ATOM Matrixを触り始めたのですが、M5StackとかM5StickCみたいに標準で文字表示する機能が見つけられず。各種ライブラリを入れるとできるようなのですが、そこまで大仰なことはしない。メモリも節約したい。そんなわけで、以前micro:bitのために作ってあったプログラムを流用して文字表示できないかと思い試行錯誤。

 まずやりたいのは、2桁の数字を同時に表示するやつ。温度とか湿度を表示したいと思ったのでした。

 ということで、まずはサンプル動画。

M5Atom Matrix 2-digit and hex

 で、コード。

#include "M5Atom.h"


/*
 * 2-DIGIT NUMERIC FONT DATA
 */

const String NUMFONTDATA[17][5] = {
  {"11", "11", "11", "11", "11"}, //0
  {"01", "01", "01", "01", "01"}, //1
  {"11", "01", "11", "10", "11"}, //2
  {"11", "01", "11", "01", "11"}, //3
  {"10", "10", "11", "01", "01"}, //4
  {"11", "10", "11", "01", "11"}, //5
  {"11", "10", "11", "11", "11"}, //6
  {"11", "01", "01", "01", "01"}, //7
  {"11", "11", "00", "11", "11"}, //8
  {"11", "11", "11", "01", "11"}, //9
  {"00", "11", "01", "11", "11"}, //a
  {"00", "10", "10", "11", "11"}, //b
  {"00", "00", "11", "10", "11"}, //c
  {"00", "01", "01", "11", "11"}, //d
  {"00", "11", "11", "10", "11"}, //e
  {"00", "01", "10", "11", "10"}, //f
  {"00", "00", "11", "00", "00"}  //-
 };

/*
 * 10進数で2桁表示
 */
void disp2digit(int v, uint8_t R, uint8_t G, uint8_t B ,uint8_t Rb=0, uint8_t Gb=0, uint8_t Bb=0){
  uint8_t DisBuffString[2 + 5 * 5 * 3];
  DisBuffString[0] = 0x05;
  DisBuffString[1] = 0x05;
    
  if(v < -9){  // -9 未満なら表示しない
    return;
  }
  int n1 = 0, n2 = 0;
  
  if (v < 0){  // - (マイナス)を表示
    n2 = 16;
  }
  else {
    n2 = floor(v % 100 /10);
    Serial.print(n2);
    Serial.print(":");
  }
  n1 = abs(floor(v % 10));
  Serial.println(n1);

  for (int i = 2; i < 25; i+=5){
        DisBuffString[2 + i * 3 + 0] = 0x0;
        DisBuffString[2 + i * 3 + 1] = 0x0;
        DisBuffString[2 + i * 3 + 2] = 0x0;
  }

  for (int y = 0; y < 5; y++) {
      for (int x = 0; x < 2; x++) {
          if ((NUMFONTDATA[n2][y]).substring(x, x+1) == "1" && n2 != 0) {
            DisBuffString[2 + (y * 5 + x) * 3 + 0] = R;
            DisBuffString[2 + (y * 5 + x) * 3 + 1] = G;
            DisBuffString[2 + (y * 5 + x) * 3 + 2] = B;
          }
          else {
            DisBuffString[2 + (y * 5 + x) * 3 + 0] = Rb;
            DisBuffString[2 + (y * 5 + x) * 3 + 1] = Gb;
            DisBuffString[2 + (y * 5 + x) * 3 + 2] = Bb;
          }
      }

      for (int z = 3; z < 5; z++) {
          if ((NUMFONTDATA[n1][y]).substring(z - 3, z-3+1) == "1") {
                DisBuffString[2 + (y * 5 + z) * 3 + 0] = R;
                DisBuffString[2 + (y * 5 + z) * 3 + 1] = G;
                DisBuffString[2 + (y * 5 + z) * 3 + 2] = B;
          }
          else {
                DisBuffString[2 + (y * 5 + z) * 3 + 0] = Rb;
                DisBuffString[2 + (y * 5 + z) * 3 + 1] = Gb;
                DisBuffString[2 + (y * 5 + z) * 3 + 2] = Bb;
          }
      }
      M5.dis.displaybuff(DisBuffString);
  }
}

/*
 * 16進数で2桁表示
 */
void dispHex(int v, uint8_t R, uint8_t G, uint8_t B ,uint8_t Rb=0, uint8_t Gb=0, uint8_t Bb=0){
  uint8_t DisBuffString[2 + 5 * 5 * 3];
  DisBuffString[0] = 0x05;
  DisBuffString[1] = 0x05;
    
  if(v < -9){  // -9 未満なら表示しない
    return;
  }
  int n1 = 0, n2 = 0;
  
  if (v < 0){  // - (マイナス)を表示
    n2 = 16;
  }
  else {
    n2 = floor(v % 256 / 16);
  }
  n1 = abs(floor(v % 16));

  for (int i = 2; i < 25; i+=5){
        DisBuffString[2 + i * 3 + 0] = 0x0;
        DisBuffString[2 + i * 3 + 1] = 0x0;
        DisBuffString[2 + i * 3 + 2] = 0x0;
  }

  for (int y = 0; y < 5; y++) {
      for (int x = 0; x < 2; x++) {
          if ((NUMFONTDATA[n2][y]).substring(x, x+1) == "1" && n2 != 0) {
            DisBuffString[2 + (y * 5 + x) * 3 + 0] = R;
            DisBuffString[2 + (y * 5 + x) * 3 + 1] = G;
            DisBuffString[2 + (y * 5 + x) * 3 + 2] = B;
          }
          else {
            DisBuffString[2 + (y * 5 + x) * 3 + 0] = Rb;
            DisBuffString[2 + (y * 5 + x) * 3 + 1] = Gb;
            DisBuffString[2 + (y * 5 + x) * 3 + 2] = Bb;
          }
      }

      for (int z = 3; z < 5; z++) {
          if ((NUMFONTDATA[n1][y]).substring(z - 3, z-3+1) == "1") {
                DisBuffString[2 + (y * 5 + z) * 3 + 0] = R;
                DisBuffString[2 + (y * 5 + z) * 3 + 1] = G;
                DisBuffString[2 + (y * 5 + z) * 3 + 2] = B;
          }
          else {
                DisBuffString[2 + (y * 5 + z) * 3 + 0] = Rb;
                DisBuffString[2 + (y * 5 + z) * 3 + 1] = Gb;
                DisBuffString[2 + (y * 5 + z) * 3 + 2] = Bb;
          }
      }
      M5.dis.displaybuff(DisBuffString);
  }
}

/*
 * Fill Screen
 */
void dispFill(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata)
{
    uint8_t DisBuff[2 + 5 * 5 * 3];

    DisBuff[0] = 0x05;
    DisBuff[1] = 0x05;
    for (int i = 0; i < 25; i++)
    {
        DisBuff[2 + i * 3 + 0] = Rdata;
        DisBuff[2 + i * 3 + 1] = Gdata;
        DisBuff[2 + i * 3 + 2] = Bdata;
    }
    M5.dis.displaybuff(DisBuff);
}


void setup()
{
  M5.begin(true, false, true);
}


void loop ()
{
    // 10進数 2桁表示で 0から99まで
    for (int i = 0; i < 100 ; i++){
      disp2digit(i, 0x40, 0x0, 0x0, 0,0,0);  // Red
      delay(200);  
    }
    
    // 16進数 2桁表示で 0からff(255)まで
    for (int i = 0; i < 256 ; i++){
      dispHex(i, 0x40, 0x40, 0x0, 0,0,0);  //Yellow
      delay(400);  
    }
}

 ここからいろいろやっていく予定。クラスにしたりライブラリにしたりとか?(よくわかってない)

 5×5という制限があるってのがなんとなく楽しいと思い始めてきました。

 それから、M5Atomの標準ライブラリを使うとちらつきなどが出るとかいうので、そのへんも今後チェックしてみようかと。確かに、書き換えが早いと、へんなノイズみたいなのが出てますね。それを使わず、FastLEDを直接使ったほうがいいとかいう情報も見つけましたが、なんか大変そうです。とりあえず、このまま進みます。

 普通の文字表示は2、3日以内にアップ予定です。

コメント