M5StickCPlus2で美咲フォント8x8NeoPixel表示
これ
を作った時のメモ
苦労した点
意図したように動かない時がある
色によってはstrip.getPixelColorがうまく取得できない時があるみたいで、
数行しか表示できないことがあった。(未解決)
setBrightnessで 50だと数行しかでなくて
setBrightnessで 150とかだと数行正しくて、途中から色が変わってしまったりとか
NeoPixelの長さが長いと途中で信号がうまくとれなくなるのかな・・・
SPIがわからなかった
NeoPixelの制御にSPIというライブラリを使った例があったけど、自分にはよくわからないものだった
・・・もしかして、SPI使って制御とかしないと同期がとれないとか意図したように動かないのとかあるのかもしれない。 あるいは更新頻度とかもっと効率よくできるのかもしれない。
参考にしたもの
NeoPixelと文字表示検索でヒットした
https://gist.github.com/Tamakichi/379f79f0861eb15f21bc90080d5c580a
ほとんどこれベースに、
ChatGPTにSPI使わないコードをお願いして一緒に作った感じ
コード
GamingBrazenBlaze.ino.java
#include <Adafruit_NeoPixel.h>
#include <misakiUTF16.h>
#include <M5StickCPlus2.h>
// Neopixelの設定
#define NUMPIXELS 64 // Neopixel ピクセル数(LED数)
#define PIN 26 // Neopixel 制御用ピン番号
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
M5.begin(); // M5StickC Plusの初期化
M5.Lcd.fillScreen(BLACK); // 画面を黒色でクリア
Serial.begin(9600);
strip.begin(); // Neopixel ストリップを初期化
strip.show(); // 全ての LED をオフにする(初期化時)
strip.setBrightness(255); // 明るさを設定 (適宜調整してください)
// 他の必要な初期化処理があればここに追加
}
void loop() {
NeoMsg("ブレイゼンブレイズ Brazen Blaze ", 0, 16, 0, 25);
NeoMsg("ブレイゼンブレイズ Brazen Blaze ", 0, 8, 8, 25);
NeoMsg("ブレイゼンブレイズ Brazen Blaze ", 8, 4, 4, 25);
//delay(1000); // 次のメッセージ表示までの間隔
}
// Neopixelの表示クリア
void NeoCLS(bool flgUpdate = true) {
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, 0); // 全てのピクセルをオフにする
}
if (flgUpdate) strip.show();
}
// 指定したピクセルの色を設定
void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, bool flgUpdate = false) {
if (no < NUMPIXELS) {
strip.setPixelColor(no, strip.Color(R, G, B)); // RGB順に設定
}
if (flgUpdate) strip.show();
}
// ドットマトリックス 左スクロール
void NeoScroll(bool flgUpdate = false) {
for (int i = 0; i < 8; i++) { // 8行すべてに対して実行
for (int j = 0; j < 7; j++) { // 各行について7ピクセル分をシフト
uint32_t color = strip.getPixelColor(i * 8 + j + 1);
strip.setPixelColor(i * 8 + j, color);
}
strip.setPixelColor(i * 8 + 7, 0); // 行の最後をクリア
}
if (flgUpdate) strip.show();
// LCDにNeoPixelの色を表示
for (int i = 0; i < NUMPIXELS; i++) {
// NeoPixelから色を取得
uint32_t color = strip.getPixelColor(i);
// RGB成分に分解
uint8_t r = (uint8_t)(color >> 16),
g = (uint8_t)(color >> 8),
b = (uint8_t)color;
// LCD上の対応する位置に点を描画
// 注: ここではNeoPixelとLCDのマッピングやスケールを適宜調整してください
int x = (i % 8) * 20; // 例: x位置を20ピクセルごとにスケールアップ
int y = (i / 8) * 20; // 例: y位置を20ピクセルごとにスケールアップ
M5.Lcd.fillCircle(x, y, 10, M5.Lcd.color565(r, g, b)); // 半径10の円を描画
}
}
// 8x8ドットマトリックス 指定座標ピクセル番号変換
inline uint8_t XYtoNo(uint8_t x, uint8_t y) {
return y * 8 + x; // マトリックスの座標をピクセル番号に変換
}
// 1文字左スクロール挿入
void NeoScrollInChar(uint8_t *fnt, uint8_t R, uint8_t G, uint8_t B, uint16_t tm) {
for (int i = 0; i < 8; i++) {
NeoScroll(false); // 左に1ドットスクロール
// フォントパターン1列分をセット
int x = 7;
// for(int x = 0;x< 8; x++)
{
for (int j = 0; j < 8; j++) {
if (fnt[j] & (0x80 >> i)) {
NeoSetRGB(XYtoNo(x, j), R, G, B, false);
} else {
NeoSetRGB(XYtoNo(x, j), 0, 0, 0, false);
}
}
}
strip.show();
delay(tm); // 指定された時間だけ待つ
}
}
// メッセージの表示
void NeoMsg(char* msg, uint8_t R, uint8_t G, uint8_t B, uint16_t tm) {
uint8_t fnt[8]; // フォントデータを格納するバッファ
NeoCLS(false); // ディスプレイをクリア
char* str = msg;
while (*str) {
if (!(str = getFontData(fnt, str))) {
Serial.println("Error");
break;
}
//NeoScrollInChar(fnt, R, G, B, tm);
NeoScrollInChar(fnt, random(255), random(255), random(255), tm);
}
strip.show();
}
32x8バージョン
- あんまり明るいとM5StickPlus2がフリーズしてしまうようなので、控えめの明るさに設定
- NeoPixelの配置がヘビ型