文章目录[隐藏]
这是我全程参考的文章
参考文章
但中途还是有遇到一些文中没提到的问题,接下来逐一解决
一、硬件连接及原理
淘宝上所买的开发板
ESP32CAM原理图
电源端接5V
进行程序烧录的时候,将GPIO0与GND短接。
烧录完,运行开发板的时候再拔掉
TXD接USB的RXD,RXD接USB的TXD(即开发板的发送端接USB的接收端)
二、Arduino安装
链接:https://pan.baidu.com/s/1jc0FrE_oiNaGxl_j_R0Y-g
提取码:r8ul
复制这段内容后打开百度网盘手机App,操作更方便哦
三、arduino与esp32cam初使用
初步摄像头使用
可以根据这个教程,实现在PC端上显示摄像视频。
四、利用Android Studio实现在手机APP内显示摄像视频
1.在layout层需要添加两个元件控件
一个imageview 命名为img
一个button 命名为downloadFile
2.Acticity的代码
package xyz.pengzhihui.esp32ipcam;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class MainActivity extends Activity implements View.OnClickListener
{
private static final String TAG = "MainActivity::";
private HandlerThread handlerThread;
private Handler handler;
private ImageView imageView;
private final int DOWNDLOAD = 1;
private final int REGISTER = 2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.downloadFile).setOnClickListener(this);
imageView = findViewById(R.id.img);
handlerThread = new HandlerThread("http");
handlerThread.start();
handler = new HttpHandler(handlerThread.getLooper());
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.downloadFile:
handler.sendEmptyMessage(DOWNDLOAD);
break;
default:
break;
}
}
//动态申请权限
public static boolean isGrantExternalRW(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1);
return false;
}
return true;
}
private class HttpHandler extends Handler
{
public HttpHandler(Looper looper)
{
super(looper);
}
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case DOWNDLOAD:
downloadFile();
break;
default:
break;
}
}
}
private void downloadFile()
{
String downloadUrl = "http://192.168.50.26:80/stream";
String savePath = "/sdcard/pic.jpg";
File file = new File(savePath);
if (file.exists())
{
file.delete();
}
if(!isGrantExternalRW(this)){
return;
}
BufferedInputStream bufferedInputStream = null;
FileOutputStream outputStream = null;
try
{
URL url = new URL(downloadUrl);
try
{
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setConnectTimeout(1000 * 5);
httpURLConnection.setReadTimeout(1000 * 5);
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200)
{
InputStream in = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(isr);
String line;
StringBuffer stringBuffer = new StringBuffer();
int i = 0;
int len;
byte[] buffer;
while ((line = bufferedReader.readLine()) != null)
{
if (line.contains("Content-Type:"))
{
line = bufferedReader.readLine();
len = Integer.parseInt(line.split(":")[1].trim());
bufferedInputStream = new BufferedInputStream(in);
buffer = new byte[len];
int t = 0;
while (t < len)
{
t += bufferedInputStream.read(buffer, t, len - t);
}
bytesToImageFile(buffer, "0A.jpg");
final Bitmap bitmap = BitmapFactory.decodeFile("sdcard/0A.jpg");
runOnUiThread(new Runnable()
{
@Override
public void run()
{
imageView.setImageBitmap(bitmap);
}
});
}
}
}
} catch (IOException e)
{
e.printStackTrace();
}
} catch (MalformedURLException e)
{
e.printStackTrace();
} finally
{
try
{
if (bufferedInputStream != null)
{
bufferedInputStream.close();
}
if (outputStream != null)
{
outputStream.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
private void bytesToImageFile(byte[] bytes, String fileName)
{
try
{
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes, 0, bytes.length);
fos.flush();
fos.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
3.需要烧录进Esp32Cam的代码
自己修改其中的局域网名和局域网密码,其他还有类似pins.h文件,需要从我开头所给的参考文章中获取。
#include <WiFi.h>
// #include <U8g2lib.h>
#include <I2Cdev.h>
#include <Wire.h>
// #include <MPU6050.h>
#include "Pins.h"
#include "Camera.h"
#include "Motor.h"
const char* ssid = ""; //填你自己的局域网名
const char* password = ""; //局域网密码
WiFiServer server(81);
// OV2640 camera
Camera ov2640;
void setup()
{
Serial.begin(115200);
Wire.begin(I2C0_SDA, I2C0_SCL);
Wire.setClock(400000);
// while (!mpu6050.testConnection());
// mpu6050.initialize();
ov2640.initialize();
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
delay(10);
}
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
ov2640.startCameraServer();
Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
server.begin();
}
float i = -1;
long heart_beat = 0;
void loop()
{
Serial.println(analogRead(38));
WiFiClient client = server.available(); // listen for incoming clients
if (client)
{
// if you get a client,
Serial.println("New Client."); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected())
{ // loop while the client's connected
if (client.available())
{ // if there's bytes to read from the client,
}
}
}
delay(50);
}
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
if (data.charAt(i) == separator || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
4.注意事项
1.关于I2Cdev.h文件可能在烧录的时候没有这个库,这个需要自行去github上下载对应的库,并导入就能正常编译了
icdev库下载
2.如果要在手机APP模拟器上连上网就需要在文件AndroidManifest.xml 加上
android:supportsRtl=“true”
3.需要在文件AndroidManifest.xml 加上android:requestLegacyExternalStorage = “true” 这个属性
Last: 如果你实在很懒,想不动脑就直接获得能运行的APP程序,一杯奶茶钱,我把所有东西打包发你。
版权声明:本文为CSDN博主「momomomoy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/timuxi/article/details/116099548
暂无评论