2017-08-11 42 views
0

我正在做一个软件,我正在建立一个飞行控制系统的回路测试。我正在使用G ++ gnu来处理飞机的Matlab仿真所提供的航班信息。G ++ to Matlab串行只读第一条消息

要获得Matlab和G ++来相互交谈,我使用的是虚拟串行端口(连接两个非物理COM端口)。因此,我使用串行通信在它们之间发送数据(COM5通过Virtual Serial Port Driver虚拟连接到COM6)。

这会让我们的问题:Matlab的将只读取从G ++发来的第一条消息,和任何剩余的消息将返回空。

的代码的目录:

  1. 打开串行端口(上G ++侧)
  2. 发送消息和发送停止(在G ++侧)
  3. 例G ++代码显示我的问题
  4. 例Matlab的接收码显示我(按G ++侧)问题

打开串行端口

class SerialPort 
{ 
    HANDLE hCom; 
    public: 
    SerialPort(char * comportname); 
    ClosePort(); 
    void send(void *buffer, int num_bytes); 
    void sendstop(SerialPort sport); 
    int readline(unsigned char *buffer); 
}; 

SerialPort::SerialPort(char * comportname) 
{ 
    // set up the serial port 
    hCom = CreateFileA(comportname,GENERIC_READ | 
    GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 

    if (hCom == INVALID_HANDLE_VALUE) printf("\n*** CreateFile failed with error : %d\n", GetLastError()); 
    DCB dcb; 
    BOOL fSuccess = GetCommState(hCom, &dcb); 
    dcb.BaudRate = CBR_115200; // 115200 baud rate 
    dcb.ByteSize = 8;    // 8 bits data 
    dcb.Parity = NOPARITY;  // no parity bit 
    dcb.StopBits = ONESTOPBIT; // one stop bit 
    dcb.fDtrControl = DTR_CONTROL_DISABLE; // no flow control 
    fSuccess = SetCommState(hCom, &dcb); 
    if(!fSuccess) printf("\n*** SetCommState failed with error : %d\n", GetLastError()); 
    fSuccess = SetCommMask(hCom, EV_TXEMPTY | EV_RXCHAR | EV_ERR); 
    if(!fSuccess) printf("\n*** SetCommMask failed with error : %d\n", GetLastError()); 

    COMMTIMEOUTS cto_time; 
    GetCommTimeouts(hCom, &cto_time); 
    cto_time.ReadIntervalTimeout = 100; // set time-out to 100 milliseconds 
    SetCommTimeouts(hCom, &cto_time); 
} 

2. 发送消息和发送停止(在G ++侧)

void SerialPort::send(void *buffer, int num_bytes) 
{ 
    DWORD dwWriteCount; 
    WriteFile(hCom, buffer, num_bytes, &dwWriteCount, NULL); 
} 
void SerialPort::sendstop(SerialPort sport){ 
    int STOPBIT[]={9};//stop bit 
    sport.send(STOPBIT,sizeof(STOPBIT)); 
} 

3. 显示我的问题的示例G ++代码

#define S_PORT "COM5" 
#include "serialport.cpp"//see #1 
#include <stdio.h> 
#include <stdlib.h> 
char serialportname[] = S_PORT; // the serial port to read/write from 
SerialPort sp(serialportname); 
printf("Waiting for first message from matlab...\n"); 
char received_string[32]; 
printf("~:"); sp.readline((unsigned char *)received_string); 
printf("%s\n",received_string);printf("\n"); 

int main(void){ 
    unsigned char rep1[]="Hello Plant"; 
    sp.send(rep1,sizeof(rep1)); 
    sp.sendstop(sp); 

    unsigned char rep2[]="Start"; 
    sp.send(rep2,sizeof(rep2));//This is where the error starts, it cant read the second message 
    sp.sendstop(sp); 
    return 0; 
} 

4. Matlab的例子,显示了我的问题接受代码

s=serial('COM6'); 
s.Baudrate=115200; 
s.StopBits=1; 
s.Terminator=9; 
fopen(s); 
fwrite(s,'Hello Processor'); 
fwrite(s,'8');%stopbit for Matlab is 9(Tab in ASCII), and GNU side's is 8(Backspace in ASCII) 

rep = fgets(s); 
rep %displaying 

rep2 = fgets(s);%this fails to read "Start" and gets an empty '' 
rep2 %displaying 
fclose(s); 

我的理论是,它是某种只读起始位,或仅阅读一些信息过来串行,或者起始位未被正确读取。

我已经尝试过

-Altering延误试图解决任何可能的同步问题

-Opening和关闭串口每封邮件

- 写入到较长的消息后,看看它是否读错了部分

- 更改停止位

注意的是,这些努力仍然可以告诉我们关于这个问题,我只是没有看到他们

其他论坛帖子(S)在这个问题上的任何信息(这并没有真正的帮助) https://www.mathworks.com/matlabcentral/answers/17004-cannot-read-from-com-port-more-than-once Matlab serial read bug

如果有人可以告诉我,我错过了什么,我会非常感激。

回答

0

经过一些更多的实验后,我发现一个似乎使它始终工作的过程。

要正确发送,需要:

  1. 通过fgetl或的fscanf或与fgets获取数据。

  2. 使用flushinput(serialportobject)(?清除缓存)

  3. 发送下一个消息之前,TX方有睡了一定的时间(对我来说是13毫秒);

示例脚本(从原始讯息使用代码):

的Tx侧:

char rep1[]="hello"; 
sp.send(rep1, sizeof(rep1)); 
sp.sendstop(sp); 
Sleep(13); //Important for next read 

的Rx侧:

rep=fscanf(s); 
flushinput(s); 
//Next read can go here