WebSocket可以在PC上运行,但不能在Android上运行吗?

时间:2019-05-08 13:12:16

标签: android websocket arduino esp8266 okhttp3

我正在尝试使用WebSockets从Android设备与ESP8266 WiFi芯片进行通信,以远程控制连接到Arduino的某些电机。首先,我使用PC和Python进行原型设计,并在ESP8266上设置WebSocket服务器...

ESP8266_server.ino

#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>

const char* ssid     = "SKYNET";
const char* password = "yourdogsauntsmaidenname";


WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

    //Serial.printf("[%u] get Message: %s\r\n", num, payload);

    switch(type) {
        case WStype_DISCONNECTED:      
            break;

        case WStype_CONNECTED: 
            {
              IPAddress ip = webSocket.remoteIP(num);
             // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);    
            }
            break;

        case WStype_TEXT:
            {
              //Serial.printf("[%u] get Text: %s\r\n", num, payload);
              String _payload = String((char *) &payload[0]);             
              Serial.print(_payload);           
            }   
            break;     

        case WStype_BIN:
            {
              hexdump(payload, lenght);
            }
            // echo data back to browser
            webSocket.sendBIN(num, payload, lenght);
            break;

    }
}

void setup() {

  // Set up serial comms
  Serial.begin(115200);

  // Set up WiFi 
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    // Serial.print(".");
     delay(200);
  }  
//  Serial.println("");
//  Serial.println("WiFi connected");  
//  Serial.println("IP address: ");
//  Serial.println(WiFi.localIP());

  delay(500);  

  // Set up web socket
//  Serial.println("Start Websocket Server");
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
}

void loop() {
  webSocket.loop();
}

WiFi芯片通过与Arduino Mega的串行连接进行连接,后者依次解析数据以控制2个直流电机的某些H桥。 Arduino还将数据中继到Arduino IDE串行监视器。

motor_control.ino

//  Serial comms from Wemos EPS8622 to Arduino Mega

#include "SoftPWM.h"

// Outputs to PWM & H bridge direction
// PWMs: 
// DC_pwm, left_pwm, right_pwm = 3, 4, 5
int pwm_out[] = {3, 4, 5};
const int num_pwm = sizeof(pwm_out) / sizeof(pwm_out[0]);

// H bridge direction control: 
// right_2, right_1, left_2, left_1, dc_2, dc_1  = 6, 7, 8, 9, 10 ,11
int dir_pins[] = {6, 7, 8, 9, 10 , 11};
const int num_dir_pins = sizeof(dir_pins) / sizeof(dir_pins[0]);

// Input buffer from ESP8266
int in_buff[] = {0, 0};
const int num_in_buff = sizeof(in_buff) / sizeof(in_buff[0]);

void setup() {

  // Set up serial comms
  Serial.begin(115200);   // Debug to Serial Monitor
  Serial3.begin(115200);  // From ESP8266

  // Set up PWM pins
  SoftPWMBegin();
  for (int i = 0; i < num_pwm; i++)
  {
    SoftPWMSet(pwm_out[i], 0);
  }

  // Set up H bridge direction pins
  for (int i = 0; i < num_dir_pins; i++)
  {
    pinMode(dir_pins[i], OUTPUT);
    digitalWrite(dir_pins[i], LOW);
  }
}

void loop() {

  // Check input from EPS8266 & send it to the H bridges
  while (Serial3.available() < num_in_buff){}

  if (Serial3.available()) {
      // read the incoming bytes
      // in_buff[0] - direction flags
      // in_buff[1] - PWM
      Serial.println(".......");
      Serial.println("In from ESP8266");
      for (int i = 0; i < num_in_buff; i++){
        in_buff[i] = Serial3.read();
        Serial.println(in_buff[i]);
      }
      Serial.println(".......");
  }

  // Set direcions on H bridges
  Serial.println("Direction pins");
  for (int i = 0; i < num_dir_pins; i++)
  {
    digitalWrite(dir_pins[i], bitRead(in_buff[0], i));
    Serial.print("pin ");
    Serial.print(dir_pins[i]);
    Serial.print(" : ");
    Serial.print(digitalRead(dir_pins[i]));
    Serial.println();
  }

  // PWM to motors
  for (int i = 0; i < num_pwm; i++)
  {
    SoftPWMSet(pwm_out[i], in_buff[1]);
  }
}

在PC端,我有一些Python代码被设置为WebSocket客户端,该客户端从终端接收用户输入并将其传输到ESP芯片。

motor_control_WiFi.py

"""
Motor control over WiFi using Wemos EPS8266 & Mega board

Motor H-bridge direction flags
    Both forwards     - b'111001, d'57, ASCII 9
    Both backwards    - b'110110, d'54, ASCII 6
    Clockwise (right) - b'111010, d'58, ASCII :
    A/Clock (left)    - b'110101, d'53, ASCII 5

"""

from ws4py.client.threadedclient import WebSocketClient
import time, requests
import struct

esp8266host = "ws://192.168.1.84:81/" 

class DummyClient(WebSocketClient):
    def opened(self):
        print("Websocket open")
    def closed(self, code, reason=None):
        print("Connexion closed down", code, reason)
    def received_message(self, m):
        print(m)

if __name__ == '__main__':
    try:
        ws = DummyClient(esp8266host)
        ws.connect()
        print("Ready !")
        direction = ""

        while direction != "q":

            direction = input("Direction: ")

            if direction == "f":
                payload = "9"
            if direction == "b":
                payload = "6"
            if direction == "r":
                payload = ":"
            if direction == "l":
                payload = "5"

            ws.send(payload)
            time.sleep(.20)

            pwm_out = int(input("PWM: "))
            pwm_out = struct.pack('<B', pwm_out)
            ws.send(pwm_out)
            time.sleep(.20)


        print("Finished, close Websocket connexion now and exit script")
        ws.send("0:0")
        ws.close()
        exit()

    except KeyboardInterrupt:
        ws.send("0:0")
        ws.close()

一切正常。因此,我的下一步是制作一个Android应用来执行我的Python代码所执行的操作。我正在使用okhttp3库,并将implementation 'com.squareup.okhttp3:okhttp:3.6.0'添加到了Gradle构建文件中,并为清单添加了Internet权限。

MainActivity.java

package qdivision.org.websocketexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class MainActivity extends AppCompatActivity {

    private Button start;
    private TextView output;
    private OkHttpClient client;

    private final class EchoWebSocketListener extends WebSocketListener {
        private static final int NORMAL_CLOSURE_STATUS = 1000;

        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            //webSocket.send("l");
            webSocket.send(ByteString.decodeHex("23"));
            webSocket.send(ByteString.decodeHex("32"));
            webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            output("Receiving : " + text);
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            output("Receiving bytes : " + bytes.hex());
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            webSocket.close(NORMAL_CLOSURE_STATUS, null);
            output("Closing : " + code + " / " + reason);
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            output("Error : " + t.getMessage());
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = (Button) findViewById(R.id.start);
        output = (TextView) findViewById(R.id.output);
        client = new OkHttpClient();

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                start();
            }
        });

    }

    private void start() {
        Request request = new Request.Builder().url("ws://192.168.1.84:81").build(); //"ws://echo.websocket.org"
        EchoWebSocketListener listener = new EchoWebSocketListener();
        WebSocket ws = client.newWebSocket(request, listener);

        client.dispatcher().executorService().shutdown();
    }

    private void output(final String txt) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                output.setText(output.getText().toString() + "\n\n" + txt);
            }
        });
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="qdivision.org.websocketexample.MainActivity">

    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Start !"
        android:layout_marginTop="40dp"
        android:textSize="17sp"/>

    <TextView
        android:id="@+id/output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/start"
        android:layout_centerHorizontal="true"
        android:textSize="16sp"
        android:layout_marginTop="30dp"/>

</RelativeLayout>

部署此程序后,我没有任何连接错误。发送的字节将回显到显示器,并且客户端无错误地断开连接。但是我没有通过Arduino串行监视器反馈任何东西已发送!

这里缺少什么?如果未发送/接收字节,怎么会没有连接错误?

编辑#1 我从Termux命令行在Android设备上运行了Python代码。代码运行,说插座是打开的,让我输入方向和PWM,但串行监视器仍然没有输入。

编辑#2 我可以使用Termux从Android设备ping ESP8266,且丢包率为0,但Python代码或应用仍未发送任何数据。

编辑#3 现在,Python代码可通过Android设备上的Termux命令行运行(不知道我如何进行任何更改,现在就可以正常使用!!! ??)。基于okhttp3的应用程序仍然不发送任何数据。

0 个答案:

没有答案
相关问题