Jetson nanoとPCA9685でサーボを動かそうとするときのI2Cエラー対処法!

はてなブックマーク - Jetson nanoとPCA9685でサーボを動かそうとするときのI2Cエラー対処法!
LINEで送る
Pocket

Jetson nanoとPCA9685でサーボを動かそうとするときのI2Cエラー対処法!をご紹介します!

目次

デフォルトのI2Cのbusはどこなのか特定できませんでした

これで、ハマる人がこれから増えると思います。

簡単なハックをすれば解決しますが、わからないと、なかなかハマります!

Traceback (most recent call last):
File "pca9685_smaple.py", line 17, in <module>
pwm = Adafruit_PCA9685.PCA9685(0x40)
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_PCA9685/PCA9685.py", line 74, in __init__
self._device = i2c.get_i2c_device(address, **kwargs)
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 63, in get_i2c_device
busnum = get_default_bus()
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 55, in get_default_bus
raise RuntimeError('Could not determine default I2C bus for platform.')
RuntimeError: Could not determine default I2C bus for platform.

ここで一旦宣伝

私の著書「今すぐ試したい!機械学習・深層学習(ディープラーニング)プログラミングレシピ」がアマゾンで予約開始しました! 初心者向けなので、是非買って読んでみてください!(^O^)/

背景

さて、まずこの記事の背景を申し上げます。最近、Jetson nanoやDonkey Carなどが流行っていて、私も色々実験したいと思っています。

まさきに、確認したいのは、やはりJetson nanoからサーボ、ステップモーター、DCモーターの動かし方です。そこで、今までやっていたRaspberry PiとPCA9685のをJetsonでできないかと思ったわけです。しかし、一連の作業をして、「Could not determine default I2C bus for platform.」と言うエラーに遭遇しました。

 

Could not determine default I2C bus for platform.

これですね!

このマシン(platform)のデフォルトのI2Cのbusはどこなのか特定できませんでした!と言うことですね!

PCA9685を動かすための設定

本題に入る前に、そもそもPCA9685を動かすための準備をしなければいけません!

まずは必要なPythonソフトウェアの準備をします。

NvidiaのGPIO libraryをインストール

この部分の手順は下記のリンクを参照して、その通りに実施してください。

https://github.com/NVIDIA/jetson-gpio

PCA9685のパッケージをインストール

pip3 install Adafruit_PCA9685 --user

配線(Jetson nano とPCA9685と接続)

配線は、簡単です。合わせて、以前のRaspberry PiとPCA9685の記事も参照してください。

RaspberryPi+Python+PCA9685で複数のサーボを制御する!簡単!

PCA9685       Jetson nano  
VCC     <->    3.3v
SDL     <->    SDL(3)
SCL     <->    SCL(5)
GND     <->    GND

接続ができたら、下記の写真のようになります。もちろんサーボとサーボ駆動用の電源(バッテリー)も接続します。

接続の確認

sudo i2cdetect -y -r 1

下記のような結果になれば、問題ないです。

0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --

プログラムは以前の記事に使ったものと全く同じプログラムとなります。

念のために、下に掲載しておきます。これ適切に名前をつけて保存します。(例えば、pca9685_sample.py)

# Simple demo of of the PCA9685 PWM servo/LED controller library.
# This will move channel 0 from min to max position repeatedly.
# Author: Tony DiCola
# License: Public Domain
from __future__ import division
import time
 
# Import the PCA9685 module.
import Adafruit_PCA9685
 
 
# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)
 
# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()
 
# Alternatively specify a different address and/or bus:
#pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)
 
# Configure min and max servo pulse lengths
servo_min = 150  # Min pulse length out of 4096
servo_max = 600  # Max pulse length out of 4096
 
# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
    pulse_length = 1000000    # 1,000,000 us per second
    pulse_length //= 60       # 60 Hz
    print('{0}us per period'.format(pulse_length))
    pulse_length //= 4096     # 12 bits of resolution
    print('{0}us per bit'.format(pulse_length))
    pulse *= 1000
    pulse //= pulse_length
    pwm.set_pwm(channel, 0, pulse)
 
# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60)
 
print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
    # Move servo on channel O between extremes.
    # ここ少し改造しました。今回はサーボ8個を動かしてみます。
    for i in range(8):
        pwm.set_pwm(i, 0, servo_min)
        time.sleep(1)
        pwm.set_pwm(i, 0, servo_max)
        time.sleep(1)

Terminalで下記のコマンドを実行します。

python3 pca9685_sample.py

そうすると、今回のテーマになっているエラーになります。

Traceback (most recent call last):
File "pca9685_smaple.py", line 17, in <module>
pwm = Adafruit_PCA9685.PCA9685(0x40)
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_PCA9685/PCA9685.py", line 74, in __init__
self._device = i2c.get_i2c_device(address, **kwargs)
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 63, in get_i2c_device
busnum = get_default_bus()
File "/home/jetson/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 55, in get_default_bus
raise RuntimeError('Could not determine default I2C bus for platform.')
RuntimeError: Could not determine default I2C bus for platform.

I2C.pyプログラムの修正(workaround)

写真のようにPCA9685のPythonパッケージにあるI2C.pyプログラムを修正します。

~/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py

 

これは、pip3 install Adafruit_PCA9685 –userでインストールした時に、インストールされたファイルです。

このプログラムで、get_default_bus()の部分が何らかの原因(これはまたじっくり調査します。先に分かった人は教えてください。)で、うまくJetson nanoのdefaultのI2Cバス番号を取得できなかったのです。

ここでは、ハードコーディングになってしまいますが、直接に、”1”と設定します。

その理由は、今回、使っているのはJetson nanoの1番のI2C バスです。

Jetson nanoのピンアウトの配置も確認できました。

 

上のPinoutの引用先はこちらです。ありがとうございます!

NVIDIA Jetson Nano J41 Header Pinout

従いまして、実際の接続に合わせて、プログラムを修正します。

def get_i2c_device(address, busnum=None, i2c_interface=None, **kwargs):
    """Return an I2C device for the specified address and on the specified bus.
    If busnum isn't specified, the default I2C bus for the platform will attempt
    to be detected.
    """
    # if busnum is None:
    #    busnum = get_default_bus()
    # return  ... busnum ...> get_default_bus
    return Device(address, "1", i2c_interface, **kwargs)

 

正常に動作しました!

上のプログラムを保存して、もう一回下記のコマンドを実行すれば、サーボは動くはずです!

python3 pca9685_sample.py

 

まとめ

いかがですか!これは、最初はなかなか意味が分からなくて、悩んでいました!

でも、流石にできないことはないですよね!一晩寝かして

今日はなんとかソリューションにたどり着けました!

皆さんもJetson nanoとPCA9685でサーボやステップモーターを動かそうとしてこのエラーに遭遇したら、この方法でやってみてください。

他のTensoFlowのセットアップや、最初の物体認識は、下記の記事をご参照ください。

Jetson nano 購入から物体認識(リンゴとミカン)までの手順

では、御機嫌よう!

はてなブックマーク - Jetson nanoとPCA9685でサーボを動かそうとするときのI2Cエラー対処法!
LINEで送る
Pocket

6 Comments

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close