マイコンArduinoを使って電光掲示板を作る。

マイコン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バイトに文字数を記憶しているからです。

 

電光掲示板の操作の様子。


www.youtube.com

 

次回モジュールを連結して4文字表示の電光掲示板に改造していきます。

 

では、また。