2012-07-05 25 views

回答

1

我有一個這樣的項目。礦山正在發送一個轉向系統的位置數據,但這個想法是一樣的。我會盡快將它上傳到Google Code。你可以在PowerWheelino查看。

的基本結構是這樣的:

  1. Android上觸摸事件發送數據(超過UDP)到服務器。
  2. UDP服務器(在這種情況下爲WRT54G路由器)接收數據並通過串行將其轉發給Arduino。
  3. Arduino決定如何處理來自串行連接的數據。

請記住,當通過串行(在IDE串行接口之外)接收數據時,Arduino會自動復位。關於此主題,請參閱我的文章here以及解決方法。以前知道這將節省我很多的疑難解答。

免責聲明:

此代碼需要一些小的修改,以實現由OP什麼要求。既然你已經用IOIO和Arduino草圖製作了一個可用的Android程序,我認爲這是你的能力。

下面是Android的UDP客戶端代碼:

觸摸事件或按下按鈕執行UdpClient::sendData()

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 

import android.util.Log; 

public class UdpClient { 
    String messageStr; 
    DatagramSocket s;; 
    int server_port; 
    InetAddress local; 
    int msg_length; 
    byte[] message; 

    public UdpClient (String ipAddress, int port){ 
     server_port = port; 
     try { 
      local = InetAddress.getByName(ipAddress); 
      s = new DatagramSocket(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
      Log.d("Powerwheelino",e.getStackTrace() + "error"); 
     } 
    } 

    public boolean sendData(byte drive, byte steering){ 
     byte drvByte = (byte) (drive & 0xFF); 
     byte steerByte = (byte) (steering & 0xFF); 
     message = new byte[2]; 
     message[0] = drvByte; 
     message[1] = steerByte; 
     msg_length = message.length; 
     //message = messageStr.getBytes(); 
     try { 
      DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port); 
      s.send(p); 
     } 
     catch (Exception e) { 
      // TODO Auto-generated catch block 
      Log.d("Powerwheelino", e.getStackTrace() +"ERROR "); 
      e.printStackTrace(); 
      return false; 
     } 
     return true; 
    } 
} 

這裏的監聽UDP服務器(C++)代碼

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
#include <string> 
#include <SerialStream.h> 

using namespace std; 

class udp_server { 
    int sock; 
    int bytes_read; 
    socklen_t addr_len; 

    struct sockaddr_in server_addr , client_addr; 

    public: 
     udp_server(int portNum) 
     { 
      if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 
       perror("Socket"); 
       exit(1); 
      } 

      server_addr.sin_family = AF_INET; 
      server_addr.sin_port = htons(portNum); 
      server_addr.sin_addr.s_addr = INADDR_ANY; 
      bzero(&(server_addr.sin_zero),8); 


      if (bind(sock,(struct sockaddr *)&server_addr, 
       sizeof(struct sockaddr)) == -1) 
      { 
       perror("Bind"); 
       exit(1); 
      } 

      addr_len = sizeof(struct sockaddr); 

      printf("\nUDPServer Waiting for client on port %d", portNum); 
       fflush(stdout); 
     } 

     int listen(char recv_data[]) { 
      while (1) 
      { 
       bytes_read = recvfrom(
           sock, 
           recv_data, 
           1024, 
           0, 
           (struct sockaddr *)&client_addr, 
           &addr_len 
          ); 

       recv_data[bytes_read] = '\0'; 
       printf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr), 
              ntohs(client_addr.sin_port)); 
       printf("%s", recv_data); 
       string drive; 
       string direction; 
       int speed, angle; 

       if ((recv_data[0] & 128) > 0) { 
        drive = "Fwd"; 
       } 
       else { 
        drive = "Rev"; 
       } 
       if ((recv_data[1] & 128) > 0) { 
        direction = "Left"; 
       } 
       else { 
        direction = "Right"; 
       } 
       speed = recv_data[0] & 127; 
       angle = recv_data[1] & 127; 
       printf("\t %s @ %d and %s @ %d", 
         drive.c_str(), 
         speed, 
         direction.c_str(), 
         angle); 
       fflush(stdout); 
      } 
      return 0; 
     } 
}; 

下面是一個使用LibSerial到Arduino的串行通信的一個片段:

LibSerial::SerialStream myss; 
SerialComm(int argc, char** argv) { 
    myss = new LibSerial::SerialStream("/dev/ttyS0", ios_base::out); 
    myss.SetBaudRate(LibSerial::SerialStreamBuf::BAUD_57600); 
    myss.SetCharSize(LibSerial::SerialStreamBuf::CHAR_SIZE_8); 
    myss.SetFlowControl(LibSerial::SerialStreamBuf::FLOW_CONTROL_NONE); 
    myss.SetParity(LibSerial::SerialStreamBuf::PARITY_NONE); 
    myss.SetNumOfStopBits(1); 

    const int Dsize = 2; 
    char buffer[1]; 
    buffer[0] = 125; //0b00000001; 
    buffer[1] = '\0'; 
    bitset(buffer[0]); 
    //myss << buffer; 
    myss.write(buffer,1); 
    //myss.Close(); 
} 
1

您可以使用帶有以太網盾的Arduino或可能是Netduino。基本上,除了藍牙(或NFC)之外,任何具有無線互聯網功能的設備,因爲這是Android使用的唯一無線協議。當用戶按下按鈕時,您可以打開SocketBluetoothSocket與第二臺設備進行通信,以打開交換機。相當簡單 - 如果您擁有無線家庭網絡,只要您的Android設備和您的微處理器位於同一網絡上,您的設備就可以通過物理線路連接到路由器。可能還有其他無線選項可以使用 - 這些只是我能做的最簡單的事情。希望這可以幫助!

+0

+1好的建議。這基本上是我所做的。 Arduino通過內置的串行連接,openWRT固件和一個自定義構建服務器應用程序連接到WRT-54G,該應用程序從android UDP連接接收數據。 – ZnArK 2012-07-06 13:54:42

+0

我忘記了與Arduino的USB串行連接...無論如何,很好的答案,我可能會在我的一些項目中使用它 – crocboy 2012-07-06 15:46:03

+0

我想netduino將服務於我的目的。感謝您的建議。 – Arjun 2012-07-09 08:56:18

1

這就是爲什麼我如何用我的iPhone(應該是Android上的相同)做到了:

  • 運行連接到同一網絡的手機,並通過USB /串口到計算機上的TCP服務器Arduino的。
  • 該服務器應該將所有通過Wi-Fi傳入的數據從您的Android手機通過USB傳送到Arduino。
  • 手機應該運行一個TCP客戶端,它發送一個簡單的單字節(可能爲零和非零)命令
  • Arduino應該被編程,以便通過中斷偵聽傳入的串行數據;如果一個字節到達,它決定是否應該打開或關閉I/O引腳。
+0

+1這正是我一直在爲android設計的。見帖子 – ZnArK 2012-07-06 13:55:41