Henry-0755

  • 2024-06-06
  • 回复了主题帖: 【Beetle ESP32 C6迷你开发板】低功耗模式与功耗测试

    walker2048 发表于 2024-6-6 08:51 大佬要不要测试下降频的功耗,我没搞过。想知道80Mhz主频的情况下,是否能使用wifi,功耗多少? 好的嘞 可以测试下 就80M下看看能不能ping通喽

  • 发表了主题帖: 【Beetle ESP32 C6迷你开发板】低功耗模式与功耗测试

    # 【Beetle ESP32 C6迷你开发板】低功耗模式与功耗测试 ## 一 低功耗模式 esp32主要有两种节能模式 light-sleep 与 deep-sleep 根据官方文档 在 Light-sleep 模式下,数字外设、CPU、以及大部分 RAM 都使用时钟门控,同时电源电压降低。退出该模式后,数字外设、CPU 和 RAM 恢复运行,内部状态保持不变。 在 Deep-sleep 模式下,CPU、大部分 RAM、以及所有由时钟 APB_CLK 驱动的数字外设都会被断电。芯片上继续处于供电状态的部分仅包括: > - RTC 控制器 > - ULP 协处理器 > - RTC 高速内存 *** 其实还有额外的降低功耗的模式Modem-sleep mode 实际就是给cpu降频+RT部分周期性启动 *** 结合datasheet中的框架图 其中 RTC 高速内存 通常是指与实时时钟模块关联的一小块快速存取内存。 ulp指白色的模块 lp相关的硬件 lp memory 指16 KB of low-power SRAM (LP SRAM) that can be accessed by HP CPU or LP CPU. It can retain data in Deep-sleep mode 进入休眠模式后依据不同的休眠等级 唤醒需要的源也不同 基本包括定时器 外部ext0/1 ULP协处理器(RISC-V核)以及light-sleep下GPIO UART唤醒 ## 二 功耗测试 板子的功耗其实高出文档很多 文档中light-sleep与deep-sleep都是uA级别 文档中描述 deep_sleep模式 demo位置`examples/system/deep_sleep/main/deep_sleep_example_main.c` 测量结果 light_sleep模式 demo位置`examples/system/light_sleep/main/light_sleep_example_main.c` 通过测试可以看出ligth_sleep模式比deep_sleep模式高出180uA是符合预期的,所以大概就是板子的一些io没有匹配上或外围电路有一点点的漏电

  • 2024-05-26
  • 发表了主题帖: 【Beetle ESP32 C6迷你开发板】ADC以及蓝牙初体验

    #【Beetle ESP32 C6迷你开发板】ADC以及蓝牙初体验 ## 一 ADC 芯片只有一个12bit的ADC通道 引出了三个channels 4 5 6如下图 摇杆需要连续的采样两个ADC通道 采样xy坐标 接线如图 demo在sdk的`examples/ble_handle/main/continuous_read_main.c` 略作修改 采样4 5通道 采样率降低 减小每次READ的长度 提高实时性 修改部分如下 ``` #define EXAMPLE_READ_LEN                    16 static adc_channel_t channel[2] = {ADC_CHANNEL_4, ADC_CHANNEL_5}; adc_continuous_handle_cfg_t adc_config = {     .max_store_buf_size = 256,     .conv_frame_size = EXAMPLE_READ_LEN, }; ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle)); adc_continuous_config_t dig_cfg = {     .sample_freq_hz = 1 * 1000,     .conv_mode = EXAMPLE_ADC_CONV_MODE,     .format = EXAMPLE_ADC_OUTPUT_TYPE, }; ``` 就可以及时的得到采样值啦 ## 二 蓝牙 想让开发板作为一个蓝牙设备可以参考 `examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c` 默认的例子采用的是Bluedroid协议的HID 编译运行 在手机上连接设备 会每隔一段时间交替设置声音加减 而要模拟其他设备 比如鼠标设备 也是在这个例子总 通过宏控制 根据EXAMPLE_MOUSE配置menuconfig ``` CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y CONFIG_EXAMPLE_MOUSE_ENABLE=y CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_CONTROLLER_DISABLED=y ``` 再编译运行 手机端匹配这个esp设备 输入配对码123456即可连接 蓝牙与网络相关的demo有许多呢 提供的demo也很全面 非常优秀的sdk~~

  • 2024-05-13
  • 发表了主题帖: 【Beetle ESP32 C6迷你开发板】开箱、LinuxMint Docker环境搭建

    # 【Beetle ESP32 C6迷你开发板】开箱、LinuxMint Docker环境搭建 # 一、前言 本次测评的产品DFROBOT家的esp32c6开发板 这种小巧低功耗,带蓝牙wifi,且自带锂电池充放电芯片很适合diy,本次测评想使用这个板子完成一个蓝牙遥控手机的小制作 板卡支持多种开发环境,C、MicroPython、Arduino,考虑想研究蓝牙以及低功耗的功能,主要使用C进行开发 # 二、开箱 正反面 连接type c上电,默认程序有cdc串口打印 开发板灯随之闪烁 # 三、编译环境 官方SDK文档介绍 [esp-idf 快速入门-官方doc](https://docs.espressif.com/projects/esp-idf/zh_CN/v5.2/esp32c6/get-started/index.html) 开发环境为linux mint,电脑上有其他开发的工程,因此采用docker来创建编译环境 参考的教程如下,都是非常详细的教程,值得推荐: linux mint 21.1上安装docker https://linuxiac.com/how-to-install-docker-on-linux-mint-21/ 安装docker_desktop https://docs.docker.com/desktop/install/debian/#install-docker-desktop 运行docker https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/tools/idf-docker-image.html# 编译 `docker run --rm -v $PWD:/project -w /project -u $UID -e HOME=/tmp espressif/idf idf.py build` 烧录 docker映射的device没研究明白,有其他tty设备但始终没有ttyACM0设备,所以找了其他的烧录方式: [esptool](https://github.com/espressif/esptool) 下载好release后,给esptool权限`sudo chmod +x esptool`接着执行命令 `./esptool --chip esp32c6 -p /dev/ttyACM0 write_flash 0x1000 ../esp-idf/examples/get-started/hello_world/build/hello_world.bin` 至此已经可以愉快的开发应用了~~

  • 2024-04-26
  • 回复了主题帖: 测评入围(第二波):Beetle ESP32 C6迷你开发板 基于ESP32-C6芯片

    个人信息无误,确认可以完成评测计划。

  • 2024-02-27
  • 加入了学习《FollowMe第4期》,观看 FollowMe第四期任务视频

  • 上传了资料: FollowMe第四期

  • 2024-02-26
  • 回复了主题帖: 【补 DigiKey“智造万物,快乐不停”创意大赛】3.usb_otg_hs虚拟串口的调试 基于ST...

    wangerxian 发表于 2024-2-26 17:19 当然不是用眼测,不停的发数据,然后看一段时间接收到的数据量,然后和时间计算。 usb眼图测试,可以测usb phy的最大速度,stm32这种各种测试应该都过了,大概就标准的12m,如果测传输速度应该是配置为usb mass storage device然后电脑上看发送的传输速度,或者otg读u盘看读取的速度

  • 回复了主题帖: 【补 DigiKey“智造万物,快乐不停”创意大赛】3.usb_otg_hs虚拟串口的调试 基于ST...

    wangerxian 发表于 2024-2-18 17:04 全速那个能测试吗,速率能达到多快? 是想测眼图吗?还是啥

  • 回复了主题帖: 【得捷Follow me第4期】+ 任务汇总 包含MaixDuino的使用

    秦天qintian0303 发表于 2024-2-26 09:14 任务汇总呢?是不是内容被吞了?建议先在word里面写,然后可以直接文件导上来 都有呀 目录结构是这样的视频介绍一、入门任务:开发环境搭建二、基础任务一:静态IP联网三、基础任务二:主控板建立TCPIP或UDP服务器四、简易FTP文件服务器心得代码习惯用markdown 导进来的

  • 2024-02-25
  • 发表了主题帖: 【得捷Follow me第4期】+ 任务汇总 包含MaixDuino的使用

    本帖最后由 Henry-0755 于 2024-2-27 15:10 编辑 # FollowMe第四期 包含MaixDuino的使用 基本介绍与任务分析 这款板子`W5500-EVB-PICO`支持的开发环境很多,包括C/C++、CircuitPython、MicroPython 官网介绍:https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico C/C++的教程参考 `https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf` 十分详细~ CircuitPython教程参考https://github.com/Wiznet/RP2040-HAT-CircuitPython/blob/master/Ethernet%20Example%20Getting%20Started%20%5BCircuitpython%5D.md MicroPython教程参考https://github.com/Wiznet/RP2040-HAT-MicroPython/blob/main/Ethernet%20Example%20Getting%20Started%20%5BMicropython%5D.md 简单看了下,c/c++的教程应该是最全的,但下载环境编译比较费时,sdk+各种example大概需要2G多的空间 Python的就很简单,下载官方给出的.uf2固件,按住bootsel键后上电,电脑弹出u盘设备,将.uf2固件放进去,python的环境就装好了,随后用vscode的CircuitPython之类的插件就可以了(功能包含cdc虚拟串口、导入库等等) ## 视频链接 https://training.eeworld.com.cn/course/68437 ## 一、入门任务:开发环境搭建 ### 1.1 描述 任务描述:开发环境搭建,BLINK,驱动液晶显示器进行显示(没有则串口HelloWorld) 没有购买屏幕,使用circuitpython来串口打印 上文我们已经搭建好circuitpython环境,接下来就是在vscode中完成blink与串口打印任务 使用circuitpython环境的话,会出现CIRCUITPY的u盘节点,在u盘目录打开vscode,将程序编写在code.py保存即可自动执行。 打开并连接串口 在vscode中使用Ctrl+Shitf+P调出命令搜索栏,搜索`CircuitPython:Open Serial Monitor`随后选择正确的串口名这里的环境是linux ubuntu所以设备名是`/dev/ttyACM1`连接后下面显示`Adafruit CircuitPython`即成功连接。 (PS:都是很基础的步骤,只是看到这次的视频直播指导没有用这个方法进行环境搭建,所以顺便提一嘴,FollowMe第二期的视频直播有上述circuitpython的教程,有兴趣的可以去看一看) ### 1.2 打印HelloWorld ```python print("Hello World") while True:     pass ``` (串口用的minicom) ### 1.3 Blink 来自官方示例 `https://docs.circuitpython.org/en/latest/shared-bindings/digitalio/index.html` ```python import time import digitalio import board led = digitalio.DigitalInOut(board.LED) led.direction = digitalio.Direction.OUTPUT while True:     led.value = True     time.sleep(0.1)     led.value = False     time.sleep(0.1) ``` 0.1s闪烁一次 ## 二、基础任务一:静态IP联网 ### 2.1 描述 任务描述:完成主控板W5500初始化(静态IP配置),并能使用局域网电脑ping通,同时W5500可以ping通互联网站点;通过抓包软件(Wireshark、Sniffer等)抓取本地PC的ping报文,展示并分析。 网络抓包工具:使用wireshark,在ubuntu的ubuntu software中就可以下载。按照软件指示设置权限并监听网路。 ### 2.2 实现 参照官网给出的连接网络例程 `https://github.com/Wiznet/RP2040-HAT-CircuitPython/blob/master/examples/Network/W5x00_Ping_Test.py` 但实际上运行就会有问题如下: ``` Traceback (most recent call last):   File "code.py", line 51, in   File "adafruit_wiznet5k/adafruit_wiznet5k.py", line 244, in __init__   File "adafruit_wiznet5k/adafruit_wiznet5k.py", line 388, in mac_address AttributeError: 'tuple' object has no attribute 'split' ``` 我猜应该是api更新导致的参数错误,示例中`MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05)`是tuple类型,将他转位bytes类型就可以了。`MY_MAC = bytes(MY_MAC)` 说起来之前FollowMe2的circuitpython也找到了库的bug哈哈哈,有时间跟一下api的更改记录再提一下修改(主要对python语法不咋熟怕搞乌龙~) 代码如下: ```python import board import busio import digitalio import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K ##SPI0 SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k Ping Test (no DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) MY_MAC = bytes(MY_MAC) IP_ADDRESS = (192, 168, 82, 144) IP_ADDRESS = bytes(IP_ADDRESS) SUBNET_MASK = (255, 255, 255, 0) SUBNET_MASK = bytes(SUBNET_MASK) GATEWAY_ADDRESS = (192,168,43,143) GATEWAY_ADDRESS = bytes(GATEWAY_ADDRESS) DNS_SERVER = (8, 8, 8, 8) DNS_SERVER = bytes(DNS_SERVER) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # Initialize ethernet interface with DHCP # eth = WIZNET5K(spi_bus, cs) # Initialize ethernet interface without DHCP eth = WIZNET5K(spi_bus, cs, is_dhcp=True, mac=MY_MAC) # Set network configuration eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) print("Chip Version:", eth.chip) print("MAC Address:", [hex(i) for i in eth.mac_address]) print("My IP address is:", eth.pretty_ip(eth.ip_address)) while True:     led.value = not led.value     time.sleep(1) print("Done!") ``` 抓包: 信息分析如图: 还是头一次进行网络抓包,看到这里给出的字段解析很完善啊,包括这是接口类型,以太网接口,时间,帧数据等等。 几个层包括物理层的数据帧概况、数据链路层以太网帧头部、以太网协议层、ICMP层 具体解析可以看这篇文章,很详细值得收藏`https://blog.csdn.net/zhizhengguan/article/details/109206015` ### 2.3 个人踩坑 1.网络与别人不同,我租房这边没有拉网线,仅通过手机开热点,然后路由器进行桥接,开发板再连接路由器,我以为网关和和别人一样,是192.168.2.1之类的路由器ip,但实际上是手机的ip, 2.当我以为网段是和手机网关一样的时候,发现网段应该和路由器的一致。。。 还是对网络结构理解不到位~~ ## 三、基础任务二:主控板建立TCPIP或UDP服务器 ### 3.1 描述 任务描述:主控板建立TCPIP或UDP服务器,局域网PC使用TCPIP或UDP客户端进行连接并发送数据,主控板接收到数据后,送液晶屏显示(没有则通过串口打印显示);通过抓包软件抓取交互报文,展示并分析。(TCP和UDP二选一,或者全都操作) ### 3.2 实现 板子作为client的程序: 采用dhcp自动获取ip了,client需要注意 ```python import board import busio import digitalio import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket ##SPI0 SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k SimpleServer Test (DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID # MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) # MY_MAC = bytes(MY_MAC) # SUBNET_MASK = (255, 255, 255, 0) # GATEWAY_ADDRESS = (192,168,43,143) # DNS_SERVER = (8, 8, 8, 8) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # # Initialize ethernet interface without DHCP # eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=True) # # Set network configuration # eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) # Initialize ethernet interface eth = WIZNET5K(spi_bus, cs, is_dhcp=True) # Initialize a socket for our server socket.set_interface(eth) server = socket.socket()  # Allocate socket for the server server_ip = eth.pretty_ip(eth.ip_address)  # IP address of server server_port = 50007  # Port to listen on server.bind((server_ip, server_port))  # Bind to IP and Port server.listen()  # Begin listening for incoming clients while True:     print(f"Accepting connections on {server_ip}:{server_port}")     conn, addr = server.accept()  # Wait for a connection from a client.     print(f"Connection accepted from {addr}, reading exactly 1024 bytes from client")     with conn:         data = conn.recv(1024)         if data:  # Wait for receiving data             print(data)             conn.send(data)  # Echo message back to client     print("Connection closed") ``` 电脑端作为client发送信息的程序: ```python import socket # 服务器地址和端口 SERVER_ADDR = ("192.168.82.35", 50007) # 创建 TCP 客户端套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接到服务器 client_socket.connect(SERVER_ADDR) print(f"连接到服务器 {SERVER_ADDR[0]}:{SERVER_ADDR[1]}") # 发送数据到客户端 message_to_send = "Hello, client!" print(f"发送的数据: {message_to_send.encode('utf-8')}") client_socket.send(message_to_send.encode('utf-8')) # 关闭连接 data = client_socket.recv(1024) print(f"接受的数据: {data.decode('utf-8')}") ``` 板子服务端收到的信息: 报文分析 这里是客户端向服务器发送的数据 也可以看到这里的TCP连接过程 SYN -> ACK -> PSH, ACK -> FIN, ACK 唤醒了大学网络工程的模糊记忆~ ### 3.3 踩坑日常 使用最新的Adafruit_CircuitPython_Wiznet5k运行demo失败:报错如下: ``` Accepting connections on 192.168.82.35:50007 Connection accepted from ('192.168.82.211', 52770), reading exactly 1024 bytes from client Traceback (most recent call last):   File "code.py", line 65, in   File "/lib/adafruit_wiznet5k/adafruit_wiznet5k_socket.py", line 276, in wrapper   File "/lib/adafruit_wiznet5k/adafruit_wiznet5k_socket.py", line 499, in recv   File "/lib/adafruit_wiznet5k/adafruit_wiznet5k_socket.py", line 276, in wrapper   File "/lib/adafruit_wiznet5k/adafruit_wiznet5k_socket.py", line 598, in recv_into TypeError: unsupported types for __gt__: 'NoneType', 'int' ``` 切换到5.0.1正常(大概看了眼,可能是在socket等待数据未满时的超时等待异常) 不晓得咋老是踩到坑里,是不是vscode插件中的lib版本太新了?uf2固件没有用beta版的? ## 四、进阶任务:NTP服务器 ### 4.1 描述 任务描述:从NTP服务器(注意数据交互格式的解析)同步时间,获取时间送显示屏(串口)显示。 我这里是将时间通过串口打印 ### 4.2 具体实现 使用第三方库的ntp服务器`adafruit_wiznet5k_ntp`来自github:https://github.com/alexsporn/Adafruit_CircuitPython_Wiznet5k/tree/main/adafruit_wiznet5k 官方也有https://github.com/adafruit/Adafruit_CircuitPython_NTP.git同样可以使用 代码较短直接将库贴出来(更改了recv接口调用方法): ```python # SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # # SPDX-License-Identifier: MIT """ `adafruit_wiznet5k_ntp` ================================================================================ Network Time Protocol (NTP) helper for CircuitPython * Author(s): Brent Rubell, irinakim Implementation Notes -------------------- **Hardware:** **Software and Dependencies:** """ import time import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket ##__version__ = "0.0.0-auto.0" ##__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_NTP.git" class NTP:     """     Wiznet5k NTP Client     :param iface: Wiznet 5k object     :param str ntp_address: The hostname of the NTP server     :param int utc: Numbers of hours to offset time from UTC     :param bool debug: Enable debugging output.     """     def __init__(self, iface, ntp_address, utc, debug=False):         self._debug = debug         self._iface = iface         socket.set_interface(self._iface)         self._sock = socket.socket(type=socket.SOCK_DGRAM)         self._sock.settimeout(1)         self._utc = utc         self._ntp_server = ntp_address         self._host = 0         self._request_id = 0  # request identifier         self._pkt_buf_ = bytearray([0x23] + [0x00] * 55)     def get_time(self):         """         Get the time from the NTP server         :return: time in seconds since the epoch         """         self._sock.bind((None, 50001))         self._sock.sendto(self._pkt_buf_, (self._ntp_server, 123))         while True:             data = self._sock.recv(128)             if data:                 sec = data[40:44]                 int_cal = int.from_bytes(sec, "big")                 cal = int_cal - 2208988800 + self._utc * 3600                 cal = time.localtime(cal)                 return cal ``` 具体实现: ```python import board import busio import digitalio import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket from adafruit_wiznet5k_ntp import NTP ##SPI0 SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k NTP Test (DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID # MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) # MY_MAC = bytes(MY_MAC) # SUBNET_MASK = (255, 255, 255, 0) # GATEWAY_ADDRESS = (192,168,43,143) # DNS_SERVER = (8, 8, 8, 8) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # # Initialize ethernet interface without DHCP # eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=True) # # Set network configuration # eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) # Initialize ethernet interface eth = WIZNET5K(spi_bus, cs, is_dhcp=True) ntp = NTP(eth, "203.107.6.88", 8) print(ntp.get_time()) ``` 打印数据如下: ``` struct_time(tm_year=2024, tm_mon=2, tm_mday=25, tm_hour=18, tm_min=1, tm_sec=53, tm_wday=1, tm_yday=58, tm_isdst=-1) ``` ## 五、终极任务:简易FTP文件服务器 ### 5.1 描述 任务描述:使用外部存储器,组建简易FTP文件服务器,并能正常上传下载文件。 ### 5.2 具体实现 现获取目录打印sd卡的内容,后启动ftp服务器 ``` # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import os import busio import digitalio import board import storage import adafruit_sdcard import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket # The SD_CS pin is the chip select line. # #     The Adalogger Featherwing with ESP8266 Feather, the SD CS pin is on board.D15 #     The Adalogger Featherwing with Atmel M0 Feather, it's on board.D10 #     The Adafruit Feather M0 Adalogger use board.SD_CS #     For the breakout boards use any pin that is not taken by SPI SD_CS = board.GP13  # setup for M0 Adalogger; change as needed # Connect to the card and mount the filesystem. spi = busio.SPI(board.GP10, board.GP11, board.GP12) cs = digitalio.DigitalInOut(SD_CS) sdcard = adafruit_sdcard.SDCard(spi, cs) vfs = storage.VfsFat(sdcard) storage.mount(vfs, "/sd") # Use the filesystem as normal! Our files are under /sd # This helper function will print the contents of the SD def print_directory(path, tabs=0):     for file in os.listdir(path):         stats = os.stat(path + "/" + file)         filesize = stats[6]         isdir = stats[0] & 0x4000         if filesize < 1000:             sizestr = str(filesize) + " bytes"         elif filesize < 1000000:             sizestr = "%0.1f KB" % (filesize / 1000)         else:             sizestr = "%0.1f MB" % (filesize / 1000000)         prettyprintname = ""         for _ in range(tabs):             prettyprintname += "   "         prettyprintname += file         if isdir:             prettyprintname += "/"         print("{0:10}".format(prettyprintname, sizestr))         # recursively print directory contents         if isdir:             print_directory(path + "/" + file, tabs + 1) print("Files on filesystem:") print("====================") print_directory("/sd") SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k SimpleServer Test (DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID # MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) # MY_MAC = bytes(MY_MAC) # SUBNET_MASK = (255, 255, 255, 0) # GATEWAY_ADDRESS = (192,168,43,143) # DNS_SERVER = (8, 8, 8, 8) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # # Initialize ethernet interface without DHCP # eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=True) # # Set network configuration # eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) # Initialize ethernet interface eth = WIZNET5K(spi_bus, cs, is_dhcp=True) from ftp_server import ftp from sys import exit socket.set_interface(eth) pool = socket print("Chip Version:", eth.chip) print("MAC Address:", [hex(i) for i in eth.mac_address]) print("My IP address is:", eth.pretty_ip(eth.ip_address)) my_ftp_server = ftp(pool, eth.pretty_ip(eth.ip_address), verbose=True, ) my_ftp_server.serve_till_quit() # This will exit after a client disconnects. my_ftp_server.deinit() ``` 上传与下载文件 在linux的环境,使用FileZilla,将test.py拷贝过去再重命名拷贝回来。 抓包看看这个流程具体干了啥 可以看到就是按照ftp协议来的,这里是list请求,板子回应了目录下的文件 另外在ftp库的代码调试中直接使用linux上的ftp命令更为便捷 常用命令 ``` ftp -d 192.xxxx  #-d调试模式,可以看到执行了哪些命令 进入到命令行通过help查看支持的命令 比如pwd put get等 ``` ### 5.3 踩坑记录: 可能是多次改固件,遇到了circuitpython目录变为只读,用flush_nuke.uf2全擦在写后再烧录才可以 ## 使用额外购买的开发板:MaixDuino ### 说明 和开发板一起选购了MaixDuino,一个k210的带摄像头的开发板,板载esp32可以联网,计划使用我们的主角w5500作为这个存储介质,实现**低功耗的定时拍照**,且可以**很方便的拔出tf卡拷贝拍照内容**的系统。 也是体现了服务器端和摄像头的分离工作。 MaixDuino使用的是MaixPyIDE,也是python的环境 IDE长这样: 右上方是实时显示的摄像头画面。 在这里编译,左下方的连接再运行即可将程序跑起来。 ### 具体实现 MaixDuino端: ```python # This file is part of MaixPY # Copyright (c) sipeed.com # # Licensed under the MIT license: #   http://www.opensource.org/licenses/mit-license.php # #network_wiznet5k() SSID = "hello_world" PASW = "qwertyuiop" addr = ("192.168.118.35", 50007) def enable_esp32():     from network_esp32 import wifi     if wifi.isconnected() == False:         for i in range(5):             try:                 # Running within 3 seconds of power-up can cause an SD load error                 # wifi.reset(is_hard=False)                 wifi.reset(is_hard=True)                 print('try AT connect wifi...')                 wifi.connect(SSID, PASW)                 if wifi.isconnected():                     break             except Exception as e:                 print(e)     print('network state:', wifi.isconnected(), wifi.ifconfig()) enable_esp32() def enable_espat():     from network_espat import wifi     if wifi.isconnected() == False:         for i in range(5):             try:                 # Running within 3 seconds of power-up can cause an SD load error                 # wifi.reset(is_hard=False)                 wifi.reset()                 print('try AT connect wifi...')                 wifi.connect(SSID, PASW)                 if wifi.isconnected():                     break             except Exception as e:                 print(e)     print('network state:', wifi.isconnected(), wifi.ifconfig()) #enable_espat() def network_wiznet5k():     from network_wiznet5k import lan     from machine import SPI     from Maix import GPIO     if lan.isconnected() == False:         WIZNET5K_SPI_SCK = 21         WIZNET5K_SPI_MOSI = 8         WIZNET5K_SPI_MISO = 15         WIZNET5K_SPI_CS = 20         spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000,                     polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO)         for i in range(5):             try:                 lan.reset(spi1, WIZNET5K_SPI_CS)                 print('try connect lan...')                 if lan.isconnected():                     break             except Exception as e:                 print(e)     print('network state:', lan.isconnected(), lan.ifconfig()) # network_wiznet5k() ########## server config ################ # Send image(jpeg) to server and display on server(PC), # server code refer to ../demo_recv_pic_server.py #WIFI_SSID   = "Sipeed_2.4G" #WIFI_PASSWD = "xxxxxxxx" #addr        = ("192.168.0.107", 3456) ################################## import socket, time, sensor, image #import lcd clock = time.clock() #lcd.init() sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time = 2000) while True:     # send pic     while True:         try:             sock = socket.socket()             print(sock)             sock.connect(addr)             break         except Exception as e:             print("connect error:", e)             sock.close()             continue     sock.settimeout(5)     send_len, count, err = 0, 0, 0     while True:         clock.tick()         if err >=10:             print("socket broken")             break         img = sensor.snapshot()         #lcd.display(img)         img = img.compress(quality=60)         img_bytes = img.to_bytes()         print("send len: ", len(img_bytes))         try:             block = int(len(img_bytes)/2048)             for i in range(block):                 send_len = sock.send(img_bytes[i*2048:(i+1)*2048])                 #time.sleep_ms(500)             send_len2 = sock.send(img_bytes[block*2048:])             #send_len = sock.send(img_bytes[0:2048])             #send_len = sock.send(img_bytes[2048:])             time.sleep_ms(500)             if send_len == 0:                 raise Exception("send fail")         except OSError as e:             if e.args[0] == 128:                 print("connection closed")                 break         except Exception as e:             print("send fail:", e)             time.sleep(1)             err += 1             continue         count += 1         print("send:", count)         print("fps:", clock.fps())         #time.sleep_ms(500)     print("close now")     sock.close() '''     ESP32_SPI firmware version: 1.4.0     try AT connect wifi...     network state: True ('192.168.0.180', '255.255.255.0', '192.168.0.1')     ping baidu.com: 40 ms     >     MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210     Type "help()" for more information.     >>> ''' ``` w5500端: ```python # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import os import busio import digitalio import board import storage import adafruit_sdcard import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket # The SD_CS pin is the chip select line. # #     The Adalogger Featherwing with ESP8266 Feather, the SD CS pin is on board.D15 #     The Adalogger Featherwing with Atmel M0 Feather, it's on board.D10 #     The Adafruit Feather M0 Adalogger use board.SD_CS #     For the breakout boards use any pin that is not taken by SPI SD_CS = board.GP13  # setup for M0 Adalogger; change as needed # Connect to the card and mount the filesystem. spi = busio.SPI(board.GP10, board.GP11, board.GP12) cs = digitalio.DigitalInOut(SD_CS) sdcard = adafruit_sdcard.SDCard(spi, cs) vfs = storage.VfsFat(sdcard) storage.mount(vfs, "/sd") # Use the filesystem as normal! Our files are under /sd # This helper function will print the contents of the SD def print_directory(path, tabs=0):     for file in os.listdir(path):         stats = os.stat(path + "/" + file)         filesize = stats[6]         isdir = stats[0] & 0x4000         if filesize < 1000:             sizestr = str(filesize) + " bytes"         elif filesize < 1000000:             sizestr = "%0.1f KB" % (filesize / 1000)         else:             sizestr = "%0.1f MB" % (filesize / 1000000)         prettyprintname = ""         for _ in range(tabs):             prettyprintname += "   "         prettyprintname += file         if isdir:             prettyprintname += "/"         print("{0:10}".format(prettyprintname, sizestr))         # recursively print directory contents         if isdir:             print_directory(path + "/" + file, tabs + 1) print("Files on filesystem:") print("====================") print_directory("/sd") SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k SimpleServer Test (DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID # MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) # MY_MAC = bytes(MY_MAC) # SUBNET_MASK = (255, 255, 255, 0) # GATEWAY_ADDRESS = (192,168,43,143) # DNS_SERVER = (8, 8, 8, 8) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # # Initialize ethernet interface without DHCP # eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=True) # # Set network configuration # eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) # Initialize ethernet interface eth = WIZNET5K(spi_bus, cs, is_dhcp=True) # Initialize a socket for our server socket.set_interface(eth) server = socket.socket()  # Allocate socket for the server server_ip = eth.pretty_ip(eth.ip_address)  # IP address of server server_port = 50007  # Port to listen on server.bind((server_ip, server_port))  # Bind to IP and Port server.listen()  # Begin listening for incoming clients while True:     print(f"Accepting connections on {server_ip}:{server_port}")     conn, addr = server.accept()  # Wait for a connection from a client.     print(f"Connection accepted from {addr}")     conn.settimeout(1)     with conn:         conn_end = False         pack_size = 1024*5         while True:             if conn_end:                 break             tmp = b''             img = b''             while True:                 client_data = conn.recv(1)                 if tmp == b'\xFF' and client_data == b'\xD8':                     img = b'\xFF\xD8'                     break                 tmp = client_data             while True:                 client_data = conn.recv(4096)                 if not client_data:                     break                 print("received data,len:",len(client_data) )                 img += client_data                 if img[-2:] == b'\xFF\xD9':                     break                 if len(client_data) > pack_size:                     break             print("recive end, pic len:", len(img))             if not img.startswith(b'\xFF\xD8') or not img.endswith(b'\xFF\xD9'):                 print("image error")                 continue             ltime = time.localtime()             file_name = str(ltime.tm_hour) + "_" + str(ltime.tm_hour) + "_" + str(ltime.tm_sec)             f = open("/sd/" + file_name + ".jpg", "wb")             f.write(img)             f.close()         conn.close()         print("receive thread end")     print("Connection closed") ``` w5500端的打印: 建立连接后保存许多图片 maixduino端的打印 获取当前帧率并发送 ## 心得体会 本次项目还挺难的啊,踩到了好多坑,python带来便捷的开发的同时也有很多代码上的风险,包括Ftp任务,参考了许多别人micopython的代码但在linux中连接就出错,后用的circuitpython改了他人的ftp服务。且对网络协议很陌生,概念也很不清晰,以后一定要查漏补缺才行。 ## 代码上传: https://download.eeworld.com.cn/detail/Henry-0755/631395

  • 上传了资料: FollowMe第四期代码

  • 2024-02-18
  • 加入了学习《直播回放: FollowMe 4 W5500-EVB-Pico 使用入门》,观看 W5500-EVB-Pico 使用入门

  • 回复了主题帖: 【得捷电子Follow me第4期】成果展示汇总帖

    写得好棒,排版也很整齐,学习了

  • 2024-02-14
  • 发表了主题帖: 【补 DigiKey“智造万物,快乐不停”创意大赛】3.usb_otg_hs虚拟串口的调试 基于ST...

    # 【补 DigiKey“智造万物,快乐不停”创意大赛】3.usb_otg_hs虚拟串口的调试 基于STM32H7B3I-DK 测试下otg_device功能并且使用otg功能作为打印终端也就是 USB CDC类(Communication Device Class)实现的虚拟串口 【Virtual Port Com】 还需要明确的是板子上是一个USB3320C-EZK芯片(高度集成全高速usb2.0),是需要使用MCO clock给时钟信号的,根据user manual: ` By default, the 24MHz clock of the camera and USB PHY is provided by the MCO1 clock signal.` 具体设置如下: 另外就是开启USB_OTG_HS功能就可以了 在生成的代码中添加测试的打印代码: ``` void StartDefaultTask(void *argument) {   /* init code for USB_DEVICE */   MX_USB_DEVICE_Init();   /* USER CODE BEGIN 5 */   /* Infinite loop */   for(;;)   {     osDelay(100);   }   /* USER CODE END 5 */ } ``` 查看设备管理器的com口和波特率 使用Putty连接对应的com口便能看到打印啦,之后就可以用这个作为串口打印了。 **踩坑** 在配置了touchgfx的情况下,配置usb后,usb可以正常工作,但屏幕不显示了。 原因: 生成代码默认会将usb的init放在`defaultTask`中,而它的栈空间开的比较小128*4,实际上会超出这个大小,导致后面的gui_task不正常 ``` const osThreadAttr_t defaultTask_attributes = {   .name = "defaultTask",   .stack_size = 128 * 4,   .priority = (osPriority_t) osPriorityNormal, }; ``` 修改为1024*4即全都正常。

  • 2024-02-10
  • 发表了主题帖: 【补 DigiKey“智造万物,快乐不停”创意大赛】2.基本gui设计 基于STM32H7B3I-DK

    # **【补 DigiKey“智造万物,快乐不停”创意大赛】**2.基本gui设计 基于STM32H7B3I-DK 论坛的各位新年好呀~之前的创意大赛未完成,过年来补一补: 本章是项目ui的设计部分: 使用的版本 Touchgfx 4.22.1 cubemx6.9.2 frameware cubeide 通过TouchGFX可以生成指定预先设定好的板级配置,选择stm32h7b3i-dk后即可生成带有cubeMX cubeIDE的项目。 这个板子也有许多demo可以参考,路径在: `Repository\XXXX_FW_XXXX\Projects\XXXXX\Demonstrations` 但这块板子的demo都没有适配stm32cubeMX6.10版本,如果通过cube mx的examples生成项目进行编译会报错,需要自己修改,但这些历程很有参考价值,比如将其中自定义的ui组件导出(对Containers中的组件右键导出),在自己的项目中引用,如想使用例程menulauncher的自定义选择组件(外层是个横向的scroller view,内层是选择的图片按键,选择中会给icon highlight) :exclamation: 在导出的过程中如果重复导入同一个widget哪怕在touchgfx中删除这个widget,(包含图片资源以及code)会无法导入,需要手动删除这些图片代码才可以。这应该算个bug 参照官方教程 `https://support.touchgfx.com/zh-CN/docs/tutorials/tutorial-04` 完成效果: ' 添加Menu的监听事件进入到对应的功能 本人没学过c++所以用起来touchgfx有点困难,以未学过的角度看一下如何实现按下中心的icon跳转到对应的界面: 首先是Touchgfx中的这个scrollwheel勾选Use Selected Style Template并在代码中实现UpdateCenterItem实现放大中心选中的icon的效果,其中scrollwheel的Item是自定义的一个image+btn,btn可以添加Interactions,实现按下的时候进行回调,调用虚拟函数来实现跳转: ```c++ //optionButtonSelected.hpp +    virtual void btnClicked(); //optionButtonSelected.cpp +void optionButtonSelected::btnClicked() +{ +    //TODO跳转 +} ```

  • 2024-01-18
  • 回复了主题帖: 领取审核名单(第五批): 辞旧,年底清仓,100+板卡来袭,有缘来领

    个人信息无误,已知晓需自己支付邮费

  • 2024-01-10
  • 回复了主题帖: 辞旧:年底清仓,100+板卡来袭,有缘来领

    申请板子:26 STM32F103V R1.1 申请理由:简单验证i2c oled以及矩阵按键,另外想用来尝试usb功能

  • 2023-12-07
  • 加入了学习《【得捷电子Follow me第2期】项目总结》,观看 【得捷电子Follow me第2期】项目总结

  • 2023-11-17
  • 回复了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】1.方案以及官方工具体验

    lugl4313820 发表于 2023-11-6 07:11 可以详细介绍一下这个开源的库与电机的购买吗,我也想学习一下电机的控制。谢谢了! simplefoc吗 有个网站的可以看看 电机买的是2804云台电机无限位的

最近访客

< 1/2 >

统计信息

已有19人来访过

  • 芯积分:147
  • 好友:--
  • 主题:9
  • 回复:9

留言

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


现在还没有留言