使用arduino作为客户端和服务器计算机之间的中介

时间:2014-04-24 21:39:33

标签: python sockets arduino

我正在使用一台使用2台计算机和连接声纳的arduino的系统;各自的功能如下:

第一台计算机是命令计算机',并向arduinos发出命令以进行传感器测量。

以太网arduino接受来自命令计算机的命令,然后将测量结果发送到操作计算机。

操作计算机根据测量结果执行操作。

所有通信都是通过python套接字模块和arduino以太网库完成的。

出于测试目的,我在同一台计算机上模拟命令和操作计算机但使用不同的套接字。命令计算机由client.py模拟,Action计算机由server.py模拟。如果我将它们直接指向对方(跳过arduino),一切都按预期工作。

然而,当我在中间添加arduino时,我遇到的问题是arduino没有响应发送给它的所有命令,整个系统都会变慢。

我无法弄清楚如何开始对此进行故障排除 - 我无法判断arduino是否能够快速连续处理这么多请求,或者我是否可能以笨重的方式处理消息,导致套接字过于频繁地不可用。任何建议将不胜感激 - 代码如下。

client.py

import socket
import time

while True:
    try:
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.connect(("192.168.0.250", 10220))
        #client_socket.connect(("192.168.0.100", 8220))
        data = "GET\nSONAR\n\n"
        print 'send to server: ' + data
        client_socket.send(data)
        #receive = client_socket.recv(2048)
        #print receive
        client_socket.close()
        time.sleep(1)
    except Exception as msg:
        print msg

这谈到simpleSonarTest.ino:

#include <avr/wdt.h>
#include <SPI.h>
#include <Ethernet.h>
#include <MyClient.h>
#include <SoftwareSerial.h>

//localClient parameters, for sending data to the server.
byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x03, 0x58};
byte ip[] = {192,168,0,250};
byte server[] = {192, 168, 0, 100};
int serverPort = 8220;
MyClient* localClient;

//Server parameters, for acting like a server.
int localPort = serverPort + 1000;
int pollPort = serverPort + 2000;
EthernetServer localServer = EthernetServer(localPort);
EthernetServer pollServer = EthernetServer(pollPort);

//sonar stuff
String content_string;
int NUM_SONARS = 1;
int sonarPin[] = {2, 3, 4, 5};
int triggerPin = 6;
int sonarThreshold = 12.0;
int sonarState[] = {0, 0, 0, 0};
long pulse;
int numPulses = 3;
int pulseArray[] = {0,0,0,0,0};
int filteredMode = 0;
float time;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);

  wdt_enable(WDTO_8S);

  localClient = new MyClient(mac, ip);
  localClient->connect(server, serverPort);

  pollServer.begin();

  for(int i = 0; i < NUM_SONARS; i++) {
    pinMode(sonarPin[i], INPUT);
  }
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  time = 0;
}

void loop() {
  wdt_reset();
  time = millis();

  EthernetClient pollClient = pollServer.available();
  if (pollClient) {
    boolean currentLineIsBlank = true;
    String receivingString = "";
    while (pollClient.connected()) {
      //while the socket is open
      if(pollClient.available()) {
        //and there is something to read on the port, then read the available characters
        char c = pollClient.read();
        receivingString += c;
        //share with the serial monitor:
        if (c == '\n' && currentLineIsBlank) {
          pollClient.println("Received message.");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // parse the incoming data
    String command = split(receivingString,'\n',0);
    String payload = split(receivingString,'\n',1);

    String key = split(payload,'=',0);
    String value = split(payload,'=',1);

    //PARSE THE KEY AND VALUE NOW
    if(command == "GET") {
      if(key == "SONAR") {
        pingSonars();
      }
    }

    pollClient.stop();
    Serial.println("Closing poll client connection.");
  }

  delay(50);
}

String split(String data, char delimiter, int index) {
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==delimiter || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void isort(int *a, int n) {
  for (int i = 1; i < n; ++i) {
    int j = a[i];
    int k;
    for (k = i - 1; (k >= 0) && (j < a[k]); k--) {
      a[k + 1] = a[k];
    }
    a[k + 1] = j;
  }
}

int mode(int *x,int n){

  int i = 0;
  int count = 0;
  int maxCount = 0;
  int mode = 0;
  int bimodal;
  int prevCount = 0;
  while(i<(n-1)){
    prevCount=count;
    count=0;
    while(x[i]==x[i+1]){
      count++;
      i++;
    }
    if(count>prevCount&count>maxCount){
      mode=x[i];
      maxCount=count;
      bimodal=0;
    }
    if(count==0){
      i++;
    }
    if(count==maxCount){//If the dataset has 2 or more modes.
      bimodal=1;
    }
    if(mode==0||bimodal==1){//Return the median if there is no mode.
      mode=x[(n/2)];
    }
    return mode;
  }
}

void printArray(int *a, int n) {

  for (int i = 0; i < n; i++)
  {
    Serial.print(a[i], DEC);
    Serial.print(' ');
  }
  Serial.println();
}

void pingSonars() {
  digitalWrite(6, HIGH);
    for(int i = 0; i < NUM_SONARS; i++) {
    for(int j = 0; j < numPulses; j++) {
      pulse = pulseIn(sonarPin[i], HIGH);
      pulseArray[j] = pulse/147; //convert to inches -- 147 uS per inches
      delay(5);
    }
    isort(pulseArray, numPulses);
    filteredMode = mode(pulseArray,numPulses);
    //printArray(pulseArray,numPulses);
    Serial.print("Filtered distance for Sonar ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(filteredMode);
    if((filteredMode < sonarThreshold) && !sonarState[i]) {
      //if we are closer than the threshold and previously were not, this is a rising edge:
      Serial.print("Sonar ");
      Serial.print(i);
      Serial.println(" triggered!");
      sonarState[i] = 1;
    }
    else if (filteredMode > sonarThreshold && sonarState[i]) {
    //if we are greater than the threshold and previously were, this is a falling edge:
      Serial.print("Sonar ");
      Serial.print(i);
      Serial.println(" falling!");
      sonarState[i] = 0;
    }
      //always respond to a poll with the current state
      content_string = "PUT\nSONAR ";
      content_string += String(i);
      content_string += "= ";
      content_string += String(sonarState[i]);
      content_string += "\n\n";
      localClient->post_request(content_string);
  }
}

将PUT消息发送到server.py

import socket

host = '192.168.0.100'
port = 8220
address = (host, port)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((address))
server_socket.listen(5)

while True:
    try:
        print "Listening for client . . ."
        conn, address = server_socket.accept()
        print "Connected to client at ", address
        #pick a large output buffer size because i dont necessarily know how big the incoming packet is
        output = conn.recv(2048);
        if output:
            print "Message received from client:"
            print output

        #conn.send("This is a response from the server.")
        conn.close()
        #print "Test message sent and connection closed."
    except KeyboardInterrupt:
        print
        print "Stop."
        break

作为参考,MyClient是以太网的包装器,用于发送HTTP样式(但不符合HTTP)的消息:

#include <WProgram.h>
#include "MyClient.h"

MyClient::MyClient(byte* mac_address, byte* ip_address) {
  Serial.println("Initializing HTTP Client...");
  Ethernet.begin(mac_address, ip_address);
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  delay(1000);
  debug = true;
}

void MyClient::connect(byte* server_address, int port) {
  //server = server_address;
  Serial.print("Attempting to connect to server at ");
  Serial.print(server_address[0]);
  Serial.print(".");
  Serial.print(server_address[1]);
  Serial.print(".");
  Serial.print(server_address[2]);
  Serial.print(".");
  Serial.print(server_address[3]);
  Serial.print("...");
  while(!client.connect(server_address, port)) {
    ;
  }
  Serial.println("Connected to server!");
}

void MyClient::disconnect() {
  client.stop();
}

bool MyClient::connected() {
  return client.connected();
}

void MyClient::get_request(String resource) {
  if(debug) {
    Serial.println("Submitting GET request.");
  }
 // Make a HTTP request:
    client.print("GET ");
    client.print(resource);
    client.println(" HTTP/1.1");
    print_host(server);    
    client.println("User-Agent: sdfSensorClient/0.1");
    client.println("Connection: close");
    client.println();
}

void MyClient::post_request(String content) {
  if(debug) {
    Serial.println("Making a POST request.");
  }
  content += "[/TCP]";
  client.println(content);
  if(debug) {
    Serial.println("Posted:");
    Serial.println(content);
  }
}

void MyClient::print_host(byte* host) {
  client.print("Host: ");
  client.print(host[0]);
  client.print(".");
  client.print(host[1]);
  client.print(".");
  client.print(host[2]);
  client.print(".");
  client.println(host[3]);
}

void MyClient::get_response() {
  while (client.available()) {
    char c = client.read();
    if(debug) {
      Serial.print(c);
    }
  }
}

bool MyClient::get_status() {
  return client.connected();
}

void MyClient::set_debug(bool status) {
  debug = status;
}

0 个答案:

没有答案
相关问题