Arduino和Raspberry之间串行通信中的数据传输错误

时间:2016-06-10 14:42:27

标签: c++ arduino serial-port communication raspberry-pi3

我试图将数据从Arduino Uno发送到RaspberryPi 3B。一旦Raspberry要求,我需要从Arduino发送14 int(最大值:6000)。这14个数字中的每一个都来自ad ADC(SPI通信)。

ARDUINO SIDE

#include "SPI.h"
byte incomingByte = 0;   // for incoming serial data

const int N_SENSORI=14;
const int DATAOUT = 11;
const int DATAIN = 12;
const int SPICLOCK = 13;
const int SLAVESELECT = 10;

//===============SPI COMMUNICATION================
short write_read_spi16(short what) {
  digitalWrite(SS, LOW);
  short res = SPI.transfer16(what);
  digitalWrite(SS, HIGH); 
  return res;
}

 //===============CONVERT INT IN BYTE AND SEND IT================
void longInt2Byte( int x){
  unsigned char buf[sizeof( int)];
  memcpy(buf,&x,sizeof(int));
Serial.write(buf,sizeof(buf));

}
//=======================================

void setup() {

  Serial.begin(115200);     
  SPI.begin();
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT); 
}
void loop() {


if (Serial.available() > 0) {         
  incomingByte= Serial.read();

  if (incomingByte=='E') {

    write_read_spi16(0b1000001101110000);  //THIS IS FOR THE ADC COMMUNICATION

    for (int i = 1; i<N_SENSORI+1; i++) { //DONE 14 TIMES.
      short s = write_read_spi16(0b1000001101110000 | (i<<10));
      int Data = s&0xFFF;
      longInt2Byte(Data);
        }       
      }
 }}

// C ++ SIDE

void stimulationController::SetupDario(){

    cout<<"Dentro al setupDario"<<endl<<flush;
    buffer=new char [1000];
    const char* _portNameSensorsDario="/dev/ttyACM1";
    //SERIAL PORT FOR HAND SENSORS
    struct termios options;
    SerialHandleSensors=open(_portNameSensorsDario, O_RDWR | O_NOCTTY | O_NDELAY); //SerialHandleSensors=open(_portNameSensors, O_RDWR | O_NOCTTY | O_NDELAY); non blocking
    if (SerialHandleSensors == -1 )
    {
        cout<<endl<<"......ERROR: Unable to open: "<<_portNameSensorsDario<<endl;
        return;
    }
    else
    {
        fcntl(SerialHandleSensors, F_SETFL,0);
        cout<<"......OPENED PORT: Succesfully opened: "<<_portNameSensorsDario<<endl;
    }

    //GET THE OPTIONS, MODIFY AND SET
    tcgetattr(SerialHandleSensors,&options);
    cfsetispeed(&options,B115200); //BAUD RATE IN
    cfsetospeed(&options,B115200); //BAUD RATE OUT
    // options.c_lflag |= (ICANON | ECHO | ECHOE);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag |= CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    tcsetattr(SerialHandleSensors,TCSANOW,&options);

    usleep(3000000);
cout<<"Fine Setup"<<endl<<flush;
}



int stimulationController::Dario( )
{

    {
    cout<<" NUOVA FUNZIONE"<<endl;


unsigned char bytes[4];
    bytes[0]=0x45;  // 'E'

    int tempWrite=write(SerialHandleSensors,bytes,1);
    if(tempWrite==-1)
    {
        cout<<"......ERROR: PROBLEM WRITING TO ROBOTIC HAND"<<endl;
        failure=true;
        return 0; 

    }

    int value=0;


    int tempRead=read(SerialHandleSensors,buffer,28);
    if(tempRead==-1)
    {
        cout<<"......ERROR: PROBLEM READING FROM ROBOTIC HAND"<<endl;
        failure=true;
        return 0;
    }


int j=0;
for( int i=0; i<28; i=i+2){
    value= buffer[i] | ((int)buffer[i+1]<<8);
    //ensorDataFoot.push_back(value);  //Aggiunge un elemento
    j=j+1;
        cout<<"Dato "<<j  <<"vale: "<<value<<endl<<flush;
    }

    return value;

}
}

问题在于,树莓方面有时会打印出正确的值,有时候(大部分时间,实际上)都没有。数据似乎重复或(例如2000年的2500次)。

我无法弄清楚问题。这可能是发送数据请求和读取之间的时间问题吗?如果是这样,有办法摆脱它吗?

我已经添加了一个do-while循环,以确保读取所有28个字节

int TotByte=28;
int ByteRead=0;
int TempRead=0;

do{ TempRead= read(SerialHandleSensors, buffer, (TotByte-ReadByte));
ReadByte= ReadByte+TempRead;
cout<<"ReadByte is: "<<ReadByte<<endl<<flush;
}while(ByteRead<TotByte);

输出:

ReadByte is: 5
ReadByte is: 15
ReadByte is: 25

然后它没有做任何事情就像那样

1 个答案:

答案 0 :(得分:0)

(代表OP发表回答):

我明白了;问题是串口的设置。供将来参考,这是工作版本。

bufferTemp=new char [1000];
    bufferDEF = new char[1000];
    const char* _portNameSensorsBT="/dev/rfcomm0";

    struct termios options;
    SerialHandleSensorsFoot=open(_portNameSensorsBT, O_RDWR ); //SerialHandleSensors=open(_portNameSensors, O_RDWR | O_NOCTTY | O_NDELAY); non blocking
    if (SerialHandleSensorsFoot == -1 )
    {
        cout<<endl<<"......ERROR: Unable to open: "<<_portNameSensorsBT<<endl;
        return 0;
    }
    else
    {
        fcntl(SerialHandleSensorsFoot, F_SETFL,0);
        cout<<"......OPENED PORT: Succesfully opened: "<<_portNameSensorsBT<<endl;
    }

    //GET THE OPTIONS, MODIFY AND SET
    tcgetattr(SerialHandleSensorsFoot,&options);
    cfsetispeed(&options,B115200); //BAUD RATE IN
    cfsetospeed(&options,B115200); //BAUD RATE OUT
    // options.c_lflag |= (ICANON | ECHO | ECHOE);

    options.c_iflag = IGNBRK | IGNPAR;
    options.c_oflag = 0; 
    options.c_lflag = 0; 

    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag |= CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    tcsetattr(SerialHandleSensorsFoot,TCSAFLUSH,&options);

    usleep(5000000);

通过这些设置,我可以与蓝牙通信,即使可能存在一些速度问题。