Last active
October 19, 2020 17:11
-
-
Save tondol/f8f9a25efe3b89e34cd7b2a384005979 to your computer and use it in GitHub Desktop.
教育漢字を含む日本語・英語文字列をスクロール
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/FastLED/FastLED | |
#include <FastLED.h> | |
// https://github.com/Tamakichi/Arduino-misakiUTF16 | |
#include <misakiUTF16.h> | |
#define FPS 45 | |
const int DATA_PIN = 32; | |
const int NUM_LEDS = 256; | |
CRGB leds[NUM_LEDS]; | |
const int CW = 8; | |
const int CH = 8; | |
int CN; | |
byte FONT[8 * 256]; | |
char string_buf[4 * 256] = " シリアルモニターで表示したい文字を送信してください! "; | |
int frame = 0; | |
void load_font() { | |
CN = 0; | |
char *p = string_buf; | |
// 先にフォントをクリアしておく | |
memset(FONT, 0, sizeof(byte) * 8 * 256); | |
while (*p) { | |
if ((p = getFontData(&FONT[CN * 8], p, 1)) == NULL) { | |
break; | |
} | |
CN++; | |
} | |
// 文字数が足りなかったら余白を付加する | |
CN = max(4, CN); | |
} | |
void setup() { | |
Serial.begin(115200); | |
delay(100); | |
// FastLEDの設定 | |
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); | |
FastLED.setBrightness(64); | |
set_max_power_in_volts_and_milliamps(5, 100); | |
load_font(); | |
} | |
/* RAW LED INDEX 実際に出力時に使われるLEDインデックス | |
* _0 15 ... | |
* _1 14 ... | |
* _2 13 ... | |
* _3 12 ... | |
* _4 11 ... | |
* _5 10 ... | |
* _6 _9 ... | |
* _7 _8 ... | |
*/ | |
/* LED INDEX オフセット計算をしやすくするための仮想LEDインデックス | |
* _0 _8 ... | |
* _1 _9 ... | |
* _2 10 ... | |
* _3 11 ... | |
* _4 12 ... | |
* _5 13 ... | |
* _6 14 ... | |
* _7 15 ... | |
*/ | |
/* CHAR INDEX (i,x,y) フォントデータの取得に使われる座標 | |
* (0,0,0) (0,1,0) ... (0,5,0) (1,0,0) ... | |
* (0,0,1) (0,1,1) ... | |
* (0,0,2) (0,1,2) ... | |
* (0,0,3) (0,1,3) ... | |
* (0,0,4) (0,1,4) ... | |
* (0,0,5) (0,1,5) ... | |
* (0,0,6) (0,1,6) ... | |
* (0,0,7) (0,1,7) ... | |
*/ | |
// 改行までの文字列を読み込み、stringに格納 | |
int get_line() { | |
if (!Serial.available()) { | |
return 0; | |
} | |
int i = 0; | |
int c; | |
while (i < 4 * 256) { | |
do { | |
c = Serial.read(); | |
} while (c == -1); | |
if (c == '\n') { | |
break; | |
} | |
string_buf[i++] = c; | |
} | |
string_buf[i] = '\0'; | |
return i; | |
} | |
// 仮想LEDインデックス -> 文字座標 | |
void getCharPositionFromLEDIndex(int *ci, int *cx, int *cy, int i) { | |
*ci = i / (CW * CH) % CN; | |
*cx = i / CH % CW; | |
*cy = i % CH; | |
} | |
// 仮想LEDインデックス -> 生LEDインデックス | |
int getRawLEDIndex(int i) { | |
int ci = i / (CW * CH) % CN; | |
int cx = i / CH % CW; | |
int cy = (i / CH % 2) ? (CH - i % CH - 1) : (i % CH); | |
return ci * CW * CH + cx * CH + cy; | |
} | |
void loop() { | |
// 定期的に文字取得チャレンジする | |
if (frame % 10 == 0) { | |
int n = get_line(); | |
if (n != 0) { | |
Serial.println(string_buf); | |
load_font(); | |
frame = 0; | |
} | |
} | |
for (int i = 0; i < NUM_LEDS; i++) { | |
int ci, cx, cy; | |
// 文字スクロールのため、オフセットされた仮想LEDインデックスを計算する | |
int offset_i = i + frame * CH; | |
getCharPositionFromLEDIndex(&ci, &cx, &cy, offset_i); | |
// 出力時は生インデックスに変換する | |
int raw_i = getRawLEDIndex(i); | |
int h = (i / CH + frame * 4) % 256; | |
int b = (FONT[ci * 8 + cy] & (0x80 >> cx)) ? 128 : 0; | |
leds[raw_i] = CHSV(h, 255, b); | |
} | |
FastLED.show(); | |
FastLED.delay(1000 / FPS); | |
frame++; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment