Power off camera after boot and before deepsleep to conserve power

This commit is contained in:
Thomas Farstrike
2025-06-24 10:39:20 +02:00
parent 11590c2167
commit f9ee7a91cd
4 changed files with 51 additions and 5 deletions
+5
View File
@@ -1,3 +1,8 @@
0.0.8
=====
- Move wifi icon to the right-hand side
- Power off camera after boot and before deepsleep to conserve power
0.0.7
=====
- Update battery icon every 5 seconds depending on VBAT/BAT_ADC
@@ -138,6 +138,20 @@ class CameraApp(Activity):
webcam.deinit(self.cam)
elif self.cam:
self.cam.deinit()
# Power off, otherwise it keeps using a lot of current
try:
from machine import Pin, I2C
i2c = I2C(1, scl=Pin(16), sda=Pin(21)) # Adjust pins and frequency
#devices = i2c.scan()
#print([hex(addr) for addr in devices]) # finds it on 60 = 0x3C after init
camera_addr = 0x3C # for OV5640
reg_addr = 0x3008
reg_high = (reg_addr >> 8) & 0xFF # 0x30
reg_low = reg_addr & 0xFF # 0x08
power_off_command = 0x42 # Power off command
i2c.writeto(camera_addr, bytes([reg_high, reg_low, power_off_command]))
except Exception as e:
print(f"Warning: powering off camera got exception: {e}")
print("camera app cleanup done.")
def set_image_size(self):
+24
View File
@@ -71,4 +71,28 @@ sdlkeyboard.set_paste_text_callback(mpos.clipboard.paste_text)
# print(f"boot_unix: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()}
#keyboard.add_event_cb(keyboard_cb, lv.EVENT.ALL, None)
# On the Waveshare ESP32-S3-Touch-LCD-2, the camera is hard-wired to power on,
# so it needs a software power off to prevent it from staying hot all the time and quickly draining the battery.
# 1) Initialize camera, otherwise it doesn't reply to I2C commands:
try:
from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling
cam = Camera(data_pins=[12,13,15,11,14,10,7,2],vsync_pin=6,href_pin=4,sda_pin=21,scl_pin=16,pclk_pin=9,xclk_pin=8,xclk_freq=20000000,powerdown_pin=-1,reset_pin=-1,pixel_format=PixelFormat.RGB565,frame_size=FrameSize.R240X240,grab_mode=GrabMode.LATEST)
cam.deinit()
except Exception as e:
print(f"camera init for power off got exception: {e}")
# 2) Soft-power off camera, otherwise it uses a lot of current for nothing:
try:
from machine import Pin, I2C
i2c = I2C(1, scl=Pin(16), sda=Pin(21)) # Adjust pins and frequency
#devices = i2c.scan()
#print([hex(addr) for addr in devices]) # finds it on 60 = 0x3C after init
camera_addr = 0x3C # for OV5640
reg_addr = 0x3008
reg_high = (reg_addr >> 8) & 0xFF # 0x30
reg_low = reg_addr & 0xFF # 0x08
power_off_command = 0x42 # Power off command
i2c.writeto(camera_addr, bytes([reg_high, reg_low, power_off_command]))
except Exception as e:
print(f"Warning: powering off camera got exception: {e}")
print("boot_unix.py finished")
+8 -5
View File
@@ -382,6 +382,7 @@ def create_drawer(display=None):
poweroff_label.center()
def poweroff_cb(e):
print("Power off action...")
remove_and_stop_current_activity() # make sure current app, like camera, does cleanup, saves progress, stops hardware etc.
import sys
if sys.platform == "esp32":
#On ESP32, there's no power off but there is a forever sleep
@@ -548,6 +549,12 @@ def setContentView(new_activity, new_screen):
end_time = utime.ticks_diff(utime.ticks_ms(), start_time)
print(f"ui.py setContentView: new_activity.onResume took {end_time}ms")
def remove_and_stop_current_activity():
current_activity, current_screen = screen_stack.pop() # Remove current screen
if current_activity:
current_activity.onPause(current_screen)
current_activity.onStop(current_screen)
current_activity.onDestroy(current_screen)
def back_screen():
print("back_screen() running")
@@ -556,11 +563,7 @@ def back_screen():
print("Warning: can't go back because screen_stack is empty.")
return False # No previous screen
#close_top_layer_msgboxes() # would be nicer to "cancel" all input events
current_activity, current_screen = screen_stack.pop() # Remove current screen
if current_activity:
current_activity.onPause(current_screen)
current_activity.onStop(current_screen)
current_activity.onDestroy(current_screen)
remove_and_stop_current_activity()
prev_activity, prev_screen = screen_stack[-1] # load previous screen
print("loading prev_screen with animation")
lv.screen_load_anim(prev_screen, lv.SCR_LOAD_ANIM.OVER_RIGHT, 500, 0, True) # True means delete the old screen, which is fine as we're going back and current_activity.onDestroy() was called