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)
可以參考這篇文章的圖示


2011-05-06

以Mindsensors NumericPad作為Arduino的輸入裝置

這是我的第一個Arduinocase
因為手中有一些NXT數位感應器,因此希望能夠結合Arduino豐富多樣的應用,在往後會有更多有趣的題材可以嘗試。
<Arduino_I 2C _NP_05.jpg>

而在這個以NumericPad作為Arduino輸入裝置的case中,會由Arduino boardI 2C通訊功能來寫入與讀取Mindsensors NumericPadregister,並將偵測到的按鍵狀態經由7-segment LED作為視覺化的輸出。
記錄的影片如下:




/video/

接下來是進行這個case所整理、記錄的資料:
Arduino UNONXT I 2C裝置的腳位對應
Arduino UNO board I 2C通訊所使用的腳位為A4(SDA)A5(SCL)
對應NXT則為Pin 6(藍色)(SDA) Pin 5(黃色)(SCL),以及以下兩個腳位的對應:
NXT Pin 4(
綠色)(4.3V Power) à Arduino 5V
NXT Pin2/3(
/)(GND)    à Arduino GND

如下圖:
<
Arduino_I 2C _PinMap.JPG>

<
Arduino_NXT_Pinout_Map.JPG>
Arduino NXT I 2C Device Library
Arduino I2C Communication Library為:<Wire.h>,撰寫操作NXT I 2C裝置的Arduino程式即可以運用這個Librarymethods
不過目前有一組NXT I2C Device Library DevTeam成員正以<Wire.h>發展NXT I2C Devices的專屬程式庫,相關資訊可參考本專案的,同時可以由這個下載點取得最新版本的Library檔案,裡面附有相當齊全的說明文件與範例程式,非常有參考價值。
在這個專案的Library,共包含兩個部分:

(1)  NXT I 2C Devices通用程式庫<NXTI2CDevice.h>:具備符合NXT register layout的基本I 2C methods,如同NXCleJOS進行I 2C通訊的呼叫方式一樣,比起直接使用<Wire.h>相對較為便利與熟悉。
(2)  部份NXT數位感應器專屬之Device Class:提供使用者程式可以直接呼叫裝置功能的methods,而不須處理Register的讀寫動作,就如同leJOS Device Class的使用方式。
目前已提供的共有11Mindsensors數位裝置,如:NXTMMXNXTHIDNXTServoNXTCam以及PSPNX等。
至於只有mindsensors Device Class的原因,我想是因為Mr.
Deeptak Patil
也是NXT I2C Device Library Dev Team專案成員之一的緣故,不過其他的數位裝置,還是可以利用(1)的方式來處理。
Arduino程式
NumericPad並沒有專屬之Device Class,所以需要以(1) I 2C access methods來讀寫registers
使用前須先留意一個在NumericPad User’s Guide所沒有提到的初始化動作,我也是參考了NXC範例程式庫(np-lib.nxc)之後才發現的,所以同樣在Arduino程式中的setup()也需要先執行NumericPad的初始化程序。
Arduino
程式用法摘要如后:

(1)   呼叫 NXTI 2C Device
class
的建構子(constructor),同時傳入NumericPadI 2C address(0xB4),來宣告及建立NumericPadinstance(numpadinstance variable)

NXTI 2C Device numpad(0xB4);
(2)   setup()中呼叫writeRegisters() method執行初始化動作:
numpad.writeRegisters(0x41, 9, Group1);
numpad.writeRegisters(0x 4A , 8, Group2);
numpad.writeRegisters(0x7D, 3, Group7);
(3)   loop()中呼叫readInteger() method讀取NumericPad的按鍵狀態值(2 Bytes,以Integer type回傳)加上adjustbitSeq()的原因是為了要調整回傳值中bit 6/7bit 10/11的順序,讓它能夠與layout一致,方便後續對應led pattern陣列的index
numpad_keyValue = adjustBitSeq(numpad.readInteger(NUMPad_Register));
(4)   bit 0開始逐一比對按鍵狀態,並輸出到7-segment LED作顯示。
範例程式:Here
Summary

7-segment LED作為輸出將會囿於只能顯示一個按鍵值的限制,而無法展現NumericPad可以回應多重觸控的功能,我在另外一個Arduino程式使用Serial Monitor就可以顯示出所有的觸控按鍵值。
不過,因為Arduino擁有豐富的電子聲光週邊,所以用來發揮多樣化的視覺、聽覺效果應該會比NXT容易。




  • 留言者: CAVE教育團隊
  • Email: zero.five@msa.hinet.net
  • 網址:
  • 日期: 2011-05-09 00:08:44
CH_Lego:

   This is a good topic for MAKE magazine, if you like.

                                                       CAVE






  • 留言者: 探奇自然科學教室
  • Email: touch_classroom@yahoo.com.tw
  • 網址:
  • 日期: 2011-05-07 16:54:34
謝謝ch lego先生的好文,我會盡快發文介紹,分享給大家知道。

順便說一下,這個Team的成員除了Deepak外,Clinton是RobotC for Arduino的人。

所以就聚在一起了!

[版主回覆05/07/2011 17:19:49]
謝謝邱老師,
剛開始玩arduino, 現在有如好奇寶寶, 到處找資料

昨天發mail問Deepak 如何寫arduino library,
他問我是否要加入 Develop team, 若有意願的話可以發信給 Clinton,
果然這一組team都是 NXT圈內人