繁体   English   中英

将数据从 Android 手机发送到 ESP32

[英]Send data from Android Phone to ESP32

我正在尝试使用 Android Studio 创建一个 android 应用程序,以便将一些数据发送到 ESP32,以便在透明监视器上显示这些数据。

在 web 上搜索,我发现了几种方法,但它们都非常复杂。 我能够搜索配对设备并将 ESP32 的 mac 地址存储在我的应用程序中。

谁能帮我从现在开始如何继续???

非常感谢 !!

1. ESP32 实现

发送数据非常简单。 基本上,您需要使用本机WebServer库或ESPAsyncWebServer库将 ESP32 制作为Web 服务器 这是一个使用本机WebServer库的快速示例:

#include <WiFi.h>
#include <WebServer.h>

WebServer server(80);

void handleRoot() {
  server.send(200, "text/plain", "Ready");
}

void handleGet() {
  if (server.hasArg("data")) {
    String data = server.arg("data");
    Serial.println("Data: " + data);
  }
  server.send(200, "text/plain", "Data Received");
}

void handlePost() {
  server.send(200, "text/plain", "Processing Data");
}

void handleUpload() {
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    Serial.println("Receiving data:");
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    Serial.write(upload.buf, upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    server.send(200, "text/plain", "Data: ");
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.softAP("ESP32");
  server.on("/", handleRoot);
  server.on("/get", HTTP_GET, handleGet);
  server.on("/post", HTTP_POST, handlePost, handleUpload);
  server.begin();
}

void loop() {
  server.handleClient();
}

为了向 ESP32 发送数据,您必须将手机连接到与 ESP32 相同的网络,在这种情况下,您只需将 Android 手机连接到 ESP32 接入点即可。 如果您在手机中扫描可用的 WiFi 网络,您应该会看到ESP32 您可以使用Web Browser检查Web 服务器是否正在运行。 只需在地址栏中输入http://192.168.4.1 ,您应该会得到响应"ready" 为了通过 HTTP GET 方法发送数据,您可以键入http://192.168.4.1/get?data=HelloWorld ,您将在串行监视器中看到HelloWorld文本。

2.Android实现

Android Studio 有很多 HTTP 库,您可能需要查看Fast Android Networking 这是一个关于如何使用它的快速示例:

build.gradle

dependencies {
    ...
    implementation 'com.amitshekhar.android:android-networking:1.0.2'
    ...
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_get"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GET"
        android:textColor="@color/white"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/btn_post"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="POST"
        android:textColor="@color/white"
        tools:ignore="HardcodedText" />

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AndroidNetworking.initialize(getApplicationContext());

        Button btnGet = findViewById(R.id.btn_get);
        btnGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                /*Send data via HTTP GET*/
                AndroidNetworking.get("http://192.168.4.1/get")
                        .addQueryParameter("data", "HelloWorld")
                        .build()
                        .getAsString(new StringRequestListener() {
                            @Override
                            public void onResponse(String response) {
                                Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onError(ANError anError) {
                                Toast.makeText(getApplicationContext(), anError.getErrorBody(), Toast.LENGTH_SHORT).show();
                            }
                        });
            }
        });


        Button btnPost = findViewById(R.id.btn_post);
        btnPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                /*Send data via HTTP POST*/
                AndroidNetworking.post("http://192.168.4.1/post")
                        .addStringBody("This is my data")
                        .build()
                        .getAsString(new StringRequestListener() {
                            @Override
                            public void onResponse(String response) {
                                Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onError(ANError anError) {
                                Toast.makeText(getApplicationContext(), anError.getErrorBody(), Toast.LENGTH_SHORT).show();
                            }
                        });
            }
        });
    }
}

这是应用程序的外观:

安卓用户界面

每当您点击 GET 或 POST 按钮时,您应该会在串行监视器中看到“HelloWorld”“这是我的数据”

就这样。 如果您想要Web Socket Server以实现更快的通信,您可以使用上面提到的ESPAsyncWebServer

经典蓝牙

1. ESP32 实现(从机)
(注意:由当前的 1.0.6 esp 平台构建,较旧的 1.0.4 - 作为主机工作良好,但对我来说作为从机有一些问题)

#include "Arduino.h"
#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup()
{
    Serial.begin(9600);
    SerialBT.begin("ESP32s"); //Bluetooth device name
    Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop()
{
    if (SerialBT.available()){ Serial.write(SerialBT.read()); }
    delay(20);
}

2. Android(主控)

AndroidManifest.xml

<application
    ...
    android:name=".ApplicationEx"
</application>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/id_btn_hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Say Hello"/>
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    Button btnHello;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnHello = findViewById(R.id.id_btn_hello);
        btnHello.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(((ApplicationEx)getApplication()).writeBt("Hello World\n".getBytes(StandardCharsets.UTF_8))){
                    Toast.makeText(getApplicationContext(), "OK, sent", Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(getApplicationContext(), "ESP not connected", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

应用例:java

import android.app.Application;
import android.os.Handler;

public class ApplicationEx extends Application{
    private final int STATUS_CHECK_INTERVAL = 500;
    private MyBtEngine mBtEngine;
        @Override
        public void onCreate() {
            super.onCreate();
            mBtEngine = new MyBtEngine();
            handlerStatusCheck.postDelayed(new Runnable() {
                @Override
                public void run() {
                    onBtStatusCheckTimer();
                    handlerStatusCheck.postDelayed(this, STATUS_CHECK_INTERVAL);
                }
            }, STATUS_CHECK_INTERVAL);
        }
    private final Handler handlerStatusCheck = new Handler();
    private void onBtStatusCheckTimer(){
        if(mBtEngine.getState() == MyBtEngine.BT_STATE_NONE) {
            mBtEngine.start();
        }
    }
    boolean writeBt(byte [] buffer){ return mBtEngine.writeBt(buffer); }
}

MyBtEngine.java

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class MyBtEngine {
    static final int BT_STATE_NONE = 0;
    static final int BT_STATE_CONNECTING = 1;
    static final int BT_STATE_CONNECTED = 2;
    //uid for all 3rd party devices (not android)
    private static final UUID UUID_BT_DEVICE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private static final String BT_DEVICE_MAC = "24:0A:C4:61:16:EE";//put your device MAC !!!!

    private BtWaitConnThread   mWaitConnThread    = null;
    private BtWorkThread       mWorkThread        = null;
    private final BluetoothAdapter mAdapter;
    private int mState;

    MyBtEngine() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mState   =  BT_STATE_NONE;
    }
    synchronized void start(){
        if(mAdapter == null){  return; }
        BluetoothDevice device;
        try{
            device = mAdapter.getRemoteDevice(BT_DEVICE_MAC);
        }
        catch (Exception e){  return; }

        if (mWaitConnThread != null) {mWaitConnThread.cancel(); mWaitConnThread = null;}
        if (mWorkThread != null) {    mWorkThread.cancel();     mWorkThread = null;}

        mWaitConnThread = new BtWaitConnThread(device);
        mWaitConnThread.start();
        setState(BT_STATE_CONNECTING);
    }
    public synchronized void stop() {
        if (mWaitConnThread != null) { mWaitConnThread.cancel(); mWaitConnThread = null; }
        if (mWorkThread != null) {     mWorkThread.cancel();     mWorkThread = null; }
        setState(BT_STATE_NONE);
    }
    private synchronized void setState(int state) {
        Log.e("MyBtEngine", "setState() " + mState + " -> " + state);
        mState = state;
    }
    synchronized int getState() {  return mState; }
    public boolean writeBt(byte[] out) {
        BtWorkThread r; // temp obj , just to keep write function not to destroyed if mWorkThread finish
        synchronized (this) {
            if((mWorkThread == null)||(mState != BT_STATE_CONNECTED)){
                return false;
            }
            r = mWorkThread;
        }
        r.write(out);
        return true;
    }
    private synchronized void startWorker(BluetoothSocket socket, BluetoothDevice device) {
        if (mWaitConnThread != null) {mWaitConnThread.cancel(); mWaitConnThread = null;}
        if (mWorkThread != null) {    mWorkThread.cancel(); mWorkThread = null;}
        mWorkThread = new BtWorkThread(socket);
        mWorkThread.start();
        setState(BT_STATE_CONNECTED);
    }
    private class BtWaitConnThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        private BtWaitConnThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
            try {
                tmp = device.createRfcommSocketToServiceRecord(UUID_BT_DEVICE);
            } catch (IOException e) { }
            mmSocket = tmp;
        }
        public void run() {
            mAdapter.cancelDiscovery();
            try {
                mmSocket.connect();
            } catch (IOException e) {
                try {
                    mmSocket.close();
                } catch (IOException e2) { }
                setState(BT_STATE_NONE);
                return;
            }
            synchronized (MyBtEngine.this) {
                mWaitConnThread = null;//set itself to null because thread exit soon
            }
            startWorker(mmSocket, mmDevice);
        }
        private void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }
    private class BtWorkThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private BtWorkThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            try {
                tmpIn  = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }
            mmInStream  = tmpIn;
            mmOutStream = tmpOut;
        }
        public void run() {
            while (true) {
                try {
                    int charFromEsp = mmInStream.read();//TODO: add code here for handling input from ESP
                } catch (IOException e) {
                    MyBtEngine.this.start();//restart from beginning
                    return; // exit worker thread
                }
            }
        }

        public boolean write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);
            } catch (IOException e) { return false; }
            return true;
        }
        private void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM