2011-05-23

連接 NXT 與 Arduino 的 RS485通訊



Arduino RS485通訊介面


Arduino廠商DFRobotIO EXPANSION SHIELD FOR ARDUINO擴充板使用MAX 485 CPA晶片來處理RS485通訊,可以用來作為與NXT之間的RS485通訊。




<
Arduino-RS485-NXT-00>




此晶片的RO(Data output)DI(Data input) Pin分別對應至Arduino Serial portD0(RX)D1(TX) Pin,因此可以運用ArduinoSerial程式庫來進行資料通訊的功能。



另外晶片之DE (output enable)RE(Receiver Enable)兩個Pins同時對應至ArduinoD2,因此對於D2 PinHIGH/LOW設定,即作為enable RS485 Transmit/Receive的功能控制。



擴充板上提供一個標示為RS485的接線端子,包含:VCCGNDAB四個接點,作為Arduino對外進行RS485通訊的的介接界面,其中的AB 接點分別對應至晶片的AB pin,而NXT即是透過這個接線端子與Arduino連接來進行RS485通訊。


<
Arduino-RS485-NXT-02>




NXT Cable連接之腳位對應:




NXT Cable使用三個腳位來連接擴充板的RS485接線端子,分別是:




Pin 5 (DIGI0)(黃色) 對應 端子 A

Pin 6 (DIGI1)(藍色) 對應 端子 B

Pin2/3
(GND)(/)對應
端子
GND





<
Arduino-RS485-NXT-03
>


<
Arduino-RS485-NXT-01>




NXT
RS485
通訊功能




參考本篇之實作說明:NXT
High Speed Communication over XBee




NXT接收來自Arduino的傳送資料




Arduino端資料傳送程式(Arduino_SendTo_NXT.pde)




/*
********************************************* */




const
int DE_RE_PIN = 2;

void setup()

{

    pinMode(DE_RE_PIN, OUTPUT);

    Serial.begin(9600);

}

void loop()

{




    digitalWrite(DE_RE_PIN, HIGH);  // Enable data transmit




    delay(1000);




    Serial.print("Hi NXT ! ");   




    delay(1000);




    Serial.print("Good Day ^^ ");




      




}




NXT端接收資料程式(NXT_Rcv_Arduino.nxc)




void
Go_Rtn()




{




   string strReceive;




   short xline = LCD_LINE4;




   while(TRUE)




   {




        until(RS485DataAvailable()) Wait(1000);




        RS485Read(strReceive);




        TextOut( 0, xline,   strReceive);




        TextOut( 0, xline-8, "                " );




        if (xline > LCD_LINE7) xline = xline
- 8;




        else                   xline = LCD_LINE4;




   }




}




void
Init_Rtn()




{




   UseRS485();




   RS485Uart(HS_BAUD_9600, HS_MODE_8N1);




}




task
main()




{




   ClearScreen();




   TextOut(0, LCD_LINE1, "Arduino --->
NXT" );




   TextOut(0, LCD_LINE2, "    via RS485  
" );  




   Init_Rtn();




   Go_Rtn();




}




程式執行畫面:





<
Arduino_to_NXT>


 




Arduino接收來自NXT的傳送資料




NXT端資料傳送程式(NXT_SendArduino.nxc)




void
Go_Rtn()




{




   string toArduinoMsg_Hi = "Hi Arduino
!@" ;




   string toArduinoMsg_GD = "Good Day :)
@" ;




   TextOut(0, LCD_LINE4, "Transmitting
..." );




   while(TRUE)




   {




        TextOut(0, LCD_LINE5, "                " );




        TextOut(0, LCD_LINE6, "                " );




        TextOut(0, LCD_LINE5, toArduinoMsg_Hi);




        SendRS485String(toArduinoMsg_Hi);




        while (RS485SendingData());       




        Wait(1000);




        TextOut(0, LCD_LINE6, toArduinoMsg_GD);




        SendRS485String(toArduinoMsg_GD);




        while (RS485SendingData());       




        Wait(1000);




   }




}




void
Init_Rtn()




{




   UseRS485();




   RS485Uart(HS_BAUD_9600, HS_MODE_8N1);




}




task
main()




{




   ClearScreen();




   TextOut(0, LCD_LINE1, "NXT --->
Arduino" );




   TextOut(0, LCD_LINE2, "    via RS485  
" );  




   Init_Rtn();




   Go_Rtn();




}




Arduino端接收資料程式(Arduino_RcvFm_NXT.pde)




const
int DE_RE_PIN = 2;




const
int MSG_LENGTH_LIMIT = 16;




char
rcvByte;




int
byteIndex=0;




char
rcvMessage [MSG_LENGTH_LIMIT];




void
printMessage()




{




     Serial.print(byteIndex+1);




     Serial.println(" bytes
received");




     for (int xi=0; xi <= byteIndex; xi++)




     {




        
if (xi < byteIndex) Serial.print(rcvMessage[xi]);




         else                Serial.println(rcvMessage[xi]);




         rcvMessage[xi] = ' ';




     }




}




void
setup()




{




    pinMode(DE_RE_PIN, OUTPUT);   




    Serial.begin(9600);




}




void
loop()




{




    digitalWrite(DE_RE_PIN, LOW);  // Enable data receive




    if (Serial.available() > 0)




    {




       rcvByte = Serial.read();      




       if ((rcvByte == '@') || (byteIndex ==
MSG_LENGTH_LIMIT))




       {         




          printMessage();




          byteIndex = 0;




          Serial.flush();




       }




       else




       {




          if ((rcvByte >= ' ') &&
(rcvByte <= 'z'))




          {




            rcvMessage[byteIndex] = rcvByte;




            byteIndex++;




          }




       }




    }    




}




程式執行畫面:





<
NXT_to_Arduino>




 






  • 留言者: YT
  • Email: yiting.lai1688@gmail.com
  • 網址:
  • 日期: 2012-01-05 04:43:58
您好:
請問您可否跟我說您此塊IO Expansion Shield是在何處購買的(可否貼上網址), 因為我最近在PChome的露天拍賣買了兩塊IO Expansion Shield, 我是使用此塊的RS-485跟泓格科技的遠端I/O模組通訊, 第一塊測試時Arduino可傳送資料但無法接收到遠端I/O模組傳回的資料,後來覺得是此塊IO Expansion Shield硬體有問題又再買了第二塊, 第二塊測試時Arduino可傳送資料給遠端I/O模組, 但我不知為何遠端I/O模組無回應, 在資料接收測試部份, 測試沒問題, 但後來我將第二塊
IO Expansion Shield接上另一塊Arduino後, 再做一次傳送資料給遠端I/O模組的測試, 這次的測試結果竟然遠端I/O模組有回應了, 但是原本可以資料接收的, 卻在上述測試之後就無法再接收到資料了, 我不知道為何會這樣, 我不知道是我的問題, 還是IO Expansion Shield又壞了(感覺此IO Expansion Shield穩定性不高), 麻煩您了, thanks
[版主回覆01/06/2012 22:42:14]

這一片卡是由DFRobot出的, 我是向原廠買的, 網址如下:
http://www.dfrobot.com/index.php?route=product/product&path=35_39&product_id=264


建議也可以買一顆 MAX485CP 晶片, 先用麵包板測試看看, 這裡有一篇文章可以參考


http://rostrich.wordpress.com/2010/05/16/nxt-and-arduino-talking-rs-485/







  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-27 21:25:06
再請教一個問題,我用過bircx中的NeXT Screen,重來看不到上面的畫面,這要如何設定?
[版主回覆11/27/2011 22:50:45]游標移到NXTScreen, 按右鍵, 就會出現選項可以設定(Pool週期)





  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-27 21:18:46
我好像找到問題發生處了…若是arduino的電源是吃USB的話, 一切都不正常,反過來由NXT供電給arduino,不論是nxt 用i2c連arduino或是用rs485連arduino,就全正常了…這是為何??
[版主回覆11/27/2011 22:48:40]

如果是RS485通訊, 你可以看到就這篇文章的接線照片, 事實上我並沒由把NXT的電源接上, 只接了GND' DIG0' DIG1, 而Arduino由USB供電, 這樣是可以正常工作的.

至於I2C通訊, 因為NXT是Master, 主控時脈與資料, 理論上由NXT供電在傳輸上會比較不受干擾.



不過, 像在這一篇文章中的圖片顯示, NXT有提供電源(接Vin), 同時Arduino也接上USB, 但工作仍然正常, 所以, 我也不是很確定真正的原因.







  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-26 09:53:00
再請教一個小問題,當使用nxt及arduino用i2c連線時二個的電源是分別供電嗎?還是全都是用nxt的電源??nxt的輸出電壓我量過只有4.7V....
[版主回覆11/26/2011 12:07:21]參考這一張照片以及接線圖 純粹由NXT來供電,
NXT在sensor port使用第四條(綠色)供電, 電壓是整流後4.3V,
電流是7個ports共用180 MA, arduino工作電壓通常是5V, 所以應該正常





  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-22 15:03:37
你好!在我向你請教這個問題之前就己經參考這篇,並改過jumper位置在rs485的位置上且把接地線拿掉,所以才能有只能單向接收的狀况;沒改jumper且同時有接地,雙向的訊息都接不到!!還有,我也試過你的程式用i2c連接arduino…結果也是很慘…完全沒反應…我後使用三用電表測了一下nxt發出的信號強度…電壓很低咧…arduino發出的信號強度就很高,很奇怪…不知問題發生在哪裏…


[版主回覆11/22/2011 22:01:17]我的直覺會不會NXT的電力不足,
對於NXT與Arduino之間的I2C通訊, 我在不同的應用經過多次測試,
唯一碰到的問題就是如果對SDA與SCL加了 pull-up之後就不能通的情況,
尤其是4.7K ,怪的是其他阻值或不加卻都可以,
其他都沒什麼問題, 甚至串接了好幾個裝置在I2C bus也OK.
再試看看,若還有問題可以PO上照片‘程式,
方便一起切磋討論






  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-22 14:55:01
HI!謝謝你的回應!不過,狀况依舊!關於你給我參考的那篇,在寫信請教你之前,我就改過jumper位置在RS485上,沒改的話,連回應都不會有…現在我在網路上訂了第二組的arduino來試著作接收。有進一步的問題及發現再向你請教,謝謝!

[版主回覆11/22/2011 22:16:29]另外再補充一下剛才I2C問題的建議,
可以先試兩部Arduino之間的I2C通訊(記得要加Pull-up),
若沒問題再試NXT,
測試時除了要common ground之外, 電力要由Master供電會比較好






  • 留言者: flytank
  • Email: tainan_61@yahoo.com.tw
  • 網址:
  • 日期: 2011-11-16 08:16:25
你好!我用了與你相同的環境,也引用你寫的程式進行測試,結果發現二件怪事…
1.把NXT的地線接在Arduino 擴充板RS485接地端之後,不論是nxt傳給arduino或是arduino傳給nxt,完全沒作用…
2.把接地線拆下後,NXT可以透過RS485傳給arduino,但nxt卻收不到arduino傳的訊息…

不知道我的問題出在哪裏?可以幫我解惑嗎?謝謝!
**我已經把nxt的韌体升級成NXC支援的加強版了,不升級無法編譯你所寫的NXC程式

[版主回覆11/16/2011 14:06:49]

在IO Expansion Shield上的 Jumper需要轉換成RS485(預設為RS232)
可以參考這篇文章的圖示


沒有留言:

張貼留言