使用WIFI通讯,手机秒变单片机大屏显示器

本文介绍了如何使用ESP-01S Wi-Fi模块和Android Studio创建一个APP,将手机转变为单片机的显示器。通过设置ESP-01S为UDP透传模式,并配置相应的Android应用,实现了手机与单片机之间的无线数据传输和控制。用户可以通过APP发送指令,控制单片机系统,同时接收单片机的反馈信息。

使用一片ESP-01S,用Android Studio开发了一个APP,手机安装后,立即变身为单片机的大屏显示器。淘汰的手机终于有用武地方了,成本不到10块钱,而且wifi无线连接。

手机做单片机显示器


需要软件工具及硬件:
1、ESP-01S模块,单片开发系统,USB串口线(TTL电平,安装好驱动),手机一部(驱动装好,可以正常连接电脑)。
2、安信可串口调试助手(厂家配套,推荐),网络调试助手。
3、java编程工具idea64,安卓开发工具Android Studio。
具体步骤:

1、ESP-01S设置好UDP透传模式

ESP-01S 是由安信可科技开发的 Wi-Fi 模块,该模块核心处理器为ESP8266 。接线参考下图。在这里插入图片的描述
接好串口线,MCU_RXD与MCU_TXD两个引脚接入串口线对应引脚。3.3V 供电(VDD)要求较高,外部供电电源输出电流建议在 500mA 以上。在电脑上使用安信可串口调试助手,波特率选择115200,连接正常的情况下ESP-01S上电后如下图。
安信可串口助手
发一个AT+RST(复位命令),要勾选发送新行选项,如能正常复位,这时就可以按下面步骤配置模块透传模式。
a、AT+RESTORE 初始化
b、AT+CWMODE_DEF=1 设置当前 Wi-Fi 模式并保存到 Flash (不开模块热点)
c、AT+CWJAP_DEF =“abc”,“0123456789” 连接 AP,保存到 Flash (AP 的 SSID 为 “abc”,密码为 “0123456789”)
d、AT+SAVETRANSLINK=1,“192.168.3.3”,440,“UDP” 保存开机透传到 Flash(UDP模式)(远端UDP主机地址、端口)
e、AT+RST 复位
复位后,串口助手显示同上图一样,不同的是点击发送命令模块不会反馈如何信息。这时发送“+++”(不选择发送新行选项)会退出透传模式,各种命令才起作用。

这时可以在电脑上打开网络调试助手,选择“UDP”协议,填写对应的IP地址(电脑的IP地址),对应的端口(440)后,点击打开,这时按钮变成红色,表示连接已建立。
在这里插入图片描述
这时可以尝试互相发送消息了。看看吧!
在这里插入图片描述

2、Android Studio上开发通讯app

这里的代码与视频显示不同,我做了简化。代码如下:
2.1 AndroidManifest.xml代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ww01">
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        xmlns:tools="http://schemas.android.com/tools"
        <uses-permission android:name="android.permission.INTERNET"></uses-permission>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.Ww01">
            <activity
                android:name=".MainActivity"
                android:exported="true"
                android:screenOrientation="portrait"
                android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

    </manifest>

2.2 activity_main.xml代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#46857070"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/linearLayout14"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="15"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="15"
            android:orientation="horizontal">

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="5"
            android:orientation="horizontal">

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="15"
            android:orientation="horizontal"></LinearLayout>
    </LinearLayout>

    <TextView
        android:id="@+id/textview_first"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@string/hello_first_fragment"
        android:textColor="#E80F42"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/T12"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="30dp"
        android:layout_marginEnd="40dp"
        android:text="TextView"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout2" />

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:layout_marginTop="56dp"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@+id/textview_first">

        <LinearLayout
            android:id="@+id/linearLayout22"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_weight="10">

            <TextView
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:rotationX="1"
                android:text="   IP地址:"
                android:textSize="20sp" />

            <EditText
                android:id="@+id/mEtIP"
                android:layout_width="150dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:autofillHints=""
                android:inputType="textPersonName"
                android:text="@string/_192_168_3_66"
                tools:ignore="TouchTargetSizeCheck" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/linearLayout23"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_weight="10">

            <TextView
                android:layout_width="100sp"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:text="@string/post"
                android:textSize="20sp" />

            <EditText
                android:id="@+id/mEtPort"
                android:layout_width="150dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:inputType="textPersonName"
                android:text="8800"
                tools:ignore="TouchTargetSizeCheck" />
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="98dp"
        android:layout_marginBottom="48dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/linearLayout3">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:orientation="vertical"></LinearLayout>

            <Button
                android:id="@+id/mBt1"
                android:layout_width="128dp"
                android:layout_height="45dp"
                android:layout_gravity="center"
                android:text="创建连接" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical"></LinearLayout>

            <Button
                android:id="@+id/mBt12"
                android:layout_width="128dp"
                android:layout_height="45dp"
                android:layout_gravity="center"
                android:text="关闭连接" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:orientation="vertical"></LinearLayout>
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:orientation="horizontal">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="15"
                android:orientation="horizontal">

            </LinearLayout>

            <Button
                android:id="@+id/mBt2"
                android:layout_width="108dp"
                android:layout_height="45dp"
                android:layout_gravity="center_vertical"
                android:gravity="center"
                android:text="开"
                tools:ignore="HardcodedText" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="10"
                android:orientation="horizontal">

            </LinearLayout>

            <Button
                android:id="@+id/mBt3"
                android:layout_width="108dp"
                android:layout_height="45dp"
                android:layout_gravity="center_vertical"
                android:text="关"
                tools:ignore="HardcodedText" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="15"
                android:orientation="horizontal"></LinearLayout>
        </LinearLayout>
    </LinearLayout>

    <TextView
        android:id="@+id/textView"
        android:layout_width="89dp"
        android:layout_height="22dp"
        android:layout_marginStart="24dp"
        android:layout_marginBottom="110dp"
        android:layout_weight="1"
        android:text="通讯控制"
        android:textColor="@color/teal_700"
        app:layout_constraintBottom_toTopOf="@+id/linearLayout3"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="89dp"
        android:layout_height="22dp"
        android:layout_marginStart="24dp"
        android:layout_weight="1"
        android:text="LED控制"
        android:textColor="@color/teal_700"
        app:layout_constraintBottom_toTopOf="@+id/linearLayout3"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

这个布局文件代码有点长,主要是为适应手机屏幕做了不少多余布局,好在也不用仔细看,哈哈。

2.3 MainActivity.java代码

package com.example.ww01;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button mBtnConnect; //  连接
    private EditText mIp;
    private EditText mPort;
    private TextView Text12;
    private String info;
    int AN1 = 0, AN2 = 0, AN0 = 0, Switch = 0;
    String AAA;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnConnect = findViewById(R.id.mBt1);  //UDP服务器开
        Button bBtnConnect = findViewById(R.id.mBt12); //UDP服务器关
        Button mMotorZ = findViewById(R.id.mBt2);//  按钮LED灯开
        Button mMotorF = findViewById(R.id.mBt3);//  按钮LED灯关
        //  IP
        mIp= findViewById(R.id.mEtIP);
        //  端口号
        mPort = findViewById(R.id.mEtPort);
        Text12 = findViewById(R.id.T12);
        mBtnConnect.setOnClickListener(this);
        bBtnConnect.setOnClickListener(this);
        mMotorZ.setOnClickListener(this);
        mMotorF.setOnClickListener(this);
        Text12.setText("myapp");
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View view) {
        view.getId();
        UDPServer mUDPServer = new UDPServer();
        switch (view.getId()) {
            case R.id.mBt1:
                if (AN0 == 0) {
                    AN0 = 1;
                    //UDPServer mUDPServer = new UDPServer();
                    mUDPServer.start();
                }
                break;
            case R.id.mBt12:
                if (AN0 == 1) {
                    AN0 = 0;
                    runOnUiThread(() -> {
                        mBtnConnect.setText("创建连接");
                        Toast.makeText(MainActivity.this, "端口正在关闭", Toast.LENGTH_LONG).show();
                    });
                }
                break;
            case R.id.mBt2:
                if (Switch == 0) {
                    AN1 = 1;
                    Switch = 1;
                }
                break;
            case R.id.mBt3:
                if (Switch == 1) {
                    AN2 = 1;
                    Switch = 0;
                }
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + view.getId());
        }
    }
    class UDPServer extends Thread {
        // 1.创建服务器端DatagramSocket,指定端口
        DatagramSocket socket;    //  套接字
        String as = mPort.getText().toString();        //获取EditText的PORT数据
        {
            try {
                socket = new DatagramSocket(Integer.parseInt(as));
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }

        byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
        DatagramPacket packet = new DatagramPacket(data, data.length);

        @SuppressLint("SetTextI18n")
        public void run() {
            runOnUiThread(() -> {
                mBtnConnect.setText("UDP服务开启");
                Toast.makeText(MainActivity.this, ("等待客户机接入......"), Toast.LENGTH_LONG).show();
            });

            if (AN0 == 0)
                socket.close();
            while (AN0 == 1) {
                try {
                    socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
                } catch (IOException e) {
                    e.printStackTrace();
                }

                info = new String(data, 0, packet.getLength());
                runOnUiThread(() -> {
                    mBtnConnect.setText("连接成功");
                    Text12.setText(info);
                });
                // 1.定义客户端的地址、端口号、数据* 向客户端响应数据
                InetAddress address = packet.getAddress();
                int port = packet.getPort();

                //AAA = info;//发送数据,返回接收到的数据
                if ((AN1+AN2)>0) {
                    if (AN1 == 1) {
                        AAA = "1";
                        AN1 = 0;
                        runOnUiThread(() -> {
                            Toast.makeText(MainActivity.this, "已经发送‘1’,成功", Toast.LENGTH_LONG).show();
                        });
                    }
                    if (AN2 == 1) {
                        AAA = "0";
                        AN2 = 0;
                        runOnUiThread(() -> {
                            Toast.makeText(MainActivity.this, "已经发送‘0’,成功", Toast.LENGTH_LONG).show();
                        });
                    }
                    byte[] data2 = AAA.getBytes();

                    // 2.创建数据报,包含响应的数据信息
                    DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
                    // 3.响应客户端
                    try {
                        socket.send(packet2);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

2.4 string.xml代码
这个有点东西,也放在这里

<resources>
    <string name="app_name">myapp</string>
    <string name="action_settings">Settings</string>
    <!-- Strings used for fragments for navigation -->
    <string name="first_fragment_label">First Fragment</string>
    <string name="second_fragment_label">Second Fragment</string>
    <string name="next">Next</string>
    <string name="previous">Previous</string>

    <string name="hello_first_fragment">连接方式:UDP</string>
    <string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
    <string name="abc">abcdz</string>
    <string name="ip">ip地址:</string>
    <string name="ip1">textPersonName</string>
    <string name="post">端口:</string>
    <string name="_192_168_3_66">192.168.3.100</string>
</resources>

3、实际使用效果

3.1 进入后显示
在这里插入图片描述
这里的IP地址没用,不用动,端口号也可以不动,也可以自己改一下。
3.2 重新设置模块网路连接,连接目标定为手机端
查一下手机的局域网IP地址,然后将上面所述ESP-01S的UDP设置重新来一遍,
d、AT+SAVETRANSLINK=1,“192.168.3.3”,440,“UDP” 保存开机透传到 Flash(UDP模式)(远端UDP主机地址、端口)
这行把IP地址位置改成手机的IP地址,端口号440改成8800或你在上图输入的端口号。ESP-01S设置好后重启。
3.3 点击上图的“创建连接”按钮。如下图,按钮显示“UDP服务开启”,准备接收客户端信息。
在这里插入图片描述

3.4 这时在串口助手中发送数据,手机中间的文本显示区就出现了该数据信息,按钮显示也变成了连接成功。
在这里插入图片描述
3.5 实验手机按钮发送信息
点击屏幕“开”“关”按钮,后在串口助手任意发一个信息、则可以收到0和1的数据,注意按钮操作需交替进行,连续按一个按钮只在第一次有命令发出。
在这里插入图片描述
如勾选定时发送则每次按键后数据都会传到串口助手。
在这里插入图片描述

4、连接单片机系统

将串口线拆除,模块连接到MCU串口,后面的工作就在你自己的单片机系统里进行了,这些我就略去了。

我分享的这个app的实例也只是验证通过ESP-01S做无线数据传输,及手机实现设备控制的功能,具体大家的使用跟据自己喜好完善。
全部工程文件下载链接:https://download.csdn.net/download/wdzh018/86881367

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值