Vol.834 10.Dec.2021

BrueTooth骨伝導イヤホン VB2019_シリアル通信

B BrueTooth骨伝導イヤホン

by fjk

 音楽鑑賞やハンズフリー通話などで利用するイヤホンは、通信方式の違いにより、有線イヤホンと無線イヤホン(主にBruetooth接続)に分けられ、無線イヤホンは、左右のイヤホンが有線で繋がっているもの(左右一体型)と有線がないもの(完全独立型)。さらに、その装着方法で以下に分類される。

1.カナル型 イヤーピースを耳穴に装着する
2.インナーイヤー型  耳穴に引っかけるように、耳にフィットさせて使う
3.ネックバンド型 イヤホンを耳に装着し、首にバンドを掛ける
4.骨伝導型 耳穴には装着せず、耳周りの骨に振動を伝える
5.耳掛け型 耳に縁の引っかける.。カナル型が多い。
6.ヘッドホン 外耳全体を包み込むように装着

 屋外での作業中に、ポケットテレビ/ラジオの音声を有線のインナーイヤー型で聴いている。インナー型は周囲の音も聞こえやすいが、耳からイヤホンが外れやすかった。カナル型は耳から外れにくくなるが周囲の音が聞こえにくく、さらにフィット感に違和感がある。
 そこで、耳穴を塞がない骨伝導イヤホンとしてOpenMove(AfterShokz製、6,999円)をブラックフライディ中にAmazonで入手した。骨伝導イヤホンの最大の特徴は、音と外部の音を同時に聴くことができ、運転や作業中でも外部の音を聞き漏らすことを回避できる。また、振動で音を伝えるので音漏れもない。
 BT接続はイヤホンの「+ボタン」を長押して電源を投入後、スマホでBT接続先を選ぶだけで、BT接続が完了し、音楽を聴いたり会話ができた(マイク付きでハンズフリ−も可、駆動時間約6時間)。耳穴に違和感を全く感ずることが無く、試聴した女房も気に入り、2台目を買うことになった。ただ、外部の音もよく聞こえるので、外部音が大きい場所ではイヤホンの音が聞こえなくなることもある。
 さて、BT機能の無いポケットテレビ/ラジオの音をBTイヤホンで聴くため、BTトランスミッタとしてJPT1(JPRIDE、3,175円、レシーバ機能もあり)も同時に購入した。JPT1とOpenMoveをBT接続後、ポータブルテレビのイヤホン端子に接続すると、「電波が受信できない」となった(ラジオは問題ない)。どうも、トランスミッタのBT信号の影響でテレビ電波の受信ができなくなったらしい。
 そこで、トランシミッタとしてabc765で紹介したBT-C1(Aukey)を使ったところ、テレビも問題なく受信ができ、ノイズもなく、テレビとラジオの音声をワイヤレスで聞くことができた。トランスミッタはテレビ電波と電波干渉のない機種を選ぶ必要がある。なお、JPT1でも1mの音声延長ケーブルを使って、トランスミッターをポータブルテレビから離したところ、テレビ電波も受信ができた。 。

骨伝導イヤホンOpenMove BTトランスミッターJPT1 テレビ/ラジオでBT接続(BT-C1)


V VisualBasic(8) 〜(USB)シリアル通信

by fjk

 USB変換ケーブルを利用してPICコンピュータとパソコンのターミナルソフト(テラターム)でシリアル通信を行う方法はabc764で報告したが、通信データを自由に使いたいので、VisualBasicを使ってシリアル通信を試みた。なお、通信の相手はabc746で使ったPICで、事前にテラタームで通信動作を再確認した。
 VBでシリアル通信を行うには、SerialPortツールが便利である。Form1に以下を貼り付ける。

(ツール) (プロパティ)  
デザイン画面
SerialPort1  
TextBox1  
TextBox2 Multiline=True
Button1 Text= 接続
Button2 Text= 切断
Button3 Text= 送信
ComboBox1  
Label1 Text= 送信データ
Label2 Text= 受信データ
Label3 Text:= comポート

 
1.利用できるシリアルポートを表示する
 USBケーブルをパソコンに接続すると、COMポートが追加される。この時のポート番号はパソコンによって異なり、ポート番号を正しく設定しないと通信ができない。そこで、フォームを開く時に、利用できるポート番号を取得し、コンボボックスに表示し、選択できるようにした。
2.シリアル通信の接続
 USBのcomポートを選択後、「接続」ボタンを押すと、シリアル接続される。comポートが選択されていないときは接続されないが、接続エラー処理をしていないので、必要であればエラー処理を行うこと。
 通信条件は、通信速度=19,200bps、パリティ=無し、ビット数=8ビット、ストップビット=1で指定している。必要に応じてデータを書き換えて下さい。
 接続されたなら、TextBox2内の文字を全て消去後、”---connected”と表示。
3.データの送信
 TextBox1に文字列を入力後、「送信」ボタンを押すと、シリアルで送信される。送信後TextBox1の内容は消去される。なお、送信データが未入力の場合は送信動作を行わない。
4。通信の切断
「切断」ボタンを押すと、通信を切断し"---disconnect"と表示。
また、フォームを閉じても通信が切断される。

 ● PICもパソコンもフロー制御を行っていないので、送信タイミングによっては、文字化けなど、正しく通信が行えない場合がある。
 ● シリアル送受信にはByteデータも扱えるメソッドを利用したが、文字列のみの通信であれば、もっと簡単なメソッドも利用できる(下記参照)。

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        GetSerialPortName()
    End Sub

    Private Sub GetSerialPortName()
        For Each spt As String In My.Computer.Ports.SerialPortNames
            ComboBox1.Items.Add(spt)
        Next
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If ComboBox1.Text = "" Then
            Return
        End If
        TextBox2.Text = ""
        SerialPort1.PortName = ComboBox1.Text          						' ポートの指定
        SerialPort1.BaudRate = 19200                    					' 通信速度指定
        SerialPort1.Parity = IO.Ports.Parity.None       					' パリティ指定
        SerialPort1.DataBits = 8                        					' ビット数指定
        SerialPort1.StopBits = IO.Ports.StopBits.One    					' ストップビット指定
        SerialPort1.Open()                              					' シリアルポートのオープン
        TextBox2.Text = "-- connected" + ControlChars.CrLf
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If TextBox1.Text = "" Then
            Return
        End If 
        Dim dat As Byte() = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetBytes(TextBox1.Text + vbLf)
        SerialPort1.Write(dat, 0, dat.GetLength(0))						' シリアルポートにデータ送信
        TextBox1.Text = ""									' テキストボックス1をクリア
    End Sub

    Private Sub SerialPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) _
	Handles SerialPort1.DataReceived
        Dim rbt As Byte() = New Byte(SerialPort1.BytesToRead - 1) {}
        SerialPort1.Read(rbt, 0, rbt.GetLength(0))      					' シリアルポートからデータ受信
        Dim dlg As New DisplayTextDelegate(AddressOf DisplayText)
        Dim str As String = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(rbt)	' 受信バイト配列を文字列変換
        Me.Invoke(dlg, New Object() {str})       						' デリゲート関数をコールする
    End Sub

    Delegate Sub DisplayTextDelegate(ByVal strDisp As String)					' Invokeメソッドで使用するデリゲート宣言

    Sub DisplayText(ByVal strDisp As String)
        TextBox2.Text &= strDisp + vbLf
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        SerialPort1.Close()                             '					 シリアルポートのクローズ
        TextBox2.Text &= "-- disconnected"
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs)
        SerialPort1.Close()                             					' シリアルポートのクローズ
    End Sub

End Class

 
5.シリアル通信実行例
通信を実行すると、以下が正常に行えることを確認できた。
 ・PICからは1秒間隔でAD変換データを送ってくる。
 ・送信データはPICからそのまま送り返されてくる。
ComboBoxでポートを選択
(今回はCOM4)
通信例("++++abcdef+++"は
送信データのエコー)
6.トラブル
(1) 改行が正しく行われない
受信した文字列に改行コードを追加しないと、文字列が繋がって表示された。
文字列の送信時に、改行コードが無いとPICが正しく受信できなかった。
  ・文字列に ControlChars.CrLf または vbLf を追加
  または、ReadLine()、WrteLine()メソッドを使う
(2)「スレッド間アクセスエラー」が発生
DataReceivedイベントでTextBox2のデータを変更しようとしたところ、やはりエラーが発生した(詳細はMicrosoftのURL参照)。これはFormとSerialport.DataRecevedのスレッドが異なるためで、異なるスレッド間の処理を行うにはDelegate宣言し、Delegate変数を準備し、AddressOfで実行するメソッドを指定し、Invokeメソッドを実行する必要がある。
エラーメッセージ 通信相手のPIC(abc764参照)

※SerialPortクラスの主な送受信メソッド

Read(格納用データ配列 As Byte(), 開始位置 As Integer, バイト数 As Integer) As Integer
受信用バッファーの指定した開始位置(0〜)からバイト数分のByteデータを読み込む。
ReadLine() As String
受信用バッファーから1行分(改行コードを含む)の文字列を読み込む。
ReadExisting() As String
現在受信用バッファーにある読込み可能な文字列データを読み込む。
Write(送信用バイト配列 As Byte(), 開始位置 As Integer, バイト数 As Integer)
送信用バッファーの指定した位置からバイト数分のByteデータを書き込み、送信する。
Write(文字列 As string)
文字列データを送信する。
WriteLine(文字列 As String)
文字列と改行コード(NewLine値)を送信する


BrueTooth骨伝導イヤホン VB2019_シリアル通信