DMXkingのLeDMX4MAXとNode-REDを使ってSPI-LEDの制御をする方法 その3

前回のケース5では消灯状態からだんだん明るくなり100%になったらまた消灯状態から繰り返すというNode-REDフローを作成しました。

今回は、だんだん明るくなってからまた暗くなっていくという内容にしました。

CASE6 : だんだん明るくなり暗くなる

フローはこのとおり

起動時に自動実行するChangeノードにLED情報や点灯速度などをいれておきます。

明るさの変化をLinearでいくか、logarithmicにするかをSwitchノードで分岐しています。

[{"id":"db3b67f99efec451","type":"inject","z":"dbd1ec4c56b673f8","name":"Trigger every 0.1 seconds","props":[{"p":"payload"}],"repeat":"0.1","crontab":"","once":true,"onceDelay":"0.5","topic":"","payload":"","payloadType":"date","x":280,"y":280,"wires":[["f3923a08c7393bac"]]},{"id":"f3923a08c7393bac","type":"function","z":"dbd1ec4c56b673f8","name":"Calculate Elapsed Time","func":"let startTime = flow.get(\"startTime\") || msg.payload;\nflow.set(\"startTime\", startTime);\n\n// スピード係数\nlet speedRatio = global.get(\"speedRatio\");\n\nlet elapsedTime = (msg.payload - startTime) / 1000.0; // in seconds\nmsg.elapsedTime = elapsedTime*speedRatio;\n\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":360,"wires":[["e7c3c1261d490779"]]},{"id":"f4339206fafed860","type":"inject","z":"dbd1ec4c56b673f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":60,"wires":[["6fd7c18579c7f0d3"]]},{"id":"6fd7c18579c7f0d3","type":"change","z":"dbd1ec4c56b673f8","name":"","rules":[{"t":"set","p":"startTime","pt":"flow","to":"","tot":"num"},{"t":"set","p":"numberOfSeries","pt":"global","to":"100","tot":"num"},{"t":"set","p":"numberOfLEDs","pt":"global","to":"60","tot":"num"},{"t":"set","p":"speedRatio","pt":"global","to":"100","tot":"str"},{"t":"set","p":"curve","pt":"global","to":"log","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":140,"wires":[["d4b501fd37d59ddb"]]},{"id":"d4b501fd37d59ddb","type":"debug","z":"dbd1ec4c56b673f8","name":"debug 9","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":480,"y":200,"wires":[]},{"id":"e7c3c1261d490779","type":"function","z":"dbd1ec4c56b673f8","name":"LED番号ごとの順番-1","func":"// グローバルパラメータ\nconst elapsedTime = parseInt(msg.elapsedTime);\n\n//const numberOfSeries = 10;\nconst numberOfSeries = global.get(\"numberOfSeries\");\n\n// const numberOfLEDs = 60;\nconst numberOfLEDs = global.get(\"numberOfLEDs\");\n\n// LEDの配列初期化\nlet arrayLED = new Array(numberOfLEDs).fill(0);\n\n// LEDのステータスと順番を計算\nconst LEDStatus = Math.floor(elapsedTime / numberOfSeries);\nconst LEDOrder = elapsedTime % numberOfSeries;\n\n// 先頭のLED番号を計算\nconst topLEDNumber = numberOfSeries * LEDStatus + LEDOrder;\n\n// 先頭LED番号のシリーズ内の位置\nconst topLEDPosition = topLEDNumber % numberOfSeries;\n\n// 各LEDの明るさを計算\nfor (let i = 0; i < numberOfLEDs; i++) {\n    const currentLEDPosition = i % numberOfSeries;\n    let brightness;\n\n    if (topLEDPosition >= currentLEDPosition) {\n        brightness = topLEDPosition - currentLEDPosition + 1;\n    } else {\n        brightness = numberOfSeries + topLEDPosition - currentLEDPosition + 1;\n    }\n\n    // 先頭LED番号が現在のLED番号より小さい場合は明るさを0に設定\n    if (topLEDNumber < i) {\n        brightness = 0;\n    }\n\n    arrayLED[i] = brightness;\n}\n\n// 結果をメッセージに設定して送信\nmsg.payload = {\n    \"LEDStatus\": LEDStatus,\n    \"LEDOrder\": LEDOrder,\n    \"topLEDNumber\": topLEDNumber,\n    \"arrayLED\": arrayLED\n};\n\nreturn msg;\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":440,"wires":[["19da4b61791a3360"]]},{"id":"38d4c78d7b21a7d5","type":"debug","z":"dbd1ec4c56b673f8","name":"debug 12","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1340,"y":280,"wires":[]},{"id":"589d291a2686d71e","type":"sACN","z":"dbd1ec4c56b673f8","server":"2c1a273ac56a5d84","universe":"","channel":"","transition":"instant","transitionRate":50,"transitionTime":1000,"name":"","x":1160,"y":540,"wires":[]},{"id":"7add210666774acc","type":"function","z":"dbd1ec4c56b673f8","name":"sACN-DATA作成(Logarithmic)","func":"// LED配列をsACNに送信\nvar arrayLED = msg.payload.arrayLED;\nconst numberOfLEDs = global.get(\"numberOfLEDs\");\nconst numberOfSeries = global.get(\"numberOfSeries\");\n\n// 明るさが最大になる中央のLEDのインデックスを計算\nconst midPoint = Math.floor(numberOfSeries / 2);\n\nvar sACNarray = [];\nvar DMXNumber;\n\n// arrayLEDのデータからRGBに変更\nfor (let i = 0; i < numberOfLEDs; i++) {\n    let LEDorder = arrayLED[i];  // LEDorderにarrayLED[i]のLED番号を入れる\n    let percentage;\n\n    if (LEDorder <= midPoint) {\n        // 中央までは明るさが指数関数的に増加\n        percentage = Math.pow((LEDorder / midPoint), 2) * 100;  // 0%から100%へ\n    } else {\n        // 中央を過ぎたら明るさが指数関数的に減少\n        percentage = Math.pow(((numberOfSeries - LEDorder) / midPoint), 2) * 100;  // 100%から0%へ\n    }\n\n    DMXNumber = i * 3;  // DMX アドレス計算\n\n    // 各アドレスにpercentageを割り当てる\n    sACNarray[DMXNumber] = percentage;\n    sACNarray[DMXNumber + 1] = percentage;\n    sACNarray[DMXNumber + 2] = percentage;\n}\n\n// 結果をメッセージに設定して送信\nmsg = {\n    topic: \"1/1\",\n    payload: sACNarray\n};\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":500,"wires":[["38d4c78d7b21a7d5","589d291a2686d71e"]]},{"id":"3a815512a51dfabd","type":"function","z":"dbd1ec4c56b673f8","name":"sACN-DATA作成(線形に変化)","func":"// arratLEDをsACNにおくる\nvar arrayLED = msg.payload.arrayLED;\n\nconst numberOfLEDs = global.get(\"numberOfLEDs\");\nconst numberOfSeries = global.get(\"numberOfSeries\");\n\n// 明るさが最大になる中央のLEDのインデックスを計算\nconst midPoint = Math.floor(numberOfSeries / 2);\n\nvar sACNarray = [];\nvar DMXNumber;\n\n\n// arrayLEDのデータからRGBに変更\nfor (let i = 0; i < numberOfLEDs; i++) {\n\n    // LEDorderにarrayLED[i]のLED番号が入れる\n    let LEDorder = arrayLED[i];\n    \n    // LEDorderごとの明るさはpercentage\n    let percentage;\n\n    if (LEDorder <= midPoint) {\n        // 中央までは明るさが増加\n        percentage = (LEDorder / midPoint) * 100;  // 0%から100%へ\n    } else {\n        // 中央を過ぎたら明るさが減少\n        percentage = ((numberOfSeries - LEDorder) / midPoint) * 100;  // 100%から0%へ\n    }\n\n    //node.warn(LEDorder);\n    \n\n    DMXNumber = i*3;\n\n    // 1アドレス\n    sACNarray[DMXNumber] = percentage;\n    sACNarray[DMXNumber+1] = percentage;\n    sACNarray[DMXNumber+2] = percentage;\n\n }\n\n\n\n\n// 結果をメッセージに設定して送信\nmsg = {\n    topic: \"1/1\",\n    payload: sACNarray\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":600,"wires":[["589d291a2686d71e"]]},{"id":"19da4b61791a3360","type":"switch","z":"dbd1ec4c56b673f8","name":"","property":"curve","propertyType":"global","rules":[{"t":"eq","v":"log","vt":"str"},{"t":"eq","v":"linear","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":540,"wires":[["7add210666774acc"],["3a815512a51dfabd"]]},{"id":"2c1a273ac56a5d84","type":"sacn-config","hostOrUniverse":"192.168.2.202","port":"5568"}]

まとめ

次回は時間によって違う演出に切り替わる方法を考えてみたいとおもいます。