Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Tamakichi
Created January 9, 2020 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tamakichi/77deea00caf0ef0e8885592f84c8d31f to your computer and use it in GitHub Desktop.
Save Tamakichi/77deea00caf0ef0e8885592f84c8d31f to your computer and use it in GitHub Desktop.
NeoPixel 16x16ドットマトリックスの制御 (Arduino Uno)
//
// Neopixel 16x16ドットマトリックス 制御 SPIバージョン by たま吉さん 2020/01/9
//
#include <SPI.h>
#include <misakiUTF16.h>
//***************
// 定数
//***************
#define PXCEL_W 16 // 横ピクセル数
#define PXCEL_H 16 // 縦ピクセル数
#define PIXCELNUM (PXCEL_W*PXCEL_H) // Neopixel ピクセル数(LED数)
#define PIN 11 // Neopixel 制御用ピン番号
#define NEOSPI_0 0b11100000 // 1ビット 値0
#define NEOSPI_1 0b11111000 // 1ビット 値1
#define NEOSPI_RST 0b00000000 // REST
//***************
// グローバル変数
//***************
uint8_t buf[PIXCELNUM*3]; // Nexpixel用ピクセル色データ(ピクセル数 x 24ビット)
//***************
// 関数
//***************
// Neopixel初期化
void NeoInit() {
memset(buf, 0, PIXCELNUM*3); // バッファの初期化
// SPIの初期化
SPI.setBitOrder(MSBFIRST); // 最上位ビットから送信
SPI.setClockDivider(SPI_CLOCK_DIV2); // クロック 8MHz
SPI.setDataMode(SPI_MODE1); // アイドル時 LOW、立上りエッジ時送信
SPI.begin(); // 開始
}
// Neopixelへのデータ送信
void NeoUpdate() {
// RESET送信
SPDR = NEOSPI_RST; // SPIデータ送信
while(!(SPSR & (1 << SPIF))) ; // 送信完了待ち
delayMicroseconds(50);
// ピクセル数x24ビット送信
for (uint16_t i = 0; i < PIXCELNUM*3; i++) {
for (uint8_t j = 0; j < 8; j++) {
SPDR = buf[i] & (0x80>>j) ? NEOSPI_1:NEOSPI_0; // SPIデータ送信
while(!(SPSR & (1 << SPIF))) ; // 送信完了待ち
}
}
}
// Neopixelの表示クリア
void NeoCLS(uint8_t flgUpdate=false) {
memset(buf, 0, PIXCELNUM*3); // バッファの初期化
if (flgUpdate)
NeoUpdate();
}
// 指定したピクセルの色を設定
void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false) {
if (no < PIXCELNUM) {
buf[no*3+0] = G;
buf[no*3+1] = R;
buf[no*3+2] = B;
}
if (flgUpdate)
NeoUpdate();
}
// ピクセルのシフト
void ShiftPixel(uint8_t flgUpdate=false) {
uint8_t tmpbuf[3];
memmove(tmpbuf,buf,3);
memmove(buf, buf+3, (PIXCELNUM-1)*3);
memmove(buf+(PIXCELNUM-1)*3,tmpbuf,3);
if (flgUpdate)
NeoUpdate();
}
// PXCEL_W×PXCEL_Hドットマトリックス 指定座標ピクセル番号変換
inline uint8_t XYtoNo(uint8_t x, uint8_t y) {
return y&1 ? PXCEL_W*y + x : PXCEL_W*y + (PXCEL_W-1) -x;
}
// ドットマトリックス 左スクロール
void NeoScroll(uint8_t flgUpdate=false) {
for (uint8_t i=0; i < PXCEL_H; i++) {
if ( i&1 ) {
memmove(&buf[i*PXCEL_W*3], &buf[(i*PXCEL_W+1)*3],(PXCEL_W-1)*3);
memset(&buf[(i*PXCEL_W+(PXCEL_W-1))*3], 0, 3);
} else {
memmove(&buf[(i*PXCEL_W+1)*3], &buf[i*PXCEL_W*3],(PXCEL_W-1)*3);
memset(&buf[i*PXCEL_W*3], 0, 3);
}
}
if (flgUpdate)
NeoUpdate();
}
// 1文字左スクロール挿入
void NeoScrollInChar(uint8_t *fnt, uint8_t R, uint8_t G, uint8_t B, uint16_t tm, uint8_t y=0) {
for (uint8_t i = 0; i < 8; i++) {
// 左1ドットスクロール
NeoScroll(false);
// フォントパターン1列分のセット
for (uint8_t j = 0; j < 8; j++) {
if (fnt[j] & (0x80 >> i)) {
NeoSetRGB(XYtoNo(PXCEL_W-1,j+y), R,G,B, false);
} else {
NeoSetRGB(XYtoNo(PXCEL_W-1,j+y), 0,0,0, false);
}
}
NeoUpdate();
delay(tm);
}
}
// メッセージの表示
void NeoMsg(char* msg, uint8_t R, uint8_t G, uint8_t B, uint16_t tm,uint8_t y=0) {
uint8_t fnt[8];
int8_t len;
char *str = msg;
NeoCLS();
while(*str) {
if (! (str = getFontData(fnt, str)) ) {
break;
}
NeoScrollInChar(fnt, R, G, B, tm, y);
}
}
void setup() {
NeoInit(); // Neopixcelの初期化
NeoCLS(); // Neopixcelの表示クリア
}
void loop() {
NeoMsg("あいうえお、",0, 16, 0, 100,4);
NeoMsg("今日は1月9日(木)です。",0, 8, 8, 100,4);
NeoMsg("かんたんなかんじの表示ができます。",16, 4, 4, 100,4);
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment