From 0376fef535996c43fb46a85fc4d3ab010ef4c98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 9 Sep 2023 18:58:13 +0800 Subject: [PATCH 1/5] upload AXP313A.py for CircuitPython --- CircuitPython/AXP313A.py | 138 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 CircuitPython/AXP313A.py diff --git a/CircuitPython/AXP313A.py b/CircuitPython/AXP313A.py new file mode 100644 index 0000000..5b3812a --- /dev/null +++ b/CircuitPython/AXP313A.py @@ -0,0 +1,138 @@ +import board +import time + +eOV2640 = 0 +e0V7725 = 1 +eTime6s = 0 +eTime10s = 1 + +class AXP313A: + ''' + @fn __init__ + @brief 初始化AXP313A + @param i2c i2c设备 + ''' + def __init__(self, i2c): + self.i2c = i2c + + def begin(self): + ''' + @fn begin + @brief 初始化传感器 + @return 返回初始化状态 + ''' + while not self.i2c.try_lock(): + pass + try: + scan = self.i2c.scan() + print("scan: ", scan) + finally: + self.i2c.unlock() + + for i in scan: + if(i == 0x36): + return True + return False + + def enable_camera_power(self,camera): + ''' + @fn enableCameraPower + @brief 使能摄像头电源 + @param camera 摄像头选择 + ''' + if camera == 0: + self.set_camera_power(1.2,2.8) + else: + self.set_camera_power(1.8,3.3) + + + def set_camera_power(self,DVDD,AVDDorDOVDD): + ''' + @fn enablePower + @brief 设置电压输出 + @param DVDD DVDD电压设置,默认电压为1.5V + @param AVDDandDOVDD AVDD和DOVDD电压设置,默认电压为2.8V + ''' + state = 0x19 + ALDOData = 0 + DLDOData = 0 + if(DVDD < 0.5) or (AVDDorDOVDD < 0.5): + ALDOData = 0 + DLDOData = 0 + elif(DVDD > 3.5) or (AVDDorDOVDD > 3.5): + ALDOData = 31 + DLDOData = 31 + else: + ALDOData = (DVDD-0.5) * 10 + DLDOData = (AVDDorDOVDD-0.5) *10 + self.WriteByte(0x10, state) + time.sleep(0.01) + self.WriteByte(0x16, int(ALDOData)) + time.sleep(0.01) + self.WriteByte(0x17, int(DLDOData)) + time.sleep(0.01) + + def set_shutdown_key_level_time(self,offLevelTime): + ''' + @fn setShutdownKeyLevelTime + @brief 设置关机按键电平时间 + @param offLevelTime 关机按键电平时间 + ''' + data = offLevelTime << 1 + self.WriteByte(0x1E, data) + time.sleep(0.01) + + def disable_power(self): + ''' + @fn disablePower + @brief 关闭摄像头电源 + ''' + data = 0x01; + self.WriteByte(0x10, data) + time.sleep(0.01) + + def WriteByte(self, reg, data): + buf = bytearray(1) + buf[0] = reg + buf.extend(bytearray([data])) + while not self.i2c.try_lock(): + pass + try: + self.i2c.writeto(0x36, buf) + finally: + self.i2c.unlock() + +if __name__ == "__main__": + import busio + + delay = lambda n: time.sleep(n/1000) + + print("i2c init") + i2c = busio.I2C(scl=board.GPIO2, sda=board.GPIO1) + while not i2c.try_lock(): + print("try lock"); + delay(1000) + i2c.unlock() + + delay(1000) + print("AXP313A init") + axp = AXP313A(i2c) + + delay(1000) + print("AXP313A begin") + while not axp.begin(): + print("init error"); + delay(1000) + + delay(1000) + print("AXP313A enable_camera_power") + axp.enable_camera_power(eOV2640) # 设置摄像头供电 power on + + delay(3000) + + print("AXP313A disable_power") + axp.disable_power() # 设置摄像头断电 power off + + print("i2c deinit") + i2c.deinit() + From 6a4f5ac194f44b340e131b150970a413d293ceb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 9 Sep 2023 19:06:48 +0800 Subject: [PATCH 2/5] upload camera demo --- ...fireBeetle_2_board_esp32_s3_camera_demo.py | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py diff --git a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py new file mode 100644 index 0000000..eb5ecc6 --- /dev/null +++ b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py @@ -0,0 +1,120 @@ +''' +DFRobot FireBeetle_2_Board_ESP32_S3 摄像头演示程序 + +参考: + https://learn.adafruit.com/adafruit-ov5640-camera-breakout/jpeg-capture-demo + https://wiki.dfrobot.com.cn/_SKU_DFR0975_FireBeetle_2_Board_ESP32_S3_Advanced_Tutorial#target_12 + +''' + +import board +import busio +import time +import espcamera +import AXP313A + +''' +PWDN_GPIO_NUM = -1 +RESET_GPIO_NUM = -1 +XCLK_GPIO_NUM = 45 +SIOD_GPIO_NUM = 1 +SIOC_GPIO_NUM = 2 + +Y9_GPIO_NUM = 48 +Y8_GPIO_NUM = 46 +Y7_GPIO_NUM = 8 +Y6_GPIO_NUM = 7 +Y5_GPIO_NUM = 4 +Y4_GPIO_NUM = 41 +Y3_GPIO_NUM = 40 +Y2_GPIO_NUM = 39 +VSYNC_GPIO_NUM = 6 +HREF_GPIO_NUM = 42 +PCLK_GPIO_NUM = 5 +''' + +# 数据引脚定义 data pins +CAMERA_DATA = ( + board.GPIO39, + board.GPIO40, + board.GPIO41, + board.GPIO4, + board.GPIO7, + board.GPIO8, + board.GPIO46, + board.GPIO48 +) + +# 控制引脚定义 controll pins +CAMERA_PCLK=board.GPIO5 +CAMERA_VSYNC=board.GPIO6 +CAMERA_HREF=board.GPIO42 +CAMERA_XCLK=board.GPIO45 + +# 延时函数定义 delay function +delay = lambda n: time.sleep(n/1000) + +print("i2c init") +i2c = busio.I2C(scl=board.GPIO2, sda=board.GPIO1) +while not i2c.try_lock(): + print("try lock"); + delay(1000) +i2c.unlock() + +delay(1000) +print("AXP313A init") +axp = AXP313A.AXP313A(i2c) + +delay(1000) +print("AXP313A begin") +while not axp.begin(): + print("init error"); + delay(1000) + +delay(1000) +print("AXP313A enable_camera_power") +axp.enable_camera_power(AXP313A.eOV2640) # 设置摄像头供电 power on + +delay(1000) + +print("Initializing camera") +cam = espcamera.Camera( + data_pins=CAMERA_DATA, + external_clock_pin=CAMERA_XCLK, + pixel_clock_pin=CAMERA_PCLK, + vsync_pin=CAMERA_VSYNC, + href_pin=CAMERA_HREF, + pixel_format=espcamera.PixelFormat.RGB565, + frame_size=espcamera.FrameSize.QVGA, + i2c=i2c, + external_clock_frequency=20_000_000, + framebuffer_count=1) +print("initialized") + +print("reconfigure") +# for display +#cam.reconfigure( +# pixel_format=espcamera.PixelFormat.RGB565, +# frame_size=espcamera.FrameSize.QVGA, +#) +#frame = cam.take(1) + +# for jpeg +cam.reconfigure( + pixel_format=espcamera.PixelFormat.JPEG, + frame_size=espcamera.FrameSize.SVGA, +) + +print("capture") +jpeg = cam.take(1) + +print("write") +filename = f"/test_001.jpg" +with open(filename, "wb") as f: + f.write(jpeg) + +print("AXP313A disable_power") +axp.disable_power() # 设置摄像头断电 power off + +print("i2c deinit") +i2c.deinit() \ No newline at end of file From 0a406c4afb36dc946b3f60805b7f660be2d7e96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 9 Sep 2023 19:09:10 +0800 Subject: [PATCH 3/5] add note for camera demo --- .../dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py index eb5ecc6..b1b9e18 100644 --- a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py +++ b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py @@ -5,6 +5,9 @@ https://learn.adafruit.com/adafruit-ov5640-camera-breakout/jpeg-capture-demo https://wiki.dfrobot.com.cn/_SKU_DFR0975_FireBeetle_2_Board_ESP32_S3_Advanced_Tutorial#target_12 +说明: + 直接存储从摄像头获取的图片到板载FLash时,应参考如下文章,设置CircuitPython可写内置存储: + https://learn.adafruit.com/circuitpython-essentials/circuitpython-storage ''' import board From 5ed02f4312e5ccf8b1df4c06f815a3dbdcda2e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 9 Sep 2023 23:11:18 +0800 Subject: [PATCH 4/5] add boot.py, settings.toml for camera demo --- CircuitPython/boot.py | 9 +++++++++ .../dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py | 8 ++++---- CircuitPython/settings.toml | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 CircuitPython/boot.py create mode 100644 CircuitPython/settings.toml diff --git a/CircuitPython/boot.py b/CircuitPython/boot.py new file mode 100644 index 0000000..959214e --- /dev/null +++ b/CircuitPython/boot.py @@ -0,0 +1,9 @@ +''' +说明: +1. 修改后,使得CircuitPython可以写入到内置存储,但将不能在电脑上直接进入U盘修改文件。 +2. 在编辑器中,修改Flase为True,或者直接注释掉上面的行,就恢复原样。 +3. 修改后,需要断电重启一次生效 +''' + +import storage +storage.remount("/", False) diff --git a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py index b1b9e18..a8ea244 100644 --- a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py +++ b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py @@ -1,12 +1,12 @@ ''' DFRobot FireBeetle_2_Board_ESP32_S3 摄像头演示程序 -参考: +使用指导:请务必参考以下网址的使用指导,否则可能会出现各种问题 + https://mc.dfrobot.com.cn/thread-316903-1-1.html + +参考资料: https://learn.adafruit.com/adafruit-ov5640-camera-breakout/jpeg-capture-demo https://wiki.dfrobot.com.cn/_SKU_DFR0975_FireBeetle_2_Board_ESP32_S3_Advanced_Tutorial#target_12 - -说明: - 直接存储从摄像头获取的图片到板载FLash时,应参考如下文章,设置CircuitPython可写内置存储: https://learn.adafruit.com/circuitpython-essentials/circuitpython-storage ''' diff --git a/CircuitPython/settings.toml b/CircuitPython/settings.toml new file mode 100644 index 0000000..5ccf993 --- /dev/null +++ b/CircuitPython/settings.toml @@ -0,0 +1,2 @@ +# 给相机处理预留内存 +CIRCUITPY_RESERVED_PSRAM=1048576 From 7134005eb984c164907b7f75d2632d913d4f4429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sun, 10 Sep 2023 09:57:45 +0800 Subject: [PATCH 5/5] add check reserved psram in demo --- .../dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py index a8ea244..746be74 100644 --- a/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py +++ b/CircuitPython/dfrobot_fireBeetle_2_board_esp32_s3_camera_demo.py @@ -13,6 +13,7 @@ import board import busio import time +import espidf import espcamera import AXP313A @@ -57,6 +58,13 @@ # 延时函数定义 delay function delay = lambda n: time.sleep(n/1000) +print("check reserved psram") +reserved_psram = espidf.get_reserved_psram() +if reserved_psram<1048576: + print("Please config settings.toml: CIRCUITPY_RESERVED_PSRAM=1048576") + print(" and then reset the board") + raise Exception("MemoryError:") + print("i2c init") i2c = busio.I2C(scl=board.GPIO2, sda=board.GPIO1) while not i2c.try_lock():