【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信

0.前言

基本上ESP32-CAM的测试也差不多了,下面放个合集,方便查找:
1.【好奇心驱动力】ESP32-CAM定时拍照存储到SD卡
2.【好奇心驱动力】ESP32-CAM PIN与GPIO引脚对应关系

1.实验目的

部分步骤和截图来源于官网
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第1张图片
最开始的设想是这样的:

  • ESP32-CAM连接人体红外感应模块(PIR)
  • 检测到人体活动并拍照存储到SD卡或者云端
  • 从存储端推送到微信提醒

因为之前写了拍照存储到SD卡的代码,需要解决的主要是连接PIR和推送到微信,连接微信的思路可以参考【好奇心驱动力】ESP8266从零开始折腾记录,不同的是ESP8266是微信远程控制开关二极管,推送消息需要再查一下怎么写。

在查的过程中发现了新平台,巴法云物联网平台,文档很详细,很多示例都是现成的,例如接入天猫精灵等等,这一点比之前用的阿里云物联网平台要简单一些。从巴法云的CSDN上有一篇【esp32-cam图片上传巴法云,http协议传输post】,后续都在这个比较简单的 平台上实现的。

现在的思路是这样的:

  • ESP32-CAM连接人体红外感应模块(PIR)
  • 检测到人体活动并拍照上传到巴法云–控制台–图云
  • 由巴法云平台直接推送给绑定的微信

2.实验方法

与【好奇心驱动力】ESP8266从零开始折腾记录开始介绍的一样,但不需要SD卡,在Arduino中设置好ESP32-CAM运行环境,然后烧录程序。

接线情况:
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第2张图片

【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第3张图片

  • 程序烧录
    主要是连接PIR,当PIR接收情况发生变化时拍照。
/*
 * 2020-07-07
 * QQ交流群:824273231
 * 微信:19092550573
 * 官网https://bemfa.com  
 *
 *此版本需要json库,再arduino IDE 选项栏,点击“工具”-->"管理库"-->搜索arduinojson 第一个库就是,点击安装即可
 *
分辨率默认配置:config.frame_size = FRAMESIZE_UXGA;
其他配置:
FRAMESIZE_UXGA (1600 x 1200)
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)

config.jpeg_quality = 10;(10-63)越小照片质量最好
数字越小表示质量越高,但是,如果图像质量的数字过低,尤其是在高分辨率时,可能会导致ESP32-CAM崩溃

*支持发布订阅模式,当图片上传时,订阅端会自动获取图片url地址,可做图片识别,人脸识别,图像分析
*/

#include 
#include "esp_camera.h"
#include 
#include 

/*********************需要修改的地方**********************/
const char* ssid = "XXXXXXXX";           //WIFI名称
const char* password = "XXXXXXXXXX";     //WIFI密码
int capture_interval = 20*1000;        // 默认20秒上传一次,可更改(本项目是自动上传,如需条件触发上传,在需要上传的时候,调用take_send_photo()即可)
const char*  post_url = "http://images.bemfa.com/upload/v1/upimages.php"; // 默认上传地址
const char*  uid = "XXXXXXXXXXXXXXXXXXXXXXXXXX";    //用户私钥,巴法云控制台获取
const char*  topic = "XXXXXXXXX";     //图云主题名字,可在控制台新建
bool sentWechat = true;               //是否推送到微信,默认不推送,true 为推送。需要在控制台先绑定微信,不然推送不到
const char*  wechatMsg = "Somebody is here.";     //推送到微信的消息,可随意修改,修改为自己需要发送的消息
/********************************************************/


bool internet_connected = false;
long current_millis;
long last_capture_millis = 0;

// 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

void setup()
{
  Serial.begin(115200);
  //PIR初始状态
  pinMode(12,INPUT);
  digitalWrite(12,LOW);
  
  if (init_wifi()) { // Connected to WiFi
    internet_connected = true;
    Serial.println("Internet connected");
  }

  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;
  //init with high specs to pre-allocate larger buffers
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}


/********初始化WIFI*********/
bool init_wifi()
{
  int connAttempts = 0;
  Serial.println("\r\nConnecting to: " + String(ssid));
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED ) {
    delay(500);
    Serial.print(".");
    if (connAttempts > 10) return false;
    connAttempts++;
  }
  return true;
}



/********推送图片*********/
static esp_err_t take_send_photo()
{
    //初始化相机并拍照
    Serial.println("Taking picture...");
    camera_fb_t * fb = NULL;
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Camera capture failed");
      return ESP_FAIL;
    }
  
    HTTPClient http;
    //设置请求url
    http.begin(post_url);
    
    //设置请求头部信息
    http.addHeader("Content-Type", "image/jpg");
    http.addHeader("Authorization", uid);
    http.addHeader("Authtopic", topic);
    if(sentWechat){ //判断是否需要推送到微信
      http.addHeader("Wechatmsg", wechatMsg);  //设置 http 请求头部信息
    }
    //发起请求,并获取状态码
    int httpResponseCode = http.POST((uint8_t *)fb->buf, fb->len);
    
    if(httpResponseCode==200){
        //获取post请求后的服务器响应信息,json格式
        String response = http.getString();  //Get the response to the request
        Serial.print("Response Msg:");
        Serial.println(response);           // 打印服务器返回的信息
        

        //json数据解析
        StaticJsonDocument<200> doc;
        DeserializationError error = deserializeJson(doc, response);
        if (error) {
          Serial.print(F("deserializeJson() failed: "));
          Serial.println(error.c_str());
        }
        const char* url = doc["url"];
        Serial.print("Get URL:");
        Serial.println(url);//打印获取的URL
    
        
    }else{
        //错误请求
        Serial.print("Error on sending POST: ");
        Serial.println(httpResponseCode);
    }
   
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
  
    //清空数据
    esp_camera_fb_return(fb);  
    //回收下次再用
    http.end();
  
}



void loop()
{
    //PIR检测电平变化
    if(digitalRead(12)==HIGH)  {
      Serial.println("Somebody is here.");
      take_send_photo();
    }
    else  {
      Serial.println("Nobody.");
    }
    delay(1000);
}

3.实验结果

串口监控输出情况,能够看到PIR监控有反应,然后拍照,上传至巴法云平台,又获取到图片云端存储地址进行解析。
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第4张图片
由巴法云直接推送到微信,省去了在阿里云物联网平台设置推送到小程序的情况。
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第5张图片
能够看到拍照的情况也正常,可以在微信直接预览
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第6张图片

4.问题汇总

有点时候传到云端会显示网络错误,目前不知道具体原因。
【好奇心驱动力】ESP32-CAM人体感应拍照并推送到微信_第7张图片

你可能感兴趣的:(好奇心驱动力,单片机,ESP32-CAM)