2017-12-26 21 views
0

Bibliothek senden: https://github.com/felHR85/UsbSerialFailing Daten auf USB-Gerät mit dem Android usbserial Bibliothek

ich android Entwicklung bin neu, so dass für alles, was ich die Antwort auf meine Frage wissen kann mich direkt ins Gesicht zu starren.

Wenn ich einen Befehl poste, erhalte ich keine Rückmeldung von dem Gerät, an das ich den Befehl sende (Lichtsteuergerät). Wenn ich jedoch ein serielles USB-Terminal (Android-App) lade und einen zufälligen (sogar ungültigen) Befehl sende, wird der Befehl, den ich mit UsbSerial gesendet habe, zuerst überprüft und überprüft, dass er ausgeführt wurde (antwortet mit "OK"). Das lässt mich glauben, dass der Befehl irgendwo in einem Puffer steckt. Ich baue die Anwendung mit API 19, weil die Geräte, die wir verwenden, nicht über Kit Kat hinaus aktualisiert werden, nicht sicher, ob das einen Unterschied macht.

Irgendwelche Ideen?

MainActivity.java

import android.content.BroadcastReceiver; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Message; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.lang.ref.WeakReference; 
import java.util.Set; 

public class MainActivity extends AppCompatActivity 
{ 
    // Class constants 

    // Class variables 

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      switch (intent.getAction()) { 
       case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED 
        Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show(); 
        break; 
       case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED 
        Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show(); 
        break; 
       case UsbService.ACTION_NO_USB: // NO USB CONNECTED 
        Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show(); 
        break; 
       case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED 
        Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show(); 
        break; 
       case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED 
        Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show(); 
        break; 
      } 
     } 
    }; 
    private UsbService usbService; 
    private TextView display; 
    private EditText editText; 
    private MyHandler mHandler; 
    private final ServiceConnection usbConnection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName arg0, IBinder arg1) { 
      usbService = ((UsbService.UsbBinder) arg1).getService(); 
      usbService.setHandler(mHandler); 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      usbService = null; 
     } 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mHandler = new MyHandler(this); 

     display = (TextView) findViewById(R.id.textView); 
     editText =(EditText) findViewById(R.id.editText); 
     Button sendButton = (Button) findViewById(R.id.button); 
     final Button sfd = (Button) findViewById(R.id.button2); 
     sendButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(!editText.getText().toString().equals("")) 
       { 
        int num = Integer.parseInt(editText.getText().toString()); 
        if(num < 1 || num > 512) { 
         display.setText("Invalid Address Operand!"); 
        } 
        else if(usbService != null) 
        { 
         String data = "sda=" + num; 
         usbService.write(data.getBytes()); 
         display.setText("SDA set to " + num); 
        } 
        else 
        { 
         display.setText("Controller Not Connected!"); 
        } 
       } 
      } 
     }); 

     sfd.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(usbService != null) 
       { 
        String cmd = "sfd"; 
        usbService.write(cmd.getBytes()); 
        display.setText("Controller Set To Factory Defaults"); 
       } 
      } 
     }); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     setFilters(); // Start listening notifications from UsbService 
     startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     unregisterReceiver(mUsbReceiver); 
     unbindService(usbConnection); 
    } 

    private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) { 
     if (!UsbService.SERVICE_CONNECTED) { 
      Intent startService = new Intent(this, service); 
      if (extras != null && !extras.isEmpty()) { 
       Set<String> keys = extras.keySet(); 
       for (String key : keys) { 
        String extra = extras.getString(key); 
        startService.putExtra(key, extra); 
       } 
      } 
      startService(startService); 
     } 
     Intent bindingIntent = new Intent(this, service); 
     bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE); 
    } 

    private void setFilters() { 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED); 
     filter.addAction(UsbService.ACTION_NO_USB); 
     filter.addAction(UsbService.ACTION_USB_DISCONNECTED); 
     filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED); 
     filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED); 
     registerReceiver(mUsbReceiver, filter); 
    } 

    /* 
    * This handler will be passed to UsbService. Data received from serial port is displayed 
    * through this handler 
    */ 
    private static class MyHandler extends Handler { 
     private final WeakReference<MainActivity> mActivity; 

     public MyHandler(MainActivity activity) { 
      mActivity = new WeakReference<>(activity); 
     } 

     @Override 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case UsbService.MESSAGE_FROM_SERIAL_PORT: 
        String data = (String) msg.obj; 
        mActivity.get().display.append(data); 
        break; 
       case UsbService.CTS_CHANGE: 
        Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show(); 
        break; 
       case UsbService.DSR_CHANGE: 
        Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show(); 
        break; 
      } 
     } 
    } 
} 

UsbService.java

import android.app.PendingIntent; 
import android.app.Service; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.hardware.usb.UsbDevice; 
import android.hardware.usb.UsbDeviceConnection; 
import android.hardware.usb.UsbManager; 
import android.os.Binder; 
import android.os.Handler; 
import android.os.IBinder; 

import com.felhr.usbserial.CDCSerialDevice; 
import com.felhr.usbserial.UsbSerialDevice; 
import com.felhr.usbserial.UsbSerialInterface; 

import java.io.UnsupportedEncodingException; 
import java.util.HashMap; 
import java.util.Map; 

public class UsbService extends Service { 

    public static final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY"; 
    public static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED"; 
    public static final String ACTION_USB_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED"; 
    public static final String ACTION_USB_NOT_SUPPORTED = "com.felhr.usbservice.USB_NOT_SUPPORTED"; 
    public static final String ACTION_NO_USB = "com.felhr.usbservice.NO_USB"; 
    public static final String ACTION_USB_PERMISSION_GRANTED = "com.felhr.usbservice.USB_PERMISSION_GRANTED"; 
    public static final String ACTION_USB_PERMISSION_NOT_GRANTED = "com.felhr.usbservice.USB_PERMISSION_NOT_GRANTED"; 
    public static final String ACTION_USB_DISCONNECTED = "com.felhr.usbservice.USB_DISCONNECTED"; 
    public static final String ACTION_CDC_DRIVER_NOT_WORKING = "com.felhr.connectivityservices.ACTION_CDC_DRIVER_NOT_WORKING"; 
    public static final String ACTION_USB_DEVICE_NOT_WORKING = "com.felhr.connectivityservices.ACTION_USB_DEVICE_NOT_WORKING"; 
    public static final int MESSAGE_FROM_SERIAL_PORT = 0; 
    public static final int CTS_CHANGE = 1; 
    public static final int DSR_CHANGE = 2; 
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; 
    private static final int BAUD_RATE = 9600; // BaudRate. Change this value if you need 
    public static boolean SERVICE_CONNECTED = false; 

    private IBinder binder = new UsbBinder(); 

    private Context context; 
    private Handler mHandler; 
    private UsbManager usbManager; 
    private UsbDevice device; 
    private UsbDeviceConnection connection; 
    private UsbSerialDevice serialPort; 

    private boolean serialPortConnected; 
    /* 
    * Data received from serial port will be received here. Just populate onReceivedData with your code 
    * In this particular example. byte stream is converted to String and send to UI thread to 
    * be treated there. 
    */ 
    private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { 
     @Override 
     public void onReceivedData(byte[] arg0) { 
      try { 
       String data = new String(arg0, "UTF-8"); 
       if (mHandler != null) 
        mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, data).sendToTarget(); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    /* 
    * State changes in the CTS line will be received here 
    */ 
    private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() { 
     @Override 
     public void onCTSChanged(boolean state) { 
      if(mHandler != null) 
       mHandler.obtainMessage(CTS_CHANGE).sendToTarget(); 
     } 
    }; 

    /* 
    * State changes in the DSR line will be received here 
    */ 
    private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() { 
     @Override 
     public void onDSRChanged(boolean state) { 
      if(mHandler != null) 
       mHandler.obtainMessage(DSR_CHANGE).sendToTarget(); 
     } 
    }; 
    /* 
    * Different notifications from OS will be received here (USB attached, detached, permission responses...) 
    * About BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html 
    */ 
    private final BroadcastReceiver usbReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context arg0, Intent arg1) { 
      if (arg1.getAction().equals(ACTION_USB_PERMISSION)) { 
       boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED); 
       if (granted) // User accepted our USB connection. Try to open the device as a serial port 
       { 
        Intent intent = new Intent(ACTION_USB_PERMISSION_GRANTED); 
        arg0.sendBroadcast(intent); 
        connection = usbManager.openDevice(device); 
        new ConnectionThread().start(); 
       } else // User not accepted our USB connection. Send an Intent to the Main Activity 
       { 
        Intent intent = new Intent(ACTION_USB_PERMISSION_NOT_GRANTED); 
        arg0.sendBroadcast(intent); 
       } 
      } else if (arg1.getAction().equals(ACTION_USB_ATTACHED)) { 
       if (!serialPortConnected) 
        findSerialPortDevice(); // A USB device has been attached. Try to open it as a Serial port 
      } else if (arg1.getAction().equals(ACTION_USB_DETACHED)) { 
       // Usb device was disconnected. send an intent to the Main Activity 
       Intent intent = new Intent(ACTION_USB_DISCONNECTED); 
       arg0.sendBroadcast(intent); 
       if (serialPortConnected) { 
        serialPort.close(); 
       } 
       serialPortConnected = false; 
      } 
     } 
    }; 

    /* 
    * onCreate will be executed when service is started. It configures an IntentFilter to listen for 
    * incoming Intents (USB ATTACHED, USB DETACHED...) and it tries to open a serial port. 
    */ 
    @Override 
    public void onCreate() { 
     this.context = this; 
     serialPortConnected = false; 
     UsbService.SERVICE_CONNECTED = true; 
     setFilter(); 
     usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 
     findSerialPortDevice(); 
    } 

    /* MUST READ about services 
    * http://developer.android.com/guide/components/services.html 
    * http://developer.android.com/guide/components/bound-services.html 
    */ 
    @Override 
    public IBinder onBind(Intent intent) { 
     return binder; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     return Service.START_NOT_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     UsbService.SERVICE_CONNECTED = false; 
    } 

    /* 
    * This function will be called from MainActivity to write data through Serial Port 
    */ 
    public void write(byte[] data) { 
     if (serialPort != null) 
      serialPort.write(data); 
    } 

    public void setHandler(Handler mHandler) { 
     this.mHandler = mHandler; 
    } 

    private void findSerialPortDevice() { 
     // This snippet will try to open the first encountered usb device connected, excluding usb root hubs 
     HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList(); 
     if (!usbDevices.isEmpty()) { 
      boolean keep = true; 
      for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) { 
       device = entry.getValue(); 
       int deviceVID = device.getVendorId(); 
       int devicePID = device.getProductId(); 

       if (deviceVID != 0x1d6b && (devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003)) { 
        // There is a device connected to our Android device. Try to open it as a Serial Port. 
        requestUserPermission(); 
        keep = false; 
       } else { 
        connection = null; 
        device = null; 
       } 

       if (!keep) 
        break; 
      } 
      if (!keep) { 
       // There is no USB devices connected (but usb host were listed). Send an intent to MainActivity. 
       Intent intent = new Intent(ACTION_NO_USB); 
       sendBroadcast(intent); 
      } 
     } else { 
      // There is no USB devices connected. Send an intent to MainActivity 
      Intent intent = new Intent(ACTION_NO_USB); 
      sendBroadcast(intent); 
     } 
    } 

    private void setFilter() { 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction(ACTION_USB_PERMISSION); 
     filter.addAction(ACTION_USB_DETACHED); 
     filter.addAction(ACTION_USB_ATTACHED); 
     registerReceiver(usbReceiver, filter); 
    } 

    /* 
    * Request user permission. The response will be received in the BroadcastReceiver 
    */ 
    private void requestUserPermission() { 
     PendingIntent mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 
     usbManager.requestPermission(device, mPendingIntent); 
    } 

    public class UsbBinder extends Binder { 
     public UsbService getService() { 
      return UsbService.this; 
     } 
    } 

    /* 
    * A simple thread to open a serial port. 
    * Although it should be a fast operation. moving usb operations away from UI thread is a good thing. 
    */ 
    private class ConnectionThread extends Thread { 
     @Override 
     public void run() { 
      serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection); 
      if (serialPort != null) { 
       if (serialPort.open()) { 
        serialPortConnected = true; 
        serialPort.setBaudRate(BAUD_RATE); 
        serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8); 
        serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1); 
        serialPort.setParity(UsbSerialInterface.PARITY_NONE); 
        /** 
        * Current flow control Options: 
        * UsbSerialInterface.FLOW_CONTROL_OFF 
        * UsbSerialInterface.FLOW_CONTROL_RTS_CTS only for CP2102 and FT232 
        * UsbSerialInterface.FLOW_CONTROL_DSR_DTR only for CP2102 and FT232 
        */ 
        serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF); 
        serialPort.read(mCallback); 
        serialPort.getCTS(ctsCallback); 
        serialPort.getDSR(dsrCallback); 

        // 
        // Some Arduinos would need some sleep because firmware wait some time to know whether a new sketch is going 
        // to be uploaded or not 
        //Thread.sleep(2000); // sleep some. YMMV with different chips. 

        // Everything went as expected. Send an intent to MainActivity 
        Intent intent = new Intent(ACTION_USB_READY); 
        context.sendBroadcast(intent); 
       } else { 
        // Serial port could not be opened, maybe an I/O error or if CDC driver was chosen, it does not really fit 
        // Send an Intent to Main Activity 
        if (serialPort instanceof CDCSerialDevice) { 
         Intent intent = new Intent(ACTION_CDC_DRIVER_NOT_WORKING); 
         context.sendBroadcast(intent); 
        } else { 
         Intent intent = new Intent(ACTION_USB_DEVICE_NOT_WORKING); 
         context.sendBroadcast(intent); 
        } 
       } 
      } else { 
       // No driver for given device, even generic CDC driver could not be loaded 
       Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED); 
       context.sendBroadcast(intent); 
      } 
     } 
    } 
} 

würde Irgendwelche Ideen oder Hilfe sehr geschätzt. Ich habe versucht, dieses Problem eine Woche lang zu lösen.

Antwort

0

Gott, ich bin ein Idiot. Ich habe nach jedem gesendeten Befehl keine neue Zeile hinzugefügt. Hoffentlich hilft das jemandem wie mir die Straße runter!

Verwandte Themen