Skip to content

Commit f9ee7a9

Browse files
Power off camera after boot and before deepsleep to conserve power
1 parent 11590c2 commit f9ee7a9

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
0.0.8
2+
=====
3+
- Move wifi icon to the right-hand side
4+
- Power off camera after boot and before deepsleep to conserve power
5+
16
0.0.7
27
=====
38
- Update battery icon every 5 seconds depending on VBAT/BAT_ADC

internal_filesystem/apps/com.micropythonos.camera/assets/camera_app.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,20 @@ def onStop(self, screen):
138138
webcam.deinit(self.cam)
139139
elif self.cam:
140140
self.cam.deinit()
141+
# Power off, otherwise it keeps using a lot of current
142+
try:
143+
from machine import Pin, I2C
144+
i2c = I2C(1, scl=Pin(16), sda=Pin(21)) # Adjust pins and frequency
145+
#devices = i2c.scan()
146+
#print([hex(addr) for addr in devices]) # finds it on 60 = 0x3C after init
147+
camera_addr = 0x3C # for OV5640
148+
reg_addr = 0x3008
149+
reg_high = (reg_addr >> 8) & 0xFF # 0x30
150+
reg_low = reg_addr & 0xFF # 0x08
151+
power_off_command = 0x42 # Power off command
152+
i2c.writeto(camera_addr, bytes([reg_high, reg_low, power_off_command]))
153+
except Exception as e:
154+
print(f"Warning: powering off camera got exception: {e}")
141155
print("camera app cleanup done.")
142156

143157
def set_image_size(self):

internal_filesystem/boot_unix.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,28 @@ def catch_escape_key(indev, indev_data):
7171
# print(f"boot_unix: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()}
7272
#keyboard.add_event_cb(keyboard_cb, lv.EVENT.ALL, None)
7373

74+
# On the Waveshare ESP32-S3-Touch-LCD-2, the camera is hard-wired to power on,
75+
# so it needs a software power off to prevent it from staying hot all the time and quickly draining the battery.
76+
# 1) Initialize camera, otherwise it doesn't reply to I2C commands:
77+
try:
78+
from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling
79+
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)
80+
cam.deinit()
81+
except Exception as e:
82+
print(f"camera init for power off got exception: {e}")
83+
# 2) Soft-power off camera, otherwise it uses a lot of current for nothing:
84+
try:
85+
from machine import Pin, I2C
86+
i2c = I2C(1, scl=Pin(16), sda=Pin(21)) # Adjust pins and frequency
87+
#devices = i2c.scan()
88+
#print([hex(addr) for addr in devices]) # finds it on 60 = 0x3C after init
89+
camera_addr = 0x3C # for OV5640
90+
reg_addr = 0x3008
91+
reg_high = (reg_addr >> 8) & 0xFF # 0x30
92+
reg_low = reg_addr & 0xFF # 0x08
93+
power_off_command = 0x42 # Power off command
94+
i2c.writeto(camera_addr, bytes([reg_high, reg_low, power_off_command]))
95+
except Exception as e:
96+
print(f"Warning: powering off camera got exception: {e}")
97+
7498
print("boot_unix.py finished")

internal_filesystem/lib/mpos/ui/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ def reset_cb(e):
382382
poweroff_label.center()
383383
def poweroff_cb(e):
384384
print("Power off action...")
385+
remove_and_stop_current_activity() # make sure current app, like camera, does cleanup, saves progress, stops hardware etc.
385386
import sys
386387
if sys.platform == "esp32":
387388
#On ESP32, there's no power off but there is a forever sleep
@@ -548,6 +549,12 @@ def setContentView(new_activity, new_screen):
548549
end_time = utime.ticks_diff(utime.ticks_ms(), start_time)
549550
print(f"ui.py setContentView: new_activity.onResume took {end_time}ms")
550551

552+
def remove_and_stop_current_activity():
553+
current_activity, current_screen = screen_stack.pop() # Remove current screen
554+
if current_activity:
555+
current_activity.onPause(current_screen)
556+
current_activity.onStop(current_screen)
557+
current_activity.onDestroy(current_screen)
551558

552559
def back_screen():
553560
print("back_screen() running")
@@ -556,11 +563,7 @@ def back_screen():
556563
print("Warning: can't go back because screen_stack is empty.")
557564
return False # No previous screen
558565
#close_top_layer_msgboxes() # would be nicer to "cancel" all input events
559-
current_activity, current_screen = screen_stack.pop() # Remove current screen
560-
if current_activity:
561-
current_activity.onPause(current_screen)
562-
current_activity.onStop(current_screen)
563-
current_activity.onDestroy(current_screen)
566+
remove_and_stop_current_activity()
564567
prev_activity, prev_screen = screen_stack[-1] # load previous screen
565568
print("loading prev_screen with animation")
566569
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

0 commit comments

Comments
 (0)