Python:与 Arduino MKR1000 的套接字通信无法正常工作

Python: Socket communication with Arduino MKR1000 not working properly

我有一个系统,我可以使用 Python 套接字(计算机是服务器)从主机发送命令,MKR1000(客户端)将根据发送的命令发回信息。

不幸的是,双向通信不稳定。我可以保证 MKR1000 收到命令并(可能)发回信息,但由于某些原因,我的主机不会收到命令。

无论如何,这是我第一次尝试套接字,所以我希望一些专家检查我的代码并可能发现这里的错误?非常感谢。

Python:

import socket
import time

def coor2bytes(coor_fnc):
    coorByte = [0, 0, 0, 0, 0, 0]

    if (coor_fnc[0] >= 0):
        coorByte[0] = (coor_fnc[0] >> 8) & 0xFF # High byte of X
        coorByte[1] = coor_fnc[0] & 0xFF # Low byte of X
    else:
        coor_fnc[0] = coor_fnc[0]*(-1)
        coorByte[0] = (coor_fnc[0] >> 8) & 0xFF # High byte of X
        coorByte[0] = coorByte[0] ^ 0x80
        coorByte[1] = coor_fnc[0] & 0xFF # Low byte of X

    if (coor_fnc[1] >= 0):
        coorByte[2] = (coor_fnc[1] >> 8) & 0xFF # High byte of Y
        coorByte[3] = coor_fnc[1] & 0xFF # Low byte of Y
    else:
        coor_fnc[1] = coor_fnc[1]*(-1)
        coorByte[2] = (coor_fnc[1] >> 8) & 0xFF # High byte of X
        coorByte[2] = coorByte[2] ^ 0x80
        coorByte[3] = coor_fnc[1] & 0xFF # Low byte of X

    if (coor_fnc[2] >= 0):
        coorByte[4] = (coor_fnc[2] >> 8) & 0xFF # High byte of Phi
        coorByte[5] = coor_fnc[2] & 0xFF # Low byte of Phi
    else:
        coor_fnc[2] = coor_fnc[2]*(-1)
        coorByte[4] = (coor_fnc[2] >> 8) & 0xFF # High byte of Phi
        coorByte[4] = coorByte[4] ^ 0x80
        coorByte[5] = coor_fnc[2] & 0xFF # Low byte of Phi

    return coorByte

def bytes2coor(byte_fnc):
    receivedCoor_fnc = [0, 0, 0]

    receivedCoor_fnc[0] = ((-1)**(byte_fnc[0]>>7)) * ((byte_fnc[1]) | (((byte_fnc[0]&0x7f)<<8)))
    receivedCoor_fnc[1] = ((-1)**(byte_fnc[2]>>7)) * ((byte_fnc[3]) | (((byte_fnc[2]&0x7f)<<8)))
    receivedCoor_fnc[2] = ((-1)**(byte_fnc[4]>>7)) * ((byte_fnc[5]) | (((byte_fnc[4]&0x7f)<<8)))

    return receivedCoor_fnc


if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


    s.bind((socket.gethostname(), 1234)) # bind(ip, port)
    print("Done binding.")
    s.listen(2)

    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!")

    clientsocket.settimeout(1)

    while True:
        print();
        print("What you want to do?")
        print("0. Send target")
        print("1. Get current coordinate")
        print("2. Set current coordinate (not yet implement)")
        try:
            a = int(input("I choose: "))
        except Exception:
            print("Error.")
            a = -1;

        if (a == 0):
            coor = [0, 0, 0]
            try:
                coor[0] = int(input("X: "))
                coor[1] = -int(input("y: "))
                coor[2] = int(input("phi: "))

                coorByte = coor2bytes(coor)

                clientsocket.send(bytes([0]))
                clientsocket.send(bytes(coorByte))
                print("I already sent the target.")

            except Exception:
                    print("Error.")

        elif (a == 1):
            receive = 0
            while (not receive):
                try:
                    clientsocket.send(bytes([1]))
                    bytesReceived = []
                    full_msg = []

                    while (len(full_msg) < 8):
                        bytesReceived = clientsocket.recv(8)
                        for x in range(len(bytesReceived)):
                            full_msg.append(bytesReceived[x])

                    receivedCoor = bytes2coor(full_msg)
                    print("coordinate received: " + str(receivedCoor))
                    receive = 1
                except socket.timeout:
                    print("Time out. Will try again.")

        elif (a == 2):
            setCoor = [0, 0, 0]
            try:
                setCoor[0] = int(input("X: "))
                setCoor[1] = -int(input("y: "))
                setCoor[2] = int(input("phi: "))

                setcoorByte = coor2bytes(setCoor)

                clientsocket.send(bytes([2]))
                clientsocket.send(bytes(setcoorByte))

                print("I already sent the new coordinate.")
            except Exception:
                    print("Error.")



        else:
            print("Not yet implement.")

Arduino:

#include <WiFi101.h>
#include <SPI.h>

// To connect to the server on laptop
char ssid[] = "iPhone";
char pass[] = "00000000";
int status = WL_IDLE_STATUS;

IPAddress server(172,20,10,3);
WiFiClient client;


// Random variable
int a, i, j, k, m;
byte buf0[7];
byte buf1[7];
byte buf2[7];

long start = millis();
int elapsedTime = 0;
int timeout = 0;

void setup() {
// put your setup code here, to run once:
//  Serial.begin(115200);
  Serial.begin(115200);
  Serial1.begin(115200);


//  status = WiFi.begin(ssid, pass);

  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
  }

  j = client.connect(server, 1234);
  while (j != 1)  {
    j = client.connect(server, 1234);
  }
}

void loop()
{
  if (client.available()) {   
    a = client.read();
    Serial.print("I got: ");
    Serial.println(a);

    if (a == 0) { // Send new target to Due
      Serial.println("I send target.");
      j = 0;
      start = millis();
      while(j<6) {
        elapsedTime = millis() - start;

        if (elapsedTime > 1000) {
          timeout = 1;
          break;
        }

        if (client.available()>0) {
          buf0[j] = client.read();
          Serial.println(buf0[j]);
          j++;        
        }
      }

      if (timeout != 1) {
        Serial1.write((byte) 0);
        // Send coordinate back to Due
        for (i = 0; i<6; i++) {
          Serial1.write(buf0[i]);
        }
      } else {
        timeout = 0;
      }

    } else if (a == 1) {
      // Get the coordinate from the Due
      Serial.println("I receive coordinate.");
      Serial1.write((byte) 1);
      k = 0;
      start = millis();
      while(k < 6) {
        elapsedTime = millis() - start; 

        if (elapsedTime > 1000) {
          timeout = 1;
          break;
        }

        if (Serial1.available() > 0) {
          buf1[k] = Serial1.read();
          Serial.println(buf1[k]);
          k++;          
        }      
      }

      if (timeout != 1) {
        for (i=0;i<6;i++)  {
          client.write(buf1[i]);
          delay(10);
        }

        client.write((byte) 0);  // fill in the blank size
        delay(10);
        client.write((byte) 0);
      } else {
        timeout = 0;
      }

//        for (int i = 0; i<8; i++) {
//          client.write((byte) 0);
//        }

    } else if (a == 2) { // set the current coordinnate to be something else.
      Serial.println("I set coordinate.");     
      m = 0;
      while(m<6) {
        if (client.available()>0) {
          buf2[m] = client.read();
          Serial.println(buf2[m]);
          m++;
        }
      }

      Serial1.write((byte) 2);
      // Send coordinate back to Due
      for (i = 0; i<6; i++) {
        Serial1.write(buf2[i]);
      }

    } else if (a == 3) { // identify yourself
      Serial.println("Identify myself.");
      client.write((byte) 1);
    }
  }
}

如果您有时间通读 Arduino 代码,那么您会发现我的 MKR 和 Due 之间实际上也有串行通信。我也可以保证 MKR 可以从 Due 接收所有这些数据,而不是陷入无限循环。

谢谢!

好吧,出于某种原因,如果我在 MKR 连接到 WiFi 之后、连接到服务器之前添加延迟,那么一切正常。