Skip to content

Instantly share code, notes, and snippets.

@tondol
Last active October 19, 2020 17:11
Show Gist options
  • Save tondol/f8f9a25efe3b89e34cd7b2a384005979 to your computer and use it in GitHub Desktop.
Save tondol/f8f9a25efe3b89e34cd7b2a384005979 to your computer and use it in GitHub Desktop.
教育漢字を含む日本語・英語文字列をスクロール
// 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