关闭ESP32-CAM LED
因为ESP32-CAM通电后LED灯是亮的,超级亮,太晃眼,所以第一需求是关掉它
void setup() {
pinMode(4, OUTPUT); // 设置GPIO4为输出模式
digitalWrite(4, LOW); // 调低电平关闭LED
}
void loop() {
}
让ESP32-CAM LED闪烁
既然可以关掉了,那能不能让它闪一下呢?
void setup() {
pinMode(4, OUTPUT); // 设置GPIO4为输出模式
}
void loop() {
digitalWrite(4, LOW);
delay(1000);
digitalWrite(4, HIGH);
delay(1000);
}
串口输出”Hello, World!”
因为ESP32-CAM是连到串口上面进行调试的,那么能不能让串口输出一些字符呢
void setup() {
Serial.begin(115200); // 初始化串口通信,波特率为115200
}
void loop() {
Serial.println("Hello, world!"); // 输出字符串到串口,并自动换行
delay(1000); // 延时1秒
}
串口控制LED灯开关
void setup() {
pinMode(4, OUTPUT); // 设置GPIO 4为输出模式
digitalWrite(4, LOW); // 关闭LED灯
Serial.begin(115200);
}
void loop() {
// 接收控制指令
if (Serial.available()) {
char command = Serial.read();
switch (command) {
case '1':
digitalWrite(4, HIGH); // 开启LED灯
Serial.println("开灯");
break;
case '0':
digitalWrite(4, LOW); // 关闭LED灯
Serial.println("关灯");
break;
}
}
delay(100);
}
手机连接ESP32-CAM WiFi
这块板子上还有个wifi,把它利用起来,如果手机能连上这个wifi,那不就相当于可以通过wifi控制这块板子了吗?
WiFi得有个名字,连接wifi的密码
给wifi分配一个ip地址
让他作为网关
再配个子网掩码
WiFi网络建立完成了
WiFi的AP模式
:AccessPoint就是接入点的意思,就是把自己共享出来允许别人连接访问接入
#include <WiFi.h>
// 替换成你喜欢的网络名称和密码
const char* ssid = "ESP32_Wifi";
const char* password = "12345678";
IPAddress local_IP(192, 168, 1, 1); // 设置本地IP地址
IPAddress gateway(192, 168, 1, 1); // 设置网关
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
void setup()
{
pinMode(4, OUTPUT); // 设置GPIO4为输出模式
digitalWrite(4, LOW); // 关闭LED灯
Serial.begin(115200); // 初始化串口通信,波特率为115200
// 配置静态IP地址
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("配置失败");
}
// 建立Wi-Fi网络
WiFi.mode(WIFI_AP);
boolean result = WiFi.softAP(ssid, password);
if (result == true) {
Serial.print("网络名 SSID: ");
Serial.println(ssid);
Serial.print("IP 地址: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("Wifi启动失败.");
}
}
void loop() {
// 其他代码
}
这样手机就可以连接上ESP32-CAM的WiFi了
ESP32-CAM建立Web服务器
ESP32已经共享在网络上了,
IP地址是:192.168.1.1
用http协议访问通常是80端口
我们要提前对这个端口做一下监听,当别人访问我们的时候,我们要给出响应
http://192.168.1.1/
访问地址就是这个格式
所以这就是web服务这就算建立起了一个web服务器
服务器就是干活的
它负责监听端口,并且做出响应,这就叫做通讯。
对方发送请求,服务器给他反馈。
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "ESP32";
const char* password = "12345678";
IPAddress local_IP(192, 168, 1, 1); // 设置本地IP地址
IPAddress gateway(192, 168, 1, 1); // 设置网关
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
AsyncWebServer server(80); // 创建服务器对象,指定监听端口80
void setup()
{
pinMode(4, OUTPUT); // 设置GPIO4为输出模式
digitalWrite(4, LOW); // 关闭LED灯
Serial.begin(115200); // 初始化串口通信,波特率为115200
// 配置静态IP地址
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("STA Failed to configure");
}
// 建立Wi-Fi网络
WiFi.mode(WIFI_AP);
boolean result = WiFi.softAP(ssid, password);
if (result == true) {
Serial.print("网络名 SSID: ");
Serial.println(ssid);
Serial.print("IP地址: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("Wifi启动失败.");
}
// 响应网站根路径的请求
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, World!");
});
server.begin(); // 启动服务器
}
void loop() {
// 其他代码
}
以上是一个根路径请求,当有人通过浏览器访问http://192.168.1.1的时候,我们就给他返回一个字符串”Hello, World!
“
手机浏览器访问ESP32-CAM Web服务器控制LED开关
同样,我们建立起来了web服务,手机连接上了我们的网络,对于手机的请求,我们也可以做相应的动作,从而实现手机控制ESP32-CAM
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "ESP32_Wifi";
const char* password = "12345678";
IPAddress local_IP(192, 168, 1, 1); // 设置本地IP地址
IPAddress gateway(192, 168, 1, 1); // 设置网关
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
AsyncWebServer server(80); // 创建服务器对象,指定监听端口80
void setup()
{
pinMode(4, OUTPUT); // 设置GPIO4为输出模式
digitalWrite(4, LOW); // 关闭LED
Serial.begin(115200); // 初始化串口通信,波特率为115200
// 配置静态IP地址
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("配置失败");
}
// 建立Wi-Fi网络
WiFi.mode(WIFI_AP);
boolean result = WiFi.softAP(ssid, password);
if (result == true) {
Serial.print("网络名 SSID: ");
Serial.println(ssid);
Serial.print("IP地址: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("WiFi启动失败.");
}
// 响应网站根路径的请求
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, World!");
});
// 响应打开LED的请求
server.on("/led/on", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(4, HIGH);
request->send(200);
});
// 响应关闭LED的请求
server.on("/led/off", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(4, LOW);
request->send(200);
});
server.begin(); // 启动服务器
}
void loop() {
// 其他代码
}
以上就是,手机连接ESP32-CAM的WiFi,打开手机浏览器,在地址栏
输入 http://192.168.1.1/ 的时候,web服务器就返回”Hello, World!”字符串
输入 http://192.168.1.1/led/on 的时候,将LED打开
输入 http://192.168.1.1/led/off 的时候,将LED关闭
从而实现手机控制
然而,真正的需求
是要用
安卓app控制ESP32-CAM上面的LED灯开关
1.ESP32-CAM通电以后建立了WiFi网络,并且启动了web服务,开始监听网络请求
此时ESP32-CAM共享出来一个网络
网络名:ESP32_WiFi
密码:12345678
IP地址:192.168.1.1
网关:192.168.1.1
子网掩码:255.255.255.0
2.当我们用手机去连接这个WiFi的时候,WiFi会自动分配给手机一个IP地址
经验证发现:
WiFi建立后Esp32-CAM的IP是192.168.4.1
连上他的手机的IP被分配成为了192.168.4.2
3.安卓端(重点)
我用的是Java写的,没用kotlin。
网上找了很多段,也问了问ChatGPT,但是都没有给出正确答案。
安卓比较复杂,遇到很多坑。
点击ON按钮
后给ESP32-CAM发送HTTP_GET请求
,ESP32-CAM接收到请求后把灯打开
点击OFF按钮
后给ESP32-CAM发送HTTP_GET请求
,ESP32-CAM接收到请求后把灯关闭
先说:app/build.gradle
文件
里面minSdk和targetSdk这个两是重点,因为有些时候一些语句写了由于版本的问题,他是不支持的。
plugins {
id 'com.android.application'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.led"
minSdk 23
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.amitshekhar.android:android-networking:1.0.2'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
再说:app/src/main/AndroidManifest.xml
文件
这三句是开启网络访问权限,这是大家已经共识的了,不开这个手机app就没有连接wifi的权限。
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
其实我开了以后也不行,弄了好久,结果找到了这一句
就写在application
因为安卓9.0以后升级了,直接明文发送请求不让发送了,加上以下这句就行了
限制明文请求
android:usesCleartextTraffic="true"
困扰了我好久,555
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.led">
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:usesCleartextTraffic="true"
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.LED">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
主界面:app/src/main/res/layout/activity_main.xml
文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<Button
android:id="@+id/onLED"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ON"
tools:ignore="HardcodedText"/>
<Button
android:id="@+id/offLED"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OFF"
tools:ignore="HardcodedText"/>
<TextView
android:id="@+id/response_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
逻辑:app/src/main/java/com/example/led/MainActivity.java
package com.example.led;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.util.Objects;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_on = findViewById(R.id.onLED);
Button button_off = findViewById(R.id.offLED);
responseText = findViewById(R.id.response_text);
button_on.setOnClickListener(this);
button_off.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.onLED) {
onLED();
}
if (v.getId() == R.id.offLED) {
offLED();
}
}
private void onLED() {
new Thread(() -> {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://192.168.4.1/led/on")
.build();
Response response = client.newCall(request).execute();
String responseData = Objects.requireNonNull(response.body()).string();
showResponse(responseData);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private void offLED() {
new Thread(() -> {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://192.168.4.1/led/off")
.build();
Response response = client.newCall(request).execute();
String responseData = Objects.requireNonNull(response.body()).string();
showResponse(responseData);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private void showResponse(final String response) {
runOnUiThread(() -> {
responseText.setText(response); //responseText最初由TextView responseText;定义,代表TextView对象。
});
}
}
原文地址:https://blog.csdn.net/weixin_45853406/article/details/130593052
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_48512.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!