2013年5月19日 星期日

Arduino : 以 serproxy 搭起和 Flash 間的橋樑

2013年5月19日 星期日
Adobe Flash 可以在電腦上輕鬆的製作出美觀的互動介面,而 Arduino 可以接上實體的感應器取得數值或是控制輸出裝置,這兩個合起玩,可以擦出什麼火花呢?
Arduino Uno 的 USB 線接上電腦,提供了一個 Serial Port 來和電腦交換訊息,這是可以運用的窗口。上網找了一下,透過 serproxy 這個小工具,可以同時監聽 Serial port 並建立一個監聽 TCP port 5531~5534 的 socket server。這樣一來,Arduino 連到 Serial Port 的窗口,而 Flash 則可以透過 XMLSocket 來連到 socket server 的窗口,軟硬體就這麼透過 serproxy 連線了!
先來玩一下 hello world 等級的小題目,用 Flash 上的兩個按鈕來控制連接在 Arduino 上的兩顆 LED,當 Flash 的綠色按鈕被按住時,接在 Arduino pin 12 的綠色 LED 就保持亮的狀態,按鈕放開後就熄滅,而 Flash 的紅色按鈕則以同樣的方式來控制接在 Arduino pin 13 上的紅色 LED。

下載與設定 serproxy

我們可以在下面的網站中找到 serproxy :


點選頁面中「Files」的連結,看到檔案清單後下載「serproxy-0.1.3-3.bin.win32.zip」即可。
將檔案解壓縮以後,裡面有一個名為「serproxy.exe」的執行檔,另一個「serproxy.cfg」則為設定檔,可以用類似 Notepad++ 的文字編輯器打開設定檔依個人需求編輯。修改之前,可以先確認一下 Arduino 是使用哪一個串列埠:
下面是 serproxy.cfg 的範例內容(我只改了comm_baud=115200):

# Config file for serproxy
# See serproxy's README file for documentation
# Transform newlines coming from the serial port into nils
# true (e.g. if using Flash) or false
newlines_to_nils=true
# Comm ports used
comm_ports=1,2,3,4
# Default settings
comm_baud=115200
comm_databits=8
comm_stopbits=1
comm_parity=none
# Idle time out in seconds
timeout=300
# Port 1 settings (ttyS0)
net_port1=5331
# Port 2 settings (ttyS1)
net_port2=5332
# Port 3 settings (ttyS2)
net_port3=5333
# Port 4 settings (ttyS3)
net_port4=5334

上面的參數可能有需要修改的有:

  • comm_ports:預設是監聽 COM1, COM2, COM3, COM4,看 Arduino 是接在哪一個串列埠。像我的是接在 COM4,這個參數就不用修改。
  • comm_baud:連線速度,這裡的設定要配合 Arduino 中的設定,像我的程式用「Serial.begin(115200);」,所以這個參數就要設為「comm_baud=115200」。
  • net_port1、net_port2、net_port3、net_port4:設定串列埠對應到 TCP 哪一個 port,socket server 會依裡的設定來建立。像我的 Arduino 是接在 COM4 ,依預設值會對應到 TCP 5334,所以在 Flash 的程式中,XMLSocket 連線時,port 就要設為 5334。

改好設定檔並儲存好以後,只要執行 「serproxy.exe」就等 Arduino 和 Flash 來傳送資料了。

Arduino 硬體配置圖

將紅色 LED 接在 pin 13,而綠色 LED 則是接在 pin 12
Arduino 程式碼

假設當我們在 Flash 中按下綠色按鈕時會送出「G:1」,放開按鈕時會送出「G:0」;而按下紅色按鈕時會送出「R:1」,放開按鈕時會送出「R:0」。serproxy 經由 socket server 收到後,會將字串送往串列埠。Arduino 中接收串列埠資料的函數有以下幾個:

  • Serial.read()
  • Serial.readBytes()
  • Serial.readBytesUntil()

Flash 送給 socket server 的字串都會以 0x00 來結束,我們利用 Serial.readBytesUntil() 就可以讓它用 0x00 來判斷資料是否讀取完畢了。以下是 Arduino 的程式碼:

#define bufferSize   16
#define greenLedPin  12
#define redLedPin    13
void setup() {
  pinMode(greenLedPin, OUTPUT); // declare the greenLedPin as an OUTPUT
  pinMode(redLedPin, OUTPUT); // declare the redLedPin as an OUTPUT
  Serial.begin(115200);
}
void loop() {
  while (Serial.available() > 0) {
    char inBuffer[bufferSize];
    int stringLength;
    stringLength = Serial.readBytesUntil('\0', inBuffer, bufferSize);
    if (stringLength > 0) {
      inBuffer[stringLength] = '\0';
      String inString = String(inBuffer);
      Serial.println(inString);
      if ( inString == "G:1" ) {
          digitalWrite(greenLedPin, HIGH);
      } else  if ( inString ==  "G:0" ) {
          digitalWrite(greenLedPin, LOW);
      } else  if ( inString == "R:1" ) {
          digitalWrite(redLedPin, HIGH);
      } else  if ( inString == "R:0" ) {
          digitalWrite(redLedPin, LOW);
      }
    }
  }
}


Flash 程式碼


Flash 的部份因為我是用 Flash 8 ,AS2 和新版的語法可能有些許不同。主要是利用 XMLSocket 來和 serproxy 所建立的 socket server 來通訊。使用兩個關鍵影格來完成任務。
影格一:

if(server == undefined) {
server = '127.0.0.1';
}
if(port == undefined || isNaN(Number(port))) {
port = 5334;
} else {
port = Number(port);
}

isConnected = false;
socket = new XMLSocket()
socket.onConnect = function(success) {
if (success) {
statusTxt.text = "conneted";
isConnected = true;
} else {
statusTxt.text = "connet failed!";
isConnected = false;
}
}
socket.onData = function(src) {
statusTxt.text =  "data : " + src;
}
socket.onClose = function() {
statusTxt.text = "disconneted";
isConnected = false;
}

主要內容說明如下:

  • socket.onConnect:設定連線成功(失敗)時要進行的動作。
  • socket.onData:設定資料接收完成要進行的動作。
  • socket.onClose:設定斷線後要進行的動作。


影格二:

stop();
infoTxt.text = "Server:" + server + "   Port:" + port;
socket.connect(server, port);
greenButton.onPress = function() {
if( isConnected ) {
socket.send("G:1");
};
}
greenButton.onRelease = function() {
if( isConnected ) {
socket.send("G:0");
};
}
redButton.onPress = function() {
if( isConnected ) {
socket.send("R:1");
};
}
redButton.onRelease = function() {
if( isConnected ) {
socket.send("R:0");
};
}

影格二主要是進行連線,並建立按鈕所要做的動作:

  • socket.connect(server, port):依指定的 IP 及 port (設定影格一)和 socket server 連線。
  • greenButton.onPress、greenButton.onRelease:設定綠色按鈕按下、放開時要進行的動作。
  • redButton.onPress、redButton.onRelease:設定紅色按鈕按下、放開時要進行的動作。

[注意] 由於 Flash 的安全管制,編譯完的 .swf 並無法在本機執行,記得要修改「受信任的位置設定」,將 .swf 的位置加入,不然,啟動 .swf 時只會看到「安全性」警語而無法正常動作。

除了 serproxy 可以轉換 Serial port 和 Socket Server 間的資料,現在還有不少小工具也有相同的功能,Arduino Playground 中的這篇文章有詳細的介紹:


有空再來試試別的程式。


檔案下載

相關文章



沒有留言:

張貼留言

 
雄::gsyan © 2009. Design by Pocket