2021年2月28日日曜日

USB PD対応充電器から12Vを取るケーブルを作ってみた

 AliexpressでUSB PDの充電器から任意の電圧が取れるアダプタが売っていたので買ってみた。USB PD Decoyとかいうやつ。

メスタイプのものは安くたくさん出てるんだけど、メスタイプだとUSB PDケーブルが必要なので充電器に直接させるようにオスタイプのものを購入してみた。
電源を取り出すためのパッドは裏側に用意されている。

抵抗を取り外したりジャンパーしたりするだけで5V,9V,12V,20Vが取り出せる模様。
まぁ充電器側もほしい電圧に対応してる必要があるけど…

デフォルトで20Vだったので抵抗を一個取り外して12Vにしてみた。
1005の抵抗だったので斜めカットC2.0の小手先でサクッと取れた。

あとは余っていた5.5/2.1なDCジャック付きのケーブルをハンダして完成。これでUSB PDの充電器から12Vが取れる!
この前作った3.5インチHDDをつなぐアダプタとかもこれで使えるから便利だな。USB PD充電器は65Wのものをもっているので12Vだと3A取り出せるので便利だなぁ。



2021年2月17日水曜日

USB Type Cなメス端子基板を購入してみた

 Aliexpressを見ていたらUSB2.0デバイスをUSB Type C端子化できそうなメス端子が乗った基板が出ていたのでつい購入してしまった。
まぁ最近そこそこ見かけるUSB 2.0に必要な端子だけが結線されたType C端子が乗った小基板である。

JRC-B008
基板にはJRC-B008って言う刻印があって反対側には5VとD- D+ GNDのパッドがある。
R1って書かれた1005用のパッドがあるけどCC1とCC2が繋がれていてもう一方はGNDになっている。
今回はデバイス側にこの端子を使用するのを想定しているのでCC1とCC2はどっちも5.1kΩでプルダウンするのがUSB Type Cの規格的に良いんだけれども、CC1とCC2がまとめられているのはホスト側によってはラズパイ4の初期型で問題になったようにオーディオモードと誤認識してしまう場合がありそう…

USB Type A→USB Type Cのケーブルを使って使用する場合は特に問題が出ないけど、USB Type C同士のケーブルを使用する際はこのままだとうまく動かない場合もありそうなので改造することにした。
改造内容としてはCC1とCC2を切り離して、どっちも5.1kΩの抵抗でプルダウンすれば良いことになる。この基盤の場合はJRC-B008っていうシルクがある面(プルダウン抵抗をつけられる面)のCC1がR1につながっているところのパターンをカットすれば簡単に対応できそうということでそれで対応することにした。抵抗は1608のほうがGNDパターンにわたすにはいい感じ。

片方1608でもう片方を既存の1005のパッドにハンダすると抵抗が二種類必要なので無理やり1608を2つ実装してみた。
とりあえずこれでUSB Type Cのケーブルでつないでもデバイス側として認識するはず…

ひと手間改造が必要だけど1個30円っていう価格ならいい感じな気がする。

2021年2月6日土曜日

nRF52840にブートローダーを書き込んでみた

 というわけで先月購入したnRF52840モジュールにこの前作ったBlack Magic ProbeでArduinoで使用するためのブートローダーを書き込んでみた。

今回はnRF52をArduinoで使用するためのAdafruit_nRF52_Bootloaderをした。このブートローダを書き込むとnRF52をUSBに接続するとUSB CDCのCOMポートとマスストレージデバイス(UF2)として認識されるので色々便利。

まずはnRF52840モジュールに直接ケーブルをはんだ付けしてUSBに接続できるようにした。

とりあえずUSBにつながればいいので、VBUS、D+、D-、GND、VDDにケーブルをはんだ付け。VBUSはUSBの5Vに直結してるけど、VDDはレギュレータ(ADP151AUJZ-3.3)を介して3.3Vを供給してる。

ちなみにこのままUSBにつないでもUSBデバイスとしてちゃんと認識されない。
ブートローダーを書き込むためにさらにBlack Magic ProbeをSWCとSWDに接続する。とりあえずブートローダ書き込んだらデバッグ端子は使わないだろうということで今回はグラバークリップで接続した。

そんでもってnRF52モジュールに電源を入れつつBlack Magic ProbeをUSBに接続。
GNU Arm Embedded Toolchainをインストールしてコマンドプロンプトでインストールしたディレクトリまで移動してarm-none-eabi-gdb.exeを起動。
Black Magic ProbeはCDCのCOMポートとして2ポート認識してるはずなのでどちらか片方がGDPでもう片方がデバッグ用のUARTのはずなんだけど、この環境では若いCOM番号がGDPでCOM11だった。環境によって変わるはず。
target extended-remote \\.\COM11
でCOM11に接続。\\.\はCOMポート番号が2桁以上に対応するために必要…
monitor swdp_scan
でSWDに接続されたマイコン一覧が出るはず。ここで一覧に出なかったら接続が間違ってるかも?
とりあえずNordic nRF52 M4が出ていたので
attach 1
で接続する。
あとはファームウェアを書き込むだけなので、パス入れるのが面倒なのでarm-none-eabi-gdb.exeと同じディレクトリにAdafruit_nRF52_BootloaderからAdafruit Feather nRF52840 Express用のファームウェアをダウンロードして入れてロードしてみた。
load feather_nrf52840_express_bootloader-0.4.0_s140_6.1.1.hex
のように指定するとファームを書き込める。
あとはquitでyを押して終了してUSBに指し直すとCOMポートとUSBマスストレージデバイスとして認識するはず。USBマスストレージデバイスとして認識したらINFO_UF2.TXTの中身を見ればブートローダーのバージョンとかが見れる。ブートローダは32.768kHzの外付けクリスタルを付けなくても動いた。

とりあえずこれでArduinoで開発する準備ができた。
ちなみにVBUSをちゃんと繋がないとUSBデバイスとしてちゃんと認識しないのね…(ちょっとはまった。)
ブートローダ書き込むだけならやっぱりBlack Magic Probe安く作れていいな。


2021年1月23日土曜日

BluepillをBlack Magic Probeにしてみた

 nRF52840にどうやってファームウェアを焼くか探していたら、Black Magic ProbeというオープンソースのSWDデバッガがあるらしいということがわかった。
STLink V2の互換品やSTM32F103搭載のマイコンボードの通称Bluepillにファームウェアを焼くだけで使えるらしい。
Black Magic Probeのファームが焼かれている製品も売っていてSegger J-linkより安いのでこうやってArduinoのブートローダーを焼くだけの目的にはいいかも?

というわけで早速手持ちのBluepillをBlack Magic Probe化してみることに。

ファームウェアはgithubからStable release v1.7.1をダウンロードしてきて使用することに。

このファームウェアを解答すると複数のbinファイルが入っているけど、今回はBluepillを使用するのでswlinkを使用することに。swlink用ファームはBluepillに最初からはんだ付けされているSWDポートをそのまま利用できるので、Bluepillにピンヘッダをハンダしなくてもこのファームを書くだけでそのままBlack Magic Probeとして使える。

というわけでまずはBluepillにblackmagic_dfu-swlink.binを書き込む。書き込み手順は過去にBluepillにArduino用のブートローダーを書き込んだときと同じなのでそちらを参照。
ピンヘッダを実装していないBluepillにICクリップでUSB TTL変換基板をつないで書き込んだ。

DFUファームウェアを書き込んだBluepillのジャンパピンをどちらも0に戻してUSBでPCBに接続するとDFUモードで認識されるので今度はZadigを使用してドライバをインストールする。

ちなみにBluepillの緑色LEDが点滅しているときがDFUモード。

Zadigを起動したらOptionsを開いてList All Devicesを選択。
するとリストにBlack Magic (Upgrade), SWLINKがでるのでそれを選択して、ドライバの種類はlibusbKを選択してReplace Driverボタンを押す。
するとドライバがインストールされてDFUモードでファームウェアを書き込めるようになる。

次にDFUモードでBlack Magic Probeのファームウェアを書き込むためにdfu-utilをダウンロードしてくる。今回はdfu-util-0.9-win64を使用した。
コマンドが面倒なのでblackmagic-swlink.binをdfu-util.exeと同じディレクトリに突っ込んでコマンドプロンプトでdfu-util.exeのディレクトリに移動。

dfu-util -d 1d50:6018,:6017 -s 0x08002000:leave -D blackmagic-swlink.bin

を実行するとBlack Magic Probeのファームウェアが書き込まれる。

書き込まれたあとはBluepillのLEDが薄く点灯するはず。これでBlack Magic Probeの準備は完了。USBで接続するとCDC COMポートが2ポート認識し、BluepillのSWDピンヘッダ(GND、CLK、DIO、3.3V)をSWDデバッガとして使用することが可能になった。
GNU Arm Embedded Toolchainから使用できる。


2021年1月17日日曜日

nRF52840モジュールを買ってみた

 ArduinoでNordicのnRF52840が開発できることを知ってちょっと気になったのでAliexpressで調べていたらEBYTEのE73-2G4M08S1Cってのが安かったので購入してみた。技適付きならMinewのMS88SF2あたりも良さげだったんだけどとりあえずお試しなので例の申請をしてみようかなと一番安いやつを…

やはり例のマークはない。チップアンテナなのに安いなぁ

シールド付き。思ったより小さかった。
裏面のシルクがなにげに便利。内側にも端子があるので基板にはリフロー実装かねぇ
結構小さいので全部のIO出すのに苦労したんだろうな…

一応ブレークアウト基板も何種類か出ているようで、BlueMicro840とかだとArduino Pro Microとコンパチとか(キーボード用?)、nRFMicroとかも小さくて良さそう。

とりあえず試しにSWDが使えるInfinionのライタとかST-Link V2のJ-Link化でSegger Flasher上でnRF5を選んで見たりしたけどどうやら使えなさそうなことがわかった…
まぁ例の申請がOK出るまでにブートローダーをどうやって書くかを調べておこうかな…

2021年1月8日金曜日

Pythonでルンバを操作してみた。

 ルンバ980でもROIが使えるらしいことがわかったので久しぶりにルンバで遊んでみることに。

980のROIポートはダスト容器取り外しボタンの右側のパーツを上に引っ張ると現れる。こんなところについていたのか…770のときはminiDIN 7Pが取っ手の下についていたけど。ちなみに980はmicroUSBになっている。

microUSB端子にケーブルを指してPCとつなぐとUSBシリアルデバイスとして自動でドライバがインストールされた。(インターネットに繋がっていればWindows Update経由で自動で入るらしい)

コマンドは昔と変わっていないらしいので550のROIの資料を確認しながらとりあえず前後左右に動けるようなものを作ってみた。pyserialを使用しているので入ってない場合はpip install pyserialでインストール必要かも。

import tkinter as tk
from tkinter import messagebox
import tkinter.ttk as ttk
import struct
import serial
from serial.tools import list_ports
import time

after_id = None


        
def busConnect():
    global bus,ser
    ser = serial.Serial()
    ser.baudrate = 115200
    ser.timeout = 0.1       # タイムアウトの時間
    ser.port = bus
    ser.open()
    #print("open " + ser.port )
    initdata = [128, 131] #start,safe mode
    ser.write(bytes(initdata))
    
    return 1

def busDisconnect():
    global bus,ser
    ser.close()
    ser = None
    
def busButton(event):
    global bus,ser
    if ser is None:
        result = busConnect()
        if result == 1:
            buttonBus.config(text = "切断")
    else:
        busDisconnect()
        buttonBus.config(text = "接続")
        
def PortSelected(event):
    global bus
    bus = PortList.get()
    buttonBus.config(state="normal")
        
def roombaMove(left,right):#モータのPWM値を±255で指定
    global ser
    senddata = [146,((right & 0xFF00) >> 8),(right & 0xFF),((left & 0xFF00) >> 8),(left & 0xFF)] 
    if ser.is_open:
        ser.write(bytes(senddata))
        print(bytes(senddata))

def buttonPress(right,left):
    roombaMove(right*var_scale.get(),left*var_scale.get())
    
def key_event(event):
    key = event.keysym
    if key == "w":
        right = 1
        left = 1
    if key == "s":
        right = -1
        left = -1
    if key == "a":
        right = -1
        left = 1
    if key == "d":
        right = 1
        left = -1
    roombaMove(right*var_scale.get(),left*var_scale.get())
    
def key_stop(event):
    roombaMove(0,0)

bus = None
ser = None

ports = list_ports.comports()    # ポートデータを取得
devices = [info.device for info in ports]

root = tk.Tk()
root.title("Roombaテストするやつ Ver0.1β")
root.geometry("300x300")
root.option_add('*font', 'FixedSys 14')

ComPort = tk.Label(text='Port:')
ComPort.place(x=20, y=20)

#コンボボックスを設置
PortList = ttk.Combobox(root, values = devices,width=10,state='readonly')
PortList.set('Select')
PortList.place(x=80, y=20)
PortList.bind("<<ComboboxSelected>>", PortSelected)

# ボタンの追加
buttonBus = tk.Button(text='接続', width=6,state="disable")
buttonBus.place(x=200, y=15)
buttonBus.bind('<ButtonRelease-1>', busButton)

buttonF = tk.Button(text='↑', width=6, command = lambda: buttonPress(1,1))
buttonF.place(x=100, y=80)
buttonS = tk.Button(text='STOP', width=6, command = lambda: buttonPress(0,0))
buttonS.place(x=100, y=120)
buttonB = tk.Button(text='↓', width=6, command = lambda: buttonPress(-1,-1))
buttonB.place(x=100, y=160)
buttonL = tk.Button(text='←', width=6, command = lambda: buttonPress(-1,1))
buttonL.place(x=30, y=120)
buttonR = tk.Button(text='→', width=6, command = lambda: buttonPress(1,-1))
buttonR.place(x=170, y=120)

var_scale = tk.IntVar()
scale = ttk.Scale(root, from_=30, to=255, variable=var_scale)
scale.place(x=80, y=220)
labelScale = tk.Label(text='Speed')
labelScale.place(x=100, y=250)

root.bind("<KeyPress>", key_event)
root.bind("<KeyRelease>", key_stop)

root.mainloop()

とりあえずWASDを使ってキーボードでも動かせるようにしてみた。ちょっとそこら辺の実装がテキトーなので一旦キーを離してから他のボタンを押さないとちょっとおかしな動作になる。今回はテストなので治すのが面倒だからいいや…

あとはスピードのスライドバーを多少動かさないと動かないかも。ルンバを通常モードに戻す場合は持ち上げればいいっぽい。(車輪にスイッチが付いている?)

USBになったことによってESP32とかのマイコンに直結するのはちょっとやりにくくなったかもしれない。miniDINのときは電源も取れたし。

2021年1月3日日曜日

VL716なSATA USB3.0変換基板を12V対応化してみた。

 年末の掃除で結構3.5インチなHDDが出てきたんだけど中身を確認するのが面倒なので放置していた…
もっとかんたんに中身を確認できたら確認するのに!ってことで2.5インチSSD用に使っていたVL716なSATA USB変換基板を改造してみた。

3.5インチドライブにつなぐためのケーブルも作ったんだけどなんか出すのが面倒で…
3.5インチのHDDは12Vが必要なんだけど、この手のUSB給電タイプの変換基板はもちろん5Vしか存在しないわけで…

ということで単純に12VのACアダプタをそのままさせるようにしてみた。これなら手軽に使える…はず…

というわけで用意するものは5.5mmジャックと適当なジャンパだけ。もともとこの基板には5V給電用の端子を実装するところがあるのでそこの一部の穴を利用して固定することに。
穴に入るように端子のGND側を削る。あと他の端子をカット。

端子がジャンパ抵抗とかに当たるので厚手の両面テープをカットして貼り付け。
部品の部分は逃しておいた。
あとはちょっと太めのダイオードの足でSATA電源の12Vと電源端子のプラス側をつなぐだけ。
一応これでも結構しっかり固定されてるけど、念の為接着しておこうかなぁ

とりあえずこれですげー便利に使えるようになった。
あまり古いHDDだと5V結構食うので注意だけどね…
本当は5Vラインで12Vラインをオン・オフできるようにロードスイッチとかつけたほうがいいんだろうけど動いたのでいいや。自己責任だけど。