基板を振って LEDでメッセージを描く「LEDスティック」です。
市販のボードのCPU部分にATmega328を載せて、Arduino IDEでプログラムを作成。
単3電池2本で動かすため、内臓の8MHzオシレータをクロック源にしています。
最終的には、市販のLEDペンライトのケースに入れました。
ボタン操作で、8種類のメッセージを選択することが出来ます。
プログラム自身は 一定時間毎に表示を切り替える簡単な処理なので、全文字が表示できるよう 振るスピードを調整する必要が有ります。 (^_^;
メインプログラム
#include "16LED_text.h"
int LED1 = 19; // PC5(A5) "L" is lit
int LED2 = 18; // PC4(A4)
int LED3 = 17; // PC3(A3)
int LED4 = 16; // PC2(A2)
int LED5 = 15; // PC1(A1)
int LED6 = 14; // PC0(A0)
int LED7 = 13; // PB5
int LED8 = 12; // PB4
int LED9 = 11; // PB3
int LED10 = 10; // PB2
int LED11 = 9; // PB1
int LED12 = 8; // PB0
int LED13 = 7; // PD7
int LED14 = 6; // PD6
int LED15 = 5; // PD5
int LED16 = 4; // PD4
int S3 = 3; // PD3: Select-SW
int S2 = 2; // PD2: Start-SW
// PD1: TxD
// PD0: RxD
int sel_SW = 0x08; // PD3
int stt_SW = 0x04; // PD2
int dMask7 = 0x07; // (0000 0xxx)
int dMask15 = 0x0F; // (0000 xxxx)
int ver = 1; // ver 0.01
int mode = 0;
int item_num = 0; // item No.
int line;
int dbg_count = 0;
int task = 0;
unsigned long tim0;
unsigned int dLED;
int blink_task = 0;
unsigned long blink_tim0;
int tMessage[] = {&mes0, &mes1, &mes2, &mes3, &mes4, &mes5, &mes6, &mes7};
int lMessage[] = {sizeof(mes0)/2,sizeof(mes1)/2,sizeof(mes2)/2,sizeof(mes3)/2,sizeof(mes4)/2,sizeof(mes5)/2,sizeof(mes6)/2,sizeof(mes7)/2};
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
//pinMode(LED_BUILTIN, OUTPUT);
pinMode(LED1, OUTPUT);
digitalWrite(LED1, HIGH);
pinMode(LED2, OUTPUT);
digitalWrite(LED2, HIGH);
pinMode(LED3, OUTPUT);
digitalWrite(LED3, HIGH);
pinMode(LED4, OUTPUT);
digitalWrite(LED4, HIGH);
pinMode(LED5, OUTPUT);
digitalWrite(LED5, HIGH);
pinMode(LED6, OUTPUT);
digitalWrite(LED6, HIGH);
pinMode(LED7, OUTPUT);
digitalWrite(LED7, HIGH);
pinMode(LED8, OUTPUT);
digitalWrite(LED8, HIGH);
pinMode(LED9, OUTPUT);
digitalWrite(LED9, HIGH);
pinMode(LED10, OUTPUT);
digitalWrite(LED10, HIGH);
pinMode(LED11, OUTPUT);
digitalWrite(LED11, HIGH);
pinMode(LED12, OUTPUT);
digitalWrite(LED12, HIGH);
pinMode(LED13, OUTPUT);
digitalWrite(LED13, HIGH);
pinMode(LED14, OUTPUT);
digitalWrite(LED14, HIGH);
pinMode(LED15, OUTPUT);
digitalWrite(LED15, HIGH);
pinMode(LED16, OUTPUT);
digitalWrite(LED16, HIGH);
pinMode(S3, INPUT);
pinMode(S2, INPUT);
Serial.begin(9600);
Serial.println("16LED v0.05");
if (~PIND & sel_SW) {mode =100;} // selSW ON => goto Test0
}
// the loop function runs over and over again forever
void loop() {
switch (mode) {
case 0:
selItem(); // Item select
break;
case 1:
showMess(tMessage[item_num], lMessage[item_num]); //
//test0();
break;
case 100:
chkSelOFF(); // Select SW OFF check
break;
case 101:
test0(); // LED1 to 16 ON/OFF
break;
case 102:
test1(); // Switch Check
break;
default:
mode = 0;
break;
}
}
//
// ***** Test Mode *****
// void test0(void) // LED No.16 to 1 ON/OFF
// void test1(void) // Switch Check
//
// ***** Normal Mode *****
// void selItem(void) // Select Item
// void showMess(int *mes, int len) // show Message
void showMess(int *mes, int len) {
switch (task) {
case 0:
line = 0;
task++;
tim0 = micros();
Serial.print("Start ");
Serial.print(item_num);
Serial.println();
break;
case 1:
if ((micros() - tim0) > 200000) {task++; }
break;
case 2:
//setLED(mes0[line]);
setLED(mes[line]);
tim0 = micros();
task++;
break;
case 3:
if ((micros() - tim0) > 3000) {
//if (line < sizeof(mes0)-1) {
if (line < len-1) {
line++;
task--;
} else {
task++;
tim0 = micros();
setLED(0);
}
}
break;
case 4:
if ((micros() - tim0) > 200000) {task++; }
break;
default:
task = 0;
mode =0;
// Serial.println("End");
break;
}
}
// ***** Mode = 0 *****
void selItem(void) { // Select Item
chkSelSW(); // item select
blinkItem(); // item No. Blinking
chkSttSW(); // Start SW check
}
void blinkItem(void) {
unsigned int l;
switch (blink_task) {
case 0:
l = 0x8000;
for (int i=0; i<item_num; i++) { l = l >> 1; }
setLED(l); // LED ON
blink_tim0 = micros();
blink_task++;
break;
case 1:
dbg_count++;
if ((micros() - blink_tim0) > 50000){
setLED(0); // LED OFF
blink_tim0 = micros();
blink_task++;
}
break;
case 2:
if ((micros() - blink_tim0) > 900000){
blink_task++;
}
break;
default:
//Serial.println(dbg_count);
//delay(10);
blink_task = 0;
break;
}
}
void chkSttSW(void) { // Start SW check
if (~PIND & stt_SW) {
mode = 1;
task = 0;
//Serial.println("Start");
}
}
void chkSelSW(void) { // item select
switch (task) {
case 0: // SW ON check
if (~PIND & sel_SW) {
item_num = (item_num + 1) & dMask7;
Serial.print("SW ON , Item = ");
Serial.print(item_num);
task++;
}
break;
case 1: // SW OFF check
if (PIND & sel_SW) {
tim0 = micros();
task++;
}
break;
case 2: // wait
if ((micros() - tim0) > 300000){
task++;
}
break;
default:
task = 0;
break;
}
}
void test1(void) { // Switch Check
switch (task) {
case 0: // LED ON
//Serial.println(PIND, HEX);
if ((~PIND & (sel_SW | stt_SW)) != 0x00) {
Serial.println((PIND & (sel_SW | stt_SW)), BIN); // (xxxx xx00)
setLED(~PIND & (sel_SW | stt_SW)); // LED ON
tim0 = micros();
task++;
}
break;
case 1: // wait & LED OFF
if ((micros() - tim0) > 300000){
setLED(0); // LED OFF
task++;
}
break;
default:
task = 0;
break;
}
}
void test0(void) {
blinkTest(); // LED16 to 1 ON/OFF
chk_T0_SW(); // Select SW check
}
void chk_T0_SW(void) { // Select SW check
if (~PIND & sel_SW) {
Serial.println("goto Test1");
mode = 102;
}
}
void blinkTest(void) { // LED16 to 1 ON/OFF
switch (task) {
case 0: // LED ON
if (dLED == 0) {dLED = 0x8000;}
setLED(dLED); // LED ON
dLED = dLED >> 1;
tim0 = micros();
task++;
break;
case 1: // wait & LED OFF
if ((micros() - tim0) > 100000){
setLED(0); // LED OFF
tim0 = micros();
task++;
}
break;
case 2: // wait
if ((micros() - tim0) > 400000){
task ++;
}
break;
default:
task = 0;
break;
}
}
void chkSelOFF(void) { // Select SW OFF check
if (PIND & sel_SW) {
Serial.println("goto Test0");
mode = 101;
}
}
void setLED(unsigned int data) {
unsigned int p,d;
p = PORTC & 0xc0; // (xx00 0000)
d = ~(data >> 10); // (00cc cccc) bb bbbb dddd
PORTC = p | (d & 0x3F); // (00cc cccc)
p = PORTB & 0xc0; // (xx00 0000)
d = ~(data >> 4); // (00bb bbbb) dddd
PORTB = p | (d & 0x3F); // (00bb bbbb)
p = PORTD & 0x0f; // (0000 xxxx)
d = ~(data << 4); // bbbb (dddd 0000)
PORTD = p | (d & 0xf0) ; // (dddd 0000)
}
表示データ(16LED_text.h)
unsigned int mes0[] = { 0, 0, 0,
0, 4104, 8184, 8184, 4104, 0, 0, 0,
960, 2016, 2032, 1016, 2032, 2016, 960, 0,
0, 0, 512, 6720, 1600, 1472, 1208, 128,
0, 0, 320, 224, 152, 192, 0, 0,
512, 520, 264, 16, 96, 384, 3584, 0,
0, 2056, 2056, 2064, 2080, 2240,20224,40960,
16384, 0 };
unsigned int mes1[] = { 0, 0, 0,
0, 2176,18560,16368, 2184, 2180, 4356, 260,
8, 48, 0, 0, 0, 4, 1048, 1056,
17472,10400, 2336, 3608, 2052, 4, 4, 0,
0, 0, 0, 4224, 4352, 4872, 5396, 5396,
6420, 4232, 112, 0, 0, 0, 0, 128,
128, 256, 256, 256, 128, 128, 64, 64,
128, 256, 0, 0 };
unsigned int mes2[] = { 0, 0, 0,
0, 2072, 2340, 2340,10532, 8184, 2336, 4640,
4112, 12, 0, 0, 0, 512, 1024, 1136,
3976, 2052, 4, 8, 112, 896, 7168, 2048,
1024, 512, 0, 0, 0, 8304, 8072, 260,
260, 516, 516, 1032, 0, 0, 0, 64,
128, 128, 128, 128, 64, 64, 64, 128 };
unsigned int mes3[] = { 0, 0, 0,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855 };
unsigned int mes4[] = {
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855 };
unsigned int mes5[] = {
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855 };
unsigned int mes6[] = {
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855 };
unsigned int mes7[] = {
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855,
61680,61680,61680,61680, 3855, 3855, 3855, 3855 };
【おまけ】 表示データの作り方
1、表計算ソフトで 「縦16×横64」程度のマス目を作る。
2、LEDを光らせたいマス目に"1"を書き込む。
3、各列毎に、一番上のマス目を「2^15」~ 一番下のマス目を「2^0」に重みづけして 「各マス目の値」を掛けた結果の「和」を計算する。
4、表示する範囲の 重みづけの和を 選択・コピーし、新しいファイルに貼り付ける。
5、新しく作ったファイルをCSV形式で保存する。
6、エディタでCSVファイルを開き データをソースに貼り付ける。
投稿者の人気記事
-
marua
さんが
2021/02/08
に
編集
をしました。
(メッセージ: 初版)
-
marua
さんが
2021/02/08
に
編集
をしました。
(メッセージ: 21/02/08 回路図 追加)
-
marua
さんが
2021/02/11
に
編集
をしました。
(メッセージ: 21/02/11 データの作り方追記)
ログインしてコメントを投稿する