質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

解決済

AndroidアプリでArduino+Bluetoothの情報を”正しく”受け取りたい(言語:kotlin)

CrisisAnatres
CrisisAnatres

総合スコア1

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2回答

0評価

0クリップ

258閲覧

投稿2022/05/26 08:59

したいこと

Arduinoのシリアル通信からBluetoothを通じてAndroidアプリで受け取り、Logcatに映し出したいです。受信はできているのですが、Arduino側で送信したものと全く同じものにして(型を整える、必要な情報だけ)受け取ることができません。方法を教えていただけますでしょうか。

構築したいシステムの概要図

イメージ説明

環境

  • Android Studio Bumblebee | 2021.1.1 Patch 3Build #AI-211.7628.21.2111.8309675, built on March 17, 2022
  • API:26 minSdk:23 targetSdk:32 compileSdk:32
  • Android端末 モデル名:Nexus7 Androidバージョン:6.0.1
  • Arduino IDE (Windows Store 1.8.57.0)
  • 使用マイコン基板Arduino Uno
  • 使用Bluetooth送信機(RN-42)詳細>https://akizukidenshi.com/catalog/g/gK-07378/

今できてること

この記事を元にArduino側で以下のプログラムを書き込み、Arduinoを接続したPC上のシリアルモニターから所望の文字や数字を送信します。

Arduino

#include <SoftwareSerial.h> SoftwareSerial btSerial(2,3); char moji;//入力・送信する文字に応じて型を変更 void setup () { btSerial.begin(115200); Serial.begin(115200); } void loop () { if(Serial.available()){ moji = Serial.read(); btSerial.write(moji);//送信部分 } delay(20); }

その送信したデータを下記のプログラム(MainActivity.kt)で作成した、AndroidアプリをインストールしたAndroid端末で受信、Logcatで確認するという流れです。

kotlin

package com.mongodb.arduinoble import android.Manifest import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothSocket import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import java.io.IOException import java.io.InputStream import java.io.OutputStream import java.nio.ByteBuffer import java.util.* const val TAG = "MainActivity" const val TARGET_DEVICE_NAME = "デバイス名(Android端末とペアリングしたRN-42のデバイス名)" const val REQUEST_ENABLE_BLUETOOTH = 1 // Defines several constants used when transmitting messages between the // service and the UI. const val MESSAGE_READ: Int = 0 const val MESSAGE_WRITE: Int = 1 const val MESSAGE_TOAST: Int = 2 //SPPを行うための専用UUID? val MYUUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") class MainActivity : AppCompatActivity() { private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter() private var connectedThread: ConnectedThread? = null private var connectThread: ConnectThread? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (bluetoothAdapter == null) { Log.d(TAG, "bluetooth is not supported.") return } if (!bluetoothAdapter.isEnabled) { val enableBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH) } val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter.bondedDevices pairedDevices?.forEach { device -> val deviceName = device.name val deviceHardwareAddress = device.address // MAC address if (device.name == TARGET_DEVICE_NAME) { Log.d(TAG, "name = %s, MAC <%s>".format(deviceName, deviceHardwareAddress)) device.uuids.forEach { uuid -> Log.d(TAG, "uuid is %s".format(uuid.uuid)) } connectThread = ConnectThread(device) connectThread?.start() return } } } fun manageMyConnectedSocket(socket: BluetoothSocket) { connectedThread = ConnectedThread(socket) connectedThread?.start() } private inner class ConnectThread(device: BluetoothDevice) : Thread() { private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) { device.createInsecureRfcommSocketToServiceRecord(MYUUID) } public override fun run() { // Cancel discovery because it otherwise slows down the connection. bluetoothAdapter?.cancelDiscovery() if (mmSocket == null) { return } val socket = mmSocket socket ?: return socket.connect() // The connection attempt succeeded. Perform work associated with // the connection in a separate thread. manageMyConnectedSocket(socket) } // Closes the client socket and causes the thread to finish. fun cancel() { try { mmSocket?.close() } catch (e: IOException) { Log.e(TAG, "Could not close the client socket", e) } } } private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() { private val mmInStream: InputStream = mmSocket.inputStream private val mmOutStream: OutputStream = mmSocket.outputStream private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream private var message: Array<String?> = arrayOfNulls(10) override fun run() { var numBytes: Int // bytes returned from read() Log.d(TAG, "connect start!") // Keep listening to the InputStream until an exception occurs. while (true) { // Read from the InputStream. numBytes = try { mmInStream.read(mmBuffer) } catch (e: IOException) { Log.d(TAG, "Input stream was disconnected", e) break } //message = arrayOf(ByteBuffer.wrap(mmBuffer).toString()) if (mmBuffer[0].toString()!="10"){ Log.d(TAG, mmBuffer[0].toString()+","+mmBuffer[1].toString()) } else{ } // // Send the obtained bytes to the UI activity. // val readMsg = handler.obtainMessage( // MESSAGE_READ, numBytes, -1, // mmBuffer) // readMsg.sendToTarget() } } // Call this method from the main activity to shut down the connection. fun cancel() { try { mmSocket.close() } catch (e: IOException) { Log.e(TAG, "Could not close the connect socket", e) } } } }

ManifestファイルでBluetoothに必要なuses-permissionは設定済みです。

実行結果

Android端末が接続されているPCのSerialモニターに、文字を打ち込み送信(Enter)を押すと、
イメージ説明
Android studio上のlogcat上には「97」と「10」が表示されます。
この場合、aの情報が97で改行?の情報が10だと思います。この数値を97と10でなくて、しっかりとaと表示させ、不要な情報である10は条件分岐などで消せればよいと考えてます。

やったこと

自分なりに考えてみたのですが下のコードで情報を受け取っていると思いました。このmmBufferに最終的に情報が入っていると考察しています。

kotlin

numBytes = try { mmInStream.read(mmBuffer) }

このmmBufferは ByteArray型(バイト配列?)であると出てきたので、型変換を行うために後ろに変換したい所望の型を付け加えたりしました。
例:整数なら.toInt()
しかし、結果は変わらずでした。
また、この記事を元にByteBuffer.wrap(longBytes).getLong()なども付け加えたりしたのですが、こちらも結果は変わりませんでした。

応用について

もし、上記の問題が解決できた場合でさらなる応用をしたいと思っています。
Arduino側で,区切りで複数のデータを送信してそのデータを受信側で区別する方法はありますでしょうか?送信側のArduinoのプログラム↓

Arduino

btSerial.write(mojia); btSerial.write(","); btSerial.write(mojib); btSerial.write(","); btSerial.write(mojic); btSerial.write("\n");

以上です。
ここで質問するのは初めてなので、冗長で分かりづらい文章になってしまいましたがご助言やコード例、考え方などを教えていただけますと幸いです。
kotlinも始めて数か月ですので、まだまだ初歩的なこともわかっていません()...
よろしくお願いいたします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori

2022/05/26 10:21

97 と 10 は a と改行の文字コードなので、普通にそのバイト列を文字列に変換すれば良いかと。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。