簡體   English   中英

Docklight和Arduino串行通信(通過RS232發送十六進制)

[英]Docklight and Arduino serial communication (sending hex through RS232)

我有以下代碼(我正在使用Arduino IDE和帶有MAX3232的NodeMCU):

#include <SoftwareSerial.h>

SoftwareSerial RS232Serial(D1, D2); // RX | TX

void setup() {
  Serial.begin(9600);
  while (!Serial);

  RS232Serial.begin(9600);
  while (!RS232Serial);
}

void loop() {

  Serial.println("Sending msg...");
  char msg[] = {0x7E, 0x00, 0x78, 0xF0, 0x7E};

  RS232Serial.write(msg, sizeof(msg));

  Serial.println("Waiting incomming message:");
  while(RS232Serial.available() <= 0) {
    delay(1);
  }

  while(RS232Serial.available() > 0) {
    Serial.print(RS232Serial.read(), HEX);
  }

  Serial.println("");

  Serial.println("------------ END -----------");

}

我正在使用Docklight測試通信。 到目前為止,我已經能夠收到NodeMCU板發送第一個char msg[] = {0x7E, 0x00, 0x78, 0xF0, 0x7E};的十六進制信息char msg[] = {0x7E, 0x00, 0x78, 0xF0, 0x7E}; 但是我無法從Docklight正確接收數據。

我嘗試從Docklight發送的十六進制為7E 00 00 70 15 7E 使用串行監視器進行調試時,有時我只會收到7E ,有時會收到0FF ,卻從未收到完整的消息。 波特率,開始/停止位和奇偶校驗設置為默認值。

我的代碼有什么問題?

無法按預期工作的原因之一是:

  • 一旦接收緩沖區中出現一個字節,您就在處理答案。

Docklight應用筆記Arduino串行通信中有一個相關示例-檢查第5頁上的代碼清單。它利用Arduino SerialEvent()函數逐字節收集傳入的電報。 僅在接收到電報標記的結尾(此處是換行符“ \\ n”)之后,它才會設置一個標志,該標志告訴main loop()中的代碼對累積的數據電報執行某些操作。

Docklight示例中使用的SerialEvent方法不是必須的。 您也可以單獨解決這個內部loop()。 但是您當然需要更改

  while(RS232Serial.available() <= 0) {

...

  while(RS232Serial.available() > 0) {

部分內容將等待接收到完整的電報(或發生超時)。

現在仍然讓我感到煩惱的是,即使您從未從Docklight發送它,您有時也會收到“ 0FF”。 這可能表明實際的RS232通信仍然存在第二個問題,但是如果沒有額外的信息就很難猜測。

但是,如上所述,對電報接收部件進行重新加工應該已經使事情變得更加清晰,因此“ 0FF”的來源可能更加明顯。

while(RS232Serial.available() <= 0) {
  delay(1);
}

您只在等待串行緩沖區至少有1個字節,但是當您調用RS232Serial.available()時,不能保證將顯示完整消息(6個字節RS232Serial.available()

在嘗試讀取串行緩沖區之前,您應該等待串行緩沖區至少累積6個字節。

while(RS232Serial.available() < 6) {
  delay(1);
}

您可以使用以下命令讀取完整的緩沖區:

while(RS232Serial.available() > 0) {
  Serial.print(RS232Serial.read(), HEX);
}

或只有6個字節,並帶有:

for (int i=0; i<6; i++) {
  Serial.print(RS232Serial.read(), HEX);
}

我不知道您的0FF ,但Serial.print(RS232Serial.read(), HEX)不會對十六進制字符串進行零填充,而實際上可能是00 0F 0F00 FF

您應該使用以下命令打印字節:

byte b = RS232Serial.read();
if (b < 16) Serial.print('0'); // zero pad
Serial.print(b, HEX);
Serial.print(' '); // add space after each byte

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM