マトリックスLED表示クロックのためのスケッチ(プログラム)です。 数字のスクロールを含みます。 最初の8×8配列の1,0を変更するなどして、任意のパターンの表示にご利用可能です。 全てコピーすれは動きますので、プログラムに慣れていない方でも使えます。 少しややこしいのは

byte IJexchange[16]={12,5,10,11,1,2,14,4,3,7,8,6,15,16,9,13};//端子番号変換用

によりArduinoの出力をMatrixLEDの正しい端子に出力する部分です。 ブレッドボード上の配線を変更した場合にはこの配列での1-16の番号の順番を変更すれば良いです。 表示の直前で

m=IJexchange[i-1];
n=IJexchange[i-1];
digitalWrite(m,!matrixDot[i-1][j-9]);
digitalWrite(n,!matrixDot[i-1][j-9]);

とすることで、matrixDot[i-1,j-9][]内での座標と実際の座標位置が一致します。

//24時間表示の後に、ドット表示
//配線変更

#include < EEPROM.h >  //EEPROMは512Byte, 電源を切った時に時間を保存するために使用(
#include < MsTimer2.h > //割り込み。24時間ごとにArduinoをリセットし、時間のずれを無くす。

byte m=0; // 点灯位置のx座標 byteで0-255まで扱えるので、今回はintの必要はなし。
byte n=0; //点灯位置のy座標
byte IJexchange[16]={12,5,10,11,1,2,14,4,3,7,8,6,15,16,9,13};//端子番号変換用
int Push=0;
unsigned int Scroll=0; //スクロール用
unsigned int No=1; //記入する数字を選択
unsigned int Shift=0;//シフト用
unsigned int kScroll=0;//スクロールのおおきさ
unsigned int H10=0;  //時間の10の位
unsigned int H0=0; //時間の1の位
unsigned int M10=0; //分の10の位
unsigned int M0=0;  //分の1の位
unsigned long TimeNowSec=0;//現在の秒数
unsigned long TimeNowMin=0;//現在の分
unsigned long TimeNowHour=0;//現在の時
unsigned long FourByte1=1;//
unsigned long AddMin=0;//時間調整用
unsigned long AddTimeUnit=0;//時間調整用
unsigned long AddTime=0;//時間調整用

//二進法時計のための座標系
boolean matrixDot[8][8]={
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};

//数字スクロールのための座標系
boolean matrixNumber[8][35]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};

//数字の0
boolean matrix0[8][4]={
{0,1,1,0},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{0,1,1,0}
};

//数字の1
boolean matrix1[8][4]={
{0,1,0,0},
{1,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{1,1,1,0}
};

//数字の2
boolean matrix2[8][4]={
{0,1,1,0},
{1,0,0,1},
{0,0,0,1},
{0,0,0,1},
{0,0,1,0},
{0,1,0,0},
{1,0,0,0},
{1,1,1,1}
};

//数字の3
boolean matrix3[8][4]={
{0,1,1,0},
{1,0,0,1},
{0,0,0,1},
{0,0,0,1},
{0,1,1,0},
{0,0,0,1},
{1,0,0,1},
{0,1,1,0}
};

//数字の4
boolean matrix4[8][4]={
{0,0,1,0},
{0,1,1,0},
{0,1,1,0},
{1,0,1,0},
{1,0,1,0},
{1,1,1,1},
{0,0,1,0},
{0,0,1,0}
};

//数字の5
boolean matrix5[8][4]={
{1,1,1,0},
{1,0,0,0},
{1,0,0,0},
{1,1,1,0},
{0,0,0,1},
{0,0,0,1},
{1,0,0,1},
{0,1,1,0}
};

//数字の6
boolean matrix6[8][4]={
{0,1,1,0},
{1,0,0,0},
{1,0,0,0},
{1,1,1,0},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{0,1,1,0}
};

//数字の7
boolean matrix7[8][4]={
{1,1,1,1},
{1,0,0,1},
{1,0,0,1},
{0,0,0,1},
{0,0,1,0},
{0,0,1,0},
{0,1,0,0},
{0,1,0,0}
};

//数字の8
boolean matrix8[8][4]={
{0,1,1,0},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{0,1,1,0},
{1,0,0,1},
{1,0,0,1},
{0,1,1,0},
};

//数字の9
boolean matrix9[8][4]={
{0,1,1,0},
{1,0,0,1},
{1,0,0,1},
{1,0,0,1},
{0,1,1,1},
{0,0,0,1},
{1,0,0,1},
{0,1,1,0},
};

//コロンマーク
boolean matrixColon[8][4]={
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0},
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0},
};


//ATmega328のリセット(20daysごとに呼び出し)
void(* resetFunc) (void) = 0; //software reset の呼び出し。

//最初だけ実行。
void setup(){
//Serial.begin(9600);  //データ転送してチェック用(未使用)
  MsTimer2::set(1728000000, resetFunc); // 20days=1728000000 msecごとにresetする
  MsTimer2::start();
 pinMode(19,INPUT);//時間合わせ用(分)。
 for(int i=1;i < =16;i++){pinMode(i,OUTPUT);}
 for(int i=1;i < =16;i++){digitalWrite(i,LOW);} 
}


//メインのループ。
//計算量の多い数字スクロールを表示し、
//その間にDotDisplayで2進法表示を入れる
//時間は二進法時計の時に読めばOK
void loop(){  
 Scroll++;
 kScroll=Scroll/25; //27*25回繰り返す
 NumberDisplay();
 if (kScroll > 27){//27回スクロールしたら元に戻して、DotDisplayを一回実施。
   Scroll=0;
   TimeDisplayGet(); //遅延用(時間を取るのは時々でOK)
   DotDisplay(); //二進法時計を表示
   TimeDisplayGet(); //遅延用(時間を取るのは時々でOK)
    }
}

//00:00形式の時間表示
void NumberDisplay(){
 for(byte i=1;i < =8;i++){
   m=IJexchange[i-1];  
   digitalWrite(m,HIGH);  //行:HIGHで点灯      
     for(byte j=9;j < =16;j++){      ///1st digit
       n=IJexchange[j-1]; //MatrixLEDの端子に合わせて、出力端子を変換する。
       digitalWrite(n,!matrixNumber[i-1][j-9+kScroll]); //数字表示用こちらはi,j座標
       for (unsigned long m=0; m < 1; m++){Push=analogRead(4);TimeNowSec=millis()/1000;if(Scroll%25==1){AddTimeUnit++;ClockAdjust();}} //遅延用
       //delayMicroseconds(100);
       digitalWrite(n,HIGH);//オフにする      
     }
   digitalWrite(m,LOW);//オフにする  
 }
}

//二進法表示
void DotDisplay(){
 for (unsigned long k=0; k < 1000; k++){//ここで二進法表示のトータルの時間が決まる。
     DotDisplayGet();
  for(byte i=1;i < =4;i++){
      m=IJexchange[i-1];   
      digitalWrite(m,HIGH);  //行:HIGHとして、列のLOWで点灯 
    for(byte j=9;j < =16;j++){      ///1st digit
      n=IJexchange[j-1];   //端子番号変換用
      digitalWrite(n,!matrixDot[i-1][j-9]); //ドット表示用こちらはi,j
        for (unsigned long m=0; m < 2; m++){Push=analogRead(4);TimeNowSec=millis()/1000;} //遅延用
      //delayMicroseconds(100);
      digitalWrite(n,HIGH);//オフにする      
     }
    digitalWrite(m,LOW);//オフにする  
   } 
 }
}

//二進法表示用の時間を得る。(上位4バイトまでで十分ですよね?)
void DotDisplayGet(){ //
 TimeNowSec=millis()/1000;
 for (int i=0;i < =3;i++){
  for (int j=0;j < =7;j++){  
   matrixDot[i][j]= (boolean) (TimeNowSec  >  >  (j+i*8)) & B1 ;//ビットシフトでi+j桁目を出して入力する。TimeNowSecが4バイトなので、4桁目(32bit)までOK.
  }
 }
}
 
void TimeDisplayGet(){ //
 
 //時間の取得
 TimeNowSec=millis()/1000;
 TimeNowMin=(TimeNowSec/60)+AddMin;
 TimeNowHour=TimeNowMin/60;
 
 M0= TimeNowMin % 10 ; // 1 minuteを求める
 M10=((TimeNowMin % 60) -M0 )/10 ; // 10 minuteを求める
 H0= (TimeNowHour % 24) % 10; // 1 hourを求める
 H10= ((TimeNowHour % 24)-H0)/10; // 10hourを求める 24h表示
 
 //時間の記入
 //No=1;
 No=H10;
 Shift=7;
 NumberChange();
 
 Shift=11;
 for (int i=0;i < =7;i++){ matrixNumber[i][0+Shift]=0;} //spaceを追加
 
 //No=2;
 No=H0;
 Shift=12;
 NumberChange(); 
 
  Shift=16;  //16-19まで
  for (int i=0;i < =7;i++){for (int j=0;j< =3;j++){ matrixNumber[i][j+Shift]=matrixColon[i][j];}}  //Colonを追加
  
 //No=5;
 No=M10;
 Shift=20;
 NumberChange();
 
  Shift=24;
  for (int i=0;i< =7;i++){ matrixNumber[i][0+Shift]=0;} //spaceを追加
 
  //No=6;
  No=M0;
  Shift=25;
  NumberChange();
}

//表示するための数字のmatrixデータを得る。
void NumberChange(){
  switch(No){
  case 0: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix0[i][j];}} break;
  case 1: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix1[i][j];}} break;
  case 2: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix2[i][j];}} break;
  case 3: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix3[i][j];}} break;
  case 4: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix4[i][j];}} break;
  case 5: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix5[i][j];}} break;
  case 6: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix6[i][j];}} break;
  case 7: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix7[i][j];}} break;
  case 8: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix8[i][j];}} break;
  case 9: for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix9[i][j];}} break;
  default:for (int i=0;i < =7;i++){for (int j=0;j < =3;j++){ matrixNumber[i][j+Shift]=matrix9[i][j];}} 
 }
}
////////////////////////////////////////////////
//時間合わせのためのプログラム

void ClockAdjust(){
  if (AddTimeUnit > 100){
if(Push > 800){
  if(kScroll < 15){AddMin=AddMin+60;kScroll=7;Scroll=kScroll*25;}
  else{AddMin++;kScroll=20;Scroll=kScroll*25;}
  TimeNowSec=millis()/1000;
  TimeDisplayGet();
}
  AddTimeUnit=0;}
}


戸田よろず研究所トップページへ

ここで公開するアイデア/装置は安全性を保障しておりません。 用途に応じた設計を行い、十分な安全検査を行ってからご利用ください。 本サイトの情報の営利目的での利用はご遠慮ください。 本サイトの内容の無断転載を禁じます。© 2011 TYK