入门-ESP32CAM(5) ESP32CAM 拍照并上传node服务

1. 创建一个简单的 express 项目

express create myapp
cd myapp
npm install

 在 routes/index.js 里面添加

router.post('/uploadImg', (req, res) => {
  const data = []

  req.on('data', chunk => {
    data.push(chunk)
  })

  const name = new Date().getTime()
  req.on('end', () => {
    const data1 = Buffer.concat(data)
    fs.writeFileSync(path.join(path.dirname(__dirname), 'public', 'uploadImgs/img_' + name + '.jpg'), data1, 'binary')
  })

  res.send('ok');
})

 在public目录下面添加uploadImgs目录

然后启动express

npm start

2. 网上找一段esp32cam 定时拍照上传的代码,参考esp32-cam 上传图片到云平台 http协议 - 巴法云 - 博客园

将代码稍加改造

const char *post_url = "http://192.168.3.4:3000/uploadImg"; // 自己启动的express 地址
// 添加 WiFiManager
void connectWifi()
{
    // 建立WiFiManager对象
    WiFiManager wifiManager;
    // wifiManager.resetSettings();
    // 自动连接WiFi。以下语句的参数是连接时的WiFi名称
    wifiManager.autoConnect(WIFI_NAME, WIFI_PASSWORD);
    Serial.println("");
    Serial.println("WiFi Connected!");
    Serial.println("");

}

  将代码烧录到开发板,可以看到开发板成功连接wifi,并每隔20秒上传一次图片

express 也能接受到图片 

 

 uploadImgs 文件夹已经出现上传图片

 

完整代码

esp32_auto_upload_img.ino

#include "esp_http_client.h"
#include "esp_camera.h"
#include <WiFi.h>
#include <ArduinoJson.h>
/*********************需要修改的地方**********************/
// const char* ssid = "newhtc";           //WIFI名称
// const char* password = "qq123456";     //WIFI密码
int capture_interval = 20 * 1000;                     // 默认20秒上传一次,可更改(本项目是自动上传,如需条件触发上传,在需要上传的时候,调用take_send_photo()即可)
const char *uid = "621f7c40100d2bac0572b9d850f5655a"; //用户私钥,巴法云控制台获取
const char *topic = "mypic";                          //主题名字,可在控制台新建
const char *wechatMsg = "";                           //如果不为空,会推送到微信,可随意修改,修改为自己需要发送的消息
const char *wecomMsg = "";                            //如果不为空,会推送到企业微信,推送到企业微信的消息,可随意修改,修改为自己需要发送的消息
const char *urlPath = "";                             //如果不为空,会生成自定义图片链接,自定义图片上传后返回的图片url,url前一部分为巴法云域名,第二部分:私钥+主题名的md5值,第三部分为设置的图片链接值。
/********************************************************/

const char *post_url = "http://192.168.3.4:3000/uploadImg"; // 自己启动的express 地址
// const char *post_url = "https://images.bemfa.com/upload/v1/upimages.php"; // 默认上传地址
static String httpResponseString; //接收服务器返回信息
bool internet_connected = false;
long current_millis;
long last_capture_millis = 0;

void connectWifi();

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

    connectWifi();

    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_SVGA;
        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;
    }
}

/********http请求处理函数*********/
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    if (evt->event_id == HTTP_EVENT_ON_DATA)
    {
        httpResponseString.concat((char *)evt->data);
    }
    return ESP_OK;
}

/********推送图片*********/
static esp_err_t take_send_photo()
{
    Serial.println("Taking picture...");
    camera_fb_t *fb = NULL;
    esp_err_t res = ESP_OK;

    fb = esp_camera_fb_get();
    if (!fb)
    {
        Serial.println("Camera capture failed");
        return ESP_FAIL;
    }
    Serial.printf("width: %d, height: %d, buf: 0x%x, len: %d\n", fb->width, fb->height, fb->buf, fb->len);

    httpResponseString = "";
    esp_http_client_handle_t http_client;
    esp_http_client_config_t config_client = {0};
    config_client.url = post_url;
    config_client.event_handler = _http_event_handler;
    config_client.method = HTTP_METHOD_POST;
    http_client = esp_http_client_init(&config_client);

    esp_http_client_set_header(http_client, "Content-Type", "image/jpeg"); //设置http头部字段

    esp_http_client_set_post_field(http_client, (const char *)fb->buf, fb->len); //设置http发送的内容和长度
    // esp_http_client_set_header(http_client, "Authorization", uid);               //设置http头部字段
    // esp_http_client_set_header(http_client, "Authtopic", topic);                 //设置http头部字段
    // esp_http_client_set_header(http_client, "wechatmsg", wechatMsg);             //设置http头部字段
    // esp_http_client_set_header(http_client, "wecommsg", wecomMsg);               //设置http头部字段
    // esp_http_client_set_header(http_client, "picpath", urlPath);                 //设置http头部字段、

    // Serial.println(String(http_client));
    esp_err_t err = esp_http_client_perform(http_client); //发送http请求
    if (err == ESP_OK)
    {
        //json数据解析
        StaticJsonDocument<200> doc;
        DeserializationError error = deserializeJson(doc, httpResponseString);
        if (error)
        {
            Serial.print(F("deserializeJson() failed: "));
            Serial.println(error.c_str());
        }
        String url = doc["url"];
        Serial.println(url); //打印获取的URL
    }
    esp_http_client_cleanup(http_client);
    esp_camera_fb_return(fb);
}

void loop()
{
    // TODO check Wifi and reconnect if needed

    //定时发送
    current_millis = millis();
    if (current_millis - last_capture_millis > capture_interval)
    { // Take another picture
        last_capture_millis = millis();
        take_send_photo();
    }
}

wifi.cpp

#include <WiFi.h>
#include <WiFiManager.h>

static const char *WIFI_NAME = "AutoConnectAP";
static const char *WIFI_PASSWORD = "";
// 连接wifi
void connectWifi()
{
    // 建立WiFiManager对象
    WiFiManager wifiManager;
    // wifiManager.resetSettings();
    // 自动连接WiFi。以下语句的参数是连接时的WiFi名称
    wifiManager.autoConnect(WIFI_NAME, WIFI_PASSWORD);
    Serial.println("");
    Serial.println("WiFi Connected!");
    Serial.println("");

}

 express里面 routes/index.js

var express = require('express');
var router = express.Router();
const path = require("path")
const fs = require("fs")

/* GET home page. */
router.get('/', function (req, res, next) {
  res.render('index', { title: 'Express' });
});


router.post('/uploadImg', (req, res) => {
  console.log(req.headers);
  const data = []

  req.on('data', chunk => {
    data.push(chunk)
  })

  const name = new Date().getTime()
  req.on('end', () => {
    const data1 = Buffer.concat(data)
    fs.writeFileSync(path.join(path.dirname(__dirname), 'public', 'uploadImgs/img_' + name + '.jpg'), data1, 'binary')
  })

  res.send('ok');
})

module.exports = router;

  • 1
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值