LoginSignup
116
70

More than 3 years have passed since last update.

Javascript(Obniz)で電光掲示板を動かし、朝の連続テレビ小説のあらすじを毎朝7時に流す。

Last updated at Posted at 2019-02-13

概要

5.gif
6.gif
7.gif

連続テレビ小説 まんぷく(112)「できたぞ!福子!」 / 佳境を迎えた即席ラーメン作り。最終調整の末、家族や仲間を集めて試食会を行うことに。みんなにおいしさを認めてもらえるのでしょうか…

2019年2月13日放送分のタイトルとあらすじが流れています。

Obnizとは

004.jpg
ObnizはJavascriptで動作するIOT開発ボードです
https://obniz.io/

電光掲示板=LEDマトリクス

005.jpg
LEDコントローラMAX7219搭載のこちらのパーツです。
https://www.amazon.co.jp/gp/product/B07FFV537V/

LEDに文字を表示する

MAX7219を操作するクラスが用意されています。
これを利用して文字を表示します。
https://obniz.io/sdk/parts/MatrixLED_MAX7219/

配線

Untitled Sketch_ブレッドボード.png

このようになっています。

008.jpg
007.jpg
090.jpg
・絡まり防止のため配線をプラ部品に通しています。
・テープや熱収縮チューブでまとめる方法もありましたが、後ほど全て分解したいのでこのようになってます。
・パーツは再利用したい:innocent:

NHK番組表API

番組リストを取得できます。
毎朝5時に更新されます。
https://api-portal.nhk.or.jp/

コード

<html>
<head>
<meta charset="utf-8">
<style>
    /*表示しているテキストがわかりやすくなるように整形 */
    body{
        display:flex;
        flex-direction:column;
    }
    canvas{
        width:32px;
        margin-bottom:5px;
    }
</style>
<script src="https://unpkg.com/obniz@1.12.2/obniz.js" crossorigin="anonymous"></script>
<script>

//////////////////////////////////////////////////////
// 環境変数
//////////////////////////////////////////////////////

// Obniz用
const obnizKey = '0000-0000';   // あなたのObniz id
const deviceName = 'MatrixLED_MAX7219'; // デバイス名
const width = 8*4;  // LEDマトリクスの幅
const height = 8;   // LEDマトリクスの高さ
const brightness = 1;   // LED明るさ 1~15
const speed = 60;   // 文字の流れるスピード
const font = '19px sans-serif'; // フォント

// NHK API用
const now = new Date();
const year = now.getFullYear();
const month = ("0"+(now.getMonth() + 1)).slice(-2);
const date =  ("0"+now.getDate()).slice(-2);
const today = `${year}-${month}-${date}`
const week = now.getDay();

const apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';    // お持ちのNHK APIキー
const apiUrl = `http://api.nhk.or.jp/v2/pg/list/040/g1/${today}.json?key=${apiKey}`;    // NHK番組API
const programTitle = "連続テレビ小説 まんぷく" // 連続テレビ小説のタイトル

//////////////////////////////////////////////////////
// 番組情報を取得 放送していない日曜日は除く
//////////////////////////////////////////////////////
if(week!=6){
    const myJSON = new XMLHttpRequest();
    myJSON.onreadystatechange = function() {
        if ((myJSON.readyState === 4) && (myJSON.status === 200)) {

            // API叩いてJSON取得
            const programs = JSON.parse(myJSON.responseText);
            const program = programs.list.g1.find((e)=> {
                if (e.id == programTitle) {
                    return e;
                }
            });

            // 表示するテキストに整形
            let text = `${program.title} / ${program.subtitle}`;

            // 取得したテキストに全角英数があって気持ち悪かったので半角に変換
            text = text.replace(/[A-Za-z0-9]/g, function(s) {
            return String.fromCharCode(s.charCodeAt(0) - 65248);
            });

            // テキストをLEDに送り出す
            display(text);

        }
    }
    myJSON.open("GET", apiUrl, true);
    myJSON.send(null);
}


//////////////////////////////////////////////////////
// 画面表示
//////////////////////////////////////////////////////
const display = (text) => {

    const obniz = new Obniz(obnizKey);
        obniz.onconnect = async () => {

        // Obnizの配線
        // 上部のLEDマトリクス
        const matrixTop = obniz.wired(deviceName, { clk:0, cs:1, din:2, gnd:3, vcc:4});
        // 下部のLEDマトリクス
        const matrixBottom = obniz.wired(deviceName, { clk:5, cs:6, din:7, gnd:8, vcc:9});

        // LEDマトリクスの初期設定
        matrixTop.init(width, height);
        matrixTop.brightness(brightness);
        matrixBottom.init(width, height);
        matrixBottom.brightness(brightness);

        //LEDマトリクスに表示させるCanvasを生成
        const canvasTop = obniz.util.createCanvasContext(width, height);
        const canvasBottom = obniz.util.createCanvasContext(width, height);

        let x = width;

        obniz.repeat(async () =>{

            // 上部LEDマトリクスに表示
            canvasTop.fillStyle = "black";
            canvasTop.fillRect(0, 0, width, height);
            canvasTop.fillStyle = "white";
            canvasTop.font = font;
            canvasTop.textBaseline = "top";
            canvasTop.fillText(text, x, -2); // 文字が上半分だけ表示されるように位置調整
            matrixTop.draw(canvasTop);

            // 下部LEDマトリクスに表示
            canvasBottom.fillStyle = "black";
            canvasBottom.fillRect(0, 0, width, height);
            canvasBottom.fillStyle = "white";
            canvasBottom.font = font;
            canvasBottom.textBaseline = "top";
            canvasBottom.fillText(text, x, -11); // 文字が下半分だけ表示されるように位置調整
            matrixBottom.draw(canvasBottom);

            x--;

        }, 1000/speed)

    }
}

</script>
</head>
<body></body>
</html>

動作中の様子

HTMLに2つのCanvasが表示されます。
e0eb81e22275935d7fe25ad50444edde.png
境目がわかるように余白を開けています

Canvas上に文字が流れます。
333.gif
これが上下それぞれのLEDに表示されます。

毎朝7時にあらすじが流れる

Obnizにはサーバーレスイベントが用意されています。
https://obniz.io/doc/about_event

決められた時間にプログラムを実行できます。

これで毎朝7時にNHK番組表を取得して
朝の連続テレビ小説「まんぷく」のあらすじが自動で流れます。

8.gif

どこでも流せる

ネット環境と電源があればどこでもあらすじが流れます。
今回はモバイルバッテリーを電源にしているので持ち運びが楽です。

ほか

LEDが1列だと読めない

1列だとフォントサイズ9pxほどにするのですが、漢字が読みにくくなってしまいました。
これではドラマのあらすじが頭に入ってきません。
9.gif
できたぞ■子!:thinking:

配線をもっと簡易にできるはず

222.png
ObnizのIOを10個も使っていますが、
表示データを工夫すればこのようにつなげた配線で
LED2列表示ができるはずなのです。

以上です。
ありがとうございました。

116
70
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
116
70