Arduino MKR 1010 WiFi с датчиком DHT11 для влажности и температуры, контролируемым приложением Android Studio, не претерAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Arduino MKR 1010 WiFi с датчиком DHT11 для влажности и температуры, контролируемым приложением Android Studio, не претер

Сообщение Anonymous »

Я новичок в студии Android и пытаюсь создать приложение, которое будет контролировать температуру и влажность с помощью Arduino MKR WiFi 1010 с соединением BLE и датчиком DHT11.
Я пишу код в фрагмент, но похоже, что onCharacteristicChanged никогда не вызывается, даже если характеристика меняется. Не могли бы вы мне помочь? Спасибо

Код: Выделить всё

package com.example.app;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;

import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;

public class temperature_fragment extends Fragment {

private static final String TAG = "TemperatureFragment";

private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private BluetoothGatt bluetoothGatt;
//queste tre classi vengono usate per gestire la connessione BLE
private BluetoothGattCharacteristic humidityCharacteristic;
private BluetoothGattCharacteristic temperatureCharacteristic;

private TextView humidityTextView;
private TextView temperatureTextView;

// UUID corretti per il servizio e le caratteristiche, sono uguali a quelli di arduino
private static final UUID SERVICE_UUID = UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb");
private static final UUID TEMPERATURE_UUID = UUID.fromString("00002a6e-0000-1000-8000-00805f9b34fb");
private static final UUID HUMIDITY_UUID = UUID.fromString("00002a6f-0000-1000-8000-00805f9b34fb");

private Handler handler;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.temperature_fragment, container, false);
humidityTextView = view.findViewById(R.id.humidityTextView);
temperatureTextView = view.findViewById(R.id.temperatureTextView);
handler = new Handler(Looper.getMainLooper());
return view;
}

@Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkPermissions();
} else {
initBluetooth();
}
}

@Override
public void onPause() {
super.onPause();
disconnectDevice();
}

//con onResume e onPause vado a gestire il ciclo di vita del fragment, connette e disconnette
//il ble

private void checkPermissions() {
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_CONNECT
}, 1);
} else {
initBluetooth();
}
}
//gestisto i permessi che mi servono per la connessione bluetooth e per cercare dispositivi nella vicinanze

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
boolean allPermissionsGranted = true;
for (int result :  grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (allPermissionsGranted) {
initBluetooth();
} else {
Log.e(TAG, "Permission denied");
}
}
}

private void initBluetooth() { //inizializzo il bluetooth sul dispositivo
bluetoothManager = (BluetoothManager) requireActivity().getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Log.e(TAG, "Bluetooth is not supported or not enabled");
return;
}
scanAndConnect();
}

private void scanAndConnect() {
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN}, 2);
return;
}
bluetoothAdapter.getBluetoothLeScanner().startScan(scanCallback);
}

private void disconnectDevice() {
if (bluetoothGatt != null) {

bluetoothGatt.disconnect();
bluetoothGatt.close();
bluetoothGatt = null;
}
}

private final ScanCallback scanCallback = new ScanCallback() {
//quando trova un dispositivo che si chiama arduino mkr wifi prova a connettersi
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();

if (device.getName() != null && device.getName().equals("Arduino MKR WiFi")) {

bluetoothGatt = device.connectGatt(requireContext(), false, gattCallback);
bluetoothAdapter.getBluetoothLeScanner().stopScan(scanCallback);
}
}

@Override
public void onBatchScanResults(java.util.List results) {
for (ScanResult result : results) {
onScanResult(0, result);
}
}

@Override
public void onScanFailed(int errorCode) {
Log.e(TAG, "Scan failed with error code: " + errorCode);
}
};
//gestisce la connessione, quando è stabilita attiva la discoverServices()
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
Log.d(TAG, "Connected to GATT server.");
Log.d(TAG, "Attempting to start service discovery: " + bluetoothGatt.discoverServices());
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
Log.d(TAG, "Disconnected from GATT server.");
handler.post(() ->  {
humidityTextView.setText("Humidity: --");
temperatureTextView.setText("Temperature: --");
});
}
}

//quando effettivamente i servizi sono stati scoperti, trova i valori di umidità e temperatura

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Services discovered.");
BluetoothGattService service = gatt.getService(SERVICE_UUID);
if (service != null) {
humidityCharacteristic = service.getCharacteristic(HUMIDITY_UUID);
temperatureCharacteristic = service.getCharacteristic(TEMPERATURE_UUID);
if (humidityCharacteristic != null) {
gatt.setCharacteristicNotification(humidityCharacteristic, true);
BluetoothGattDescriptor descriptor = humidityCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean result = gatt.writeDescriptor(descriptor);
Log.d(TAG, "Humidity characteristic found and notification enabled.");
} else {
Log.e(TAG, "Humidity characteristic not found.");
}
if (temperatureCharacteristic != null) {
gatt.setCharacteristicNotification(temperatureCharacteristic, true);
BluetoothGattDescriptor descriptor = temperatureCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean result = gatt.writeDescriptor(descriptor);
Log.d(TAG, "Temperature descriptor write result: " + result);
Log.d(TAG, "Temperature characteristic found and notification enabled.");
} else {
Log.e(TAG, "Temperature characteristic not found.");
}
} else {
Log.e(TAG, "Service not found.");
}
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}

//va a leggere i valori delle caratteristiche quando cambiano aggiornando le text view
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "onCharacteristicChanged called.");
handler.post(() -> {
Log.d(TAG, "Inside handler.post()");
byte[] data = characteristic.getValue();
Log.d(TAG, "Raw data: " + Arrays.toString(data));
if (characteristic.getUuid().equals(HUMIDITY_UUID)) {
float humidity = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_SFLOAT, 0);
Log.d(TAG, "Humidity characteristic changed: " + humidity);
humidityTextView.setText(String.format(Locale.getDefault(),"Humidity: %.2f%%", humidity));
} else if (characteristic.getUuid().equals(TEMPERATURE_UUID)) {
float temperature = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_SFLOAT, 0);
Log.d(TAG, "Temperature characteristic changed: " + temperature);
temperatureTextView.setText(String.format(Locale.getDefault(),"Temperature: %.2f°C", temperature));
}
});
}
};
}
Это код Arduino:

Код: Выделить всё

#include 
#include "DHT.h"

#define DHTPIN 2     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11   // DHT 11

DHT dht(DHTPIN, DHTTYPE); // Initialize the DHT component

BLEService myService("0000180a-0000-1000-8000-00805f9b34fb"); // Device Information Service
BLEFloatCharacteristic temperatureCharacteristic("00002a6e-0000-1000-8000-00805f9b34fb", BLERead | BLENotify);  // Temperature characteristic
BLEFloatCharacteristic humidityCharacteristic("00002a6f-0000-1000-8000-00805f9b34fb", BLERead | BLENotify); // Humidity characteristic

long prevElapsedTime = 0;

void setup() {
Serial.begin(9600);
while (!Serial) {};

if (!BLE.begin()) {
Serial.println("Failed to start BLE. Consider updating the firmware of the wifi module to the latest version");
while (1);
}

dht.begin();

BLE.setLocalName("Arduino MKR WiFi");
BLE.setAdvertisedService(myService);

myService.addCharacteristic(temperatureCharacteristic);
myService.addCharacteristic(humidityCharacteristic);

BLE.addService(myService);

temperatureCharacteristic.writeValue(0.0);
humidityCharacteristic.writeValue(0.0);

BLE.advertise();
Serial.println("BLE active. Waiting for connections...");
}

void loop() {
BLEDevice centralDevice = BLE.central();

if (centralDevice) {
Serial.print("Connected to central device: ");
Serial.println(centralDevice.address());

while (centralDevice.connected()) {
long currentElapsedTime = millis();
if (currentElapsedTime - prevElapsedTime >= 10000) {
prevElapsedTime = currentElapsedTime;

float humidity = dht.readHumidity();
float temperature = dht.readTemperature();

if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}

temperatureCharacteristic.writeValue(temperature);
humidityCharacteristic.writeValue(humidity);

Serial.print("Temperatura: ");
Serial.print(temperature);
Serial.print(" °C, Umidità: ");
Serial.print(humidity);
Serial.println(" %");
}
}

Serial.println("Disconnected from central BLE device");
}
}
Изменив обработчик, я теперь вижу влажность, но получаю значение 0,0%, а температура не определяется.
В журнале я вижу это:
введите здесь описание изображения
Вместо этого на Arduino я вижу реальные значения температуры и влажности:
введите здесь описание изображения

Подробнее здесь: https://stackoverflow.com/questions/786 ... -controlle
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»