サーボドライバを用いてLEDをスムーズに調光する


それは非常に快適なエリオットのおかげでプログラミングを行うにはNerves プラットフォーム.エリクサーは、我々が他の言語で怖く見える問題のために美しく、流暢で読みやすいコードを書くことを許します.これは私の学習電子機器についての別のランダムな研究ノートです.
とにかく、今日、私は神経iotプラットホームによって供給される私のラズベリーパイゼロWから、LEDの明るさを制御するように感じます.始める前に、パルス幅変調(PWM)がどのようなものであるかを理解する必要があります.

パルス幅変調


長い話短い、それは波形のオフ時間にオン時間の比率を制御することです.すなわち、デジタル信号を用いてアナログデータを表現する.私は個人的にWikipediaから以下のこのイメージが好きです.

GPIOを通してLEDを制御するという文脈では、PWMを使って2つのことができます.

1 .様々なオン/オフタイミングのLEDを点滅させる


frequency (Hz) 例えば1〜2 Hzでは低いので、LEDスイッチのオン・オフを定期的に見ることができます.それで、変わることによってduty cycle , 瞬きのタイミングを変えることができます.楽しい.

LEDの明るさを変える


周波数が例えば100 Hzまで高くなるにつれて、我々はもはや特定の点を超えて瞬きを観察することはできない.このような周波数では、デューティサイクルは輝度のように作用する.すなわち、波のグラフの面積を明るさとみなすことができる.デジタル信号をアナログに変換するこの技術は、一般的であり、サーボモータの制御など、多くの異なる用途に適用される.

ラズベリーパイからPWMを使う方法


大まかに言えば、ラズベリーpiからPWMを制御する2つの方法があります.

ラズベリーパイのオンボードPWMモジュール


によるとRaspberry Pi's GPIO usage documentation , PWMが利用できるピンは以下の通りです.
  • GPIO 12
  • GPIO 13
  • GPIO 18
  • GPIO 19
  • エリクシールでpigpiox ライブラリを構築し、波形を送信できるようにする機能を提供しますpigpio daemon .
    gpio = 12
    frequency = 100
    
    # I don't know what unit it is but `1_000_000` was the maximum value.
    Pigpiox.Pwm.hardware_pwm(gpio, frequency, 1_000_000)
    

    外部PWMモジュール


    外部サーボドライバボードのような使用Adafruit 16-Channel PWM/Servo Driver , 我々は、より多くのチャンネルでより多くの柔軟性を持ちます.欠点は、そのサーボドライバを使用するためのエリクサーライブラリはなかったでも勉強しましたAdafruit's official Python code , それは簡単ではなくロケット科学ではなかった.だから私は書くことを決めたmy own library in Elixir . それが他の錬金術師を助けるならば、それは素晴らしいです.重要なことは、ボードはPCA 9685 PWMコントローラを使用しているので、そのchip's data sheet 真実の唯一の源です.
    使用mnishiguchi/servo_kit ライブラリは、LEDの明るさを変更する方法です.
    # Initialize a driver.
    driver = ServoKit.PCA9685.new(%{i2c_bus: "i2c-1", frequency: 100})
    
    # Set the duty cycle to 66.6% for Channel 15.
    ServoKit.PCA9685.set_pwm_duty_cycle(driver, 15, 66.6)
    

    デモ


    ハードウェア


    以下に準備した項目です.

  • Raspberry Pi Zero W
  • 私は、そして、愛を使いますthis Pi case 帽子用に

  • Micro SD card
  • 私は、マイクロSDカードの上で神経のファームウェアを燃やします.
  • Adafruit 16-Channel PWM / Servo Bonnet for Raspberry Pi
  • 5V 2A (2000mA) switching power supply
  • jumber wires
  • 220オームresistors
  • LED
  • ソフトウェア


  • Nerves - iOTプラットフォームを使用して構築

  • mnishiguchi/servo_kit - エリクサーでPCA 9685 PWM/サーボコントローラを使用してください
  • 配線


    チャンネル0、4、8を使います.The servo connectors have three pins for each channel :
  • 制御信号
  • 電源
  • グラウンド
  • しかし、LEDのために、我々が必要とするすべては、制御信号と一般の地面です.


    プログラミング


    私がこのデモのために書いたコードは、ここにあります.それはAdafruit's RGB Backlit LCDs tutorial .
    driver = ServoKit.PCA9685.new(%{i2c_bus: "i2c-1", frequency: 100})
    
    ch_red = 0
    ch_green = 4
    ch_blue = 8
    
    loop_fn = fn loop_fn ->
      (0..99) |> Enum.each(fn x ->
        driver
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_red, x)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_green, 0)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_blue, 99 - x)
        Process.sleep(50)
      end)
    
      (0..99) |> Enum.each(fn x ->
        driver
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_red, 99 - x)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_green, x)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_blue, 0)
        Process.sleep(50)
      end)
    
      (0..99) |> Enum.each(fn x ->
        driver
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_red, 0)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_green, 99 - x)
        |> ServoKit.PCA9685.set_pwm_duty_cycle(ch_blue, x)
        Process.sleep(50)
      end)
    
      loop_fn.(loop_fn)
    end
    
    loop_fn.(loop_fn)
    

    結論


    私はエレクトロニクスnoobとして、PWMは最初は少し怖い見たが、一度それに慣れると、その基本的な使用は比較的簡単です.スペシャリストは波形を正確に計算して、モニターするようです、しかし、私はカジュアルな愛好家がそれについて心配する必要はないと思います.
    PWMで武装し、さらに進むことができます.controlling a servo , changing RGB-backlit LCD display's background colors , など