Raspberry Pi 備忘録 / Mbedもあるよ!

Raspberry Pi であれこれやった事の記録

Raspberry pi でロボットアームを動かす その5 ウェブカメラと画像解析

アームの先端にWEBカメラを付けて、認識させてみる

まず、動作確認その他めのために、Displayを取得したい。

X11VNC でリモートデスクトップ

最初 xrdp でリモートデスクトップ接続していたのですが、Xlib: extension “RANDR” missing on display “:1.0” とでて、対処の仕方がわからなかったので、X11VNC に切り替えました。

画面に出ている映像を取得する感じなので、自動で xwindow まで到達させておきます。

/etc/lightdm/lightdm.conf で、ログインさせておきたいユーザーを指定。

解像度指定

/boot/config.txt frambebuffer の2行。

$ sudo apt-get install x11vnc
$ x11vnc

ポートが出るので、わかりますが、初回なら 5900 でしょう。

一旦切断?した後、再度接続する際には、

$ x11vnc

します。

x11vnc 自動起動

cat .config/autostart/x11vnc.desktop 
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=X11VNC
Comment=X11VNC
Exec=x11vnc
StartupNortify=false
Terminal=false
Hidden=false

opencv のインストール

$ sudo apt-get install libopencv-dev
$ sudo apt-get install python-opencv

opencv のテスト

適当な画像を読み込んで、処理して、x-window に window を出すテストを行う。

realvnc などで、接続しておく。

RBG を HSV に変換 & 2値化

OpenCV: Changing Colorspaces

境界線の抽出

OpenCV: Contours : Getting Started

コーディング

contour が複数ある際にどうするかですが、今回は単純に一番大きな四角だけを拾うようにしました。

#!/usr/bin/env python
# -*- coding: utf-8 -*
import sys
import cv2
import numpy as np
import pprint as pp

def main():
        image = cv2.imread('001.png')
        cv2.namedWindow("original");
        cv2.moveWindow("original", 10, 50);
        cv2.imshow('original', image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

        image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)      # HSV, range of Hue is 0-180
        #image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)        # HSV_FULL, range of Hue is 0-360
#       pp.pprint(image_hsv)

        h = image_hsv[:, :, 0]
        s = image_hsv[:, :, 1]
        v = image_hsv[:, :, 2]

        width   = h[0,:].size
        height  = h[:,0].size
        print( 'width %s, height %s' % (width, height) )

        blue_min = np.array([110, 100, 100], np.uint8)
        blue_max = np.array([140, 255, 255], np.uint8)
        threshold_blue_img = cv2.inRange(image_hsv, blue_min, blue_max)

        cv2.namedWindow("threshold_blue_img");
        cv2.moveWindow("threshold_blue_img", 10, 50);
        cv2.imshow('threshold_blue_img', threshold_blue_img)
#       cv2.imwrite("threshold_blue_img.png", threshold_blue_img); 
        cv2.waitKey(0)
        cv2.destroyAllWindows()

#       pp.pprint(threshold_blue_img)
        contours,hierarchy = cv2.findContours(threshold_blue_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#       pp.pprint(contours)

        cv2.namedWindow("contours");
        cv2.moveWindow("contours", 10, 50);
        cv2.drawContours(image, contours,-1,(0,255,0),3)
        cv2.imshow('contours', image)
#       cv2.imwrite("contours.png", image); 
        cv2.waitKey(0)
        cv2.destroyAllWindows()

        rects = []
        for contour in contours:
                approx = cv2.convexHull(contour)
                rect = cv2.boundingRect(approx) # x,y,w,h 
                rects.append(rect)  
        pp.pprint( rects )

        biggest_rect        = getBiggestRect( rects )

        center_x        = biggest_rect[0] + biggest_rect[2]/2
        center_y        = biggest_rect[1] + biggest_rect[3]/2

        image = cv2.imread('001.png')
        cv2.rectangle(image, (biggest_rect[0], biggest_rect[1]), (biggest_rect[0]+biggest_rect[2], biggest_rect[1]+biggest_rect[3]), (0, 0, 255), 1[f:id:pongsuke:20170130171525p:plain])
        cv2.line(image, (center_x, 0), (center_x, height), (0, 0, 255)) # Draw Red Line
        cv2.line(image, (0, center_y), (width, center_y), (0, 0, 255)) # Draw Red Line
        cv2.imshow('Line', image)
#       cv2.imwrite("Line.png", image); 
        cv2.moveWindow("Line", 10, 50);
        cv2.waitKey(0)
        cv2.destroyAllWindows()

def getBiggestRect( rects ):
        pre_area        = 0
        biggest_index   = 0
        for i, rect in enumerate(rects):
                area    = rect[2] * rect[3]
                if area > pre_area:
                        pre_area        = area
                        biggest_index   = i
        return rects[biggest_index]

if __name__ == '__main__':
        try:
                main()
        except KeyboardInterrupt:
                sys.exit(0)
実行結果

オリジナルの画像(風景写真に、青の丸を3つ書き込んであります。) f:id:pongsuke:20170130171525p:plain

青とそれ以外の2値化後 f:id:pongsuke:20170130171652p:plain

contours f:id:pongsuke:20170130171707p:plain

一番大きな四角を拾う f:id:pongsuke:20170130171720p:plain

opencv と ウェブカメラ

緑で2値化して、輪郭抽出して、1番大きな四角で囲みます。

#!/usr/bin/python
# coding: utf-8 

import sys
import cv2
import numpy as np
import pprint as pp

cap = cv2.VideoCapture(0)

def capture_camera():
        green_min = np.array([40, 70, 70], np.uint8)
        green_max = np.array([80, 255, 255], np.uint8)
        while True:
                ret, frame = cap.read()


                # 2値化
                image_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)      # HSV, range of Hue is 0-180
                h = image_hsv[:, :, 0]
                s = image_hsv[:, :, 1]
                v = image_hsv[:, :, 2]
                width   = h[0,:].size
                height  = h[:,0].size
#               print( 'width %s, height %s' % (width, height) )

                threshold_green_img = cv2.inRange(image_hsv, green_min, green_max)
                # 輪郭抽出
                contours, hierarchy = cv2.findContours(threshold_green_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#               pp.pprint( contours )

                cv2.drawContours(frame, contours, -1, (0,255,0), 3)

                if len(contours) > 0 :
                        rects = []
                        for contour in contours:
                                approx = cv2.convexHull(contour)
                                rect = cv2.boundingRect(approx) # x,y,w,h 
                                rects.append(rect)  
                        pp.pprint( len(rects) )
                        max_rect        = getBiggestRect( rects )
                        center_x        = max_rect[0] + max_rect[2]/2
                        center_y        = max_rect[1] + max_rect[3]/2
                        # 囲む
                        cv2.rectangle(frame, (max_rect[0], max_rect[1]), (max_rect[0]+max_rect[2], max_rect[1]+max_rect[3]), (0, 0, 255), 3)
                        # 線を引く
                        cv2.line(frame, (center_x, 0), (center_x, height), (0, 0, 255)) # Draw Red Line
                        cv2.line(frame, (0, center_y), (width, center_y), (0, 0, 255)) # Draw Red Line

                cv2.imshow('threshold_green_img', frame)

                #frameを表示
                #cv2.imshow('camera capture', frame)

                #10msecキー入力待ち
                k = cv2.waitKey(10)
                #Escキーを押されたら終了
                if k == 27:
                        break

def getBiggestRect( rects ):
        pre_area        = 0
        biggest_index   = 0
        for i, rect in enumerate(rects):
                area    = rect[2] * rect[3]
                if area > pre_area:
                        pre_area        = area
                        biggest_index   = i
        return rects[biggest_index]



if __name__ == '__main__':
        try:
                while True:
                        capture_camera()
                        break

        except KeyboardInterrupt:
                        pass

#キャプチャを終了
cap.release()
cv2.destroyAllWindows()

実行

f:id:pongsuke:20170131164039j:plain

電圧計を使ってみる & ピンプラグ給電を試す

テスターではなく、電圧計を使ってみます。

電圧計その1

まず、1つ250円のこちら。

超小型2線式LEDデジタル電圧計(パネルメータ)3桁表示 DC3〜15V(赤色)オートレンジ: 測定器・計測器関連 秋月電子通商 電子部品 ネット通販

まず、安定化電源で 3.4v をだして、電圧計をチェック。

f:id:pongsuke:20170120151616j:plain

Raspberry pi 5v を計測しました。

f:id:pongsuke:20170120154017j:plain

結構低いです。

電圧計その2

USBタイプです。

多機能USB簡易電圧・電流チェッカー(積算電流・電力・時間表示対応) RT−USBVAC3QC: 測定器・計測器関連 秋月電子通商 電子部品 ネット通販

WEBカメラを刺してみました。
これは、刺しているだけで、動作はさせていない状態です。

f:id:pongsuke:20170120154008j:plain

次に、MjewpStreamer でストリーミングしてみた。

f:id:pongsuke:20170120154020j:plain

ピンプラグ給電を試します

GPIOの 5v と GND に5vを供給して起動します。
3.3vに繋いだら、多分壊れる。

ACアダプター

5v 4A を買った。

とりあえず電圧を測定してみる。

f:id:pongsuke:20170120155631j:plain

5.2v出てます。
大丈夫かな・・・。

カメラ接続だけ。 f:id:pongsuke:20170120155636j:plain

カメラ起動中 f:id:pongsuke:20170120155639j:plain

高く与えた電圧の分、高くなっている。

Raspberry pi でロボットアームを動かす その4 接続と動作テスト

MG996R も、DS3218 も、可動域が違いますがほぼ一緒です。

PCA9685 で、60hzで全部動かしちゃいます。

150 で最小値、 600 で最大値 を取ってくれる、、、みたいです。

可動域

MG996R 120度
DS3218 180度

ちなみに、可動域を超えて動かそうとすると、すごい発熱します!

ハンドの部分は、モーターの可動域そのままは使用しません。
ハンドの可動域を超えて動こうとして壊れないように、範囲を限定して動かします。

私の場合は

min     = 250
max     = 395

です。

コーディング

ハンド以外も、パーセント指定で動かせたほうが楽かと思い、書き直しました。

#!/usr/bin/python
# coding: utf-8 

from __future__ import division
import time
import Adafruit_PCA9685

# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)

pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)

def MG996R_BASE( percent ):
        channel = 0
        min     = 150
        max     = 600
        a_percent       = (max-min)/100
        pwm.set_pwm(channel, 0, int(a_percent*percent)+min)

def DS3218_LEAN_UNDER( percent ):
        percent = 100 - percent
        channel = 1
        min     = 250
        max     = 500
        a_percent       = (max-min)/100
        pwm.set_pwm(channel, 0, int(a_percent*percent)+min)

def MG996R_LEAN_UPPER( percent ):
        channel = 2
        min     = 150
        max     = 500
        a_percent       = (max-min)/100
        pwm.set_pwm(channel, 0, int(a_percent*percent)+min)

def MG996R_WRIST( percent ):
        channel = 3
        min     = 150
        max     = 600
        a_percent       = (max-min)/100
        pwm.set_pwm(channel, 0, int(a_percent*percent)+min)

def MG996R_HAND( percent ):
        channel = 4
        min     = 250
        max     = 395
        a_percent       = (max-min)/100
        pwm.set_pwm(channel, 0, int(a_percent*percent)+min)

def calibration():
        MG996R_BASE(0)
        time.sleep(1)
        MG996R_BASE(50)
        time.sleep(1)
        MG996R_BASE(100)
        time.sleep(1)
        MG996R_BASE(50)
        time.sleep(1)

        DS3218_LEAN_UNDER(0)
        time.sleep(1)
        DS3218_LEAN_UNDER(50)
        time.sleep(1)
        DS3218_LEAN_UNDER(100)
        time.sleep(1)
        DS3218_LEAN_UNDER(50)
        time.sleep(1)

        MG996R_LEAN_UPPER(0)
        time.sleep(1)
        MG996R_LEAN_UPPER(50)
        time.sleep(1)
        MG996R_LEAN_UPPER(100)
        time.sleep(1)
        MG996R_LEAN_UPPER(10)
        time.sleep(1)

        MG996R_WRIST(0)
        time.sleep(1)
        MG996R_WRIST(50)
        time.sleep(1)
        MG996R_WRIST(100)
        time.sleep(1)
        MG996R_WRIST(50)
        time.sleep(1)

        MG996R_HAND( 5 )
        time.sleep(1)
        MG996R_HAND( 95 )
        time.sleep(1)

def move01():
        MG996R_HAND(80)
        time.sleep(1)
        MG996R_HAND(0)
        time.sleep(1)
        DS3218_LEAN_UNDER(20)
        time.sleep(1)
        MG996R_BASE(40)
        time.sleep(1)
        MG996R_BASE(48)
        time.sleep(1)
        MG996R_LEAN_UPPER(10)
        time.sleep(1)
        MG996R_LEAN_UPPER(18)
        time.sleep(1)

        time.sleep(2)

        for var in range(0, 4):
                MG996R_HAND(10)
                time.sleep(0.5)
                MG996R_HAND(90)
                time.sleep(0.5)

if __name__ == '__main__':
        try:
                while True:
                        #calibration()
                        move01()
                        break

        except KeyboardInterrupt:
                pass

MG996R_BASE(50)                 # 旋回
time.sleep(0.5)
DS3218_LEAN_UNDER(80)   # 傾斜・下
time.sleep(0.5)
MG996R_LEAN_UPPER(10)   # 傾斜・上
time.sleep(0.5)
MG996R_WRIST(50)                #ハンド回転
time.sleep(0.5)
MG996R_HAND( 50 )               # ハンド開閉
time.sleep(0.5)
print("END.\n")

電源の交換

それぞれ独立して動かす分には、6V 2A で足りることがわかったので、別途用意した ACアダプター(6V 2.8A)を使用することにしました。

動作も問題無さそうです。

以下の2つを使用しました。

スイッチングACアダプター6V2.8A 100V〜240V GF18−US0628−T: 電源一般 秋月電子通商 電子部品 ネット通販

2.1mm標準DCジャック⇔小型ねじ端子台(着脱可能): パーツ一般 秋月電子通商 電子部品 ネット通販

f:id:pongsuke:20170117124453j:plain

Raspberry pi でロボットアームを動かす その3 PCA9685

I2C接続16チャンネル サーボ&PWM駆動キット PCA9685 を試す

はんだ付け

先にPINを付けてから、電源のターミナルをつける。
そうしないと、裏返した際に傾いて、はんだ付けしにくい。

配線

SCL - RPI GPIO3
SDA - RPI GPIO2
GND - RPI GND
Vcc - RPI 5v

I2C を有効にする

raspi-config から行う。

動作確認

$ sudo i2cdetect -y 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 -- -- -- -- -- -- -- 

Adafruitのライブラリとサンプルを使う。

$ git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
$ cd Adafruit_Python_PCA9685
$ sudo python setup.py install

サンプルスクリプトを書き換える。

0と1に繋いであります。

$ cat PCA9685.py 
#!/usr/bin/python
# coding: utf-8 

from __future__ import division
import time
import Adafruit_PCA9685

# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)

pwm = Adafruit_PCA9685.PCA9685()

def set_servo_pulse(channel, pulse):
        pulse_length = 1000000    # 1,000,000 us per second
        pulse_length //= 50       # 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 /= pulse_length
        print "%d pulse" % pulse
        pwm.set_pwm(channel, 0, int(pulse))

pwm_set = [800, 1200]

if __name__ == '__main__':
        try:
                while True:
                        channel = 0
                        set_servo_pulse(channel, pwm_set[0])
                        time.sleep(1)
                        set_servo_pulse(channel, pwm_set[1])
                        time.sleep(1)

                        channel = 1
                        set_servo_pulse(channel, pwm_set[0])
                        time.sleep(1)
                        set_servo_pulse(channel, pwm_set[1])
                        time.sleep(1)

        except KeyboardInterrupt:
                pass

スクリプトその2

モーターの仕様に合わせて、50hzにしたり、DUty比を計算して値を当ててみたりしたんですが、どうも、PCA9685 と、Adafruitさんのドライバにおいては、サンプルに有るように、 60hz, 150最小, 600最大 で組んでしまったほうが良さそうです。

ドライバの詳細を読み込めば、分かるのかもしれませんが、現在の結論は、そうなってしまった。

$ cat PCA9685.py 
#!/usr/bin/python
# coding: utf-8 

from __future__ import division
import time
import Adafruit_PCA9685

# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)

pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)

if __name__ == '__main__':
        try:
                while True:
                        channel = 0
                        pwm.set_pwm(channel, 0, 150)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 375)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 600)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 375)
                        time.sleep(1)

                        channel = 1
                        pwm.set_pwm(channel, 0, 150)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 375)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 600)
                        time.sleep(1)
                        pwm.set_pwm(channel, 0, 375)
                        time.sleep(1)


        except KeyboardInterrupt:
                pass

pwm.set_pwm(0, 0, 375)
time.sleep(1)
pwm.set_pwm(1, 0, 375)
time.sleep(1)
print("END.\n")

モーターをゼロポジションにする

上記のスクリプトで、とにかく 375 で終了にさせておく。

ただし、下から3つ目のサーボモーターは、設計図のままだと、可動域の中央ではない。
上を向かせて組まないといけない。

アームを組み上げる

これの、1:19 あたりから5軸の組み立て方が出ます。
最初は3軸用なので注意。

www.youtube.com

注意点!

1.ネジとホーンの種類

サーボモーターと一緒に入っているネジとホーン(5袋)は使用しません。

別の袋に入っている、金属のホーンと、その復路に貼っているネジで組み上げます。

2. ネジの長さが長すぎる とくに、ハンドの部分。
ホーンの厚みよりもネジが長いので、当たっちゃいます。
ペンチでカットしました。

3. ハンドの可動域 120度全て動かせません。(開きすぎちゃう)
渡しの場合は、DUry比で50%で組合上げて、色々ずれて? 結局、

min = 250
max = 395

と成りました。

min で閉じて、 max で開き切ります。

なので、それ以上、それ以下にならないようにコーディングします。

f:id:pongsuke:20170116161417j:plain

f:id:pongsuke:20170116161437j:plain

f:id:pongsuke:20170116161443j:plain

Raspberry pi でロボットアームを動かす その2

モーターの動作確認

MG996R の動作確認

6v 1A に設定した安定化電源から給電しました。

f:id:pongsuke:20170106111203p:plain

配線は、上記の通り。
周波数も、上記の通り 50hz です。

$ cat MG996R.py 
#!/usr/bin/python
# coding: utf-8 

import RPi.GPIO as GPIO
import time
import sys 

# GPIO 21番を使用
PIN = 21

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.OUT)
servo = GPIO.PWM(PIN, 50)       # GPIO.PWM(PIN, [周波数(Hz)])

val = [2.5,3.6875,4.875,6.0625,7.25,8.4375,9.625,10.8125,12]

if __name__ == '__main__':
        try:
                servo.start(0.0)

                servo.ChangeDutyCycle(val[0])
                time.sleep(0.5)
                servo.ChangeDutyCycle(val[8])
                time.sleep(0.5)
                servo.ChangeDutyCycle(val[0])
                time.sleep(0.5)

                while True:
                        for i, dc in enumerate(val):
                                servo.ChangeDutyCycle(dc)
                                print("Angle:" + str(i*22.5)+"  dc = %.4f" % dc) 
                                time.sleep(0.5)
                        for i, dc in enumerate( reversed(val) ):
                                servo.ChangeDutyCycle(dc)
                                print("Angle:" + str(180 - i*22.5)+"  dc = %.4f" % dc) 
                                time.sleep(0.5)

        except KeyboardInterrupt:
                pass

servo.ChangeDutyCycle(val[4])
time.sleep(1.5)
servo.stop()
GPIO.cleanup()

DS3218

安定化電源(6v, 1A設定)につないで、RPIからPWMを送るのですが、どうもピクピクしてしまう。

試しに RPI 5v から給電した所、正常に動いた。

ただし、電圧低下のシグナルが出るので、このままでは良くない。

しばらく原因がわからなかったのですが、どうも、ただのアンペア不足だったようです。2A出すようにしたら、正常に動き始めました。

流す電流も大きくなってきたので、PCA9685 を入れることにしました。

Raspberry pi でロボットアームを動かす その1

ロボットアームを動かしてみたい。

色々とロボットアームを検討したのですが、最終的に、これを日本のAmazonで買った。

f:id:pongsuke:20170106105927j:plain

5軸だ。

www.sainsmart.com

使用するモーター

4 x 9kg servo = Tower Pro, MG996R 55g metal gear servo * 4
1 x 20kg servo = DS3218

だ。

MG996R

データシート曰く、

Specifications
 Weight: 55 g
 Dimension: 40.7 x 19.7 x 42.9 mm approx.
 Stall torque: 9.4 kgf・cm (4.8 V ), 11 kgf・cm (6 V)
 Operating speed: 0.17 s/60o (4.8 V), 0.14 s/60o (6 V)
 Operating voltage: 4.8 V a 7.2 V
 Running Current 500 mA - 900 mA (6V)
 Stall Current 2.5 A (6V)
 Dead band width: 5 μs
 Stable and shock proof double ball bearing design
 Temperature range: 0 oC - 55 oC

1.0Aは見ておいたほうが良いのだろう。
同時に複数箇所動かすのは、電流が足りなくなりそう。

f:id:pongsuke:20170106111203p:plain

DS3218

データシートが見つからないが、下記のサイトが詳しい。
消える前に引用しておく。

LD-1501MG 17KGロボット用180度高トルクデジタルサーボ セール - バングッド

Specifications:
- Weight: 60g
- Size: 40*20*40.5mm
- Speed: 0.16sec/60 7.4V
- Nm: 15kg/cm 6V ; 17kg/cm 7.4V
- Work voltage: 6-7.4V
- Cable length: 30cm
- Accessories includes plastic servo horm and servo arm, screws, rubber sleeve, etc
Rotation Angle: maximum 180 degree

Instruction:
PWM pulse width adjustment angle, the period is 20ms, duty cycle 0.5ms~2.5ms of the pulse width level corresponding to 0 degree -180 degree, that is a linear relationship. Usually the servo actuator controller uses 500-2500 value corresponding to the servo control of the output angle of the duty ratio of 0.5ms~2.5ms, so that the control accuracy of the LD-1501MG servo is 3us, the minimum control accuracy can reach 0.3 degrees within the 2000 pulse width!

20ms周期 = 50hz

  0度 = 0,5ms = 0.5/20 = 2.5%
180度 = 2.0ms =  2/20 = 10.0%

電流に関して

MG996R 6v, DS3218 6v で良さそうだ。

USB 5v で完結すると理想的だ。

USB 5v を 6b に昇圧させれば良いんだろうとは思うが、そもそも、USBには 5v 2.5A 程度が最大だ。
どのみち1つのUSBでは動かせないだろう・・・。

DC-DCコンバーター も視野に入れつつ、とりあえずは、手元にある 2.5A までの安定化電源でテストしようと思う。