本帖最后由 aramy 于 2023-8-22 21:07 编辑
参加Dfrobot官方的S3 的申请试用,人品大爆发,居然中了。真是开心。板子上有OV2640的摄像头,加上ESP32-S3强大的算力。一直有羡慕乐鑫在AI方面的功能,现在自己有了板子,也会去努力尝试一番的。
拿到板子晚了几天,迫不及待地将esp-who下的例程,烧写进去,不出意外地不能工作。看来还是得一步一步地学习。那么就先从熟悉点的 Arduino开始吧!用Vscode+platformio先做个最简单的串口程序。
- #include <Arduino.h>
- #include "esp32-hal-log.h"
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Starting"); // will be shown in the terminal
- Serial.setDebugOutput(true);
- }
-
- void loop()
- {
- log_e("Total PSRAM: %d Free PSRAM: %d ", ESP.getPsramSize(), ESP.getFreePsram());
- Serial.println("Hello!");
- delay(1000);
- }
复制代码
结果是啥都不输出。翻看论坛中老师的帖子明白是配置错误,修改了%homepath%\.platformio\platforms\espressif32\boards下的dfrobot_firebeetle2_esp32s3.json文件,至此成功地输出了串口日志。
- {
- "build": {
- "arduino": {
- "partitions":"app3M_fat9M_16MB.csv",
- "ldscript": "esp32s3_out.ld",
- "memory_type":"qio_opi"
- },
- "core": "esp32",
- "extra_flags": [
- "-DBOARD_HAS_PSRAM",
- "-DARDUINO_ESP32S3_DEV",
- "-DARDUINO_USB_MODE=1",
- "-DARDUINO_RUNNING_CORE=1",
- "-DARDUINO_EVENT_RUNNING_CORE=1",
- "-DARDUINO_USB_CDC_ON_BOOT=1"
- ],
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x83CF"
- ],
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "dfrobot_firebeetle2_esp32s3"
- },
- "connectivity": [
- "wifi"
- ],
- "debug": {
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "DFRobot Firebeetle 2 ESP32-S3",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://www.dfrobot.com/product-1590.html",
- "vendor": "DFRobot"
- }
复制代码
接下来就是去读取OV2640的数据了,参考camera_web_server的例程,将读取摄像头部分单独剥离出来,尝试初始化摄像头,但是报错:E (18) camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND。提示端口打卡错误。
经过老师提醒,再去看电路图才发现摄像头的电源由一颗AXP313A电源芯片来控制,需要给它I2C命令来进行驱动。https://github.com/cdjq/DFRobot_AXP313A这里有驱动电源的例子,参考着例子重新驱动起摄像头,成功读取了OV2640. - #include "ov2640.h"
- #include "esp32-hal-log.h"
- DFRobot_AXP313A axp;
-
- uint8_t camera_init()
- {
- axp.enableCameraPower(axp.eOV2640); // 设置摄像头供电
- delay(200);
- //摄像头配置初始化
- camera_config_t camera_config = {
- .pin_pwdn = -1,
- .pin_reset = -1,
- .pin_xclk = CAM_XCLK,
- .pin_sscb_sda = CAM_SDA,
- .pin_sscb_scl = CAM_SCL,
-
- .pin_d7 = CAM_D7,
- .pin_d6 = CAM_D6,
- .pin_d5 = CAM_D5,
- .pin_d4 = CAM_D4,
- .pin_d3 = CAM_D3,
- .pin_d2 = CAM_D2,
- .pin_d1 = CAM_D1,
- .pin_d0 = CAM_D0,
- .pin_vsync = CAM_VSYNC,
- .pin_href = CAM_HSYNC,
- .pin_pclk = CAM_PCLK,
-
- .xclk_freq_hz = 20000000,
- .ledc_timer = LEDC_TIMER_0,
- .ledc_channel = LEDC_CHANNEL_0,
- .pixel_format = PIXFORMAT_JPEG,
- .frame_size = FRAMESIZE_SVGA,
- .jpeg_quality = 8,
- .fb_count = 2};
-
- // camera init
- esp_err_t err = esp_camera_init(&camera_config);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Camera Init Failed");
- }
- // sensor_t *s = esp_camera_sensor_get();
-
- return 0;
- }
-
- // 将图片发送给网络.
- void TaskImgToWifi(void *pvParameters)
- {
- startstream();
- camera_init();
- camera_fb_t *pic = NULL;
- for (;;)
- {
- pic = esp_camera_fb_get();
- log_d("img_buf_len=%d , width=%d , height=%d ", pic->len, pic->height, pic->width);
- // log_e("Total heap: %d, %d", ESP.getHeapSize(),ESP.getFreeHeap());
- // log_e("Total PSRAM: %d, %d", ESP.getPsramSize(), ESP.getFreePsram());
- stprint(pic);
- esp_camera_fb_return(pic);
- }
- }
复制代码
- #include <Arduino.h>
- #include "wifi_conn.h"
- #include "ov2640.h"
- #include "esp32-hal-log.h"
- #include <picstream.h>
-
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Starting"); // will be shown in the terminal
- Serial.setDebugOutput(true);
- // camera_init();
- // delay(1000);
- xTaskCreatePinnedToCore(keepWiFiAlive, "keepWiFiAlive", 2048, NULL, 1, NULL, ARDUINO_RUNNING_CORE); //检查wifi状态的任务
- delay(1000);
- xTaskCreatePinnedToCore(TaskImgToWifi, "TaskImgToWifi", 2048, NULL, 1, NULL, ARDUINO_RUNNING_CORE); //启动摄像头任务
- }
-
- void loop()
- {
- // log_e("Total PSRAM: %d Free PSRAM: %d ", ESP.getPsramSize(), ESP.getFreePsram());
- Serial.println(WiFi.localIP());
- delay(5000);
- }
复制代码
因为这个板子没有屏幕,所以这里使用了http流的方式,将获得到的图片分发出去。终端上只要是在同一个局域网内,通过浏览器就可以直接访问到摄像头的图片了。 - #include "picstream.h"
- #define PART_BOUNDARY "123456789000000000000987654321"
- static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
- static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
- static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
-
-
- httpd_handle_t stream_httpd = NULL;
- httpd_handle_t camera_httpd = NULL;
- camera_fb_t * fb = NULL;
- camera_fb_t fm;
- boolean re=0;
- static esp_err_t stream_handler(httpd_req_t *req){
- esp_err_t res = ESP_OK;
- size_t _jpg_buf_len = 0;
- uint8_t * _jpg_buf = NULL;
- char * part_buf[64];
- res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
- if(res != ESP_OK){
- return res;
- }
- while(true){
- // fb= esp_camera_fb_get();
- delay(1);
- if(re){
- // Serial.println(2);
- if(fb->format != PIXFORMAT_JPEG){
- bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
- esp_camera_fb_return(fb);
- fb = NULL;
- if(!jpeg_converted){
- Serial.println("JPEG compression failed");
- res = ESP_FAIL;
- }
- } else {
- _jpg_buf_len = fb->len;
- _jpg_buf = fb->buf;
- }
- if(res == ESP_OK){
- size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
- res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
- }
- if(res == ESP_OK){
- res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
- }
- if(res == ESP_OK){
- res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
- }
- if(res != ESP_OK){
- break;
- }
- if(fb){
- esp_camera_fb_return(fb);
- fb = NULL;
- _jpg_buf = NULL;
- }
- if(_jpg_buf){
- free(_jpg_buf);
- _jpg_buf = NULL;
- }
- re=0;
- }
- }
- return res;
- }
-
- void startstream()
- {
- httpd_config_t config = HTTPD_DEFAULT_CONFIG();
-
- httpd_uri_t stream_uri = {
- .uri = "/",
- .method = HTTP_GET,
- .handler = stream_handler,
- .user_ctx = NULL
- };
- Serial.printf("Starting stream server on port: '%d'\n", config.server_port);
- if (httpd_start(&stream_httpd, &config) == ESP_OK) {
- httpd_register_uri_handler(stream_httpd, &stream_uri);
- }else{
- Serial.println("Starting stream server failed");
- }
- }
- void stprint(camera_fb_t * frame){
- // fm=*frame;
- fb=frame;
- re=1;
- }
复制代码
先能点亮摄像头啦!摄像头膜还没撕,感觉代码有内存泄漏,时间久了会死机。继续折腾。
|