#java #android #bluetooth #stm32 #uart
#java #Android #bluetooth #stm32 #uart
Вопрос:
Я пытаюсь отправить данные по Bluetooth на плату stm32f411. Я использую модуль Bluetooth HC-05 v2, который обменивается данными через интерфейс UART. Когда я отправляю данные с компьютера, это работает отлично — данные отправляются, и ответ STM принимается через UART в режиме реального времени. Однако переключение на модуль Bluetooth и отправка и получение данных из приложения Android работают не так, как ожидалось. На данный момент я хочу отправить данные ASCII (пока только 0 и 1, но цель состоит в том, чтобы отправить целые числа от 0 до 100). Возможно, это как-то связано с длиной сообщения или скоростью передачи данных приложения.
Я также пытался отправлять данные в виде байтового, а не байтового массива, но это не сработало — когда я отправил 0, он работал нормально, но когда я отправил 1, я получил 120 десятичных знаков в STM, 2 я получил 128, 3 я получил 248. Когда я попытался отправить те же данные обратно в приложение, каждое сообщение начиналось с [B @, за которым обычно следует 7 символов.
Мой код Android studio:
public class MainActivity extends AppCompatActivity {
Button someButton;
ListView pairedDevListView;
Switch bluetoothSwitch;
BluetoothAdapter myBluetoothAdapter;
Intent bluetoothEnablingIntent;
TextView connectionStatusText;
SeekBar rightEnSeekBar, leftEnSeekBar;
SendReceive sendReceive;
BluetoothDevice[] bluetoothPairedDevArray;
int REQUEST_ENABLE_BLUETOOTH = 1;
int requestCodeForEnable;
static final int STATE_LISTENING = 1;
static final int STATE_CONNECTING = 2;
static final int STATE_CONNECTED = 3;
static final int STATE_CONNECTION_FAILED = 4;
static final int STATE_MESSAGE_RECEIVED = 5;
private static final String APP_NAME = "STM32";
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
switch (message.what){
case STATE_LISTENING:
connectionStatusText.setText("Listening");
break;
case STATE_CONNECTING:
connectionStatusText.setText("Connecting");
break;
case STATE_CONNECTED:
connectionStatusText.setText("Connected");
break;
case STATE_CONNECTION_FAILED:
connectionStatusText.setText("Connection failed");
break;
case STATE_MESSAGE_RECEIVED:
byte[] readBuff = (byte[]) message.obj;
//String tempMsg = new String(readBuff, 0 , message.arg1);
String tempMsg = null;
try {
tempMsg = new String(readBuff, "ASCII");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), String.valueOf(readBuff), Toast.LENGTH_SHORT).show();
connectionStatusText.setText(tempMsg);
break;
}
return true;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothEnablingIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
requestCodeForEnable = 1;
if(!myBluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
findViewByIds();
implementListeners();
}
private void findViewByIds() {
pairedDevListView = findViewById(R.id.pairedDevicesListView);
bluetoothSwitch = findViewById(R.id.btSwitch);
connectionStatusText = findViewById(R.id.statusTextView);
rightEnSeekBar = findViewById(R.id.rightSeekBar);
leftEnSeekBar = findViewById(R.id.leftSeekBar);
someButton = findViewById(R.id.button2);
}
private void implementListeners() {
//BLUETOOTH ENABLING SWITCH
bluetoothSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
if(myBluetoothAdapter == null){
Toast.makeText(getApplicationContext(),"Bluetooth is not supported on this device", Toast.LENGTH_LONG).show();
}
else{
if(!myBluetoothAdapter.isEnabled()){
startActivityForResult(bluetoothEnablingIntent, requestCodeForEnable);
}
}
}
else{
if(myBluetoothAdapter.isEnabled()){
myBluetoothAdapter.disable();
Toast.makeText(getApplicationContext(), "Bluetooth is disabled", Toast.LENGTH_LONG).show();
}
}
}
});
//CLICKING ON DEVICE FROM PAIRED DEVICE LIST
pairedDevListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass = new ClientClass(bluetoothPairedDevArray[i]);
clientClass.start();
connectionStatusText.setText("Connecting");
}
});
someButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String string = "1";
try {
sendReceive.write(string.getBytes("ASCII"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
//SHOWING PAIRED DEVICES WHEN SWITCH IS CHECKED
private void showPairedDevices() {
Set<BluetoothDevice> btDevices = myBluetoothAdapter.getBondedDevices();
bluetoothPairedDevArray = new BluetoothDevice[btDevices.size()];
String[] deviceNames = new String[btDevices.size()];
int index = 0;
if(btDevices.size() > 0){
for(BluetoothDevice device: btDevices){
deviceNames[index] = device.getName();
bluetoothPairedDevArray[index] = device;
index ;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNames);
pairedDevListView.setAdapter(arrayAdapter);
}
}
//SHOWING POP UP MESSAGE
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(requestCode == requestCodeForEnable){
if(resultCode == RESULT_OK){
Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_LONG).show();
showPairedDevices();
}
else if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth enabling cancelled", Toast.LENGTH_LONG).show();
}
}
}
private class ClientClass extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ClientClass(BluetoothDevice device1){
this.device = device1;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
myBluetoothAdapter.cancelDiscovery();
try {
socket.connect();
Message message = Message.obtain();
message.what = STATE_CONNECTED;
handler.sendMessage(message);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
Message message = Message.obtain();
message.what = STATE_CONNECTION_FAILED;
handler.sendMessage(message);
}
}
}
private class SendReceive extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public SendReceive(BluetoothSocket socket) {
bluetoothSocket = socket;
InputStream tempIn = null;
OutputStream tempOut = null;
try {
tempIn = bluetoothSocket.getInputStream();
tempOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
inputStream = tempIn;
outputStream = tempOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVED, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes) {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Мой STM-код:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
switch (atoi(amp;Received)) {
case 0:
size = sprintf(Data, "STOPnr");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
break;
case 1:
size = sprintf(Data, "STARTnr");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
break;
default:
size = sprintf(Data, "Odebrano nieznany znak: %cnr", Received);
break;
}
HAL_UART_Transmit_IT(amp;huart1, Data, size);
HAL_UART_Receive_IT(amp;huart1, amp;Received, 1);
HAL_GPIO_TogglePin(RED_LED_GPIO_Port, RED_LED_Pin);
}
Комментарии:
1. Было бы полезно, если бы вы упростили свой вопрос и настройку. В вопросе неясно, действительно ли у вас есть два вопроса (HC-05 не работает, а двоичные данные не работают). Неясно, какой тест был выполнен с какой настройкой. Чтобы упростить настройку, изолируйте проблему либо на HC-05, Android, либо на STM32F411. Если ваш компьютер поддерживает Bluetooth, вы можете напрямую подключиться к модулю HC-05. В противном случае найдите подходящее приложение для Android. Вы также можете подключить модуль HC-05 к USB-последовательному преобразователю, а затем к своему компьютеру. Вернитесь сюда, как только узнаете, в каком компоненте возникла проблема.
2. HC-05 и STM работают. Проблема, на мой взгляд, заключается в передаче данных из приложения — моя проблема в том, что я хочу отправить числа в кодировке ASCII 1-100, но, как я уже сказал, приложение, похоже, отправляет другие данные, хотя в методе getBytes() я указал кодировку.
3. Если проблема в приложении для Android, о чем весь код, заголовок вопросов и описание STM32F411? Я предлагаю вам взять USB-последовательный конвертер, подключить HC-05 обратно к компьютеру и RealTerm и описать проблему и настройку в новом вопросе.