admin管理员组文章数量:1794759
使用WIFI通讯,手机秒变单片机大屏显示器
使用一片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="schemas.android/apk/res/android" package="com.example.ww01"> android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" xmlns:tools="schemas.android/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="schemas.android/apk/res/android" xmlns:app="schemas.android/apk/res-auto" xmlns:tools="schemas.android/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.DatagramPacket; import java.DatagramSocket; import java.InetAddress; import java.Socket; import java.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做无线数据传输,及手机实现设备控制的功能,具体大家的使用跟据自己喜好完善。 全部工程文件下载链接:download.csdn/download/wdzh018/86881367
版权声明:本文标题:使用WIFI通讯,手机秒变单片机大屏显示器 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686470409a71105.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论