バック・トゥ・ザ・フューチャーのあれ

このエントリーをはてなブックマークに追加

これはなに?

映画に出てくる「あれ」をMAX7219とLEDアレイで作ってみました。タイマーになっています。

どう動くか

obnizはチェーン接続されているMAX7219の最初の1つにだけ繋がれています。

中央の緑が今の時間を示しています。

2つまでタイマーを設定できます。

タイマーの時刻になるとアラームがブザーから鳴ります

Program

<!-- HTML Example -->
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.5.0/obniz.js"></script>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
  
<body>
  <div id="obniz-debug"></div>
  <p>アラームA
    <input type="date" id="dateA">
    <input type="time" id="timeA">
    <button id="set_a" class="btn btn-primary">SET A</button>
  </p>
  <p>アラームB
    <input type="date" id="dateB">
    <input type="time" id="timeB">
    <button id="set_b" class="btn btn-primary">SET B</button>
  </p>
  

<script>
  var obniz = new Obniz("OBNIZ_ID_HERE");
  obniz.onconnect = async function () {
    
    // アラーム用スピーカー
    var speaker = obniz.wired("Speaker", {signal:9, gnd:11});
    
    // 7セグ接続
    var segment = obniz.wired("7SegmentLED_MAX7219", { clk:0, cs:1, din:2, gnd:3, vcc:4});
    segment.init(9,5); // コロン部分に1桁割り当てているので、4桁+1桁で5桁として初期化
    segment.clearAll();
    
    // 色によって輝度が違うので、brightnessAll関数を使わずに個別に設定
    segment.brightness(0,15);
    segment.brightness(1,15);
    segment.brightness(2,15);
    segment.brightness(3,2);
    segment.brightness(4,2);
    segment.brightness(5,2);
    segment.brightness(6,5);
    segment.brightness(7,5);
    segment.brightness(8,5);
    
    // アラーム用
    var timerFlagA = 0;
    var timerFlagB = 0;
    var DateTimeA = new Date(0);
    var DateTimeB = new Date(0);
    var DateTime = new Date();
    
    // それぞれのディスプレイに表示する内容を保持する配列
    var Red_Date = [];
    var Red_Year = [];
    var Red_Time = [];
    var Grn_Date = [];
    var Grn_Year = [];
    var Grn_Time = [];
    var Ylw_Date = [];
    var Ylw_Year = [];
    var Ylw_Time = [];
    
    getCurrentTime();
    display();
    
    obniz.repeat(async function(){	// 5秒おきに時刻取得、画面更新
      getCurrentTime();
      display();

      if(DateTimeA.getTime() || DateTimeB.getTime()){	// アラームA,Bのいずれかが設定されているとき実行
        if (DateTimeA < DateTime && timerFlagA == 1 ){ 		// アラームAの設定時刻を過ぎてフラグが1のときだけ実行
          alarm();
          console.log("アラームA");
          timerFlagA = 0;
        }
        
        if (DateTimeB < DateTime && timerFlagB == 1 ){ 		// アラームBの設定時刻を過ぎてフラグが1のときだけ実行
          alarm();
          console.log("アラームB");
          timerFlagB = 0;
        }
      }
    }, 5000);
    
    
    function display(){
      // Yellow disprays
      segment.setNumber(0,1,Ylw_Date[0],false);
      segment.setNumber(0,2,Ylw_Date[1],true);
      segment.setNumber(0,3,Ylw_Date[2],false);
      segment.setNumber(0,4,Ylw_Date[3],false);

      segment.setNumber(1,1,Ylw_Year[0],false);
      segment.setNumber(1,2,Ylw_Year[1],false);
      segment.setNumber(1,3,Ylw_Year[2],false);
      segment.setNumber(1,4,Ylw_Year[3],false);

      segment.setNumber(2,1,Ylw_Time[0],false);
      segment.setNumber(2,2,Ylw_Time[1],false);
      segment.setNumber(2,3,Ylw_Time[2],false);
      segment.setNumber(2,4,Ylw_Time[3],false);

      // Green displays
      segment.setNumber(3,1,Grn_Date[0],false);
      segment.setNumber(3,2,Grn_Date[1],true);
      segment.setNumber(3,3,Grn_Date[2],false);
      segment.setNumber(3,4,Grn_Date[3],false);

      segment.setNumber(4,1,Grn_Year[0],false);
      segment.setNumber(4,2,Grn_Year[1],false);
      segment.setNumber(4,3,Grn_Year[2],false);
      segment.setNumber(4,4,Grn_Year[3],false);

      segment.setNumber(5,1,Grn_Time[0],false);
      segment.setNumber(5,2,Grn_Time[1],false);
      segment.setNumber(5,3,Grn_Time[2],false);
      segment.setNumber(5,4,Grn_Time[3],false);

      // Red displays
      segment.setNumber(6,1,Red_Date[0],false);
      segment.setNumber(6,2,Red_Date[1],true);
      segment.setNumber(6,3,Red_Date[2],false);
      segment.setNumber(6,4,Red_Date[3],false);

      segment.setNumber(7,1,Red_Year[0],false);
      segment.setNumber(7,2,Red_Year[1],false);
      segment.setNumber(7,3,Red_Year[2],false);
      segment.setNumber(7,4,Red_Year[3],false);

      segment.setNumber(8,1,Red_Time[0],false);
      segment.setNumber(8,2,Red_Time[1],false);
      segment.setNumber(8,3,Red_Time[2],false);
      segment.setNumber(8,4,Red_Time[3],false);
    };
    
    function getCurrentTime() {		// 現在時刻を取得する関数
      DateTime=new Date();
      var c_year = DateTime.getFullYear();
      var c_month = DateTime.getMonth()+1;
      var c_day = DateTime.getDate();
      var c_hours = DateTime.getHours();
      var c_minutes = DateTime.getMinutes();

      Grn_Year = divideNum(c_year);
      Grn_Time = divideNum(c_hours).concat(divideNum(c_minutes));
      Grn_Date = divideNum(c_month).concat(divideNum(c_day));
    };
    
    function divideNum(digitsNum) { // 数字を一文字ずつ分解し配列に入れる関数
      var textArr = String(digitsNum).split('');
      var numArr = [];
      for (var i = 0; i < textArr.length; i++) {
        numArr[i] = parseInt(textArr[i]);
      }
      if (textArr.length == 1){ // 数字が一桁だった場合は配列の先頭に"0"を追加
        numArr.unshift(0);
      }
      return numArr;
    };
    
    async function alarm() {
      for (var i = 0; i < 3; i++) {
        speaker.play(1000);
        await obniz.wait(500);
        speaker.stop();
        await obniz.wait(500);
      }
    };
    
    $("#set_a").on("click",function(){
      var a_date_text = document.getElementById('dateA').value;
      var a_time_text = document.getElementById('timeA').value;
      var a_date_arr = String(a_date_text).split('-');
      var a_time_arr = String(a_time_text).split(':');
      
      Red_Year = divideNum(a_date_arr[0]);
      Red_Time = divideNum(a_time_arr[0]).concat(divideNum(a_time_arr[1]));
      Red_Date = divideNum(a_date_arr[1]).concat(divideNum(a_date_arr[2]));
      
      DateTimeA = new Date(a_date_arr[0], a_date_arr[1] - 1, a_date_arr[2], a_time_arr[0], a_time_arr[1], 0);
      console.log("アラームAが設定されました:");
      console.log(DateTimeA);
      
      timerFlagA = 1;
      
      display();
    });
    
    $("#set_b").on("click",function(){
      var b_date_text = document.getElementById('dateB').value;
      var b_time_text = document.getElementById('timeB').value;
      var b_date_arr = String(b_date_text).split('-');
      var b_time_arr = String(b_time_text).split(':');
      
      Ylw_Year = divideNum(b_date_arr[0]);
      Ylw_Time = divideNum(b_time_arr[0]).concat(divideNum(b_time_arr[1]));
      Ylw_Date = divideNum(b_date_arr[1]).concat(divideNum(b_date_arr[2]));
      
      DateTimeB = new Date(b_date_arr[0], b_date_arr[1] - 1, b_date_arr[2], b_time_arr[0], b_time_arr[1], 0);
      console.log("アラームBが設定されました:");
      console.log(DateTimeB);
      
      timerFlagB = 1;
      
      display();
    });
    
    while(true){	// コロンの点滅
      segment.setNumber(2,0,2,false);
      segment.setNumber(8,0,2,false);
      segment.setNumber(5,0,2,false);
      await obniz.wait(500);
      segment.setNumber(2,0,"off",false);
      segment.setNumber(8,0,"off",false);
      segment.setNumber(5,0,"off",false);
      await obniz.wait(500);
    };
  
  };

  obniz.onclose = async function(){
    $("#on").off("click");
    $("#off").off("click"); 
    $("#set_a").off("click");
    $("#set_b").off("click");
  };
</script>
</body>
</html>

今すぐ実行

HTMLがブラウザで開かれて実行されます。