IOロジックツール

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

What's this

obniz のioをWebから操作できます。
ただのon/offだけじゃなく、ドライブ方法やプルアップ-ダウンも操作できます。

Program

<!-- HTML Example -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>WebApp Logic Tool - obniz</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.2.1.min.js"
          integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
          integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
          crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>


  <script src="https://unpkg.com/obniz@1.9.1/obniz.js"></script>
  <style>
    .io {
      border: 1px solid #000;
      border-radius: 5px;
      padding: 10px;
      margin-bottom: 10px;

    }

    .io .tab-content {
      margin: 10px;
    }

    .io .configbox {
      text-align: center;
      vertical-align: middle;
      border: 1px solid #ccc;
      margin: 3px;
      border-radius: 5px;
    }

    .io .configbox.disable {
      border: none;
      background-color: #ccc;
      color: #FFF;
    }

    .io .configbox.high {
      border: none;
      background-color: #d9534f;
      color: #FFF;
    }

    .io .configbox.low {
      border: none;
      background-color: #449d44;
      color: #FFF;
    }

    .io .nav-tabs .nav-link.disabled {
      color: #d9534f;
      font-weight: bold;

    }

    .hidden {
      display: none;
    }

    #template {
      display: none;
    }

  </style>
</head>

<body>
<div id="obniz-debug"></div>
<br>
<div class="text-center">
  <h1> Logic tool</h1>
</div>

<div class="container">

  <div class="col text-center" id="connecting-status">
    connecting...
  </div>
  <div id="contents-target" class="hidden row">

  </div>

  <div id="template">
    <div class="col-lg-6 col-md-12 col-sm-12" data-io="{IO_NO}">
      <div class="io">
        <div class="row">
          <div class="col-12">
            <ul class="nav nav-tabs" id="io{IO_NO}Tab">
              <li class="nav-item">
                <a class="nav-link disabled" href="#">io{IO_NO}</a>
              </li>
              <li class="nav-item">
                <a class="nav-link active" id="input{IO_NO}-tab" data-toggle="tab" href="#input{IO_NO}" role="tab"
                   aria-controls="input{IO_NO}" aria-selected="true">Input Mode</a>

              </li>
              <li class="nav-item">
                <a class="nav-link" id="output{IO_NO}-tab" data-toggle="tab" href="#output{IO_NO}" role="tab"
                   aria-controls="output{IO_NO}" aria-selected="false">Output Mode</a>
              </li>
            </ul>
          </div>
          <div class="col-12">
            <div class="tab-content" id="myTabContent">
              <div class="tab-pane fade show active" id="input{IO_NO}" role="tabpanel"
                   aria-labelledby="input{IO_NO}-tab">
                <div class="row">
                  <div class="col configbox" data-type="pull"></div>
                  <div class="col configbox low" data-type="input"></div>
                </div>
              </div>
              <div class="tab-pane fade" id="output{IO_NO}" role="tabpanel" aria-labelledby="output{IO_NO}-tab">
                <div class="row">
                  <div class="col configbox" data-type="drive"></div>
                  <div class="col configbox" data-type="pull"></div>
                  <div class="col configbox low" data-type="output"></div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>
    </div>
  </div>
</div> <!-- container -->

<script>

  let configList = {
    types: ["input", "output"],
    pull: [null, "0v", "3v", "5v"],
    drive: ["3v", "5v", "open-drain"],
    output: ["false", "true"]
  };

  let ioState = [];
  let template = $("#template").html();
  for (let i = 0; i < 12; i++) {
    $("#contents-target").append(template.replace(/{IO_NO}/g, "" + i));
    let targetIoDiv = $("div[data-io=" + i + "]");

    targetIoDiv.find("div[data-type=pull]").on("click", ((no) => {
      return () => {
        return toggleIO(no, "pull")
      }
    })(i));
    targetIoDiv.find("div[data-type=drive]").on("click", ((no) => {
      return () => {
        return toggleIO(no, "drive")
      }
    })(i));
    targetIoDiv.find("div[data-type=output]").on("click", ((no) => {
      return () => {
        return toggleIO(no, "output")
      }
    })(i));

    $('a[href="#input' + i + '"]').on('shown.bs.tab', ((no) => {
      return () => {
        setIOState(no, "type", "input")
      }
    })(i));

    $('a[href="#output' + i + '"]').on('shown.bs.tab', ((no) => {
      return () => {
        setIOState(no, "type", "output")
      }
    })(i));

    ioState.push({type: "input", pull: null, drive: "3v", "output": "false", "input": "false"});

  }

  function toggleIO(no, type) {
    if (!connected) {
      return;
    }
    let current = ioState[no][type];
    let list = configList[type];
    let i = list.indexOf(current);
    i++;
    if (i >= list.length) {
      i = 0;
    }
    setIOState(no, type, list[i]);

  }

  function setIOState(no, type, value) {

    if (!connected) {
      return;
    }
    ioState[no][type] = value;
    setIO(no);
    drawIO(no);
  }

  function setIO(io) {
    if (!connected) {
      return;
    }
    let state = ioState[io];
    let pin = obniz.getIO(io);
    pin.drive(state.drive);
    pin.pull(state.pull);

    if (state.type === "output") {
      pin.input(); // for cahnge to/from 5V
      pin.output(state.output == 1);
    } else if (state.type === "input") {
      pin.input(function (value) {
        state.input = value ? 'true' : 'false';
        drawIO(io)
      });
    }
  }

  function drawIO(io) {
    if (!connected) {
      return;
    }
    let state = ioState[io];
    let targetIoDiv = $("div[data-io=" + io + "]");
    targetIoDiv.find('#' + state.type + io + '-tab').tab('show'); // Select tab by name

    targetIoDiv.find("div[data-type=pull]").html("<b>pull</b><br/>" + (state.pull ? state.pull : "disable"));
    targetIoDiv.find("div[data-type=drive]").html("<b>drive</b><br/>" + (state.drive ? state.drive: "disable"));
    if(state.drive !== "open-drain"){
      let div = targetIoDiv.find("#output"+io +" div[data-type=pull]");
      div.html("<b>pull</b><br/>" + "disable");
      div.addClass("disable");
    }else{
      let div = targetIoDiv.find("#output"+io +" div[data-type=pull]");
      div.removeClass("disable");
    }
    let outputDiv = targetIoDiv.find("div[data-type=output]");
    outputDiv.html("<b>output</b><br/>" + state.output);
    outputDiv.addClass(state.output === 'false' ? "low" : "high");
    outputDiv.removeClass(state.output === 'false' ? "high" : "low");
    let inputDiv = targetIoDiv.find("div[data-type=input]");
    inputDiv.html("<b>input</b><br/>" + state.input);
    inputDiv.addClass(state.input === 'false' ? "low" : "high");
    inputDiv.removeClass(state.input === 'false' ? "high" : "low");
  }


  /* This will be over written on obniz.io webapp page */
  let obniz = new Obniz("OBNIZ_ID_HERE");
  let connected = false;
  obniz.onconnect = function () {
    connected = true;
    $("#connecting-status").addClass("hidden");
    $("#contents-target").removeClass("hidden");
    for (let i = 0; i < 12; i++) {
      setIO(i);
      drawIO(i);

    }
  };
  obniz.onclose = function () {
    connected = false;
    $("#connecting-status").removeClass("hidden");
    $("#contents-target").addClass("hidden");
  };


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

今すぐ実行

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