LoginSignup
6
1

More than 3 years have passed since last update.

風をよむ風鈴を作ってみた

Last updated at Posted at 2019-08-18

風をよむ

風をよむって未来を予想って感じですよね
同名の番組が世界情勢を伝える番組ですし
ちなみに慣用句には風をよむってなかったでした

作ったもの

Image from Gyazo

使ったもの

  • obniz ハードv2.0.0
  • [node[(node.org/ja) v12.3.1
  • nodeライブラリ package.jsonの内容一部
  "dependencies": {
    "axios": "^0.19.0",
    "obniz": "^2.2.0",
    "simplenoise": "^1.0.1"
  }

ソースコード

"use strict";

const axios = require("axios");

const WEATHER_API = "http://api.openweathermap.org/data/2.5/forecast";
const CITY_ID = "1850147"; //tokyo
const APP_ID = process.env.WEATHER_APP_ID;

const Obniz = require("obniz");
let obniz = new Obniz(process.env.OBNIZ_ID);

const noise = require("simplenoise");
noise.seed(Math.random());

obniz.onconnect = async function() {
  // 初回に風速を取得
  let windSp = await getNextWindSpeed();
  console.log("get wind speed : " + windSp);
  obniz.display.clear();
  obniz.display.print("get wind speed : " + windSp);

  // 1時間に1回風速を取得,更新する
  setInterval(async function() {
    windSp = await getNextWindSpeed();
    console.log("update wind speed : " + windSp);
    obniz.display.clear();
    obniz.display.print("update wind speed : " + windSp);
  }, 3600000); //1時間

  let servo = obniz.wired("ServoMotor", { gnd: 0, vcc: 1, signal: 2 });
  // 基本角
  // servo.angle(90);

  let count = 0;
  // 1.5秒ごとにサーボを動かす
  obniz.repeat(async function() {
    // console.log(windSp);
    let noiseVal = noise.simplex2(0, count);
    // 風が強ければ値の変化の大きさも大きく
    // 風の大きさ5が大きい想定
    // サーボ120が垂直想定
    let servoVal = 90 - noiseVal * 80 * (windSp / 4);
    console.log(servoVal);
    servo.angle(servoVal);
    // 風が強ければ値の変化も早く
    count += windSp;
  }, 1500);
};

// 一番直近の風速度を返す 浮動小数 風速かな?
async function getNextWindSpeed() {
  const d = await getNextWeather();
  if (!d) return -1;
  if (!d["wind"]) return -2;
  if (!d["wind"]["speed"]) return -3;
  return d["wind"]["speed"];
}

// 一番直近の天気データを返す
async function getNextWeather() {
  const res = await axios.get(WEATHER_API, {
    params: {
      id: CITY_ID,
      appid: APP_ID
    }
  });
  // console.log(res);

  // 現在時刻取得
  let date = new Date();
  let nowUnix = date.getTime() / 1000;

  // データから3時間ごとのリストを抽出
  // 現在の日付の0時からデータが存在するので,現在時刻より後ろで一番近いデータを抽出
  let list = res.data.list;
  for (let i = 0; i < list.length; i++) {
    let dUnix = list[i].dt - 32400; //utcと東京の誤差
    // let d = new Date(list[i].dt_txt);
    // データのリストの順番は時刻昇順と信じて
    if (nowUnix < dUnix) {
      // 3時間ごとのデータなのでだいたい3時間後
      return list[i];
    }
  }
  return null;
}

一時間ごとに約3時間後の風力を取得してその風力によってサーボモータを動かす振り幅などを決めています
1.5秒間隔でサーボの次の角度の値を決めて回転しています

パーリンノイズの利用

パーリンノイズをわかりやすく解説してくれているサイト
https://postd.cc/understanding-perlin-noise/

波形や炎,水,雲の生成なんかにも利用されているようで,今回の風を擬似的に生成するのに使用してみました
グラフを作ってみたのが以下です

random と noise.png

今回のサーボモータに置き換えると縦の振幅がサーボの角度で,横軸が時間とします
パーリンノイズでは振幅はもちろんのこと横方向の変化速度というか波長の調節もできます
風速によりこの振幅の最大値と波長も変えていきます
ちなみに記事最初に載せた動画は風速4の状態です

風速による振幅と波長の違い.png

上記のぐらふでは0〜180°のサーボを利用しているので,90°を中心に±90の変化をさせています
風速が弱いと波長が伸びるようにしていたのですが,いざそのアルゴリズムをグラフ化するともうちょっと伸ばしてもいい気がしてきますね

まとめ

台風が話題になったときに東京にて利用してみました
台風ってだけ聞いてどうなるんだろうと思ってたところそんなに風鈴がならずで,結果的に東京にはそんなに強い風が来なかったでした
いちよう風をよめたのかなと思います
と,台風と風鈴ってことでより夏っぽくなれたかなと

しかし,サーボの駆動部分が見えているとやはり音よりそこに目がいって,その動きで強そうってなるのでうまくパッケージングしたいですね

音付きの動画をyoutubeにアップしたのでそちらもご覧いただければと思います
https://www.youtube.com/watch?v=2N4i2rjbFcM

今度は逆に普通の風鈴の煽られ具合をセンシングしたいですね

6
1
0

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
6
1