ET 로보콘 블루투스 로그 수신

이 기사는 케이시 에스캐럿 Advent Calendar 2018의 24 일째 기사입니다.

금년도도 ET로보콘에 참가했습니다만, 난소 에리어에 계단이 더해져 매우 고생했습니다.
계단에 한정하지 않고 공략에 있어서, 단차이거나 거리인지를 계측할 필요가 있었습니다만, 계측하려면 로그에 출력해 확인할 필요가 있습니다.
그래서 VB.Net을 사용하여 Bluetooth를 통해 로봇에서 로그를 가져오고 표시하는 도구를 만들고 싶습니다.

준비



위에서 설명한대로 VB.Net을 사용하므로 다음을 설치합니다.
  • Visual Studio 2017 Community 2017

  • 프로젝트 생성



    파일 > 새로 만들기 > 프로젝트에서 Visual Basic의 Windows Forms 응용 프로그램(.NET Framework)을 선택하여 새 프로젝트를 생성합니다.
    (프로젝트명 등은 적절히 변경)

    양식 배치



    프로젝트를 만든 후 다음 그림과 같이 폼에 구성 요소를 배치합니다.


    코드(VB.Net)



    컴포넌트를 배치한 후 코드를 설명합니다.

    포트 정보 얻기



    컴퓨터에서 사용 가능한 직렬 포트를 열거하고 콤보 상자에 추가합니다.
        ''' <summary>
        ''' 接続可能なポート番号の取得・設定
        ''' </summary>
        Private Sub initPortName()
            ' ポート番号の取得・ソート
            Dim portNames As String() = SerialPort.GetPortNames()
            Array.Sort(portNames, StringComparer.OrdinalIgnoreCase)
    
            With Me.cmbPort
                .Items.Clear()
    
                For Each port In portNames
                    .Items.Add(port)
                Next
    
                .SelectedIndex = 0
            End With
        End Sub
    

    포트 열린 닫기



    앞에서 추가한 콤보 박스에서 선택한 포트로 시리얼 포트를 오픈·클로즈 하는 처리입니다.
        ''' <summary>
        ''' Bluetooth ポートオープン
        ''' </summary>
        Private Sub openBluetooth()
            Try
                With Me.spBluetooth
                    'オープンするシリアルポートをコンボボックスから取り出す.
                    .PortName = Me.cmbPort.SelectedItem.ToString()
    
                    'ボーレートをコンボボックスから取り出す.
                    .BaudRate = 7200
    
                    'データビットをセットする. (データビット = 8ビット)
                    .DataBits = 8
    
                    'パリティビットをセットする. (パリティビット = なし)
                    .Parity = Parity.None
    
                    'ストップビットをセットする. (ストップビット = 1ビット)
                    .StopBits = StopBits.One
    
                    '文字コードをセットする.
                    .Encoding = Encoding.UTF8
    
                    'シリアルポートをオープンする.
                    .Open()
    
                    Me.btnConnect.Enabled = False
                End With
            Catch ex As Exception
                MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub
    
        ''' <summary>
        ''' Bluetooth ポートクローズ
        ''' </summary>
        Private Sub closeBluetooth()
            Try
                Me.spBluetooth.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub
    

    데이터 송수신



    여기에서는 시리얼 포트로부터 수신한 데이터를 리스트에 기입해, 또, 데이터를 송신하는 처리를 실현하고 있습니다.
        Private Delegate Sub addRecvLogDataDelegate(recv As String)
    
        ''' <summary>
        ''' 受信文字列の追加
        ''' </summary>
        ''' <param name="recv">受信文字列</param>
        Private Sub addRecvLogData(recv As String)
            If IsNothing(recv) Then
                Return
            End If
    
            Me.lstLog.Items.Add(recv)
            Me.lstLog.SelectedIndex = Me.lstLog.Items.Count - 1
        End Sub
    
        ''' <summary>
        ''' 指定文字列の送信
        ''' </summary>
        ''' <param name="text">送信文字列</param>
        Private Sub sendText(ByVal text As String)
            Try
                'シリアルポートからテキストを送信する.
                Me.spBluetooth.Write(text.TrimEnd())
            Catch ex As Exception
                MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub
    

    이벤트 핸들러



    폼에 추가한 컴퍼넌트군의 이벤트 핸들러를 추가합니다.
        ''' <summary>
        ''' フォーム ロードハンドラ
        ''' </summary>
        Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            initPortName()
        End Sub
    
        ''' <summary>
        ''' 接続ボタンクリックハンドラ
        ''' </summary>
        Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
            If Me.spBluetooth.IsOpen Then
                closeBluetooth()
            Else
                openBluetooth()
            End If
        End Sub
    
        ''' <summary>
        ''' 送信ボタンクリックハンドラ
        ''' </summary>
        Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
            sendText("1")
        End Sub
    
        ''' <summary>
        ''' シリアルポート 受信ハンドラ
        ''' </summary>
        Private Sub spBluetooth_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles spBluetooth.DataReceived
            'オープンしていない場合、処理を行わない.
            If Not Me.spBluetooth.IsOpen Then
                Return
            End If
    
            Try
                'メインスレッドへ受信データを渡す
                Invoke(New addRecvLogDataDelegate(AddressOf addRecvLogData), Me.spBluetooth.ReadExisting())
            Catch ex As Exception
                MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    
        End Sub
    

    시작 확인



    이것으로 도구가 완료되었습니다.
    이동하고 콤보 상자를 클릭하면 직렬 포트가 표시된다고 생각합니다.



    코드(C)



    계속해서, 로봇측(C)입니다만, 이쪽은 지원 사이트 에 기재가 있으므로, 기동 개시 부분과 로그 송신 부분을 발췌하는 것에 둡니다.

    시작 시작 부분
        // Bluetooth接続
        while(!ev3_bluetooth_is_connected()){
            tslp_tsk(100);
        }
    
        FILE* bt = ev3_serial_open_file(EV3_SERIAL_BT);
    
        while (1) {
            uint8_t c = fgetc(bt);
            if (c == '1') {
               // スタート処理
               break;
            }
        }
    
        fclose(bt);
    

    로그 전송 부분
        const char *pMsg = "Hello EV3!";
    
        FILE* sp;
    
        sp = ev3_serial_open_file(EV3_SERIAL_DEFAULT)
    
        fprintf(sp, "%s\r\n", pMsg);
    
        fclose(sp);
    

    동작 확인



    확인 준비



    코드 부분이 완료되었으므로 로그를 수신할 수 있습니다.
    …하지만 다음 설정을 수행해야 합니다.
  • rc.conf.ini 파일 수정
  • 페어링 설정

  • 로봇내의 설정파일(rc.conf.ini)에서 이하의 기재를 실시합니다.
    [Bluetooth]
    LocalName=xxxxxx
    PinCode=xxxx
    [Debug]
    DefaultPort=BT
    

    그리고는, 실제로 로봇을 기동해 페어링을 실시하면, 준비 완료입니다.

    동작 검증



    로봇과 도구를 시작합니다.
    연결 버튼을 누르고 실제로 연결이 완료되면 연결 버튼이 Disable 상태가 됩니다.
    이 상태에서 시작 버튼을 누르면 로봇 측에 "1"이 전송되고 로봇 측에서 보낸 로그가 목록 상자에 표시됩니다.



    마지막으로



    어떻습니까?
    이제 로그를 수신할 수 있습니다.
    다만, 이대로라면 쓰기가 나쁘기 때문에, 수신한 로그를 파일에 떨어뜨릴 수 있도록 하거나, 로그에 키워드를 묶어, 좁혀 표시로 하거나 하면 편리성이 높아진다고 생각합니다.

    좋은 웹페이지 즐겨찾기