Arduino是否当之无愧地占据电子爱好者心中电子制作神器的宝座?

2026-05-25 15:291阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1661个文字,预计阅读时间需要7分钟。

Arduino是否当之无愧地占据电子爱好者心中电子制作神器的宝座?

前言:之前看过一个智能猫眼摄像头,我很有兴趣,但那个IDF平台实在难整,我光安装就花了整整一天,网不好下载的包可能有问题。命令行操作也相当繁琐,我就想试试无。

前言

之前看了官方玩过一个智能猫眼摄像头,我很有兴趣,但是那个 IDF 平台属实难整,我光安装都整了一天,网不好下载的包可能有问题。然后命令行操作也比较麻烦,我就想到了无敌的 arduino ,ESP32-CAM 这个板子本来就是 arduino 支持的,移植上去问题不大。SDDC 连接器的移植,按之前我移植 SDDC 的经验,官方代码的代码规范和可移植性都很不错,移植的难度不大。那就开干!


硬件选择

这我用的是和爱智官方一样的,安信可的ESP32 - CAM 摄像头,这里推荐这种分成两块板子的这种,还有一种把串口集成到一块板子上的,发热太严重,烧录程序的时候需要手动按 IO0 然后按 RST 按键。


然后在 arduino 上选择对应的开发板:

代码获取

从爱智官方的示例文章:ESP32 SDDC 设备开发 中可以获取到SDDC 连接器的示例代码,和 SDDC 连接器的库,然后 arduino 的设备代码可以直接用 arduino 提供的示例代码来改。

当然,你们看到篇文章的时候,就不用管这么多啦︿( ̄︶ ̄)︿

看过我之前文章的朋友肯定都知道,我早就帮大伙打包好了~
只需要去 -- 我们的微信公众号 我最讨厌添加各种微信公众号才能获取资源了,所以还是老样子, 直接去灵感桌面的秘密宝库 获取代码,或者直接 clone:

gitee.com/inspiration-desktop/DEV-lib-arduino.git

这次用到的是下图红圈的三个文件夹:

cjson:我移植的 cjson 库,就是标准的 cjson 库,放到 arduino 安装目录下的 libraries 文件夹里,百度一下 cjson 的函数使用就行了。

LIBESP32_CAM:是我移植自官方的SDDC 连接器库,也是放入 libraries 文件夹里就行。里面是 SDDC 协议的处理函数,我们不用管。因为这个库包含了 SDDC 协议相关内容,我们就不再用原来的 libsddc 库了

sddc_demo 文件夹里面就是我们各种传感器的 demo 代码了:

红圈的 ESP32_Camera文件夹里面就是我们代码,点进去就能看见 ESP32_Camera.ino 文件,双击文件会自动启动 arduino-IDE 打开代码。在工具 -> 端口 选择对应的 COM 口然后点击上传就可以把代码烧录到板子里:

具体 arduino 使用教程可以看我之前的文章 arduino开发指导 和 手把手带你 arduino 开发:基于ESP32S 的第一个应用-红外测温枪(带引脚图)

代码解析

这个代码因为是移植爱智和 arduino 官方的代码,相关解析已经很多了,我就重点讲一下我修改的部分。
我主要修改了 esp_on_message() 和 esp_send_image(),esp_connector_task()函数。
代码如下:

/* * Send image to connector */ static void esp_send_image(sddc_connector_t *conn) { void *data; size_t size; size_t totol_len = 0; size_t len; int ret; data = fb->buf; size = fb->len; while (totol_len < size) { //len = min((size - totol_len), (1460 - 16)); len = min((size - totol_len), 1420); ret = sddc_connector_put(conn, data, len, (totol_len + len) == size); if (ret < 0) { sddc_printf("Failed to put!\n"); break; } totol_len += len; data += len; } sddc_printf("Total put %d byte\n", totol_len); esp_camera_fb_return(fb); }

esp_send_image() 函数这主要是删掉了原有的调用拍照的函数,因为拍照的逻辑放在了 esp_on_message 函数中,而且 esp_camera_fb_get() 会返回一个 fd 作为全局变量使用,就不需要在这重新拍一张照片了。

/* * sddc connector task */ static void esp_connector_task(void *arg) { sddc_connector_t *conn; BaseType_t ret; while (1) { ret = xQueueReceive(conn_mqueue_handle, &conn, portMAX_DELAY); if (ret == pdTRUE) { esp_send_image(conn); sddc_connector_destroy(conn); cam_flag = 0; } } vTaskDelete(NULL); } /* * Lock timer callback function */ static void esp_lock_timer_callback(TimerHandle_t handle) { sddc_printf("Close the door!\n"); }

esp_connector_task 函数加入了一个全局变量 cam_flag 避免由于拍照太快导致发送不及时。

/* * Handle MESSAGE */ static sddc_bool_t esp_on_message(sddc_t *sddc, const uint8_t *uid, const char *message, size_t len) { cJSON *root = cJSON_Parse(message); cJSON *value; cJSON *cam; char *str; int ret; sddc_return_value_if_fail(root, SDDC_TRUE); str = cJSON_Print(root); sddc_goto_error_if_fail(str); sddc_printf("esp_on_message: %s\n", str); cJSON_free(str); cam = cJSON_GetObjectItem(root, "cam"); if (cJSON_IsString(cam)) { if (strcmp(cam->valuestring, "image") == 0 && (cam_flag == 0)) { char *str; size_t size; cam_flag = 1; // 拍照 fb = esp_camera_fb_get(); sddc_goto_error_if_fail(fb); // 获得图像数据大小 size = fb->len; // 连接器 cJSON *connector = cJSON_GetObjectItem(root, "connector"); sddc_goto_error_if_fail(cJSON_IsObject(connector)); cJSON *port = cJSON_GetObjectItem(connector, "port"); sddc_goto_error_if_fail(cJSON_IsNumber(port)); cJSON *token = cJSON_GetObjectItem(connector, "token"); sddc_goto_error_if_fail(!token || cJSON_IsString(token)); sddc_connector_t *conn = sddc_connector_create(sddc, uid, port->valuedouble, token ? token->valuestring : NULL, SDDC_FALSE); if (conn == NULL) { cam_flag = 0; printf("error !\n"); }else { printf("连接创建成功!\n"); } sddc_goto_error_if_fail(conn); // 创建 cJSON 对象 value = cJSON_CreateObject(); sddc_goto_error_if_fail(value); // size 为图像数据大小 cJSON_AddNumberToObject(value, "size", size); sddc_printf("Send picture to EdgerOS, file size %d\n", size); // cJSON 对象转换成字符串 str = cJSON_Print(value); sddc_goto_error_if_fail(str); // 发送图片大小消息 sddc_broadcast_message(sddc, str, strlen(str), 1, SDDC_FALSE, NULL); cJSON_free(str); if(conn_mqueue_handle == NULL) { Serial.println("conn_mqueue_handle ERROR"); } if(&conn == NULL) { Serial.println("&conn ERROR"); } ret = xQueueSend(conn_mqueue_handle, &conn, 0); if (ret != pdTRUE) { sddc_connector_destroy(conn); sddc_goto_error_if_fail(ret == pdTRUE); } } else if (strcmp(cam->valuestring, "shoot") == 0) { cJSON *root = NULL; char *str; size_t size; // 摄像头捕捉一帧图像 fb = esp_camera_fb_get(); sddc_goto_error_if_fail(fb); // 获得图像数据大小 size = fb->len; // 创建 cJSON 对象 root = cJSON_CreateObject(); sddc_goto_error_if_fail(root); // cmd 为 recv cJSON_AddStringToObject(root, "cam", "image"); // size 为图像数据大小 cJSON_AddNumberToObject(root, "size", size); sddc_printf("Send picture to EdgerOS, file size %d\n", size); // cJSON 对象转换成字符串 str = cJSON_Print(root); sddc_goto_error_if_fail(str); // 发送消息 sddc_broadcast_message(sddc, str, strlen(str), 1, SDDC_FALSE, NULL); cJSON_free(str); } } else { sddc_printf("Command no specify!\n"); } error: cJSON_Delete(root); esp_camera_fb_return(fb); return SDDC_TRUE; }

主要改动是因为这一份官方代码的锁和摄像头是一体的,而且官方的 IDF 平台使用的 camera_run(),camera_get_data_size() 和 camera_get_fb() 这几个函数在 arduino 上没有,我改成了esp_camera_fb_get() ,还添加了一个在连接器之前先发送一个 size 用来校验图片完整性。

其他的设备初始化和配置啥的我都用的 arduino 示例代码的配置


总结

我智能猫眼的应用代码被我搞丢了,得去找官方看看那边有没有保留,所以暂时没法展示。

Arduino是否当之无愧地占据电子爱好者心中电子制作神器的宝座?

本文共计1661个文字,预计阅读时间需要7分钟。

Arduino是否当之无愧地占据电子爱好者心中电子制作神器的宝座?

前言:之前看过一个智能猫眼摄像头,我很有兴趣,但那个IDF平台实在难整,我光安装就花了整整一天,网不好下载的包可能有问题。命令行操作也相当繁琐,我就想试试无。

前言

之前看了官方玩过一个智能猫眼摄像头,我很有兴趣,但是那个 IDF 平台属实难整,我光安装都整了一天,网不好下载的包可能有问题。然后命令行操作也比较麻烦,我就想到了无敌的 arduino ,ESP32-CAM 这个板子本来就是 arduino 支持的,移植上去问题不大。SDDC 连接器的移植,按之前我移植 SDDC 的经验,官方代码的代码规范和可移植性都很不错,移植的难度不大。那就开干!


硬件选择

这我用的是和爱智官方一样的,安信可的ESP32 - CAM 摄像头,这里推荐这种分成两块板子的这种,还有一种把串口集成到一块板子上的,发热太严重,烧录程序的时候需要手动按 IO0 然后按 RST 按键。


然后在 arduino 上选择对应的开发板:

代码获取

从爱智官方的示例文章:ESP32 SDDC 设备开发 中可以获取到SDDC 连接器的示例代码,和 SDDC 连接器的库,然后 arduino 的设备代码可以直接用 arduino 提供的示例代码来改。

当然,你们看到篇文章的时候,就不用管这么多啦︿( ̄︶ ̄)︿

看过我之前文章的朋友肯定都知道,我早就帮大伙打包好了~
只需要去 -- 我们的微信公众号 我最讨厌添加各种微信公众号才能获取资源了,所以还是老样子, 直接去灵感桌面的秘密宝库 获取代码,或者直接 clone:

gitee.com/inspiration-desktop/DEV-lib-arduino.git

这次用到的是下图红圈的三个文件夹:

cjson:我移植的 cjson 库,就是标准的 cjson 库,放到 arduino 安装目录下的 libraries 文件夹里,百度一下 cjson 的函数使用就行了。

LIBESP32_CAM:是我移植自官方的SDDC 连接器库,也是放入 libraries 文件夹里就行。里面是 SDDC 协议的处理函数,我们不用管。因为这个库包含了 SDDC 协议相关内容,我们就不再用原来的 libsddc 库了

sddc_demo 文件夹里面就是我们各种传感器的 demo 代码了:

红圈的 ESP32_Camera文件夹里面就是我们代码,点进去就能看见 ESP32_Camera.ino 文件,双击文件会自动启动 arduino-IDE 打开代码。在工具 -> 端口 选择对应的 COM 口然后点击上传就可以把代码烧录到板子里:

具体 arduino 使用教程可以看我之前的文章 arduino开发指导 和 手把手带你 arduino 开发:基于ESP32S 的第一个应用-红外测温枪(带引脚图)

代码解析

这个代码因为是移植爱智和 arduino 官方的代码,相关解析已经很多了,我就重点讲一下我修改的部分。
我主要修改了 esp_on_message() 和 esp_send_image(),esp_connector_task()函数。
代码如下:

/* * Send image to connector */ static void esp_send_image(sddc_connector_t *conn) { void *data; size_t size; size_t totol_len = 0; size_t len; int ret; data = fb->buf; size = fb->len; while (totol_len < size) { //len = min((size - totol_len), (1460 - 16)); len = min((size - totol_len), 1420); ret = sddc_connector_put(conn, data, len, (totol_len + len) == size); if (ret < 0) { sddc_printf("Failed to put!\n"); break; } totol_len += len; data += len; } sddc_printf("Total put %d byte\n", totol_len); esp_camera_fb_return(fb); }

esp_send_image() 函数这主要是删掉了原有的调用拍照的函数,因为拍照的逻辑放在了 esp_on_message 函数中,而且 esp_camera_fb_get() 会返回一个 fd 作为全局变量使用,就不需要在这重新拍一张照片了。

/* * sddc connector task */ static void esp_connector_task(void *arg) { sddc_connector_t *conn; BaseType_t ret; while (1) { ret = xQueueReceive(conn_mqueue_handle, &conn, portMAX_DELAY); if (ret == pdTRUE) { esp_send_image(conn); sddc_connector_destroy(conn); cam_flag = 0; } } vTaskDelete(NULL); } /* * Lock timer callback function */ static void esp_lock_timer_callback(TimerHandle_t handle) { sddc_printf("Close the door!\n"); }

esp_connector_task 函数加入了一个全局变量 cam_flag 避免由于拍照太快导致发送不及时。

/* * Handle MESSAGE */ static sddc_bool_t esp_on_message(sddc_t *sddc, const uint8_t *uid, const char *message, size_t len) { cJSON *root = cJSON_Parse(message); cJSON *value; cJSON *cam; char *str; int ret; sddc_return_value_if_fail(root, SDDC_TRUE); str = cJSON_Print(root); sddc_goto_error_if_fail(str); sddc_printf("esp_on_message: %s\n", str); cJSON_free(str); cam = cJSON_GetObjectItem(root, "cam"); if (cJSON_IsString(cam)) { if (strcmp(cam->valuestring, "image") == 0 && (cam_flag == 0)) { char *str; size_t size; cam_flag = 1; // 拍照 fb = esp_camera_fb_get(); sddc_goto_error_if_fail(fb); // 获得图像数据大小 size = fb->len; // 连接器 cJSON *connector = cJSON_GetObjectItem(root, "connector"); sddc_goto_error_if_fail(cJSON_IsObject(connector)); cJSON *port = cJSON_GetObjectItem(connector, "port"); sddc_goto_error_if_fail(cJSON_IsNumber(port)); cJSON *token = cJSON_GetObjectItem(connector, "token"); sddc_goto_error_if_fail(!token || cJSON_IsString(token)); sddc_connector_t *conn = sddc_connector_create(sddc, uid, port->valuedouble, token ? token->valuestring : NULL, SDDC_FALSE); if (conn == NULL) { cam_flag = 0; printf("error !\n"); }else { printf("连接创建成功!\n"); } sddc_goto_error_if_fail(conn); // 创建 cJSON 对象 value = cJSON_CreateObject(); sddc_goto_error_if_fail(value); // size 为图像数据大小 cJSON_AddNumberToObject(value, "size", size); sddc_printf("Send picture to EdgerOS, file size %d\n", size); // cJSON 对象转换成字符串 str = cJSON_Print(value); sddc_goto_error_if_fail(str); // 发送图片大小消息 sddc_broadcast_message(sddc, str, strlen(str), 1, SDDC_FALSE, NULL); cJSON_free(str); if(conn_mqueue_handle == NULL) { Serial.println("conn_mqueue_handle ERROR"); } if(&conn == NULL) { Serial.println("&conn ERROR"); } ret = xQueueSend(conn_mqueue_handle, &conn, 0); if (ret != pdTRUE) { sddc_connector_destroy(conn); sddc_goto_error_if_fail(ret == pdTRUE); } } else if (strcmp(cam->valuestring, "shoot") == 0) { cJSON *root = NULL; char *str; size_t size; // 摄像头捕捉一帧图像 fb = esp_camera_fb_get(); sddc_goto_error_if_fail(fb); // 获得图像数据大小 size = fb->len; // 创建 cJSON 对象 root = cJSON_CreateObject(); sddc_goto_error_if_fail(root); // cmd 为 recv cJSON_AddStringToObject(root, "cam", "image"); // size 为图像数据大小 cJSON_AddNumberToObject(root, "size", size); sddc_printf("Send picture to EdgerOS, file size %d\n", size); // cJSON 对象转换成字符串 str = cJSON_Print(root); sddc_goto_error_if_fail(str); // 发送消息 sddc_broadcast_message(sddc, str, strlen(str), 1, SDDC_FALSE, NULL); cJSON_free(str); } } else { sddc_printf("Command no specify!\n"); } error: cJSON_Delete(root); esp_camera_fb_return(fb); return SDDC_TRUE; }

主要改动是因为这一份官方代码的锁和摄像头是一体的,而且官方的 IDF 平台使用的 camera_run(),camera_get_data_size() 和 camera_get_fb() 这几个函数在 arduino 上没有,我改成了esp_camera_fb_get() ,还添加了一个在连接器之前先发送一个 size 用来校验图片完整性。

其他的设备初始化和配置啥的我都用的 arduino 示例代码的配置


总结

我智能猫眼的应用代码被我搞丢了,得去找官方看看那边有没有保留,所以暂时没法展示。

Arduino是否当之无愧地占据电子爱好者心中电子制作神器的宝座?