2018年1月27日土曜日

FTDIのFT232RLでESP8266に自動書き込みしてみた。

ESP-WROOM-02に書き込んでテストしているとBOOTボタンとリセットボタンを押すのが面倒になってきたのでFTDIのFT232RLを使用して自動で書き込みできるようにしてみた。
USBシリアルが内蔵されている開発ボードとかだと普通に入っていたりするんだけど、USBシリアル変換基板を眺めていたら裏面にそのまま実装できてしまうんじゃないかと思ったのでやってみた。
USBシリアル変換基板は何種類か持っていたんだけど、DTRとRSTが出せて、3Mbpsに対応したのがFT232RLだったので、こいつを改造することに。
Silicon LabsのCP2102は1Mbpsまでだし…
CP2102Nに張り替えれば3Mbpsまで行けるけど。
基本的にこの手のモジュールは書き込み機が内蔵されていないArduino Pro Mini 328用のピン配列になっているので、DTRしか出ていない。なのでRSTはコントローラーICに直結して出さないといけない。

改造に必要なのは10kΩの抵抗2つとNPNトランジスタ2つだけ。RTS(FT232RL側)とRST(ESPのリセット)紛らわしかったかな…
ついでに3.3V電源も強化するように600mAまで流せる3.3Vレギュレータも内蔵することに。
ESP-WROOM-02はUSBシリアル変換ICに内蔵されてるLDOだけだと駆動できないし…

今回改造に使用するUSBシリアル変換アダプタはDTRとCTSが出ている6ピンのタイプ。
このモジュールは3.3V仕様に変更できるタイプだったのでUARTの信号レベルが3.3Vになるように3.3V仕様に変更した。(5Vのパッドにつながってるところをカットして3.3Vのパッドにジャンパする)

さらにDTRとCTSとVCCのピンヘッダにつながってるパターンをカットして、それぞれResetとIO0と3.3Vのレギュレータの出力をつなぐだけ。全部裏面に実装してみた。

チップ抵抗(なんかの基板から剥がした小さいやつ)と適当なSOT-23のトランジスタを使用したのでとても小さく仕上がった。
ちょうど裏側に5Vと3.3Vの切り替えのジャンパが来ていたのでレギュレータの電源はそこから頂戴することに。GNDベタになっていたのでレジスト剥がせばどこからでもGND取れるし…

DTRはもともと出ていたパターンを切って横取り。RTSは出ていなかったのでピンから直接頂戴した。

ESP-WROOM-02の基板側も改造してリセット端子とIO0に接続できるようにした。
これでESP-WROOM-02に書き込むときは自動でリセットされて書き込みモードに入るようになったので便利だ。そして3Mbps書き込みめっちゃ早い。

2018年1月5日金曜日

ニンテンドースイッチでキーボードとマウスを使う

前回Coov N100でオプションのCoov HUB K4を購入すればキーボードとマウスが使えるという話をしましたが、友人用に代理購入してみた。
スイッチはもともとキーボードを文字入力用とかには使えるみたいだけど、このアダプタを使ってつなぐとゲームの操作に使用できるようになる。
今回も使い方を教えるためと、動作確認のために開封させていただいた。

Coov N100は結構小さい箱だったので潰れたりしてなかったけど、HUB K4はちょっと端っこのほうが破れてた…
eBayで購入して1週間で届いたのですごく速い方だと思う。

箱を開けるとこんな感じ。


付属品はちょっと特殊なケーブルのみ。長さは1mちょいあるかも。

見た目はほんとに普通のハブ。単純にN100の方でVIDとPID読んで認識してるだけで普通のハブなんじゃないかなというぐらい。
PCにつなぐと普通のUSB2.0の汎用ハブとして認識する。VIDは1A40でPIDは0101だった。

Coov N100とは付属のケーブルで接続するとこうなる。

HUB K4自体はminiUSBなのでmicroUSB端子は余る。N100の説明書には不使用と書いてあったが、COOV N200との接続用かも知れない。
OTGケーブルとしても使えるかも?

HUB K4はN100のファームウェアがV3.0以上なら使えるっぽいけど、V4.0が出たということでN100のファームウェアをアップデートしておいた。

V4.0からはAndroidアプリでマウス変換時のパラメータをいじれる様になっりDS4の新しいやつに対応したりしてるっぽい?

USBキーボードとマウスを設定するために適当なコントローラが必要なのでXbox Oneコントローラを使用した。

N100のファームウェアはV3.0以上が必要。
そしてUSBキーボードとマウス設定用に適当なコントローラが必要っぽい。
例によって本体設定のProコントローラの有線接続はオンになってないと動きません。

今回はXbox Oneコントローラを使用したのでボタン配置もXbox One用で説明するので別なコントローラを使って設定する際は読み替えてください。
 1.キーマップモードに入るためにXboxボタンとBボタンを同時押し。
 2.キーボード、マウスの割り当てたいボタンを押す。
 3.Xboxコントローラで割当先のボタンを押す。
 4.ホームボタンを押すとマップモード終了。
でとりあえずはキーマップできる。
更にキーマップはキー入れ替えのときと同様に続けて登録することもできる。
例えばProコンで言う、Aボタンを右クリック、Bボタンを左クリックにしたい場合は
Xboxボタン+B
右クリック→Bボタン(XboxコンのBボタンはプロコンで言うAボタン)
左クリック→Aボタン
Xboxボタン
という順番に押せば良い。

マウスの動きをスティックに割り当てたいときもマップモードに入ってから
マウスをちょっとだけ右に動かす→スティックを右に倒す
みたいな感じで登録できる。

今回使用したDeathAdder 3500の場合はサイドボタンも割り当てることができた。
ココらへんはマウスによるかも。


実機がないから試せないんだけど、この機能はXbox OneやPS4でも使えるらしい。その場合は純正コンを認証用に繋ぐ必要があるようだけど。
N100とHUB K4はeBayで買うと合わせて2400円ぐらいなので、Cross Hair converterとかXIM4とかより断然安い。機能とかはちょっと違うだろうけど。

PCゲーマーでどうしてもコントローラでの操作になれない人にはよいかもしれない。
マウサーとかいうハードウェアチートになるかもしれないので使用時は注意かも。
結構ジャイロ使ってる人のほうが強そうな気もしたり…
何にせよ任天堂認定ハードではないので注意が必要かもです。


2018年1月3日水曜日

DiscordのTTS BotをAITalkで喋らせてみた

先日Discord用のTTS(Text to Speach)ボットをPythonとOpen JTalkで作ってみたんだけど、Docomoが音声合成APIを公開しているっぽいので今度はDocomoの音声合成APIに対応させてみた。

Docomoの音声合成APIは数種類提供されているようだけど、今回はAIのAITalkを使ってみた。VOICEROIDにも使われているエンジンなので聞き馴染みがあるかも。
そして声の種類が11種類なのでユーザーごとに違う声を割り振ることによりゲーム中でも誰が発言しているかがわかる!

今回はDocomoのAPIを利用してインターネット経由で音声合成データを取得するので、docomo Developer supportに登録して、音声合成のAPI_KEYを取得しておく。

なんかDiscordのTTSボット以外にも使えそうだったのでAITalk部分は別ファイルにしてみた。

とりあえずDocomo APIを叩いて音声合成データを取得する部分を作ってみた。
ただしAPIから戻ってくる音声データがリニアPCM,1ch,16000サンプル,16bit(ビッグエンディアン)なのでそのまま再生できない…
ということでWAVEデータに変換する部分も同じPythonプログラム内でやることに。

WAVEデータにするやりかたとしてはビッグエンディアン→リトルエンディアンに変換
PythonのWaveモジュールを使ってWAVEのヘッダを追加
という形にしてみた。Pythonの標準モジュールだけでできたのでよかった。

#coding: utf-8
import array
import subprocess
import requests
import wave
import re
import io

def aitalk(text,speaker):
    API_KEY = 'APIキーを入れる'
    url = "https://api.apigw.smt.docomo.ne.jp/aiTalk/v1/textToSpeech?APIKEY="+API_KEY


    speakerlist = ['nozomi','seiji','akari','anzu','hiroshi','kaho', 'koutarou','maki','nanako','osamu','sumire']
    if 0 <= speaker <= 10:
        print(speakerlist[speaker])
    else:
        speaker = 10

    character = {
    'speaker' : speakerlist[speaker],
    'pitch' : '1',
    'range' : '1',
    'rate' : '1.1',
    'volume' : '2'
    }

    xml = u'<?xml version="1.0" encoding="utf-8" ?>'
    voice = '<voice name="' + character["speaker"] + '">'
    prosody = '<prosody rate="'+ character['rate'] +'" pitch="'+ character['pitch'] +'" range="'+ character['range'] +'">'
    xml += '<speak version="1.1">'+ voice + prosody + text + '</prosody></voice></speak>'
    xml = xml.encode("UTF-8")
    print("Connecting API")
    response = requests.post(
    url,
    data=xml,
    headers={
    'Content-Type': 'application/ssml+xml',
    'Accept' : 'audio/L16',
    'Content-Length' : str(len(xml))
    }
    )

    if response.status_code != 200 :
        print("Error Connecting API : " + response.status_code)
        exit()
    else :
        print("API Connection Success")

    lend = array.array('h',response.content)
    lend.byteswap()
    wav_buffer = io.BytesIO()
    with wave.open(wav_buffer, 'wb') as wavfile:
        wavfile.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wavfile.writeframes(lend)
        wavfile.close()
    return wav_buffer.getvalue()


使い方は上のソースコードをaitalk.pyとして保存して
API_KEYのところに自分で取得したAPIキーを入力して
メインのプログラムにimport aitalkして
wav_buffer = aitalk.aitalk(音声合成したいテキスト,声の種類)
のようにすればwavデータをそのまま渡してくれる。
音声合成したいテキストはDiscordのTTS Botの場合はメッセージをそのまま渡してみたけど問題なく合成されてる感じ。むしろOpen JTalkよりイントネーションも漢字の読み方もいい感じ。声の種類は0から10で指定できる。どの番号がどの声かはソースコード見ればすぐわかるかも。
※Python初心者なので変なところあるかも。

せっかくwavファイル作らないで行けるかなーと思ったのに、結局discord.pyのcreate_ffmpeg_playerではwavデータをそのまま渡すのがよくわからなかったので一旦wavファイルに保存してしまっているという。

とりあえずDiscord TTS Botの方は、
・TeamSpeak3みたいにユーザーが入ってきたら音声でお知らせ
・ユーザーごとに違う声を割り当てて読み上げ
・ggrksとかwktkとか音声合成が読み上げにくいワードは辞書により変換して読み上げ
・AOEみたいに番号で特定の音声を鳴らす
・テキストの流れが早くても順番に音声合成
とかそこそこ使えるレベルになってきた。
AITalkにしたおかげで棒読みちゃんより聞き取りやすいかも。

Pythonで作ってあるのでRaspberry Piで24時間稼働できるんだけどたまーにDiscord鯖との接続が切れたりしているので再接続処理などを入れ無いといけないかも。
いかんせんメインプログラムはいまだにソースコードが汚いので今回はaitalk.py部分の紹介にとどまろうと思う…
動作安定したら公開するかも。(需要ないかな…