2017-07-10 253 views
0

我有一個問題,用於從串口分離引擎控制系統字符串數據。通信協議描述如下。如何在Arduino上分割ECU字符串數據?

示例: 檢索顯示在FADEC LCD屏幕上的數據。如果命令是RSD,那麼輸出將是:

**C7h 2Ch 52h 53h 44h 2Ch 0Dh** 

C7h -> Sync 
2Ch -> 「,」 Separator 
52h -> 「R」 
53h -> 「S」 
44h -> 「D」 
2Ch -> 「,」 Separator 
0Dh -> CR, last byte. 

ECU將返回兩個字符串。第一個是收到的命令的副本,後面跟着要求的數據。在上面的例子中,它將返回:

**C7h, RSD, 0Dh** 
C7h -> Sync byte 
2Ch -> 「,」 Separator 

Payload in ASCII 「TrimLow EGT 20CRpm 50.000Pw=124」 
2Ch -> 「,」 Separator 
0Dh -> CR, last byte. 

我以字符串格式讀取屏幕上的所有數據。當我向ECU發送RCV時,它將按照上述形式返回RPM,溫度,泵電壓,電池電壓和節氣門。

Xicoy說明:(命令,即,有效載荷)

RCV讀取電流值RPM,EGT在ºC,水泵電源,電池的電壓,油門%

byte veri[]= { 0xC7, 0x2C, 0x52, 0x43, 0x56, 0x2C, 0x0D }; // for RCV 

和數據表(第5-6-7頁):http://www.xicoy.com/SerialAdapt1_0.pdf

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(10, 11); // RX, TX 
int i=0; 
byte veri[]= { 0xC7, 0x2C, 0x52, 0x43, 0x56, 0x2C, 0x0D }; // RCV 
int myTimeout = 100; 

void setup() { 
    Serial.begin(9600); 
    mySerial.begin(9600); 
    mySerial.setTimeout(myTimeout); 
} 

void loop() { 
    Serial.println(mySerial.readString()); 
    for(i=0;i<7;i++) 
    { 
    mySerial.write(veri[i]); 
    } 
} 

我該如何分開RPM,EGT°C,泵電壓,電池電壓以及從ECU返回的數據包中的節流百分比?在辨別過程之後,我會通過第二個串口將它發送到LabView。 RPM值可以是6位數字(大約120000 RPM),排氣溫度是3位數字(EGT 800°C),這些數字可能會丟失,因爲除了油門值以外,所有數字都是零。你能分享一個樣本嗎?謝謝。

圖片:

+0

是否有Arduino的CSV解析庫?我對Arduinos不是很熟悉。 – Gaurav

+1

一個普通的'sscanf'可以工作。由於Arduino使用C++的變體,因此可能有其他方法來獲取子字符串。 –

回答

-1

由於值大,他們不能被parseInt()解析。因此,你將需要通過首先找到逗號做一些字符串解析:

void setup() { 
    Serial.begin(9600); 
} 

void loop() { 

    String csv = "123,34566,12"; 

    int lastcommaPos; 
    int commaPos = csv.indexOf(',', 0); // find first comma 
    String val1 = csv.substring(0, commaPos); // grab first value 

    lastcommaPos = commaPos + 1; 
    commaPos = csv.indexOf(',', lastcommaPos); // find next comma 
    String val2 = csv.substring(lastcommaPos, commaPos); // grab next value 

    lastcommaPos = commaPos + 1; 
    commaPos = csv.indexOf(',', lastcommaPos); // find next comma 
    String val3 = csv.substring(lastcommaPos, commaPos); // grab next value 

    Serial.println(val1); 
    Serial.println(val2); 
    Serial.println(val3); 

    delay(2000); 
} 

所以一般:

  1. 保持位置的跟蹤
  2. 查找下一個逗號
  3. 抓住兩者之間的子串
  4. 更新位置
  5. 重複直到完成。
+0

不適合我..謝謝 – aytac

+0

@aytac我看到你正在解析大的價值。請看看我更新的答案。 – TomServo

+0

@aytac我剛剛發佈了一個完整的工作示例,現在在Uno上運行。這工作。 – TomServo

-1

也回答是;

#include <SoftwareSerial.h> 

SoftwareSerial mySerial(10, 11); // RX, TX 

int i=0; 
byte veri[]= { 0xC7, 0x2C, 0x52, 0x43, 0x56, 0x2C, 0x0D }; // RCV 
int myTimeout = 10; 
String veri2[]={}; 
void setup() { 
Serial.begin(9600); 
while (!Serial) { 
} 
analogWrite(5,250); 
mySerial.begin(9600); 
mySerial.setTimeout(myTimeout); 
} 

void loop() { // run over and over 

for(i=0;i<7;i++) 
{ 
mySerial.write(veri[i]); 
} 

String split = mySerial.readString(); 
String word3 = getValue(split, ',',0); 
Serial.println(word3); 
for(i=0;i<7;i++) 
{ 
mySerial.write(veri[i]); 
} 

String split2 = mySerial.readString(); 
String word4= getValue(split2, ',',1); 
Serial.println(word4); 
/* 
split = mySerial.readString(); 
word3 = getValue(split, ',',2); 
Serial.println(word3); 
split = mySerial.readString(); 
word3 = getValue(split, ',',3); 
Serial.println(word3); 
split = mySerial.readString(); 
word3 = getValue(split, ',',4); 
Serial.println(word3); 
split = mySerial.readString(); 
word3 = getValue(split, ',',5); 
Serial.println(word3); 
split = mySerial.readString(); 
word3 = getValue(split, ',',6); 
Serial.println(word3); 
split = mySerial.readString(); 
word3 = getValue(split, ',',7); 
Serial.println(word3); 
} 

*/

String getValue(String data, char separator, int index) 
{ 
int found = 0; 
int strIndex[] = {0, -1}; 
int maxIndex = data.length()-1; 

for(int i=0; i<=maxIndex && found<=index; i++){ 
if(data.charAt(i)==separator || i==maxIndex){ 
    found++; 
    strIndex[0] = strIndex[1]+1; 
    strIndex[1] = (i == maxIndex) ? i+1 : i; 
} 
} 

return found>index ? data.substring(strIndex[0], strIndex[1]) : ""; 
}