1 Star 0 Fork 1

VENTIM / 22.7 esp32cam多功能摄像机

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
esp32cam_TFT7.5 key3切换功能.txt 22.14 KB
一键复制 编辑 原始数据 按行查看 历史
志宇益生菌 提交于 2023-10-28 11:48 . 提交已有的代码备份文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
// Example for library:
// https://github.com/Bodmer/TJpg_Decoder
//这里使用内核0 解码jpg 内核1执行逻辑代码和tft显示
//并行使用esp32 的2个内核,例程测试解码+渲染=66+37=66ms
//我自己测试结果:
//自带320 240 图片,无缩放显示160 120上,36ms
//缩放2 79ms
//改为DMA传输 缩放2 为80ms 使用DMA改善不大?
//测试改为摄像头图像 缩放1 24-28ms, DMA 比上一个解码库快20ms左右!
//测试 缩放1 320 240 的一角 48ms左右
//测试 缩放2 320 240变160 120 65-71ms,整体都比上一个库快!
/*FRAMESIZE_QVGA (320 x 240)
FRAMESIZE_CIF (352 x 288)
FRAMESIZE_VGA (640 x 480)
FRAMESIZE_SVGA (800 x 600)
FRAMESIZE_XGA (1024 x 768)
FRAMESIZE_SXGA (1280 x 1024)
FRAMESIZE_UXGA (1600 x 1200)
*/
//1 文字图形ok
//2 拍照显示到tft,周期显示特定图片。 显示缩放0.5和左上拍摄图片 相关函数
// 》有时正常,有时显示拍照的图片不完整
//3 拍照设置为160x120,尝试改善刷屏的屏闪 使用DMA方式 测试原装板子,运行正常 刚好大小的 1张图43ms
//4 移植SDMMC代码 拍照存储。间歇显示存储,存完需要重启tft才正常,原因可能是去初始化DMA导致。 重启前后图片间隔3s
//5.1 使用新库TJpg_Decoder,实现拍照显示,速度比上一个库快。
//5.2 将SD卡相关代码移植进来。 360*240缩放dma显示 70ms左右。 整体刷新间隔: 差不多70ms
//6 整理代码、增加adc功能按键及处理函数 电池电压,按键存sd
//7 增加长按短按的判断、关闭tft及背光函数、长按key3切换功能、条件让core0休眠
//8
//5V de 关闭tft及复位,减少20ma
//关闭摄像头电源,减少74
//关闭内核0 减少20
//SD卡拔去 11ma
//按键3(设置/切换模式) 按键4(拍照存储/) 面对屏幕。设置界面(短按/长按)
//按键1(加) 按键2(减)
//
//界面:1、tft摄像机,2、局域网摄像头 3、物联网摄像头 4、桌面天气
//开发按键功能菜单, 增加wifi图传功能,桌面天气
//自动复位后,存储SD卡失败!!再次测试可以!
//SD卡存储 与 tft分时使用! 或者能否同时
//大led引脚是否改动?
//(短按/长按) 【【功能设计】】
//【tft摄像机】 质量、大小、开关屏、放大、延时摄影、录像?
//3(设置/切换模式) 4(拍照存储/提示界面) 1(放大/增大size) 2(缩小/减小size)
//[设置界面] 3(设置or确认/切换模式) 4(退出设置/提示界面) 1(加左/) 按键2(减右/)
//【局域网wifi图传】 网页界面控制 默认不亮屏,
//3(/灭屏) 4(/提示界面+亮屏)
//【物联网摄像头】 小程序控制查询
//3(/灭屏) 4(/提示界面+亮屏)
//【桌面天气】 wifi联网tft显示 关闭摄像头
//3(/灭屏) 4(/提示界面+亮屏)
//现在tft的引脚连接: 在tft的User_Setup.h里
//#define TFT_MOSI 13 固定
//#define TFT_SCLK 14 固定
//#define TFT_CS 15 //可省略 片选 可接地持续运行
//#define TFT_DC 2 //1数据 0命令
#define TFT_RST 12 //可省略 低电平复位 可连接esp32复位引脚,上电复位 BLK也连在这个引脚
//SD卡占用引脚: 剩余引脚: 串口(1、3),0,16(spram占用) 33(adc做多按键!)
//HS2_DATA0 2 spi-MISO
//HS2_DATA1 4 可省略
//HS2_DATA2 12 可省略
//HS2_DATA3 13 spi-SS
//HS2_CMD 15 spi-MOSI
//HS2_CLK 14 spi-SCK
//io33 作为adc输入,开机先检测电压,为电池电压
//按下按键会让电压低于电池电压,即可判断
#define adc_io 33
#define adc_power_change 0.00112//(3.3* 197.0 / 150.0 /4096.0 ) //adc转化为电池电压参数
int adc_num = 0;
float power_v=3.6; //理论电压值 变量名不改
#define power_adjust ((power_v-3.16)*0.46) //调整电压值 非线性
char adc_flag=0; //0可更新电源电压 1-4为对应按键按下
#define adc_flag0_upnum 5 //当按键按下<=检测次数,认为是短按
#define adc_Lpress_num 13 //当按键 按下>检测次数 认为长按
/*#########################
Taking picture...
Camera capture ok
===============
JPEG image info
===============
Width :320
Height :240
Components :1
MCU / row :20
MCU / col :30
Scan type :2
MCU width :16
MCU height :8
===============
Total render time was : 80 ms
#########################
Mouse 1
===============
JPEG image info
===============
Width :160
Height :107
Components :1
MCU / row :10
MCU / col :7
Scan type :4
MCU width :16
MCU height :16
===============
Total render time was : 51 ms
*/
//#define minimum(a,b) (((a) < (b)) ? (a) : (b)) //返回小的数值
#include <SPI.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include <TJpg_Decoder.h> //该文件里注释了//#include <LittleFS.h>
#include "FS.h"
#include "SD_MMC.h"
//#include <WiFi.h>
#include "esp_camera.h"
// CAMERA_MODEL_AI_THINKER 对应板子的摄像头设置参数
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
camera_fb_t * fb = NULL; //照片指针
char frame_size_num1=2; //有关设置图片大小的 0-8 越大越大
char jpeg_quality_num1=10; //有关图片 质量 越小越好 10跟20好像肉眼差不多
//DMA有关的 缓冲区
uint16_t dmaBuffer1[16*8]; //乒乓缓冲区1
uint16_t dmaBuffer2[16*8]; //2
uint16_t* dmaBufferPtr = dmaBuffer1; //指向缓冲区
bool dmaBufferSel = 0; //选哪一个区
//文件路径名称
String path = "/2020_6_18_TIME_19_0_47.jpg";
//其他变量
uint16_t main_count=0; //主循环 统计循环多少次
char esp32cam_mode=0; //esp32cam的模式,0-3对应4种 开发功能
char core0_work_flag = 0; //内核0 是否运行 0不运行 1运行
// 全局变量对处理器0和1都可用
TaskHandle_t Task1;
//const uint8_t* arrayName; // 包含Jpeg的闪存阵列的名称
bool decoding_flag = false; //1开始+正在解码 0全部解码完成
bool mcuReady_showOk_flag = false; // 当前已解码MCU块 1解码完成未显示 0显示完成可以解码下一个
uint16_t mcuBuffer[16*16]; // 抓取解码MCU块快照的缓冲区
int32_t mcu_x, mcu_y, mcu_w, mcu_h; // 呈现MCU的位置 显示的x,y,mcu的宽高
bool camera_init(char frame_size_num = 3 , char jpeg_quality_num = 12){ //图像大小 0-6 越大越大
//配置摄像头 参数
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
//判断 若有PSRAM则质量更高一些
if (psramFound()) { //有PSRAM硬件,更大的ram空间
Serial.println("psramFound!"); //此时io16被占用 CS
switch(frame_size_num){ //FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
case 0: config.frame_size = FRAMESIZE_QQVGA; break; //QQVGA (160 x 120)
case 1: config.frame_size = FRAMESIZE_QQVGA2; break; //QQVGA2 (128 x 160)
//HQVGA
case 2: config.frame_size = FRAMESIZE_QVGA; break; //QVGA (320 x 240)
case 3: config.frame_size = FRAMESIZE_CIF; break; //CIF (352 x 288)
case 4: config.frame_size = FRAMESIZE_VGA; break; //VGA (640 x 480)
case 5: config.frame_size = FRAMESIZE_SVGA; break; //SVGA (800 x 600)
case 6: config.frame_size = FRAMESIZE_XGA; break; //XGA (1024 x 768)
case 7: config.frame_size = FRAMESIZE_SXGA; break; //SXGA (1280 x 1024)
case 8: config.frame_size = FRAMESIZE_UXGA; break; //UXGA (1600 x 1200)
default: frame_size_num=3;config.frame_size = FRAMESIZE_SVGA; break;
}
Serial.printf("frame_size = %d [0-6]\r\n", frame_size_num);
Serial.printf("jpeg_quality = %d [0-xx]\r\n", jpeg_quality_num);
// config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = jpeg_quality_num; //10; //越小越好
config.fb_count = 2;
} else { //没有则质量低一些
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
esp_err_t err = esp_camera_init(&config); //摄像头初始化
if (err != ESP_OK) { //若初始化失败
Serial.printf("Camera init failed with error 0x%x", err);
return false;
}
else return true;
}
//处理器0 当前MCU解码后 拷贝副本
bool core0_mcu_decoded(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap){ //处理器0 调用执行
if ( y >= tft.height() ) return 0; //停止进一步解码,因为图像已超出屏幕底部
while(mcuReady_showOk_flag) yield(); //如果最后一个MCU块到TFT的渲染仍在进行中,请在此等待
memcpy(mcuBuffer, bitmap, 16*16*2); //复制当次解码的 MCU块图像
mcu_x = x; // Grab postion and size of MCU block
mcu_y = y;
mcu_w = w;
mcu_h = h;
mcuReady_showOk_flag = true; //告知处理器1可以开始渲染MCU 解码好了未显示
return 1; // 返回1以解码下一个Jpeg MCU块
}
//处理器0 开始及解码Jpeg图像
void core0_decode_jpg(void* p) { //处理器0 执行
for(;;) {
// 解码Jpeg图像
if (decoding_flag) { //1 才开始进行解码
TJpgDec.drawJpg(0, 0, fb->buf, fb->len); // 运行,直到完整的图像解码,阻塞
decoding_flag = false; // 0 表示解码结束
}
yield(); //节省资源给其他进程运行时间 Must yield in this loop
if(core0_work_flag==0) break;
}
vTaskDelete(NULL); //结束当前任务
}
//DMA显示已解码的jpg 其实是跟解码进程并行执行
void show_JPEG_160x120DMA(int ypos=8) { //使用dma的方式 屏幕刷新不闪烁! 这个速度下不用dma也不闪吧?
//espcam中 mcu_w=16,mcu_h=8
uint16_t w = 0, h = 0;
//检索关于图像的信息
//TJpgDec.getJpgSize(&w, &h, fb->buf, fb->len);
//Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
uint32_t drawTime = millis(); //有关计算耗时
mcuReady_showOk_flag = false; // Flag which is set true when a MCU block is ready for display
decoding_flag = true; // Flag to tell task to decode the image
//仅在解码正在进行或MCU准备好渲染时渲染MCU块
//注意:需要或mcuReady_showOk_flag,以便在解码结束后呈现最后一个块
// 必须首先使用startWrite,以便在DMA和SPI通道设置保持配置期间TFT片选保持低电平
tft.startWrite();
while(decoding_flag || mcuReady_showOk_flag) {
if (mcuReady_showOk_flag) {
//tft.pushImage(mcu_x, mcu_y, mcu_w, mcu_h, mcuBuffer);
if (dmaBufferSel) dmaBufferPtr = dmaBuffer2;
else dmaBufferPtr = dmaBuffer1;
dmaBufferSel = !dmaBufferSel; //交替选择 缓冲区
tft.pushImageDMA(mcu_x, mcu_y + ypos, mcu_w, mcu_h, mcuBuffer, dmaBufferPtr);
//tft.pushImageDMA(mcu_x, mcu_y, mcu_w, mcu_h, mcuBuffer, dmaBufferPtr);
mcuReady_showOk_flag = false;
}
// Must yield in this loop
yield();
}
// 必须使用endWrite来释放TFT片选并释放SPI通道
tft.endWrite();
// 计算绘制图像需要多长时间
drawTime = millis() - drawTime;
Serial.print(F("render time was (ms) : ")); Serial.println(drawTime);
}
//SDMMC初始化------------
void sd_init(){
if (!SD_MMC.begin()) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD_MMC.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD_MMC card attached");
return;
}
Serial.print("SD_MMC Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
}
else if (cardType == CARD_SD) {
Serial.println("SDSC");
}
else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
}
else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024); //获取SD卡大小,大小单位是MB
Serial.printf("SD_MMC size: %lluMB\n", cardSize);
//SD卡测试
// listDir(SD_MMC, "/", 0);
// createDir(SD_MMC, "/mydir");
// listDir(SD_MMC, "/", 0);
// removeDir(SD_MMC, "/mydir");
// listDir(SD_MMC, "/", 2);
// writeFile(SD_MMC, "/hello.txt", "Hello ");
// appendFile(SD_MMC, "/hello.txt", "World!\n");
// readFile(SD_MMC, "/hello.txt");
// deleteFile(SD_MMC, "/foo.txt");
// renameFile(SD_MMC, "/hello.txt", "/foo.txt");
// readFile(SD_MMC, "/foo.txt");
// testFileIO(SD_MMC, "/test.txt");
// Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
// Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
//
}
void sd_deinit(){
SD_MMC.end(); //卸载
// pinMode(2,INPUT ); //
// pinMode(4,INPUT ); //
// pinMode(12,INPUT ); //
// pinMode(13,INPUT ); //
// pinMode(14,INPUT ); //
// pinMode(15,INPUT ); //
}
//存储图片到SD卡中
void save_pic_sd(camera_fb_t *fb){ //图片指针
path = "/2022+"+String(millis())+".jpg";
Serial.print("save pic path:"); Serial.println(path);
if (fb == NULL)
{
Serial.println( "get picture failed"); //代表获取图片失败
} else {
fs::FS &fs = SD_MMC;
// Serial.printf("Writing file: ");
// Serial.println(path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("file creat failed");
}
else
{
file.write(fb->buf , fb->len); //payload , lengte vd payload
Serial.println("write ok");
}
//return the frame buffer back to the driver for reuse
//esp_camera_fb_return(fb);
}
}
//tft显示屏
void tft_init(){
tft.begin();
// pinMode(2,INPUT ); //
// pinMode(4,INPUT ); //
// pinMode(12,INPUT ); //
// pinMode(13,INPUT ); //
// pinMode(14,INPUT ); //
// pinMode(15,INPUT ); //
tft.initDMA(); //初始化对应DMA
// pinMode(15,OUTPUT ); //
// digitalWrite(15, 0);
//
// pinMode(12,OUTPUT ); //
// digitalWrite(12, 1);
}
void tft_deinit(){
tft.deInitDMA(); //初始化对应DMA
// pinMode(2,INPUT ); //
// pinMode(12,INPUT ); //
// pinMode(13,INPUT ); //
// pinMode(14,INPUT ); //
// pinMode(15,INPUT ); //
}
//求平均 原先的数值,此时数值,多少个数平均
float average1(float aver_old,float now_value,int num){
aver_old = (aver_old*(num-1)+now_value)/num;
return aver_old;
}
//保存照片到sd卡后 重启设备
void save_restart(camera_fb_t *fb){
tft_deinit();
sd_init(); //SD卡初始化
save_pic_sd(fb);
//delay(2000);
sd_deinit();
delay(100);
//tft_init(); //SD卡后 好像无法完全初始化
ESP.restart(); // 板子重启 这里复位前后图片时间间隔3s左右 好像可以,循环复位使用正常
}
//adc读取处理电压,更新电池电压以及判断按键按下抬起 不会重复触发,按下只返回1次
char adc_power_key(){ //1-4为对应按键短按,5-8为按键长按, 0是可更新电源电压,//-1是在判断是否长按短按
static int adc_flag_num=0; //计算adc判断 非0连续次数,用于判断按键长按 短按逻辑
static char adc_key_num=0; //上次的按键数 用于长按 短按 的判断逻辑
adc_num = analogRead(adc_io);
if(adc_num>2200){ //是电池电压的
power_v = average1(power_v,adc_num * adc_power_change ,5);
Serial.println(" "+ String(power_v-power_adjust) + 'V');
tft.drawString("V:", 0,0);
tft.drawFloat(power_v-power_adjust, 3, 16,0);
//tft.drawString("V ", 82,0);
if(adc_flag_num==0) return 0; //无按键按下 此时为检测电池电压
else{
if(adc_flag_num>adc_Lpress_num){ //长按
adc_flag_num=0;
return adc_key_num+4;
}
else if(adc_flag_num<=adc_flag0_upnum){ //短按
adc_flag_num=0;
return adc_key_num;
}
else adc_flag_num=0; //在这之间,无响应
}
}
else if(adc_num<200){ //按键4检测 拍照/提示界面
adc_key_num = 4;
adc_flag_num++;
}
else if(adc_num<750){ //按键3 设置/切换模式
adc_key_num = 3;
adc_flag_num++;
if(adc_flag_num>=adc_Lpress_num){ //第一次判断为长按
esp32cam_mode = 0; //默认从0开始
while(adc_num<2200){ //若继续按着,就死循环
tft.fillScreen(TFT_BLACK); //背景黑色
tft.setTextSize(2); //设置字体大小
tft.drawString("1.TFT CAM", 16,32);
tft.drawString("2.WIFI CAM", 16,48);
tft.drawString("3.IOT CAM", 16,64);
tft.drawString("4.TFT Weather", 16,80);
tft.setTextSize(1); //设置字体大小
//esp32cam_mode=(esp32cam_mode+1)%4;
tft.fillCircle(8,16*esp32cam_mode+40,8,TFT_BLUE); //画圆
for(int i=0;i<10;i++){
if(analogRead(adc_io)>=2200) break;
else delay(100);
}
adc_num = analogRead(adc_io);
if(adc_num<750){ //按键还按着,就 模式序号+1
esp32cam_mode=(esp32cam_mode+1)%4;
}
else{ //不按了,按 esp32cam_mode 跳转对应的功能模块
delay(500);
//切换跳转
adc_flag_num=0;
return adc_key_num+4;
}
}
}
}
else if(adc_num<1350){ //按键2
adc_key_num = 2;
adc_flag_num++;
}
else{ //按键1
adc_key_num = 1;
adc_flag_num++;
}
return -1; //按键按下,还在判断长按还是短按的时候
}
void close_tft(){ //关闭tft屏及背光 SD卡使用时无效
tft_deinit();
delay(100);
pinMode(TFT_RST,OUTPUT ); // tft的复位引脚 也连着BLK背光控制引脚
digitalWrite(TFT_RST, 0); //低电平为关闭
}
void setup()
{
//创建在处理器0上运行的任务core0_decode_jpg来解码Jpeg
xTaskCreatePinnedToCore(core0_decode_jpg, "core0_decode_jpg", 10000, NULL, 0, NULL, 0);
core0_work_flag=1;
Serial.begin(115200);
Serial.println("\n\n 【项目】: esp32 cam tft 摄像机");
// btStop(); //关闭 蓝牙 好像开机默认是关闭发的
// WiFi.disconnect(true); //断开且关闭STA网络 好像一样,约35ma
// WiFi.mode( WIFI_MODE_NULL ); //关闭wifi 这行而已,电流34ma
//sd_init(); //SD卡初始化
// adc_num = analogRead(adc_io);
// power_v = adc_num * adc_power_change;
// Serial.print(adc_num); //
// Serial.println(" "+ String(power_v) + 'V');
//tft.init(); //之前用这个
tft.begin();
tft.initDMA(); //初始化对应DMA
tft.setTextColor(0xFFFF, 0x0000);
tft.fillScreen(TFT_BLACK);
tft.setRotation(3); //显示方向 13横向 3为wifi天线与tft排针同向
// tft.drawString("Power:", 0,0);
// tft.drawFloat(power_v, 3, 50,0);
// 设置缩放 1, 2, 4, or 8
TJpgDec.setJpgScale(2);
// The byte order can be swapped (set true for TFT_eSPI)
TJpgDec.setSwapBytes(true);
//每个mcu解码后 会执行的函数 回调函数
TJpgDec.setCallback(core0_mcu_decoded);
esp_camera_deinit(); //摄像头去初始化 防止没断电导致cam初始化失败
pinMode(32,OUTPUT ); // 32是 cam电源控制引脚
digitalWrite(32, 1); // 高电平 断电 cam的
delay(10);
pinMode(32,INPUT ); //释放 引脚
if(camera_init(frame_size_num1,jpeg_quality_num1)==true) Serial.println("camera init ok!");
else{
Serial.println("camera init error!");
return;
}
}
void loop()
{
if(main_count>60000) main_count=0;
else main_count++;
adc_flag = adc_power_key(); //
Serial.print(adc_num); //
Serial.println("");
switch(adc_flag){
//case -1: break;
case 0: break;//Serial.println(""); //电池电压获取成功
case 1: Serial.println("key1 Short press"); tft.drawString("key1 S", 60,0); core0_work_flag=0; break; //按键1短按
case 2: Serial.println("key2 Short press"); tft.drawString("key2 S", 60,0); pinMode(32,OUTPUT );digitalWrite(32, 1); break; //按键2短按
case 3: Serial.println("key3 Short press"); tft.drawString("key3 S", 60,0); break; //按键3短按
case 4: Serial.println("key4 Short press"); tft.drawString("key4 S", 60,0); save_restart(fb); break; //按键4短按
case 5: Serial.println("key1 Long press"); tft.drawString("key1 L", 60,0); break; //按键1长按
case 6: Serial.println("key2 Long press"); tft.drawString("key2 L", 60,0);pinMode(32,OUTPUT );digitalWrite(32, 0);pinMode(32,INPUT );break; break; //按键2长按
case 7: Serial.println("key3 Long press"); tft.drawString("key3 L", 60,0); break; //按键3长按
case 8: Serial.println("key4 Long press"); tft.drawString("key4 L", 60,0); close_tft(); break; //按键4长按
default: break;
}
//Serial.println("Taking picture...");
//esp_err_t res = ESP_OK;
fb = esp_camera_fb_get(); //拍照 返回照片指针
if (!fb) { //拍照失败
Serial.println("Camera capture failed!");
}
else{
// if(main_count%300==0){ //200次存一张图片
// save_restart(fb);
// }
// else
{ //在这的话,大约 40-73ms 复杂图70ms左右
//tft_init();
//tft.setRotation(3); //显示方向 横向
//tft.fillScreen(TFT_BLACK);
// JpegDec.decodeArray(fb->buf, fb->len); //解码 jpg
// Serial.println("decode ok");
show_JPEG_160x120DMA(8); //固定偏移 解码+显示
Serial.println("#########################");
//delay(2000);
//tft_deinit();
//delay(200);
}
esp_camera_fb_return(fb); //应该是销毁图片指针
}
}
C++
1
https://gitee.com/ventim/esp32cam-camera.git
git@gitee.com:ventim/esp32cam-camera.git
ventim
esp32cam-camera
22.7 esp32cam多功能摄像机
master

搜索帮助