マイコンArduinoを使って電光掲示板を作る。
続き
今回はEEPROMのデータのスクロール表示と表示数を増やしていきます。
書き替えたプログラム
#include <EEPROM.h>
byte address[] = {5, 4, 3, 2}; // アドレスは扱いやすい様に配列で持つ
short data_hex[16 * 31] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x3ffc, 0x0180, 0x7ffe, 0x4182, 0x5ffa, 0x1ff8, 0x3ffc,
0x2184, 0x2184, 0x3ffc, 0x2184, 0x3ffe, 0x0183, 0x01fe, 0x0000,
0x0000, 0x2184, 0x318c, 0x1988, 0x0998, 0x0180, 0x7ffe, 0x0640,
0x0640, 0x0640, 0x0440, 0x0c42, 0x1842, 0x3042, 0xe07e, 0x0000,
0x1000, 0x13fe, 0x1306, 0x7ffe, 0x7f06, 0x1306, 0x13fe, 0x1580,
0x3bfe, 0x7612, 0x17f2, 0x1312, 0x131a, 0x11f6, 0x701c, 0x0000,
0x0000, 0x3ffc, 0x0000, 0x0000, 0x0000, 0x7ffe, 0x7ffe, 0x0180,
0x1998, 0x1188, 0x318c, 0x2184, 0x6186, 0xc182, 0x0f80, 0x0000,
0x0000, 0x11fe, 0x1100, 0x1100, 0x7d00, 0x11fe, 0x3906, 0x3966,
0x3524, 0x552c, 0xd138, 0x9118, 0x1338, 0x126e, 0x16c3, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
int pos = 0;
short inData = 0;
short value = 0;
boolean toggle = false;
boolean eep = false;
boolean completion = false;
boolean stopflag = false;
boolean pin13 = false;
boolean pin14 = false;
int count = 0;
int scroll = 0;
int scroll_speed = 5;
int margin = 32;
void setup() {
for (int i = 2; i < 13; i++) {
pinMode(i, OUTPUT); // 各ピンの設定 全てアウトプット
}
pinMode(13,INPUT_PULLUP);
pinMode(14,INPUT_PULLUP);
digitalWrite(11,LOW); // SE L 自動でRAM切り替わり
digitalWrite(12,LOW); // A/BB 書き込み用RAM選択
digitalWrite(6,LOW); // GREEN 緑データ
digitalWrite(7,LOW); // CLK クロック
digitalWrite(8,LOW); // WE 書き込み信号 Hで書き込み
digitalWrite(9,LOW); // RED 赤データ
digitalWrite(10,LOW);// ALE アドレスラッチ Hで有効
Serial.begin(19200);
pos = EEPROM.read(0x3ff) * 16;
if (digitalRead(13) == 0)
eep = true;
else
change();
}
void loop() {
if (Serial.available() > 0 && stopflag) {
inData = Serial.read();
if (!toggle) {
value = inData * 256;
}
else {
value |= inData;
data_hex[pos++] = value;
}
toggle = !toggle;
}
if (eep) {
if (!stopflag) {
eep_disp();
count++;
if (count > scroll_speed) {
count = 0;
scroll++;
if (scroll > pos + margin)
scroll = 0;
}
if (digitalRead(14) == 0) {
pos = 0;
scroll = 0;
toggle = false;
stopflag = true;
pin14 = true;
}
if (digitalRead(13) == 0 && !pin13 && !pin14) {
eep = false;
pin13 = true;
}
if (digitalRead(13) == 1)
pin13 = false;
}
else if (digitalRead(13) == 0 && pos > 0) {
for (int i = 0;i < pos + margin + margin;i++) {
if (i < margin)
EEPROM.put(i * 2, 0);
else if (i >= pos + margin)
EEPROM.put(i * 2, 0);
else
EEPROM.put(i * 2, data_hex[i - margin]);
}
stopflag = false;
if (pos > 0)
EEPROM.write(0x3ff, pos / 16);
}
}
else {
disp();
count++;
if (count > scroll_speed) {
count = 0;
scroll++;
if (scroll > 16 * 7)
scroll = 0;
}
if (digitalRead(13) == 0 && !pin13) {
eep = true;
pin13 = true;
}
if (digitalRead(13) == 1)
pin13 = false;
}
}
void eep_disp(){
for (int i = 0; i < 16; i++) { // アドレス0~15
for (int j = 0; j < sizeof(address); j++)
if ((i & 0x1 << j) != 0) // address[0]~address[3]にビットをセット
digitalWrite(address[j], HIGH);
else
digitalWrite(address[j], LOW);
for (int k = 0;k < 32;k++) {
digitalWrite(9,LOW); // RED 赤データ
if ((EEPROM.read((k + scroll) * 2) + EEPROM.read((k + scroll) * 2 + 1) * 256 & 0x1 << i) != 0) {
digitalWrite(9,HIGH); // RED 赤データ
}
shift_clock(); // クロック
}
write_ale_we(); // 書き込み操作 関数にまとめて有る
}
}
void disp() {
for (int i = 0; i < 16; i++) { // アドレス0~15
for (int j = 0; j < sizeof(address); j++)
if ((i & 0x1 << j) != 0) // address[0]~address[3]にビットをセット
digitalWrite(address[j], HIGH);
else
digitalWrite(address[j], LOW);
for (int k = 0;k < 32;k++) {
if ((data_hex[k + scroll] & 0x8000 >> i) != 0)
digitalWrite(9,HIGH); // RED 赤データ // データのセット
else
digitalWrite(9,LOW); // RED 赤データ // データのセット
shift_clock(); // クロック
}
write_ale_we(); // 書き込み操作 関数にまとめて有る
}
}
void shift_clock() {
digitalWrite(7,HIGH); // クロック
digitalWrite(7,LOW); // クロック
}
void write_ale_we() {
digitalWrite(10,HIGH);// ALE アドレスラッチ Hで有効
digitalWrite(8,HIGH); // WE 書き込み信号 Hで書き込み
digitalWrite(8,LOW); // WE 書き込み信号 Hで書き込み
digitalWrite(10,LOW); // ALE アドレスラッチ Hで有効
}
void change() {
short local_hex[16 * 9];
// データをクリア
for (int n = 0;n < 16 * 9;n++) {
local_hex[n] = 0;
}
for (int i = 0;i < 9;i++) {
for (int j = 0;j < 16;j++) {
for (int k = 0;k < 16;k++) {
if ((data_hex[j + i * 16] & 0x8000 >> k) != 0)
local_hex[k + i * 16] |= 0x8000 >> j;
}
}
}
for (int n = 0;n < 16 * 9;n++) {
data_hex[n] = local_hex[n];
}
}
太字が追加部分
EEPROM関連が大幅に変わりました。
以前の書き込みは2文字限定でしたが31文字までになりdata_hex[16 * 31]で領域を確保
digitalRead(13)のボタンで通常モードとEEPROMモードの切り替えが可能
digitalRead(14)のボタンでEEPROMの書き込みモードに切り替わります。
data_hex[16 * 31]と31文字までになっていますがEEPROMの容量が1024バイトで最後の1バイトに文字数を記憶しているからです。
電光掲示板の操作の様子。
次回モジュールを連結して4文字表示の電光掲示板に改造していきます。
では、また。