2016-06-21 128 views
0

GoodEvening everyone,藍牙數據傳輸速度問題

我試圖在Arduino lilypad和覆盆子Pi3B之間進行通信。

我能夠發送和接收數據,但通信非常慢!

我從拉斯普發送字符的Arduino,它響應以這種形式發回一包30字節的一些信息:

#字節1字節2 ... byte28!

樹莓代碼:

#include <stdio.h> /* Standard input/output definitions */ 
#include <string.h> /* String function definitions */ 
#include <fcntl.h> /* File control definitions */ 
#include <errno.h> /* Error number definitions */ 
#include <termios.h> /* POSIX terminal control definitions */ 
#include <vector>             
#include <fstream> //for file read/write 
#include <iostream> 
#include <unistd.h> 
#include <sstream> //use for hex conversion 
#include <sys/time.h> 
#include <time.h> 

using namespace std; 

    char* buffer; 
    int SerialHandleSensorsFoot;          
    char* bufferTemp;            
    char* bufferDEF;             
    typedef vector<double> rawData; 





int main() 
{ 




    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); 

    ////END OF SETTINGS, START OF COMMUNICATION/////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 


    unsigned char bytes[4]; 
    rawData FootSensors;   
    rawData AllData; 

struct timeval tvalBefore, tvalAfter; 

    int tempRead=0; 
    int posizione = 0; 
    int tempWrite=0; 
    //int byteDaLeggere = 29; 
    //int numerobyte=28; 
    bytes[0]=0x45; 
    //int value; 
    //struct timeval tStart, tEnd, t0, t1, t2; 
// long int elapsedTime10[70], elapsedTimeES, elapsedTime20[70]; 
    long unsigned int c1=0; 
    long unsigned int c2=0; 
    long unsigned int c3=0; 
    long unsigned int c4=0; 
    long unsigned int c5=0; 
    long unsigned int c6=0; 
    cout<<"START"<<endl; 
    gettimeofday (&tvalBefore, NULL);     ///SET START TIME 
    int num=50;    ///NUMBER OF TIMES YOU REQUEST A SET OF 14 SENSORS VALUES 

    /// data: # b1 b2 b3 b4 b5 b6 b7 ... b27 b28 ! 
    ///  ^        ^
    ///   |         | 
    ///  start        end 

    for(int k=0; k<num; k++){ 

    int byteDaLeggere=29; ///after you have found the '#' you want to read 29 byte 

    tempWrite=write(SerialHandleSensorsFoot,bytes,1); ///send 'E' to Arduino 



    if(tempWrite==-1) 
    { 
     cout<<"......ERROR: PROBLEM WRITING TO ROBOTIC HAND"<<endl; 

     return 0; 
    } 

    else{ 
      do{  c1++;                   ///   C1= how many times we read before finding a '#' 
        tempRead = read(SerialHandleSensorsFoot, bufferTemp, 1); 


        if (tempRead == -1) 
         { cout<<"......ERROR: PROBLEM READING FROM ROBOTIC HAND"<<endl; 


          return 0; 
         } 
       } while (bufferTemp[0] != '#'); 






      do{ 
       c2=c2+1;    ///   C2 
       tempRead = read (SerialHandleSensorsFoot, bufferTemp,byteDaLeggere); 

//cout<<"tempread vale: " <<tempRead<<endl; 
        if (tempRead <0) 
          { cout<<"......ERROR: PROBLEM READING FROM ROBOTIC HAND"<<endl; 
           c3++;                ///   C3 
           return 0;     
          } 

        if (tempRead > 0){ 
           c4++;                ///   C4 
         for(int i=0; i< tempRead; i++){ 
         bufferDEF[posizione] = bufferTemp[i]; 

         posizione = posizione + 1;} 


         byteDaLeggere=byteDaLeggere-tempRead; 

        } 

        if (tempRead ==0){ 
         c5++; 
         cout<<"tempRead vale zero!!"<<endl;} 

      }while (byteDaLeggere); 

      //cout<<"Posizione vale: "<<posizione<<endl<<flush; 

      if(bufferDEF[posizione-1] == '!'){ 

     c6++; 

      } 
      else {cout<<"DATO NON LETTO"<<endl;} 
} 
} 
gettimeofday (&tvalAfter, NULL); 
cout<<"FINE"<<endl; 
printf("Time in microseconds: %ld microseconds\n", 
      ((tvalAfter.tv_sec - tvalBefore.tv_sec)*1000000L 
      +tvalAfter.tv_usec) - tvalBefore.tv_usec); 

      cout<<"I've read "<<c1-num<<" charactes before finding '#'"<<endl; 
      cout<<"I've tried to read "<<c2<<" times before getting all the "<<num<<" datas"<<endl; 

      cout<<c3<<"--> Errors in reading function 'tempRead()'"<<endl; 
      cout<<c4<<"--> times I've read something"<<endl; 
      cout<<c5<<"--> times tempread() was 0"<<endl; 
      cout<<c6<<"/"<<num<<" Dati corretti"<<endl; 


} 

的Arduino代碼:

#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; 


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

void longInt2Byte(int x){ 
    unsigned char buf[sizeof(int)]; 
    memcpy(buf,&x,sizeof(int)); 
Serial.write(buf,sizeof(buf)); 



} 

void send16(int value) 
{ 
    Serial.write(value & 0xFF); 
    Serial.write((value >> 8) & 0xFF); 
    /*byte Most=(value & 0xFF); 
    byte Last=((value >> 8) & 0xFF); 
    Serial.print("\nPrimo: "); 
    Serial.print(Most,BIN); 
    Serial.print("\nSecondo: "); 
    Serial.print(Last,BIN);*/ 
} 
//======================================= 

void setup() { 

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

} 
void loop() { 

     // Mando solo quando ricevo qualcosa 
if (Serial.available() > 0) {// Se ho un byte in entrata...   
    incomingByte= Serial.read(); 

    if (incomingByte=='E') { 

Serial.write('#'); 
/* write_read_spi16(0b1000001101110000); 

    for (int i = 1; i<N_SENSORI+1; i++) { 
     short s = write_read_spi16(0b1000001101110000 | (i<<10)); 
     int Lettura = s&0xFFF; 
    send16(Lettura); 
    } 
*/ 

     send16(1234); 
     send16(1111); 
     send16(2222); 
     send16(3333); 
     send16(4444); 
     send16(5555); 
     send16(6666); 
     send16(7777); 
     send16(8888); 
     send16(9999); 
     send16(9898); 
     send16(7676); 
     send16(5454); 
     send16(3232); 


    Serial.write('!'); 


}}} 

正如你可以看到,從Arduino的側面,數據是爲了驗證這水煤漿是不是由於一些ADC問題硬編碼。

這段代碼的輸出是:

....OPENED PORT: Succesfully opened: /dev/rfcomm0 
START 
FINE 
Time in microseconds: 2902017 microseconds 
I've read 0 characters before finding '#' 
I've tried to read 93 times before getting all the 50 datas 
0 --> Errors in reading function "tempRead()" 
93 --> Times I've read something 
0 --> Times tempRead() was 0 
50/50 correct datas 

,你可以看到,它嘗試一次讀取所有的29個字節,但未能一半的時間,所以需要2個講座,收集一個完整的軟件包的29個字節。 傳送50次需要3秒!我需要像50Hz的東西

如果我使用USB連接,它需要0.2秒傳輸50次,但它使用多於6個Cicles收集29個字節。

謝謝你的時間!

的Dario

回答

0

在Arduino的代碼,它出現Serial.write()被調用用於每個字節。這可能會在空中產生一個單獨的RFCOMM框架。

在調用Serial.write()之前,您可以將30個字節聚合到單個緩衝區。

爲了進一步優化,您可能必須捕獲空氣/ HCI日誌。其他要看的是RFCOMM幀大小和Sniff參數(如果有的話)。

+0

我發佈後有同樣的想法!即使在一個字符串中發送所有字節也不能修復它。 我會研究你建議的其他事情。感謝您的建議 –