Не получается ожидаемый результат: FTDI-Android
Я использую приведенный ниже код для связи между FDTI и Android-устройством:
import android.content.Context;
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
public abstract class FTDIHelper2 {
// log tag
final int PORT_INDEX = 0;
final String TT = "Trace";
final byte XON = 0x11; /* Resume transmission */
final byte XOFF = 0x13; /* Pause transmission */
public D2xxManager mFTD2xx = null;
public Context global_context;
FT_Device ftDev;
int currentPortIndex = -1;
int baudRate; /* baud rate */
byte stopBit; /* 1:1stop bits, 2:2 stop bits */
byte dataBit; /* 8:8bit, 7: 7bit */
byte parity; /* 0: none, 1: odd, 2: even, 3: mark, 4: space */
byte flowControl; /* 0:none, 1: CTS/RTS, 2:DTR/DSR, 3:XOFF/XON */
boolean uart_configured = false;
boolean bReadTheadEnable = false;
boolean mIsDataWriteDone = false;
ReceiveDataListener receiveDataListener;
ReadThread mReadThread = new ReadThread();
private String mResponseCommand = "";
private String mRequestCommand = null;
/**
* Method used to define the completion of data.
* If the full response will not come than it keeps appending the data.
*
* @param responseData
* @return
*/
public abstract boolean isCompleteResponse(String requestData, String responseData);
/**
* Called when the activity is first created.
*/
public void onCreate(Context context, ReceiveDataListener ml) {
this.receiveDataListener = ml;
try {
mFTD2xx = D2xxManager.getInstance(context);
} catch (D2xxManager.D2xxException e) {
}
global_context = context;
//Setting default parameters
baudRate = 115200;
stopBit = 1;
dataBit = 8;
parity = 0;
flowControl = 0;
}
public void sendData(String requestCommand) {
if (requestCommand == null) {
return;
}
mRequestCommand = requestCommand;
////////////////////////////
////////////////////////////
//Error
if (ftDev == null || !ftDev.isOpen()) {
//device not connected
receiveDataListener.deviceNotConfigure(requestCommand, 0);
return;
} else if (!uart_configured) {
//device not configured
receiveDataListener.deviceNotConfigure(requestCommand, 1);
return;
}
////////////////////////////
////////////////////////////
////////////////////////////
////////////////////////////
//Send data
int numBytes = requestCommand.length();
if (numBytes > 0) {
byte[] writeBuffer = new byte[512];
for (int i = 0; i < numBytes; i++) {
writeBuffer[i] = (byte) (requestCommand.charAt(i));
}
ftDev.write(writeBuffer, numBytes);
}
startEndlessReadThread();
////////////////////////////
////////////////////////////
}
public void onStart() {
int devCount = createDeviceList();
if (devCount > 0) {
connectFunction();
setConfig(baudRate, dataBit, stopBit, parity, flowControl);
sendData(mRequestCommand);
}
}
public void onResume() {
if (null == ftDev || !ftDev.isOpen()) {
int devCount = createDeviceList();
if (devCount > 0) {
connectFunction();
setConfig(baudRate, dataBit, stopBit, parity, flowControl);
sendData(mRequestCommand);
}
}
}
public void onDestroy() {
disconnectFunction();
mFTD2xx = null;
}
public int createDeviceList() {
int tempDevCount = mFTD2xx.createDeviceInfoList(global_context);
if (tempDevCount <= 0) {
currentPortIndex = -1;
return -1;
}
return tempDevCount;
}
public void disconnectFunction() {
currentPortIndex = -1;
stopReadThread();
if (ftDev != null && ftDev.isOpen()) {
ftDev.close();
ftDev = null;
}
}
public void connectFunction() {
if (ftDev != null && ftDev.isOpen()) {
ftDev.close();
currentPortIndex = -1;
}
ftDev = mFTD2xx.openByIndex(global_context, PORT_INDEX);
if (ftDev == null || !ftDev.isOpen()) {
receiveDataListener.deviceNotConfigure("Open port(" + PORT_INDEX + ") NG!");
return;
}
if (currentPortIndex == PORT_INDEX) {
return;
}
if (bReadTheadEnable) {
stopReadThread();
}
uart_configured = false;
currentPortIndex = PORT_INDEX;
if (!bReadTheadEnable) {
mReadThread = new ReadThread();
mReadThread.start();
}
}
void setConfig(int baud, byte dataBits, byte stopBits, byte parity, byte flowControl) {
if (ftDev == null) {
receiveDataListener.deviceNotConfigure("Error");
return;
}
// configure port
// reset to UART mode for 232 devices
ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(baud);
switch (dataBits) {
case 7:
dataBits = D2xxManager.FT_DATA_BITS_7;
break;
case 8:
dataBits = D2xxManager.FT_DATA_BITS_8;
break;
default:
dataBits = D2xxManager.FT_DATA_BITS_8;
break;
}
switch (stopBits) {
case 1:
stopBits = D2xxManager.FT_STOP_BITS_1;
break;
case 2:
stopBits = D2xxManager.FT_STOP_BITS_2;
break;
default:
stopBits = D2xxManager.FT_STOP_BITS_1;
break;
}
switch (parity) {
case 0:
parity = D2xxManager.FT_PARITY_NONE;
break;
case 1:
parity = D2xxManager.FT_PARITY_ODD;
break;
case 2:
parity = D2xxManager.FT_PARITY_EVEN;
break;
case 3:
parity = D2xxManager.FT_PARITY_MARK;
break;
case 4:
parity = D2xxManager.FT_PARITY_SPACE;
break;
default:
parity = D2xxManager.FT_PARITY_NONE;
break;
}
ftDev.setDataCharacteristics(dataBits, stopBits, parity);
short flowCtrlSetting;
switch (flowControl) {
case 0:
flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
break;
case 1:
flowCtrlSetting = D2xxManager.FT_FLOW_RTS_CTS;
break;
case 2:
flowCtrlSetting = D2xxManager.FT_FLOW_DTR_DSR;
break;
case 3:
flowCtrlSetting = D2xxManager.FT_FLOW_XON_XOFF;
break;
default:
flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
break;
}
ftDev.setFlowControl(flowCtrlSetting, XON, XOFF);
receiveDataListener.configurationDone();
uart_configured = true;
}
public void stopReadThread() {
bReadTheadEnable = false;
mReadThread.interrupt();
}
public void startEndlessReadThread() {
bReadTheadEnable = true;
mIsDataWriteDone = true;
mReadThread.interrupt();
}
/** Listener used to give the callback to registered activity**/
public interface ReceiveDataListener {
void callback(String data);
void configurationDone();
void deviceNotConfigure(String text, int Status);
void deviceNotConfigure(String errorMsg);
}
class ReadThread extends Thread {
final int USB_DATA_BUFFER = 8192;
ReadThread() {
this.setPriority(MAX_PRIORITY);
}
public void run() {
byte[] usbdata = new byte[USB_DATA_BUFFER];
bReadTheadEnable = true;
while (bReadTheadEnable) {
if (!mIsDataWriteDone) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
int readCount = ftDev != null ? ftDev.getQueueStatus() : 0;
if (readCount > 0) {
if (readCount > USB_DATA_BUFFER) {
readCount = USB_DATA_BUFFER;
}
ftDev.read(usbdata, readCount);
String data = "";
for (int i = 0; i < USB_DATA_BUFFER; i++) {
if (usbdata[i] != 0) {
data = data + (char) usbdata[i];
}
}
if (isCompleteResponse(mRequestCommand, mResponseCommand + data)) {
mIsDataWriteDone = false;
receiveDataListener.callback(mResponseCommand + data);
mResponseCommand = "";
} else {
//incompleted response, need to append data
mResponseCommand = mResponseCommand + data;
}
}
}
}
}
}
Я использую FDTI в деятельности, как показано ниже:
ABC extends Activity implements FTDIHelper.ReceiveDataListener {
FTDIHelper ftdiHelper = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
ftdiHelper = new CustomFTDIHelper();
ftdiHelper.onCreate(this.getApplicationContext(), this);
}
@Override
protected void onStart() {
super.onStart();
ftdiHelper.onStart();
}
@Override
protected void onStop() {
super.onStop();
ftdiHelper.onStop();
}
@Override
protected void onResume() {
super.onResume();
ftdiHelper.onResume();
}
@Override
protected void onDestroy() {
ftdiHelper.onDestroy();
super.onDestroy();
}
@Override
protected void onResume() {
String requestData = "someCommand";
ftdiHelper.sendData(requestData);
}
@Override
public void callback(final String responseData) {
Log.d("test", responseData);
}
}
Большую часть времени я получаю ожидаемый результат, но иногда я не получаю, например:
Я сделал запрос с текстом $ ABC1 #, ожидаемый результат должен быть $ XYZ #, но иногда я не получаю ожидаемый результат, например: $ ABC1 ## ENSE #, $ ABC2 # и т. Д.
Похоже, что данные поступают из FTDI, иногда они добавляют старые данные к новым, а иногда не отправляют фактический результат.
Пожалуйста, проверьте код и исправьте, если требуется.