2023-8-22 21:07:50 [显示全部楼层]
876浏览
查看: 876|回复: 4

[ESP8266/ESP32] FireBeetle 2 ESP32-S3试用——用arduino先点亮摄像头

[复制链接]
本帖最后由 aramy 于 2023-8-22 21:07 编辑

参加Dfrobot官方的S3 的申请试用,人品大爆发,居然中了。真是开心。板子上有OV2640的摄像头,加上ESP32-S3强大的算力。一直有羡慕乐鑫在AI方面的功能,现在自己有了板子,也会去努力尝试一番的。
FireBeetle 2 ESP32-S3试用——用arduino先点亮摄像头图1



拿到板子晚了几天,迫不及待地将esp-who下的例程,烧写进去,不出意外地不能工作。看来还是得一步一步地学习。那么就先从熟悉点的Arduino开始吧!用Vscode+platformio先做个最简单的串口程序。
  1. #include <Arduino.h>
  2. #include "esp32-hal-log.h"
  3. void setup()
  4. {
  5.   Serial.begin(115200);
  6.   Serial.println("Starting"); // will be shown in the terminal
  7.   Serial.setDebugOutput(true);
  8. }
  9. void loop()
  10. {
  11.   log_e("Total PSRAM: %d   Free PSRAM: %d ", ESP.getPsramSize(), ESP.getFreePsram());
  12.   Serial.println("Hello!");
  13.   delay(1000);
  14. }
复制代码
结果是啥都不输出。翻看论坛中老师的帖子明白是配置错误,修改了%homepath%\.platformio\platforms\espressif32\boards下的dfrobot_firebeetle2_esp32s3.json文件,至此成功地输出了串口日志。
  1. {
  2.   "build": {
  3.     "arduino": {
  4.       "partitions":"app3M_fat9M_16MB.csv",
  5.       "ldscript": "esp32s3_out.ld",
  6.       "memory_type":"qio_opi"
  7.     },
  8.     "core": "esp32",
  9.     "extra_flags": [
  10.             "-DBOARD_HAS_PSRAM",
  11.       "-DARDUINO_ESP32S3_DEV",
  12.       "-DARDUINO_USB_MODE=1",
  13.       "-DARDUINO_RUNNING_CORE=1",
  14.       "-DARDUINO_EVENT_RUNNING_CORE=1",      
  15.       "-DARDUINO_USB_CDC_ON_BOOT=1"
  16.     ],
  17.     "f_cpu": "240000000L",
  18.     "f_flash": "80000000L",
  19.     "flash_mode": "qio",
  20.     "hwids": [
  21.       [
  22.         "0x303A",
  23.         "0x83CF"
  24.       ],
  25.       [
  26.         "0x303A",
  27.         "0x1001"
  28.       ]
  29.     ],
  30.     "mcu": "esp32s3",
  31.     "variant": "dfrobot_firebeetle2_esp32s3"
  32.   },
  33.   "connectivity": [
  34.     "wifi"
  35.   ],
  36.   "debug": {
  37.     "openocd_target": "esp32s3.cfg"
  38.   },
  39.   "frameworks": [
  40.     "arduino",
  41.     "espidf"
  42.   ],
  43.   "name": "DFRobot Firebeetle 2 ESP32-S3",
  44.   "upload": {
  45.     "flash_size": "16MB",
  46.     "maximum_ram_size": 327680,
  47.     "maximum_size": 16777216,
  48.     "require_upload_port": true,
  49.     "speed": 460800
  50.   },
  51.   "url": "https://www.dfrobot.com/product-1590.html",
  52.   "vendor": "DFRobot"
  53. }
复制代码
接下来就是去读取OV2640的数据了,参考camera_web_server的例程,将读取摄像头部分单独剥离出来,尝试初始化摄像头,但是报错:E (18) camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND。提示端口打卡错误。
FireBeetle 2 ESP32-S3试用——用arduino先点亮摄像头图2
经过老师提醒,再去看电路图才发现摄像头的电源由一颗AXP313A电源芯片来控制,需要给它I2C命令来进行驱动。https://github.com/cdjq/DFRobot_AXP313A这里有驱动电源的例子,参考着例子重新驱动起摄像头,成功读取了OV2640.
  1. #include "ov2640.h"
  2. #include "esp32-hal-log.h"
  3. DFRobot_AXP313A axp;
  4. uint8_t camera_init()
  5. {
  6.     axp.enableCameraPower(axp.eOV2640);                                                                 // 设置摄像头供电
  7.     delay(200);
  8.     //摄像头配置初始化
  9.     camera_config_t camera_config = {
  10.         .pin_pwdn = -1,
  11.         .pin_reset = -1,
  12.         .pin_xclk = CAM_XCLK,
  13.         .pin_sscb_sda = CAM_SDA,
  14.         .pin_sscb_scl = CAM_SCL,
  15.         .pin_d7 = CAM_D7,
  16.         .pin_d6 = CAM_D6,
  17.         .pin_d5 = CAM_D5,
  18.         .pin_d4 = CAM_D4,
  19.         .pin_d3 = CAM_D3,
  20.         .pin_d2 = CAM_D2,
  21.         .pin_d1 = CAM_D1,
  22.         .pin_d0 = CAM_D0,
  23.         .pin_vsync = CAM_VSYNC,
  24.         .pin_href = CAM_HSYNC,
  25.         .pin_pclk = CAM_PCLK,
  26.         .xclk_freq_hz = 20000000,
  27.         .ledc_timer = LEDC_TIMER_0,
  28.         .ledc_channel = LEDC_CHANNEL_0,
  29.         .pixel_format = PIXFORMAT_JPEG,
  30.         .frame_size = FRAMESIZE_SVGA,
  31.         .jpeg_quality = 8,
  32.         .fb_count = 2};
  33.     // camera init
  34.     esp_err_t err = esp_camera_init(&camera_config);
  35.     if (err != ESP_OK)
  36.     {
  37.         ESP_LOGE(TAG, "Camera Init Failed");
  38.     }
  39.     // sensor_t *s = esp_camera_sensor_get();
  40.    
  41.     return 0;
  42. }
  43. // 将图片发送给网络.
  44. void TaskImgToWifi(void *pvParameters)
  45. {
  46.     startstream();
  47.     camera_init();
  48.     camera_fb_t *pic = NULL;
  49.     for (;;)
  50.     {
  51.         pic = esp_camera_fb_get();
  52.         log_d("img_buf_len=%d , width=%d , height=%d ", pic->len, pic->height, pic->width);
  53.         // log_e("Total heap:  %d,  %d", ESP.getHeapSize(),ESP.getFreeHeap());
  54.         // log_e("Total PSRAM: %d,  %d", ESP.getPsramSize(), ESP.getFreePsram());
  55.         stprint(pic);
  56.         esp_camera_fb_return(pic);
  57.     }
  58. }
复制代码
  1. #include <Arduino.h>
  2. #include "wifi_conn.h"
  3. #include "ov2640.h"
  4. #include "esp32-hal-log.h"
  5. #include <picstream.h>
  6. void setup()
  7. {
  8.   Serial.begin(115200);
  9.   Serial.println("Starting"); // will be shown in the terminal
  10.   Serial.setDebugOutput(true);
  11.   // camera_init();
  12.   // delay(1000);
  13.   xTaskCreatePinnedToCore(keepWiFiAlive, "keepWiFiAlive", 2048, NULL, 1, NULL, ARDUINO_RUNNING_CORE); //检查wifi状态的任务
  14.   delay(1000);
  15.   xTaskCreatePinnedToCore(TaskImgToWifi, "TaskImgToWifi", 2048, NULL, 1, NULL, ARDUINO_RUNNING_CORE);   //启动摄像头任务
  16. }
  17. void loop()
  18. {
  19.   // log_e("Total PSRAM: %d   Free PSRAM: %d ", ESP.getPsramSize(), ESP.getFreePsram());
  20.   Serial.println(WiFi.localIP());
  21.   delay(5000);
  22. }
复制代码
因为这个板子没有屏幕,所以这里使用了http流的方式,将获得到的图片分发出去。终端上只要是在同一个局域网内,通过浏览器就可以直接访问到摄像头的图片了。
  1. #include "picstream.h"
  2. #define PART_BOUNDARY "123456789000000000000987654321"
  3. static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
  4. static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
  5. static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
  6. httpd_handle_t stream_httpd = NULL;
  7. httpd_handle_t camera_httpd = NULL;
  8. camera_fb_t * fb = NULL;
  9. camera_fb_t fm;
  10. boolean re=0;
  11. static esp_err_t stream_handler(httpd_req_t *req){
  12.     esp_err_t res = ESP_OK;
  13.     size_t _jpg_buf_len = 0;
  14.     uint8_t * _jpg_buf = NULL;
  15.     char * part_buf[64];
  16.     res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  17.     if(res != ESP_OK){
  18.         return res;
  19.     }
  20.     while(true){
  21.         // fb= esp_camera_fb_get();
  22.         delay(1);
  23.         if(re){
  24.             // Serial.println(2);
  25.         if(fb->format != PIXFORMAT_JPEG){
  26.             bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
  27.             esp_camera_fb_return(fb);
  28.             fb = NULL;
  29.             if(!jpeg_converted){
  30.                 Serial.println("JPEG compression failed");
  31.                 res = ESP_FAIL;
  32.             }
  33.         } else {
  34.             _jpg_buf_len = fb->len;
  35.             _jpg_buf = fb->buf;
  36.         }
  37.         if(res == ESP_OK){
  38.             size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
  39.             res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
  40.         }
  41.         if(res == ESP_OK){
  42.             res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
  43.         }
  44.         if(res == ESP_OK){
  45.             res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
  46.         }
  47.         if(res != ESP_OK){
  48.             break;
  49.         }
  50.                 if(fb){
  51.             esp_camera_fb_return(fb);
  52.             fb = NULL;
  53.             _jpg_buf = NULL;
  54.         }
  55.         if(_jpg_buf){
  56.             free(_jpg_buf);
  57.             _jpg_buf = NULL;
  58.         }
  59.         re=0;
  60.         }
  61.     }
  62.         return res;
  63. }
  64. void startstream()
  65. {
  66.         httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  67.        httpd_uri_t stream_uri = {
  68.         .uri       = "/",
  69.         .method    = HTTP_GET,
  70.         .handler   = stream_handler,
  71.         .user_ctx  = NULL
  72.     };
  73.     Serial.printf("Starting stream server on port: '%d'\n", config.server_port);
  74.     if (httpd_start(&stream_httpd, &config) == ESP_OK) {
  75.         httpd_register_uri_handler(stream_httpd, &stream_uri);
  76.     }else{
  77.         Serial.println("Starting stream server failed");
  78.     }
  79. }
  80. void stprint(camera_fb_t * frame){
  81.     // fm=*frame;
  82.     fb=frame;
  83.     re=1;
  84. }
复制代码

FireBeetle 2 ESP32-S3试用——用arduino先点亮摄像头图3
先能点亮摄像头啦!摄像头膜还没撕,感觉代码有内存泄漏,时间久了会死机。继续折腾。



花生编程  中级技匠

发表于 2023-8-23 21:43:04

厉害厉害
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-8-23 21:44:20

不错不错!
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-8-24 14:45:41

厉害厉害
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-8-24 14:51:34

赞赞赞赞赞
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail