eew_Ya3s2d

  • 2024-10-30
  • 回复了主题帖: 【2024 DigiKey 创意大赛】ESP32-S3-LCD-EV-BOARD点亮lcd、联网、SNTP校时

    Jacktang 发表于 2024-10-25 07:24 时间戳范围的单位是ms,gmtime处理时间的单位是秒,所以需要把时间戳先除以1000再传入函数,这是技巧 是呀,一开始没仔细看,获取到的都成了最大值了,都是固定的时间,还以为出问题没获取到时间

  • 2024-10-23
  • 发表了主题帖: 【2024 DigiKey 创意大赛】ESP32-S3-LCD-EV-BOARD点亮lcd、联网、SNTP校时

    大家好,我是郑工,尘世间一个迷途小工程师。   这次大赛想挑战一下自己,也想写一个手把手esp idf开发入门的帖子,所以这次大赛决定用esp idf开发应用(真是给自己整了个大活呀T_T)   经过了好多天的调试,终于是把WiFi联网功能与SNTP功能给摸透了,下面就给大家分享一下一些经验,希望对大家有帮助。   一、点亮lcd屏幕   由于我们是拿的乐鑫官方的开发板,所以其实点亮屏幕是很简单的,直接用官方的例程就可以了,GitHub地址如下: esp-dev-kits/esp32-s3-lcd-ev-board at master · espressif/esp-dev-kits · GitHub 出厂的程序用的是86box_smart_panel,我看过代码了,逻辑和界面写了好多,不方面我们从零开始学习,所以我决定还是用lvgl_demo这个例程。   直接帮我们把lvgl移植好了,省去我们好多的开发工作,而esp32s3一直lvgl的文档视频网上都挺多的了,总的来说不难,就是下载lvgl官方库,然后对接液晶接口和触摸接口。这里就不详细介绍了。   然后我们就可以开始做界面开发了,这里我学习了一些代码写界面的方法,感觉跟用tkinter开发界面一样,每个控件每个控件的创建,调整大小样式布局,没有仿真,esp32s3的下载速度又说不上快,调整多几次,一个小时就过去了。所以最后我选择使用squareline studio开发界面。   这样只要拖拽,调整属性什么的,图片也会自动转码,实在是可以节省很多功夫。   二、联网   用乐鑫的芯片又怎么可以不使用联网功能呢,下面是一段简单的联网测试代码 static EventGroupHandle_t wifi_event_group; #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 static void event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data){ static uint32_t wifi_retry_cnt = 0; if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { esp_wifi_connect(); }else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { if( wifi_retry_cnt < 10){ ESP_LOGI(TAG, "WiFi disconnected, retrying..."); esp_wifi_connect(); wifi_retry_cnt++; }else { ESP_LOGE(TAG, "WiFi disconnected, retrying failed"); xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT); } }else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; ESP_LOGI(TAG, "Got IP address: %s", ip4addr_ntoa(&event->ip_info.ip)); wifi_retry_cnt = 0; xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); } } void wifi_init_sta(void){ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); wifi_event_group = xEventGroupCreate(); // tcpip_adapter_init(); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); wifi_config_t wifi_config = { .sta = { .ssid = "QC", .password = "Qaz123456", .scan_method = WIFI_FAST_SCAN, .sort_method = WIFI_CONNECT_AP_BY_SIGNAL, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK(esp_wifi_start() ); ESP_LOGI(TAG, "wifi_init finished."); EventBits_t bits = xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); if (bits & WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, "connected to ap"); }else if (bits & WIFI_FAIL_BIT) { ESP_LOGI(TAG, "fail to connected to ap"); }else { ESP_LOGE(TAG, "WIFI_EVENT_STA_DISCONNECTED"); } ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler)); ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); vEventGroupDelete(wifi_event_group); } 简单来说,esp32s3联网有以下的步骤: 初始化网络堆栈: 初始化网络接口和协议栈。 ESP_ERROR_CHECK(esp_netif_init()); 创建默认的 Wi-Fi 接口: 创建一个默认的 Wi-Fi Station(STA)接口。 esp_netif_create_default_wifi_sta(); 配置 Wi-Fi 接口: 设置 Wi-Fi 的模式和配置参数。 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 设置 Wi-Fi 模式: 设置 ESP32-S3 为 Wi-Fi Station 模式。 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 配置 Wi-Fi 凭证: 设置 Wi-Fi SSID 和密码。 wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); strncpy((char *)wifi_config.sta.ssid, "your_ssid", sizeof(wifi_config.sta.ssid)); strncpy((char *)wifi_config.sta.password, "your_password", sizeof(wifi_config.sta.password)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); 启动 Wi-Fi: 启动 Wi-Fi 接口。 ESP_ERROR_CHECK(esp_wifi_start()); 连接到 Wi-Fi 网络: 使用 esp_wifi_connect() 函数连接到 Wi-Fi 网络。 ESP_ERROR_CHECK(esp_wifi_connect()); 等待连接完成: 通常需要等待 Wi-Fi 连接完成,可以通过轮询或注册事件回调函数来实现。 while (!esp_netif_is_connected()) { vTaskDelay(pdMS_TO_TICKS(1000)); } 获取 IP 地址: 连接成功后,获取分配给 ESP32-S3 的 IP 地址。 ip_info_t ip; esp_netif_get_ip_info(esp_netif_get_handle(ESP_IF_WIFI_STA), &ip); 使用网络: 此时 ESP32-S3 已经连接到 Wi-Fi 网络,可以进行网络通信。 然后函数需要添加以下判断网络状态,自动重连的业务代码即可。   三、SNTP校时   这个主题我做了两个程序,一个是根据之前做follow me任务使用的网络时间服务api获取时间,二个是使用ESP-IDF提供的SNTP(simple network time potocol)。下面我就帖以下代码讲解以下。   网络api #include "cJSON.h" #include "esp_http_client.h" struct tm timeinfo; void parse_json_time(const char *json_str) { // 解析 JSON 字符串 cJSON *json = cJSON_Parse(json_str); if (json == NULL) { const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { ESP_LOGE(TAG, "Error before: %s", error_ptr); } return; } // 提取 server_time 字段 cJSON *server_time_item = cJSON_GetObjectItemCaseSensitive(json, "server_time"); if (cJSON_IsNumber(server_time_item)) { // 获取时间戳 long server_time = server_time_item->valuedouble /1000; // 将时间戳转换为本地时间 time_t l_time = (time_t)server_time; struct tm *utc_time = gmtime(&l_time); utc_time->tm_hour += 8; //东八区 if(utc_time->tm_hour > 23) //防止过界 utc_time->tm_hour -= 24; timeinfo = *utc_time; // 格式化时间并打印 char time_str[32]; printf("TIME: %02d:%02d:%02d\n",utc_time->tm_hour, utc_time->tm_min, utc_time->tm_sec); strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", utc_time); ESP_LOGI(TAG, "Server time: %s", time_str); } else { ESP_LOGE(TAG, "server_time is not a number"); } // 清理 cJSON 对象 cJSON_Delete(json); } void http_test_task(void *pvParameters) { char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0}; //用于接收通过http协议返回的数据 int content_length = 0; //http协议头的长度 struct tm* l_time = get_time(); //02-2 配置http结构体 //定义http配置结构体,并且进行清零 esp_http_client_config_t config ; memset(&config,0,sizeof(config)); //向配置结构体内部写入url static const char *URL = "http://api.pinduoduo.com/api/server/_stm"; config.url = URL; //初始化结构体 esp_http_client_handle_t client = esp_http_client_init(&config); //初始化http连接 //设置发送请求 esp_http_client_set_method(client, HTTP_METHOD_GET); //02-3 循环通讯 while(1) { // 与目标主机创建连接,并且声明写入内容长度为0 esp_err_t err = esp_http_client_open(client, 0); //如果连接失败 if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); } //如果连接成功 else { //读取目标主机的返回内容的协议头 content_length = esp_http_client_fetch_headers(client); //如果协议头长度小于0,说明没有成功读取到 if (content_length < 0) { ESP_LOGE(TAG, "HTTP client fetch headers failed"); } //如果成功读取到了协议头 else { //读取目标主机通过http的响应内容 int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER); if (data_read >= 0) { //打印响应内容,包括响应状态,响应体长度及其内容 ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d", esp_http_client_get_status_code(client), //获取响应状态信息 esp_http_client_get_content_length(client)); //获取响应信息长度 // printf("data:%s\n", output_buffer); parse_json_time(output_buffer); } //如果不成功 else { ESP_LOGE(TAG, "Failed to read response"); } } } //关闭连接 esp_http_client_close(client); //延时 vTaskDelay(pdMS_TO_TICKS(1000)); } } 测试代码可以通过xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);添加任务。   代码主要就是通过网络请求访问http://api.pinduoduo.com/api/server/_stm拼多多时间api,获取时间戳,返回数据的样式是如: {"server_time":1729698004538} 的时间戳,然后解析json获取"server_time"对应的值,再把时间戳通过gmtin函数转换为标准时间,需要注意的是 1、时间戳范围的单位是ms,gmtime处理时间的单位是秒,所以需要把时间戳先除以1000再传入函数。 2、获取的时间戳是本初子午线上的时间,北京时间需要把时间+8处理。   这种办法很难实现精确到秒的时间显示,或许可以请求一次,后续内部自己创建一个时间维护,然后定期去校准时间,不然如我例子那样,每一秒请求一次,会浪费好多网络资源,而且请求返回也需要时间,经常会发生跳秒的情况,实现效果并不理想   SNTP时间服务器   第二个办法就是使用ESP-IDF提供的SNTP时间服务器,使用方法简单,不怎么占用系统资源,不需要维护系统时间,代码如下: static void initialize_sntp(void); static void obtain_time(void); static void time_sync_notification_cb(struct timeval *tv) { ESP_LOGI(TAG, "Notification of a time synchronization event, sec=%lu", tv->tv_sec); settimeofday(tv, NULL); } void app_sntp_init(void) { setenv("TZ", "CST-8", 1); tzset(); obtain_time(); } static void obtain_time(void) { initialize_sntp(); int retry = 0; const int retry_count = 10; while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) { ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count); vTaskDelay(2000 / portTICK_PERIOD_MS); } if (retry == retry_count) { ESP_LOGI(TAG, "Could not obtain time after %d attempts", retry); }else { ESP_LOGI(TAG, "Time synchronized"); } } static void initialize_sntp(void) { ESP_LOGI(TAG, "Initializing SNTP"); esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); //设置3个时间服务器 esp_sntp_setservername(0, "ntp.aliyun.com"); esp_sntp_setservername(1, "time.asia.apple.com"); esp_sntp_setservername(2, "pool.ntp.org"); esp_sntp_set_time_sync_notification_cb(time_sync_notification_cb); esp_sntp_init(); } 大家可以看到,代码非常的简单,基本上执行一次,就可以通过time函数获取本地时间了,获取时间的方法也很简单,只需要调用两个函数就可以 // 获取当前时间 time_t unix_time = time(NULL); // 将时间转换为本地时间,这是非线程安全的方法,只有一个参数,所以不能在多线程中使用 struct tm *time_info = localtime(&unix_time); 时间更新的间隔可以使用idf.py menuconfig打开系统设置,在Component config -> LWIP -> SNTP下设置Request interval to update time(ms)中设置,我设置了12小时校准一次,一般也够用了。   需要注意的是,最好不要在任何的callback函数或者中断处理中调用obtain_time函数,不然都有可能被卡死,结合上面的联网内容,可以在断网重连之后重新校准一次时间。   后面还会增加天气功能进去,到时候就是使用网络api的方法,注册心知天气的个人业务即可。 查看你的 API 密钥 | 心知天气文档 (seniverse.com)

  • 回复了主题帖: 【2024 DigiKey 创意大赛】ESP-IDF安装使用

    hellokitty_bean 发表于 2024-10-19 21:47 是在Ubuntu下安装esp-idf,还是就在Windows下安装esp-idf?   ubuntu下载的,通过mobaXterm访问ubuntu,不过现在看好多人都用Windows下载idf了,等开发完再试试看

  • 2024-10-18
  • 回复了主题帖: 【2024 DigiKey 创意大赛】ESP-IDF安装使用

    秦天qintian0303 发表于 2024-10-15 13:03 跑Linux系统好弄吗?    还可以,开发还是用vscode,然后编译下载传输文件都可以用MobaXterm。感觉都还好,没啥影响

  • 2024-10-15
  • 发表了主题帖: 【2024 DigiKey 创意大赛】ESP-IDF安装使用

    大家好,我是郑工,尘世间一个迷途小工程师   好久没回归EE主线了,我们赶紧来搞得捷创意大赛吧   今天来开始安装ESP-IDF。ESP-IDF是ESP系列芯片的主流开发环境,但是也是公认安装最麻烦的。我也琢磨搞了一天,所以还是给大家分享一下,也当做一个记录吧   安装ESP-IDF 下载Linux系统,Ubuntu服务器版本20.04 下载地址Ubuntu 20.04.6 LTS (Focal Fossa)   使用VMware安装,安装时记得安装SSH服务 用命令sudo apt-get net-tools安装网络服务 使用命令ifconig查看IP地址 使用MobaXtern的SSH连接连接到Ubuntu上 根据教程ubuntu20.04更换清华源-CSDN博客更换城国内源 使用命令sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0安装必要软件 创建新文件夹mkdir esp32  cd esp32进入新文件夹 使用git clone https://gitee.com/EspressifSystems/esp-gitee-tools.git 拉取esp gitee tools  cd esp-gitee-tools/进入文件夹 使用命令./jihu-mirror.sh set安装,然后cd ..退出文件夹 使用命令git clone --recursive https://github.com/espressif/esp-idf.git 拉取esp idf  cd esp-idf  git checkout v5.2 切换版本 更新子模块git submodule update --init --recursive 使用命令../esp-gitee-tools/install.sh 安装工具   使用python3.8是问题最少,最稳定的版本 这也是为什么Linux用服务器版20.04的原因   vscode使用说明   点击扩展,安装插件       安装完会多一个远程资源管理器,打开配置文件                 设置ESP-IDF的环境变量 进入esp-idf目录 执行脚本source export.sh 这是设置的临时环境变量 需要永久设置,可以cd ~ Ls -al查看所有文件有个.profile文件,终端登录后会默认执行文件里面的文件  vim .profile 编辑文件 最后一行点i,插入,输入source esp32/esp-idf/export.sh,点esc退出插入模式,然后输入:wq写入退出

  • 发表了主题帖: 【得捷Follow me第二季第1期】任务汇总+舵机与AGS02MA气体传感器使用

    本帖最后由 eew_Ya3s2d 于 2024-10-18 15:46 编辑 Hello,大家好,我是郑工,尘世间一个迷途小工程师。   这个帖子我们来汇总一下所有的任务与讲解一下   0、物料清单:     CPX主板     舵机     AGS02MA气体传感器   首先是我自己感觉有些尴尬的视频讲解 [localvideo]eedfda84f28c67abea9939b1ddca653e[/localvideo] 这个视频拍着拍着就拍到差不多15分钟了,视频2个G,最后是压缩了之后才能上传,下次拍视频之前还是得选不要太高清才行   入门任务(必做):开发环境搭建,板载LED点亮 【Follow me第二季第1期】任务0:开发环境搭建,板载LED点亮 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 程序就是通过time.sleep函数产生一个pwm去点亮led,不断更改pwm的占空比,这样led看起来就led就会有亮暗变化,像呼吸灯 最主要的函数是下面这个,产生一个简单的pwm,控制led灯。 def onLed(onTime, duty): if onTime > 0: led.value = True time.sleep(onTime) if duty - onTime > 0: led.value = False time.sleep(duty - onTime) [localvideo]8c23d536df42401548b2dd2f7df07893[/localvideo]   基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换 【Follow me第二季第1期】任务1:控制板载炫彩LED,跑马灯点亮和颜色变换 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 这个其实就是控制WS2812B灯珠做流水灯,总体来说就是用neopixel库来实现彩色灯的效果,封装得太好,显得没有难度,其实中间一些时序问题,当年我也是想破头 颜色变换写了两种不同函数去遍历。 def Wheel2(i, r_in, g_in): if i < 0 or i > 10: r = g = b = 0 elif i % 3 == 0: r = r_in g = g_in b = 255 - r - g elif i % 3 == 1: r = g_in b = r_in g = 255 - r - b else: g = r_in b = g_in r = 255 - b - g return (r, g, b) def rainbow_cycle2(): dir = True for r in range(255): start = 0 stop = 255 - r step = 1 if not dir: start = 255 - r stop = 0 step = -1 for g in range(start, stop, step): for i in range(10): pixels[i] = Wheel2(i, r, g) pixels.show() time.sleep(colorFulWaitTime / 50) dir = not dir def wheel(pos): if pos < 0 or pos > 768: r = g = b = 0 elif pos < 256: r = int(pos) g = int(255 - pos) b = 0 elif pos < 512: pos -= 256 r = int(255 - pos) g = 0 b = int(pos) else: pos -= 512 r = 0 g = int(pos) b = int(255 - pos) return (r, g, b) def rainbow_cycle(): for j in range(767): for i in range(num_pixels): pixel_index = (i * 767 // num_pixels) + j pixels[i] = wheel(pixel_index % 767) pixels.show() time.sleep(colorFulWaitTime) [localvideo]22f9bc383bf6e55af3472be4f947f179[/localvideo]   基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度 【Follow me第二季第1期】任务2:监测环境温度和光线,通过板载LED展示舒适程度 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 这个任务就是读取AD任务,通过读取光敏AD上的值,获取照度,通过adafruit_thermistor库,可以直接获取温度值,也是站在别人的肩膀上,顿时感觉轻松好多 库的使用也非常简单,我写了一些注释,只要初始化设置好,后面直接得到温度,简单快捷 import adafruit_thermistor # 模拟输入的管脚 pin = board.TEMPERATURE # 热敏电阻的常温阻值 resistor = 10000 # 普通电阻的阻值 resistance = 10000 # 热敏电阻的阻值温度 nominal_temp = 25 # 热敏电阻的B系数 b_coefficient = 3950 # 还有最后一个参数,参数名为high_side,表示热敏电阻是否连接在上端,默认为True,可以不填 thermistor = adafruit_thermistor.Thermistor( pin, resistor, resistance, nominal_temp, b_coefficient) 程序通过灯珠数量反应照度值,通过灯珠颜色反应温度。不过灯珠就在光敏三极管旁边,还是有一些影响。     基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警 【Follow me第二季第1期】任务3:接近检测 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 这是我耗时最久的一个任务,用红外收发实在是完成不了,最后是用了超声波距离模块实现程序功能,超声波模块只需要测量反馈的脉冲长度就可以知道物体的距离的,测试距离使用time.monotonic_ns()函数计算时间戳的差值(单位ns)即可,如下面代码 # 发送出发信号,时间是500us,只要比需求长就可以了 ir_tx.value = True time.sleep(0.0005) ir_tx.value = False rx_count = 0 # 等待回复的高电平 while ir_rx.value is False: time.sleep(0.0001) rx_count = rx_count + 1 if rx_count > 10000: # 发送高电平之后等待时间太长,认为是发送失败 break start_time = time.monotonic_ns() #获取高电平开始的时间戳,单位是ns while ir_rx.value is True: pass end_time = time.monotonic_ns() #获取高电平结束的时间戳,单位是ns duration = round((end_time - start_time)/1000000, 2) if duration < 0.05: # 时间太短 continue print(f'duration time:{duration} ms') distance = round(duration*17.0, 1) # 时间*340m/s(34cm/ms)/2 print(f'distance:{distance} cm') [localvideo]98bcbcd1ec2107ae87dc9cffc0d17e29[/localvideo]   进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果 【Follow me第二季第1期】任务4:制作不倒翁——展示不倒翁运动过程中的不同灯光效果 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 这是一个整活的任务,其实我很多精力都用在搞那个不倒翁底座那里去了T_T 加速度传感器使用也非常简单,只需要调用库即可,如下 import board import busio import adafruit_lis3dh i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA) lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19) # Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G). lis3dh.range = adafruit_lis3dh.RANGE_2_G ax, ay, az = [ value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration ] [localvideo]047a18051831057b8517ff7198dcf743[/localvideo]   最后补充一下我另外买的两个零件,一个是舵机,一个是AGS02MA气体传感器   舵机 舵机主要就是通过pwm占空比来控制舵机的动作,从规格书我们可以看到具体的控制方式   从上面可以看到,停止脉冲是1500us,顺时针方向是700-1500us,逆时针方向是1500-2300us   所以只要用pwmio库产生一个pwm就可以控制舵机 # create a PWMOut object on Pin A1. pwm = pwmio.PWMOut(board.A1, frequency=50, duty_cycle=7536) # 2294 0.7ms min # 4915 1.5ms stop # 7536 2.3ms max 我这里产生的是一个50hz的pwm波   AGS02MA气体传感器 这个要调试其实也有些麻烦,不过其实用法也简单,就那么两三个指令需要调试,不过直到我找到下面这个网站,所有困难都烟消云散了,还是得再次感叹一下python社区的人多力量大,我们都是站在巨人的肩膀上 adafruit-circuitpython-ags02ma - 用于 AGS02MA 气体传感器的 CircuitPython / Python 库_PyPI中文网   直接安装就可以了。然后找到文件   放到板子里面就可以使用了,文件里也说了使用方法   代码如下: import board import busio import time from adafruit_ags02ma import AGS02MA # Initialize I2C bus. i2c = busio.I2C(board.SCL, board.SDA, frequency = 20000) ags = AGS02MA(i2c, address=0x1A) while True: res = ags.gas_resistance tvoc = ags.TVOC print(f'tvoc:{tvoc},res:{res}') time.sleep(2) 可惜的是,CPX线路板的硬件I2C并不支持20k的通讯速率,而AGS02MA的最大通讯速率是30k。最后我是使用ESP-S3 feather这个板子来完成,同样是follow me活动的板子,同样是使用circuit python代码完成的         感想 最后的最后,还是得感谢举办方,感谢得捷电子,感谢EE。在不断摸索的过程中,感受到前人智慧的浩渺,我只是后来者,模仿者,轻松拿来使用的人。并没有什么值得骄傲的。科学进步才是社会发展的动力,我仍然需要虚心学习更多的知识,创造更美好的生活。   下面是课程链接: 【得捷Follow me第二季第1期】任务汇总+舵机与AGS02MA气体传感器使用-EEWORLD大学堂 源码: Follow me第二季第一期 所有代码 + 库-嵌入式开发相关资料下载-EEWORLD下载中心  

  • 2024-10-14
  • 回复了主题帖: 【Follow me第二季第1期】任务3:接近检测

    wangerxian 发表于 2024-10-12 15:34 用python写超声波代码这么简单的吗? AS100S是个专用芯片,使用起来就是简单,现在好像都是用模块比较多

  • 上传了资料: Follow me第二季第一期 所有代码 + 库

  • 2024-10-13
  • 发表了主题帖: 【Follow me第二季第1期】任务4:制作不倒翁——展示不倒翁运动过程中的不同灯光效果

    大家好,我是郑工,尘世间一个迷途小工程师。   我们赶紧把任务4完成了,制作一个不倒翁,之前我在路边捡到一个木头,如下:   我们来搞个不倒翁吧,电子上没办法整活,我们来整个木工活   经过我一堆磨切敲打,终于把木头弄成下面这个形状了 (请忽略木头上那条裂纹,搞了一天,木头裂了,人都要炸了,最后用了些电工胶粘在一起了,我们是电子论坛,这是可以接收的,以后有机会得搞个车床才行)   再打上木蜡油上去,经过晾晒,这个底座就可以用了     好了,木工活搞完了,我们继续来搞我们些原理分析吧。   CPX的板子上,自带了一个lis3dh,这个芯片是ST生产的三轴线性加速度传感器,具有超低功耗,1到5.3k输出速率,提供±2g/±4g/±8g/±16g的动态用户可选全量程,好用的芯片   首先是初始化,因为两个管脚就是芯片的I2C管脚,在board库里面有定义board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA,所以初始化比较简单,代码如下: import board import busio import adafruit_lis3dh i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA) lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19) # Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G). lis3dh.range = adafruit_lis3dh.RANGE_2_G 然后读取三轴加速度的值,只需要通过函数: ax, ay, az = [         value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration     ] 因为读取出来是重力加速度,所以需要除以重力加速度   然后计算俯仰角跟横滚角: # 计算俯仰角     pitch = math.atan2(ay, math.sqrt(ax*ax + az*az)) * 180 / math.pi;     # 计算横滚角     roll = math.atan2(ax, math.sqrt(ay*ay + az*az)) * 180 / math.pi;   俯仰角就是物体前后倾斜的角度,横滚角就是物体横向翻滚的角度。   这里我做了个逻辑判断,如果两个角度都小于5度,则表示没有倾斜,如果倾斜之后,则用 (俯仰角/横滚角) 计算比例,再用arctan函数计算对应的角度,再转换成数值,对应到10个灯珠上。函数表现如下,基本能实现线路板倾斜,对应的灯珠能亮起来红灯。 if abs(pitch) < 5 and abs(roll) < 5: # 倾斜角度小于5度,认为水平,显示绿灯 pixels.fill((0, 15, 0)) pixels.show() else: if roll == 0: # 防止roll等于0的错误 roll = 1 arc = math.atan(pitch/roll)* 180 / math.pi num = ((arc + 90) / 180) * 4.7 if roll > 0: fill_led(int(num)) else: fill_led(int(num + 5))  

  • 2024-10-12
  • 发表了主题帖: 【Follow me第二季第1期】任务3:接近检测

    本帖最后由 eew_Ya3s2d 于 2024-10-12 10:02 编辑 大家好,我是郑工,尘世间一个迷途小工程师。   最近家里比较忙,人到中年,忙忙碌碌的,正如张爱玲在《半生缘》里写的“中年以后的男人,时常会觉得孤独,因为他一睁开眼睛,周围都是要依靠他的人,却没有他可以依靠的人”。咦,等等,我们是工程师,回到正题,说说这次FM活动第一期的任务3,这个任务我也研究了一些时间,做了一些实验,我们先说说原理。   电路图如下:   红外发送的电路很简单就是用一个npn三极管去驱动红外发射管。   红外接收电路就用了一个专用芯片VSOP383。在网上找到了原理图,框图如下     可以看到红外接收管如果的地方,有个bias偏置电路,所以在无发送的时候,也会有个偏置电压,用万用表测试了一下,这个电压是0.925v。用白光测试了一下,发现红外接收管对于白光是不敏感的。然后规格书上也说了,器件是对38kHz的红外光敏感,可以看到下图的频率响应。   而在CPX的规格书里面说明了,可以用A10作为接近感应器的输入管脚。   最后,进入REPL查询我们可以知道管脚定义并不是A10,而是IR_PROXIMITY (附:进入REPL的办法,可以用mu,打开串口,使用ctr + c暂停程序,然后按回车进入REPL。REPL代表“读取-评估-打印-循环”(Read-Evaluate-Print Loop),它是一个交互式编程环境,允许用户输入代码并立即执行,然后显示结果。这非常有用,尤其是当你需要对代码进行故障排除或测试新想法时。)   所以我们的程序思路其实就很明确了,就是使用IR_TX管脚,输入一个38khz的脉冲或者多个脉冲,然后立刻去读取IR_PROXIMITY的AD值。当有物体接近的时候,反射光会叠加到芯片的偏置上,接近得越近,AD的数值就越大。   之前我些了一个简单的代码,程序也可以运行,跟我猜想的也一样,代码如下: import analogio import digitalio import board import time ir_tx = digitalio.DigitalInOut(board.IR_TX) ir_tx.direction = digitalio.Direction.OUTPUT proximity = analogio.AnalogIn(board.IR_PROXIMITY) delay_time = 0.00001 while True: for i in range(2): time.sleep(delay_time) ir_tx.value = True time.sleep(delay_time) ir_tx.value = False proximity_value = proximity.value print("proximity Level: %d" % proximity_value) time.sleep(0.1) 延时的数值确定为10微秒是因为38khz方波的周期为26微秒,高电平,低电平的时间都为13微秒,粗略估计进入退出time.sleep函数的时间3微秒,函数是用于大致测试使用的,没有卡太准,我用示波器测试看到波形确实也是有的,波形如下:   讲真这波形跟我想象中还是有些出入,可能这发射跟接收之间并没有严格隔离,所以其实可以看到发射期间IR_PROXIMITY的电压都有上升的,只是我接近的时候,在准备低电平那时候有个尖峰,没接近的时候,就没这个尖峰。在我正想研究这个到底有什么内在逻辑的时候,这个波形消失了。然而我单独测试发射或者接收,也是没问题的,搞了好久,都没理解到底哪里出问题了,搞得我一度很气馁,也研究过好多坛友的帖子,感觉也是大差不差,甚至我担心38k输入不准确,使用pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=35768)产生一个准确的38k方波,都是一点反应没有。不知道是不是被我用示波器捅的时候捅出什么问题了。   加上生活工作上一些琐事,让我一直拖延到了现在,我想事情还是得解决的,既然这条路走不通,我们要创造条件完成任务,所以我买了一个超声波距离传感器   由图可见使用的是CS100A超声波芯片。这个芯片的使用方式也很简单,在 TRIG 管脚输入一个 10US 以上的高电平(一般建议 50US 左右),芯片(TP,TN管脚)便可发出 8 个 40KHZ 的超声波脉冲,然后(RP,RN)检测回波信号。当检测到回波信号后,通过 ECHO 管脚输出。   根据 ECHO 管脚输出高电平的持续时间可以计算距离值。即距离值为:(高电平时间*340m/s)/2。当测量距离超过测量范围时,CS100A 仍会通过 ECHO 管脚输出高电平的信号,高电 平的宽度约为 33ms 。   测量周期:当芯片通过 ECHO 管脚输出的高电平脉冲后,便可进行下一次测量,所以测量周期取决于测量距离,当测距很近时,ECHO 返回的脉冲宽度较窄,测量周期就很短;当测距较远时,ECHO 返回的脉冲宽度较宽,测量周期也就相应的变长。   最坏情况下,被测物体超出测量范围,此时返回的脉冲宽度最长,约为 33ms,所以最坏情况下的测量周期大于 33ms 即可(比如测量周期可取 50ms)。       这是正常时候的波形     这是超出范围的波形   计算其实就比较简单,音波在空气中的传播速度是340m/s = 34000cm/1000ms = 34cm/ms。距离 = 时间 x 速度,考虑上一来一回,所以 距离 = 时间 x 速度 / 2。最后距离 = 时间 x 17,单位是厘米。由此可知,33ms也有500+m,显然是超出我们想侦测的范围。   由此我写了以下的代码侦测距离 # 发送出发信号,时间是500us,只要比需求长就可以了 ir_tx.value = True time.sleep(0.0005) ir_tx.value = False rx_count = 0 # 等待回复的高电平 while ir_rx.value is False: time.sleep(0.0001) rx_count = rx_count + 1 if rx_count > 10000: # 发送高电平之后等待时间太长,认为是发送失败 break start_time = time.monotonic_ns() #获取高电平开始的时间戳,单位是ns while ir_rx.value is True: pass end_time = time.monotonic_ns() #获取高电平结束的时间戳,单位是ns duration = round((end_time - start_time)/1000000, 2) if duration < 0.05: # 时间太短 continue print(f'duration time:{duration} ms') distance = round(duration*17.0, 1) # 时间*340m/s(34cm/ms)/2 print(f'distance:{distance} cm') 代码并不复杂,就是发送一个出发信号,然后等待回复,用time.monotonic_ns()函数获取时间戳,计算开始与结束的时间差。   后面需要简单说一下的就是播放音频的代码。其实就是一些代码的参(复)考(制) CircuitPython Audio Out | Adafruit Circuit Playground Express | Adafruit Learning System 简单说就是使用audioio库里面的AudioOut作为播放器,用audiocore或者audioio里的WaveFile加载音频文件,这样就可以播放音频文件了。 try: from audiocore import WaveFile except ImportError: from audioio import WaveFile try: from audioio import AudioOut except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! def play_file(filename): print("Playing file: " + filename) wave_file = open(filename, "rb") with WaveFile(wave_file) as wave: with AudioOut(board.SPEAKER) as audio: audio.play(wave) while audio.playing: pass print("Finished") 灯光警报就没什么好说的,之前就提过的内容,因为距离测试耗费的时间太长了,就没有整什么花活,可以参考我之前的帖子 【Follow me第二季第1期】任务1:控制板载炫彩LED,跑马灯点亮和颜色变换 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 或者等我把任务代码提交了,直接拷贝一下。   专业的超声波测距模块还是挺准的,我测试精确度都有厘米级别了。

  • 2024-08-09
  • 发表了主题帖: 【2024 DigiKey 创意大赛】开箱贴(ESP32-S3-LCD-EV-BOARD、SEN-21231人在传感器)

    大家好,我是郑工,尘世间一个迷途小工程师。   这次特别荣幸能参加得捷创意大赛,这次我做的题目是一个智能植物管理系统,这次得好好搞,选的都是ESP32,带一块3.95" 480x480的屏幕。话不多说,我们直接来看实物吧!!   这是这次比赛的主角ESP32-S3-LCD-EV-BOARD,乐鑫官方的板子,整个质感还是做得挺好的,demo程序看起来也挺协调的,看背后丝印,这是1.5版本的板子,详细资料可以看下面链接 ESP32-S3-LCD-EV-Board v1.5 - - — esp-dev-kits latest 文档 (espressif.com)   然后是SEN-21231人在传感器   背面,可以看到是ESP32-S3的方案,相机有些渣,不过比我肉眼好了,现在年纪大了,这些小字都看不清了T_T   资料如下 person_sensor_docs/README.md at main · usefulsensors/person_sensor_docs · GitHub   兄弟萌,得捷现在又把压力给到我了,要努力加油干!!

  • 2024-08-01
  • 发表了主题帖: 【Follow me第二季第1期】任务2:监测环境温度和光线,通过板载LED展示舒适程度

    大家好,我是郑工,尘世间一个迷途小工程师。   这两天家里有些事情,耽误了些时间,我们继续下一个任务,监控温度和照度。   首先是温度,我们先看看原理图     可以看到原理还是比较简单的,就是一个热敏电阻,下拉一个10k电阻做分压,用ADC接口去读取这个口的电压就可以。   不过查资料之后,CircuitPython有个库adafruit_thermistor可以直接适配这种情况的温度读取。代码如下: import adafruit_thermistor # 模拟输入的管脚 pin = board.TEMPERATURE # 热敏电阻的常温阻值 resistor = 10000 # 普通电阻的阻值 resistance = 10000 # 热敏电阻的阻值温度 nominal_temp = 25 # 热敏电阻的B系数 b_coefficient = 3950 # 还有最后一个参数,参数名为high_side,表示热敏电阻是否连接在上端,默认为True,可以不填 thermistor = adafruit_thermistor.Thermistor( pin, resistor, resistance, nominal_temp, b_coefficient) 后续只需要读取thermistor.temperature就可以获取的摄氏温度的值。   然后到照度值,我们先看看原理图   原理也就是一个光电三极管下接一个10k电阻,当光照到光电三极管,会产生光电流,等效电阻减小,电压升高。初始化代码如下: import analogio # Adc的值为0-65535(16bit) light = analogio.AnalogIn(board.LIGHT) 后续只需要查询light.value就可以获取adc的值,范围0-65535   后续代码根据获取的数值显示舒适程度,使用neopixel灯珠显示,初始化代码如下: import neopixel pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.05, auto_write=False) pixels.fill((0, 0, 0)) pixels.show() 后面的功能逻辑就是温度高为红色,温度低为蓝色,中间温度在这两个颜色之间切换 照度呢就是照度越低,灯珠数量越多,代表越舒服,越适合睡觉。   也是一个有些乱的逻辑,没有仔细深究。大家有什么想法可以跟我说说,我去改一下。以下是具体代码 index = 0 while True: # light value remapped to pixel position peak = simpleio.map_range(light.value, 500, 10000, 0, 10) # def map_range( # x: float, # in_min: float, # in_max: float, # out_min: float, # out_max: float) -> float: light_num = 10 - peak print('\n\n') print(f'time: {index}') index = index + 1 print(f'light val:{light.value}') print(f'light num:{int(light_num)}') color = simpleio.map_range(thermistor.temperature, 10, 35, 0, 255) temp_color = (int(color) , 0, 255 - int(color)) print(f'temperature:{int(thermistor.temperature)}') print(f'temp num:{color}') for i in range(10): if i <= light_num: pixels[i] = temp_color else: pixels[i] = (0, 0, 0) pixels.show() time.sleep(1) 使用了simpleio的map_range函数,这个函数会根据输入的数据,做出等级划分。

  • 回复了主题帖: 【Follow me第二季第1期】任务1:控制板载炫彩LED,跑马灯点亮和颜色变换

    Jacktang 发表于 2024-7-31 07:30 里胡哨的跑马灯环节,, 整个图片或小视频就完美了 [localvideo]ac5de446be1f2801a853515553fd1fba[/localvideo] 简单拍了段,其实也就是简单做一下遍历算法,时间比较长

  • 2024-07-30
  • 发表了主题帖: 【Follow me第二季第1期】任务1:控制板载炫彩LED,跑马灯点亮和颜色变换

    大家好,我是郑工,尘世间一个迷途小工程师。   昨天有些事情,没给大家分享第一个任务,今天继续。   任务一是控制WS2812B灯珠,其实就是学习使用neopixel库,需要参考这个网址-->Adafruit CircuitPython NeoPixel — Adafruit CircuitPython NeoPixel Library 1.0 documentation   说白了就是需要知道用的是哪个管教,一共有多少个灯珠,亮度是多少之类的信息,最重要最重要就是初始化做好,其他啥问题没有,下面是我的初始化函数: pixel_pin = board.NEOPIXEL num_pixels = 10 ORDER = neopixel.GRB pixels = neopixel.NeoPixel( pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=ORDER ) 然后需要做的就是给pixels赋值颜色了,有两种方式,一种是调用pixels.fill()函数,所有灯珠都同一个颜色,另一个是给pixels[i]赋值。   最后就是调用pixels.shows()函数执行操作就新行了。   剩下的就是花里胡哨的跑马灯环节。我自己做了两种循环模式,一种是在RGB三种颜色上渐变,另一种是指定RGB之和为255的情况下渐变。也算是争奇斗艳,花里胡哨了。下面是两个函数,有兴趣的同学可以琢磨一下,有啥问题跟我沟通沟通哈!   def Wheel2(i, r_in, g_in): if i < 0 or i > 10: r = g = b = 0 elif i % 3 == 0: r = r_in g = g_in b = 255 - r - g elif i % 3 == 1: r = g_in b = r_in g = 255 - r - b else: g = r_in b = g_in r = 255 - b - g return (r, g, b) def rainbow_cycle2(): dir = True for r in range(255): start = 0 stop = 255 - r step = 1 if not dir: start = 255 - r stop = 0 step = -1 for g in range(start, stop, step): for i in range(10): pixels[i] = Wheel2(i, r, g) pixels.show() time.sleep(colorFulWaitTime / 50) dir = not dir def wheel(pos): if pos < 0 or pos > 768: r = g = b = 0 elif pos < 256: r = int(pos) g = int(255 - pos) b = 0 elif pos < 512: pos -= 256 r = int(255 - pos) g = 0 b = int(pos) else: pos -= 512 r = 0 g = int(pos) b = int(255 - pos) return (r, g, b) def rainbow_cycle(): for j in range(767): for i in range(num_pixels): pixel_index = (i * 767 // num_pixels) + j pixels[i] = wheel(pixel_index % 767) pixels.show() time.sleep(colorFulWaitTime)  

  • 2024-07-27
  • 回复了主题帖: 【Follow me第二季第1期】开箱帖(现在得捷速度就是这么块)

    秦天qintian0303 发表于 2024-7-26 13:32 祝贺楼主喜提开发板,其实我还没有想到舵机干嘛用,还不如搞个屏呢 FM任务里面要用到这个东西,屏幕我自己也有,后面看看怎么驱动一下哈,到时候再告诉你哈

  • 2024-07-26
  • 发表了主题帖: 【Follow me第二季第1期】任务0:开发环境搭建,板载LED点亮

    大家好,我是郑工,尘世间一个迷途小工程师。   昨天给大家分享了开箱帖,今天迫不及待就完成了Follow me的基础任务,搭载开发环境,点亮第一个LED灯。   这次使用的核心板Circuit Playground Express,简称CPX有非常丰富的板载功能。可以使用微软MakeCode,CircuitPython,Arduino还有Code.org CSD四个方式开发。   我们这个帖子,我用的是CircuitPython的方式开发。   首先是搭建开发环境。主要还是参考下面官方网址: CircuitPython | Adafruit Circuit Playground Express | Adafruit Learning System   一、升级CPX固件   1、下载最新版的cp Circuit Playground Express Download (circuitpython.org) 2、选择US,下载.UF2 3、内置的模块有 adafruit_bus_device, adafruit_pixelbuf, analogio, array, audiobusio, audiocore, audioio, bitbangio, board, builtins, busio, busio.SPI, busio.UART, codeop, collections, countio, digitalio, errno, locale, math, microcontroller, neopixel_write, nvm, onewireio, os, pulseio, pwmio, rainbowio, random, rotaryio, rtc, storage, struct, supervisor, sys, time, touchio, usb_cdc, usb_hid, usb_midi, warnings。后面要用可以查一下看看   4、我这里的文件名叫adafruit-circuitpython-circuitplayground_express-en_US-9.1.1.uf2,大家可以参考一下 5、把板子连接电脑,快速点击RESET按键两次,板子上所有指示灯会变成绿色,如果变成红色,请检查一下usb线(如果确认不是线的问题,就单击一下,第一次上电的情况)   电脑会多出一个叫CPLAYBOOT的盘,把固件拖到盘里   成功后,盘的名字会变成CIRCUITPY,我们就是在这个   二、安装开发环境Mu   下面就安装Mu软件了Download Mu (codewith.mu) 下载软件安装包   安装后第一次打开选择模式为CircuitPython     编译器右下角会显示CircuitPython,同时这个芯片表示已经连接好CPX的板子,无连接的话,芯片上会有个红色的叉     至此开发环境已经搭建完成了,大家可以在MU上编程,编程后点击检查校验代码对错,然后保存到CIRCUITPY盘里的code.py文件。     三、点亮LED灯   点亮LED会用到的模块有board,digitalio,time import board import digitalio import time 然后初始化管脚 led = digitalio.DigitalInOut(board.LED) led.direction = digitalio.Direction.OUTPUT 简单的闪烁我觉得有些简单了,整了点花活,做了个简单的呼吸灯程序,代码如下 timeOn = 0 step = 0.0001 #duty is 0.01s -> 100Hz isIncrease = True def onLed(onTime, duty): if onTime > 0: led.value = True time.sleep(onTime) if duty - onTime > 0: led.value = False time.sleep(duty - onTime) while True: if isIncrease: timeOn = 0 - step for i in range(100): if isIncrease: timeOn = timeOn + step else: timeOn = timeOn - step onLed(timeOn, step * 100) for i in range(100): onLed(timeOn, step * 100) isIncrease = not isIncrease 程序逻辑就是不断更改led的占空比。   大家有什么问题,欢迎留言哈。

  • 回复了主题帖: 【Follow me第二季第1期】开箱帖(现在得捷速度就是这么块)

    吾妻思萌 发表于 2024-7-26 08:23 现货,现在就发的货 期货,遥遥无期的货 现货是真的香,期货不能碰,不止板子,还有房子

  • 2024-07-25
  • 加入了学习《DigiKey 应用说:蓝牙5.4 新特性解读及实例演示》,观看 蓝牙5.4 新特性解读及实例演示

  • 发表了主题帖: 【Follow me第二季第1期】开箱帖(现在得捷速度就是这么块)

    大家好,我是郑工,尘世间一个迷途小工程师。   有幸被选上得捷follow me第二季第一期的活动。首先还是得感谢得捷,感谢ee,感谢各位领导给我这个机会。   看到许多未被选上小伙伴嗷嗷待哺的眼光,我顿感肩上的担子重了一些些。   这里收到这次活动所购(白)买(piao)【玩笑】到的板子!   给各位小伙伴看看,后面有什么经验,问题也会在论坛上跟各位坛友分享一下,希望各位坛友多多帮忙。   这是采用32位ARM M0核心的ATSAMD21微控制器的核心板,上面有运动、温度、光、声音传感器,还带红外收发。可以说是为了感应万物而生的。     这是活动推荐的舵机,讲真我还没用过,不过活动推荐的,想来难度不大     这是我为了探(作)索(si)新功能买的气体传感器,一切未知,也不知道能不能驱动得了。   万一有啥问题,希望各位坛友大力帮忙

  • 2024-07-10
  • 回复了主题帖: 【得捷Follow me第3期】XIAO主板读取磁力开关

    wangerxian 发表于 2024-1-29 14:32 这传感器的检测距离大概是多少? 也就一两厘米,可能跟磁铁的磁性也有关系

最近访客

< 1/3 >

统计信息

已有44人来访过

  • 芯积分:134
  • 好友:1
  • 主题:16
  • 回复:19

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言