0

複数の RGB カラー フェードを複数のライトに送信する linux/bash スクリプトがあります。すべてのライトは独自の色を持つことができますが、フェードイン/フェードアウトにはすべての色が同じ時間を使用する必要があります。そのため、初期値と速度乗数に基づいて、3 つの異なるターゲット値範囲のシーケンスを送信します。

私が遭遇した問題は、色が赤、緑、青の 3 つのチャネル (0-255) によって定義されていることです。対象となる色によっては、1 つのチャネルの値が 10 で、もう 1 つのチャネルの値が 230 である可能性があります。スムーズに作業するには、0 から開始し、同じ時間/ステップで最大値で終了する必要があります。さらに問題なのは、値を 0.112 として使用できないことです。0 または 1 である必要があります。

現時点では、使用する色の量を制限し、チャネルごとに「半分の範囲」の値のみを設定することで、この問題を解決できました。例えば。R255 G128 B000. このようにして、私はそれを機能させることができました(不正確さの許容範囲内で)。各チャネルに対して、各チャネルのフェードイン/アウトの速度に影響を与える個別の基本乗数を作成しました(255 2xの場合、128 の場合は 1x、000 の場合は 0x)

3 つのライトがあり、必要なライトにのみ値シーケンスを送信したいので、3 つの RGB 値を合計してゼロが等しいかどうかを確認します。そうであれば、割り当てられたライトはトリガーされません。

[Q] このスクリプトを最適化して、すべての RGB 値で機能し、色間でフェードできるようにする方法を教えてください。最も重要な条件は、グローバル速度乗数を適用できる必要があり、コンマの後ろに値を指定できないことです。

以下は、これまでに作成したスクリプトです。基本的には同じ行をコピーして貼り付けたものですが、他の名前が付いているため、他のライトの複製を取り出しました。

maxR=000, maxG=000, maxB=255, speed=10, 
toggle=$(($maxR + $maxG + $maxB))
subR=$(echo $maxR | cut -c-1), subG=$(echo $maxG | cut -c-1), subB=$(echo $maxB | cut -c-1), 
mulR=$(($subR*$speed)), mulG=$(($subG*$speed)), mulB=$(($subB*$speed))

count=0

while [ $count -lt 3 ] ; do
    count=$(($count +1))
    while [ $varR -lt $maxR ] || [ $valG -lt $maxG ] || [ $valB -lt $maxB ] ; do
        [[ $toggle -gt 0 ]] && $valR to red && $valG to green && $valB to blue
        varR=$(($varR +$mulR))
        valG=$(($valG +$mulG))
        valB=$(($valB +$mulB))
    done

    sleep 1

    while [ $varR -gt 0 ] || [ $valG -gt 0 ] || [ $valB -gt 0 ] ; do
        [[ $toggle -gt 0 ]] && $valR to red && $valG to green && $valB to blue
        varR=$(($varR -$mulR))
        valG=$(($valG -$mulG))
        valB=$(($valB -$mulB)) 
    done

    sleep 3
done
4

2 に答える 2

1

このスクリプトは、任意の色から別の色へと滑らかにフェードする色を表す RGB 値のシーケンスを生成します。これは 8 ビットの整数のみを使用します (もちろん、Ash と Bash は整数演算しか実行できませんが、より大きな値を処理することはできます)。

フェードはどの方向にもできます。たとえば、赤は小さな値から大きな値に変化し、青は大きな値から小さな値に変化します。

2 つの色の間で最小数のステップが実行されます。ステップ値とスリープ値を渡して、フェードが発生するレートを制御できます。

色を直接設定する機能があります。

いくつかの追加情報がコメントに含まれています。

最後にいくつかのデモ コードがあります。大量のテキストを出力します (set_color()関数はechoプレースホルダーとして使用します)。または別のページャーを使用lessして、出力を確認してスクロールできるようにします。

./fader | less

echo を、実際に色を設定するコマンドに置き換えます。

#!/usr/local/bin/ash
#
# by Dennis Williamson - 2012-07-26
# for http://stackoverflow.com/questions/11594670/generate-color-fades-via-bash
#
# fade smoothly from any arbitrary color to another
#
# no values are range checked, but this feature could be easily added
#

set_color () {
    local light=$1
    red=$2 green=$3 blue=$4 # global - see below
    # placeholder for the command that sets led color on a particular light
    echo "$light, $red, $green, $blue"
}

abs () {
    if [ $1 -lt 0 ]
    then
        echo "$(($1 * -1))"
    else
        echo "$1"
    fi
}

max () {
    local arg max=0
    for arg
    do
        if [ "$arg" -gt "$max" ]
        then
            max=$arg
        fi
    done
    echo "$max"
}

fade () {
    local light=$1 step=$2 sleep=$3
    local start_red=$4 start_green=$5 start_blue=$6
    local end_red=$7 end_green=$8 end_blue=$9
    local delta_red=$(abs $(($end_red - $start_red)) )
    local delta_green=$(abs $(($end_green - $start_green)) )
    local delta_blue=$(abs $(($end_blue - $start_blue)) )
    local i=0
    local max=$(max "$delta_red" "$delta_green" "$delta_blue")

    if [ "$delta_red" = 0 ] && [ "$delta_green" = 0 ] && [ "$delta_blue" = 0 ]
    then
        return
    fi

    if [ "$step" -lt 1 ]
    then
        step=1
    fi

    while [ "$i" -le "$max" ]
    do

        red=$(( $start_red + ($end_red - $start_red)  * $i / $max ))
        green=$(( $start_green + ($end_green - $start_green) * $i / $max ))
        blue=$(( $start_blue + ($end_blue - $start_blue) * $i / $max))
        set_color "$light" "$red" "$green" "$blue"
        sleep $sleep
        i=$(($i + $step))
    done
    # $red, $green and $blue are global variables and will be available to the
    # caller after this function exits. The values may differ from the input
    # end values if a step other than one is chosen. Because of that, these
    # values are useful for subsequent calls as new start values to continue
    # an earlier fade or to reverse fade back to a previous start value.
}

# demos (produces a lot of output)

# fade LED, step, sleep, start R G B, end R G B
fade one 3 0 100 200 15 154 144 200
fade one 3 0 "$red" "$green" "$blue" 100 200 15
fade two 1 1 30 40 50 70 20 10
fade three 1 0 0 255 0 0 0 255

i=0
while [ "$i" -lt 10 ]
do
    set_color one 255 0 0
    set_color two 0 255 0
    set_color three 0 0 255
    sleep 2
    set_color one 0 255 0
    set_color two 0 0 255
    set_color three 255 0 0
    sleep 2
    set_color one 0 0 255
    set_color two 255 0 0
    set_color three 0 255 0
    sleep 2
    i=$(($i + 1))
done
于 2012-07-26T13:03:39.483 に答える