melihyarikkaya / react-native-serialport

React Native - Usb Serial Port Communication For Android Platform
MIT License
106 stars 105 forks source link

ISSUE: After connection unable to hold connection to write #56

Closed ErMapsh closed 9 months ago

ErMapsh commented 9 months ago

1. after connection made after not able to hold connection, that why I need to write multiple times to hold the connection alive and then If i unplug and plug the USB device get multiple send write requests and multiple right requests

{
  "name": "Package.json file",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android --reset-cache",
    "a": "react-native run-android",
    "ios": "react-native run-ios",
    "i": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.14.1",
    "@react-native-community/netinfo": "^5.9.7",
    "@react-native-community/slider": "^4.1.0",
    "@react-navigation/drawer": "^6.6.7",
    "@react-navigation/material-bottom-tabs": "^6.1.0",
    "@react-navigation/native": "^6.0.7",
    "@react-navigation/native-stack": "^6.3.0",
    "@react-navigation/stack": "^5.14.9",
    "@svgdotjs/svg.filter.js": "^3.0.8",
    "react": "16.13.1",
    "react-apexcharts": "^1.4.1",
    "react-native": "0.63.4",
    "react-native-alert-notification": "^0.4.0",
    "react-native-element-dropdown": "^2.10.1",
    "react-native-fast-image": "^8.6.3",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-gifted-charts": "^1.4.7",
    "react-native-linear-gradient": "^2.8.3",
    "react-native-orientation": "^3.1.3",
    "react-native-paper": "^5.12.3",
    "react-native-reanimated": "^2.2.4",
    "react-native-safe-area-context": "3.3.0",
    "react-native-screens": "3.18.0",
    "react-native-serialport": "^1.3.1",
    "react-native-svg": "^12.5.1",
    "react-native-vector-icons": "^7.1.0",
    "react-native-webview": "^11.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.8.4",
    "@babel/runtime": "^7.8.4",
    "@react-native-community/eslint-config": "^1.1.0",
    "@types/jest": "^25.2.3",
    "@types/react-native": "^0.63.75",
    "@types/react-native-vector-icons": "^6.4.18",
    "@types/react-test-renderer": "^16.9.2",
    "axios": "^1.6.7",
    "babel-jest": "^25.1.0",
    "eslint": "^6.5.1",
    "jest": "^25.1.0",
    "metro-react-native-babel-preset": "^0.59.0",
    "node-fetch": "^3.3.2",
    "react-test-renderer": "16.13.1",
    "typescript": "^3.8.3"
  },
  "resolutions": {
    "@types/react": "^16"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}
import React, { memo, Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  ScrollView,
  Alert,
  DeviceEventEmitter,
} from 'react-native';
import { RNSerialport, definitions, actions } from 'react-native-serialport';
import { Appbar, withTheme } from 'react-native-paper';
import axios from 'axios';
import Api from '../../../Api';
import AsyncStorage from '@react-native-async-storage/async-storage';

class Device extends Component {
  constructor(props) {
    super(props);
    this.state = {
      servisStarted: false,
      connected: false,
      usbAttached: false,
      output: '',
      outputArray: [],
      baudRate: '115200',
      interface: '-1',
      sendText: 'CMDSTATUSX',
      returnedDataType: definitions.RETURNED_DATA_TYPES.HEXSTRING,
    };

    this.startUsbListener = this.startUsbListener.bind(this);
    this.stopUsbListener = this.stopUsbListener.bind(this);
    // this.checkConnectionIsOpen()
  }

  componentDidMount() {
    try {
      this.startUsbListener();
    } catch (error) { }
  }

  componentWillUnmount() {
    try {
      this.stopUsbListener();
    } catch (error) { }

  }

  startUsbListener() {
    DeviceEventEmitter.addListener(
      actions.ON_SERVICE_STARTED,
      this.onServiceStarted,
      this,
    );
    DeviceEventEmitter.addListener(
      actions.ON_SERVICE_STOPPED,
      this.onServiceStopped,
      this,
    );
    DeviceEventEmitter.addListener(
      actions.ON_DEVICE_ATTACHED,
      this.onDeviceAttached,
      this,
    );
    DeviceEventEmitter.addListener(
      actions.ON_DEVICE_DETACHED,
      this.onDeviceDetached,
      this,
    );
    DeviceEventEmitter.addListener(actions.ON_ERROR, this.onError, this);
    DeviceEventEmitter.addListener(
      actions.ON_CONNECTED,
      this.onConnected,
      this,
    );
    DeviceEventEmitter.addListener(
      actions.ON_DISCONNECTED,
      this.onDisconnected,
      this,
    );
    DeviceEventEmitter.addListener(actions.ON_READ_DATA, this.onReadData, this);

    RNSerialport.setReturnedDataType(2);

    RNSerialport.setAutoConnectBaudRate(115200);
    RNSerialport.setDriver('cdc');
    RNSerialport.setReturnedDataType(1);
    RNSerialport.setAutoConnect(true);
    // RNSerialport.setInterface(1);
    RNSerialport.startUsbService();
    // this.fillDeviceList();
  }

  stopUsbListener = async () => {
    DeviceEventEmitter.removeAllListeners();
    const isOpen = await RNSerialport.isOpen();
    if (isOpen) {
      Alert.alert('isOpen', isOpen);
      RNSerialport.disconnect();
    }
    RNSerialport.stopUsbService();
  };

  onServiceStarted(response: any) {
    this.setState({ servisStarted: true });
    if (response.deviceAttached) {
      this.onDeviceAttached();
    }
  }
  onServiceStopped() {
    this.setState({ servisStarted: false });
  }
  onDeviceAttached() {
    this.setState({ usbAttached: true });
    console.log('RN serial device attached');
    this.checkConnectionIsOpen();
    if (this.state.usbAttached && !this.state.connected) {
      // try to connect
      this.connectToDevice();
    }
  }

  async connectToDevice() {
    let isSerialDeviceConnected = await RNSerialport.isOpen();
    if (!isSerialDeviceConnected) {
      const deviceList = await RNSerialport.getDeviceList();
      // console.log(deviceList);
      if (deviceList && deviceList[0]) {
        // console.log('into device connect');
        // console.log(deviceList);
        let connection = RNSerialport.connectDevice(deviceList[0].name, 115200);
        // console.log(connection);
        isSerialDeviceConnected = await RNSerialport.isOpen();
      }
    }
  }

  fillDeviceList = async () => {
    try {
      let command = 'CMDSTATUSX';
      let isSerialDeviceConnected = await RNSerialport.isOpen();
      if (!isSerialDeviceConnected) {
        const deviceList = await RNSerialport.getDeviceList();
        if (deviceList && deviceList[0]) {
          let connection = RNSerialport.connectDevice(deviceList[0].name, 115200);
          isSerialDeviceConnected = await RNSerialport.isOpen();
          setInterval(() => {
            this.sendcommand(command);
          }, 5000);
        }
      }
    } catch (error) {
      console.log(error)
    }
  };

  sendcommand(command: any) {
    RNSerialport.writeString(`${command}\r`);
    console.log('-----send command------', command);
  }
  onDeviceDetached() {
    this.setState({
      ...this.state, usbAttached: false, connected: false,
    });
  }
  onConnected() {
    this.setState({ ...this.state, connected: true });
    console.log('RN serial connected');
    if (this.state.usbAttached && this.state.connected) {
      this.fillDeviceList();
    }
  }
  onDisconnected() {
    // this.setState({ ...this.state, connected: false });
    this.setState({ connected: false });
  }

  onReadData(data) {
    if (this.state.connected && this.state.usbAttached) {
      let rawPayload = RNSerialport.intArrayToUtf16(data.payload);
      console.log('RN serial read:', rawPayload);
      this.sendData(rawPayload)
    }
  }

  async sendData(value: any) {
    try {
      const id = await AsyncStorage.getItem('id');
      let body = {
        data: value
      }
      // console.log(body)
      const res = await axios.post(Api.deviceStatus + id, body)
    } catch (error) {
      // do not do anything
      // console.log(error.message)
    }
  }

  async onError(error) {
    // console.error(error);
    console.log('RN serial error:', error);
    if (this.state.usbAttached && this.state.connected) {
      const deviceList = await RNSerialport.getDeviceList();
      if (deviceList && deviceList[0]?.name) {
        // try to connect device
        RNSerialport.connectDevice(deviceList[0].name, 115200);
      }
    }
  }

  checkConnectionIsOpen = async () => {
    let a = await RNSerialport.isOpen()
    console.log('connection is open: ', a);
    if (!a) {

      this.setState({
        ...this.state,
        connected: false,
        usbAttached: false,
      })
    } else {
      this.setState({
        ...this.state,
        connected: true,
        usbAttached: true,
      })
    }
  }

  // handleConvertButton() {
  //   let data = '';
  //   if (
  //     this.state.returnedDataType === definitions.RETURNED_DATA_TYPES.HEXSTRING
  //   ) {
  //     data = RNSerialport.hexToUtf16(this.state.output);
  //   } else if (
  //     this.state.returnedDataType === definitions.RETURNED_DATA_TYPES.INTARRAY
  //   ) {
  //     data = RNSerialport.intArrayToUtf16(this.state.outputArray);
  //   } else {
  //     return;
  //   }
  //   this.setState({ output: data });
  // }

  handleClearButton() {
    this.setState({
      ...this.state,
      output: ''
    });
    this.setState({
      ...this.state,
      outputArray: []
    });
  }

  buttonStyle = (status) => {
    return status
      ? styles.button
      : Object.assign({}, styles.button, { backgroundColor: '#C0C0C0' });
  };

  render() {
    const { theme } = this.props;
    return (
      <ScrollView style={styles.body}>
        <Appbar.Header
          style={{
            borderBottomWidth: 2,
            borderColor: theme.colors.primary,
          }}>
          <Appbar.Content
            title="Device"
            titleStyle={{
              color: theme.colors.primary,
              fontFamily: theme.fonts.thin.fontFamily,
              fontSize: 25,
            }}
          />
        </Appbar.Header>
        <View style={styles.container}>
          <View style={styles.header}>
            <View style={styles.line}>
              <Text style={styles.title}>Service:</Text>
              <Text style={styles.value}>
                {this.state.servisStarted ? 'Started' : 'Not Started'}
              </Text>
            </View>
            <View style={styles.line}>
              <Text style={styles.title}>Usb:</Text>
              <Text style={styles.value}>
                {this.state.usbAttached ? 'Attached' : 'Not Attached'}
              </Text>
            </View>
            <View style={styles.line}>
              <Text style={styles.title}>Connection:</Text>
              <Text style={styles.value}>
                {this.state.connected ? 'Connected' : 'Not Connected'}
              </Text>
            </View>
          </View>
        </View>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  full: {
    flex: 1,
  },
  body: {
    flex: 1,
  },
  container: {
    flex: 1,
    marginTop: 20,
    marginLeft: 16,
    marginRight: 16,
  },
  header: {
    display: 'flex',
    justifyContent: 'center',
    //alignItems: "center"
  },
  line: {
    display: 'flex',
    flexDirection: 'row',
  },
  line2: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  title: {
    width: 100,
  },
  value: {
    marginLeft: 20,
  },
  output: {
    marginTop: 10,
    height: 300,
    padding: 10,
    backgroundColor: '#FFFFFF',
    borderWidth: 1,
  },
  inputContainer: {
    marginTop: 10,
    borderBottomWidth: 2,
  },
  textInput: {
    paddingLeft: 10,
    paddingRight: 10,
    height: 40,
  },
  button: {
    marginTop: 16,
    marginBottom: 16,
    paddingLeft: 15,
    paddingRight: 15,
    height: 40,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#147efb',
    borderRadius: 3,
  },
  buttonText: {
    color: '#FFFFFF',
  },
});

export default memo(withTheme(Device));
ErMapsh commented 9 months ago

Device issue misconfig