kenjdavidson / react-native-bluetooth-classic

⚛ Bluetooth classic Android(Bluetooth)/IOS(ExternalAccessory) module for serial communication
https://kenjdavidson.github.io/react-native-bluetooth-classic
MIT License
247 stars 93 forks source link

No response from connected device #319

Closed sinan2000 closed 4 months ago

sinan2000 commented 4 months ago

Mobile Device Environment

Device: Samsung Galaxy S8+ OS: Android version 9

Application Environment Provide information about your development environment: React Native version: 0.73.6 RN Bluetooth Classic version: v1.73.0-rc.8

Hello, I successfully communicate with the bluetooth adapter from the Serial Bluetooth Terminal app with the following settings: charset UTF-8 Buffer size 10 kB Receive Newline STX/ETX Send Newline STX/ETX And I get the response.

The device I am talking about is a bluetooth adapter for a PLC. Here is the communication protocol information: Start code - STX slave station no - hexadecimal value, 2 number command no - hexadecimal value, 2 number data - 0-500 ASCII code checksum - calculated with LRC end code - ETX

I successfully calculate the checksum and log the entire command. Here is an example command, the most basic one: image

However, when I try to do this in my Expo app, I do not get any response. I think there is a problem with how I connect, write or receive messages. I tried sending it as hexadecimal string, array of bytes but without any response. Here is my current implementation:

const connectToDevice = async (device) => {
    try {
      const connected = await RNBluetoothClassic.connectToDevice(device.address);
      console.log('Connected to device:', device);
      setConnectedDevice(connected);
      navigation.navigate('Control');
    } catch (error) {
      console.error(error);
    }
  };

  //And here are the relevant parts of the control page, where I write or read:
  // for reading:
  useEffect(() => {
        if (connectedDevice) {
            const subscription = connectedDevice.onDataReceived((data) => {
                console.log('Received data:', data);
                setConversation(prev => [...prev, { type: 'received', content: data }]);
            });

            return () => subscription.remove();
        }
    }, [connectedDevice]);

    //for writing:
    function formatPLCMessage(){
            const stationIdHex = parseInt('01', 16);
        const commandNoHex = parseInt('40', 16);
        const checksumHex = parseInt('C7', 16);
        const message = [0x02, stationIdHex, commandNoHex, checksumHex, 0x03];

        return message;
    } // (hard-coded values, just for testing)

    const sendMessage = async () => {
        if (connectedDevice && connectedDevice.isConnected()) {
            const formattedMessage = formatPLCMessage();
            console.log('Sending message:', formattedMessage);

            try {
                const result = await connectedDevice.write(formattedMessage);
                console.log('Send Result:', result);
                setConversation(prev => [...prev, { type: 'sent', content: formattedMessage }]);
            } catch (error) {
                console.error('Error communicating with PLC:', error);
            }

            setMessage('');
        } else {
            console.error('Device is not connected');
        }
    };

I am new to this, so I know nearly nothing about bluetooth communication, but I have to set the connection options and send messages in expected format, in order to get responses. Any help? Thank you very much!

sinan2000 commented 4 months ago

Mention: I use a context for maintaining the connectedDevice the same across my screens.

kenjdavidson commented 4 months ago

The primary functionality for this library is to provide delimited messages (strings) communication. You are using a byte array connection, which looks like you could maybe get away with delimited messages of ETX but this is unlikely. I would suggest you look through the documentation/issues/discussions for how to connect using the binary connection. This will be a little better, but may not work completely out of the box.

If react native is a must for this project, i would suggest writing your own native module from scratch to handle this protocol. You can, look at how to implement you own custom connection type (although this is only for Android), and would take some custom Java code to get working.

sinan2000 commented 4 months ago

Thank you very much! Have a good day.

kenjdavidson commented 4 months ago

Sorry it wasn't the answer you were looking for. Hopefully some of these help:

Hex Encoding/Decoding - https://kenjdavidson.com/react-native-bluetooth-classic/guides/hex-encoding-decoding/

This page documents a couple things:

Note that I've been out of the React Native game for a while. I'm not sure if this method is still supported with the new Turbo Modules that 0.70+ use.

This is also only available on Android, I never got around to implementing the custom package in IOS, since when I was doing it the functionality wasn't 100% there and I couldn't get it working without breaking other functionality. I assumed it was such a small subset of people that needed it on IOS that I left it out.

Binary Device Connection - https://kenjdavidson.com/react-native-bluetooth-classic/android/device-connection/

it's not well documented, mainly because I threw it in there from different issues that were being opened. I'm fairly certain it works (although I don't have much confirmation beyond me playing with it). I'm not sure if it's used out in real life.