OrangePi-PCを使ってみる

サーボモータを動かす

サーボモータを動かすために、Debian Jessieでは、こちらのPWMド ライバーが必要でしたが、
Debian Stretchでは、OverlayドライバーとしてPWMドライバーが用意されています。
PWMドライバーの有効化はarmbian-configを使って行います。
armbian-configを起動し以下の手順で進めます。






< Save > を押して < Exit >を押すと以下のスクリーンになります。


ここで<Reboot>を選ぶとリブートします。
再起動が完了すると以下のデバイスが使えるようになります。
これ以降、オンボードのデバッグポートはPWMポートとなり、デバッグポートを使ったログインはできなくなります。
デバッグポートにTTL-USB変換モジュールを繋げているとブート時にkernelがハングします。
$ ls -a /sys/class/pwm/pwmchip0
.  ..  device  export  npwm  power  subsystem  uevent  unexport



OrangePiのハードウェアPWMはオンボードデバッグポートの真ん中(PA5)しかありません。
そこで、サーボモータのSignalピン(オレンジ)はオンボードデバッグポートの真ん中(PA5)に接続します。
今回はサーボモータとしてSG90を使いました。
サーボモータ(SG90) OrangePi-PC
オレンジ
PA5

5V
茶色
GND




PWMポートの動作確認のためにSG90を使ってみました。
SG90のデー タシートには、PWM Period(20mSec)とポジション毎のパルス幅が記載されていますが、
ポジションごとのパルス幅は、こちらの実測値を使いました。
以下のスクリプトでSG90が 0°→ +90° → -90° → 0° に動きます。
コマンドについてはこ ちらを参考にしました。
#!/bin/bash
#Export PWM channel for user control.
sudo sh -c "echo 0 > /sys/class/pwm/pwmchip0/export"

#Select the period of PWM signal. Value is in nanoseconds.
sudo sh -c "echo 20000000 > /sys/class/pwm/pwmchip0/pwm0/period"

#Change the polarity of the PWM signal.
#The polarity can only be changed if the PWM is not enabled.
sudo sh -c "echo "normal" > /sys/class/pwm/pwmchip0/pwm0/polarity"

#Enable the PWM signal.
sudo sh -c "echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable"

#Select the duty cycle. Value is in nanoseconds and must be less than the period.
#Move to Center
sudo sh -c "echo 1450000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"
sleep 2

#Move to Angle +90
sudo sh -c "echo 2350000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"
sleep 2

#Move to Angle -90
sudo sh -c "echo 625000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"
sleep 2

#Move to Center
sudo sh -c "echo 1450000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"
sleep 2


#Disable the PWM signal.
sudo sh -c "echo 0 > /sys/class/pwm/pwmchip0/pwm0/enable"

#UnExport PWM channel for user control.
sudo sh -c "echo 0 > /sys/class/pwm/pwmchip0/unexport"



こちらで紹介しているperipheryライブラリ にはPWMクラスが有ります。
以下のPythonスクリプトで、SG90が 0°→ +90° → -90° → 0° に動きます。
ソースを確認しましたがclose()しても、PWMデバイスはUnExportされません。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
from periphery import PWM
import time

#Open PWM channel 0, pin 0
#Open /sys/class/pwm/pwmchip0/pwm0
pwm = PWM(0, 0)

#Select the period of PWM signal
#Write /sys/class/pwm/pwmchip0/pwm0/period
pwm.period = 0.02 # 20,000,000 nanoSec

#Change the polarity of the PWM signal
#Write /sys/class/pwm/pwmchip0/pwm0/polarity
pwm.polarity = "normal"

#Enable the PWM signal
#Write /sys/class/pwm/pwmchip0/pwm0/enable
pwm.enable()

#Select the duty cycle
#Write /sys/class/pwm/pwmchip0/pwm0/duty_cycle
#Move to Center
pwm.duty_cycle = 0.0725 # 0.0725 * 20,000,000 = 1,450,000 nanoSec
time.sleep(2)

#Move to Angle +90
pwm.duty_cycle = 0.1175 # 0.1175 * 20,000,000 = 2,350,000 nanoSec
time.sleep(2)

#Move to Angle -90
pwm.duty_cycle = 0.03125 # 0.03125 * 20,000,000 = 625,000 nanoSec
time.sleep(2)

#Move to Center
pwm.duty_cycle = 0.0725 # 0.0725 * 20,000,000 = 1,450,000 nanoSec
time.sleep(2)

#Not unexpoert
pwm.close()

PWM Period(20mSec)は周波数に換算すると1/0.02=50Hzとなります。
PWM Period(50Hz)の指定は以下のメソッドでも可能です。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
from periphery import PWM
import time

#Open PWM channel 0, pin 0
#Open /sys/class/pwm/pwmchip0/pwm0
pwm = PWM(0, 0)

#Set Freqency 50Hz
#Write /sys/class/pwm/pwmchip0/pwm0/period
pwm.frequency = 50 # 1.0 / 50.0 = 0.02Sec

#Change the polarity of the PWM signal
#Write /sys/class/pwm/pwmchip0/pwm0/polarity
pwm.polarity = "normal"

#Enable the PWM signal
#Write /sys/class/pwm/pwmchip0/pwm0/enable
pwm.enable()

#Select the duty cycle
#Write /sys/class/pwm/pwmchip0/pwm0/duty_cycle
#Move to Center
pwm.duty_cycle = 0.0725 # 0.0725 * 20,000,000 = 1,450,000 nanoSec
time.sleep(2)

#Move to Angle +90
pwm.duty_cycle = 0.1175 # 0.1175 * 20,000,000 = 2,350,000 nanoSec
time.sleep(2)

#Move to Angle -90
pwm.duty_cycle = 0.03125 # 0.03125 * 20,000,000 = 625,000 nanoSec
time.sleep(2)

#Move to Center
pwm.duty_cycle = 0.0725 # 0.0725 * 20,000,000 = 1,450,000 nanoSec
time.sleep(2)

#Not unexpoert
pwm.close()

続く...