Skip to content

Instantly share code, notes, and snippets.

@skittleson
Last active September 23, 2025 21:36
Show Gist options
  • Select an option

  • Save skittleson/e869a039a01b66fb8add218053b663ef to your computer and use it in GitHub Desktop.

Select an option

Save skittleson/e869a039a01b66fb8add218053b663ef to your computer and use it in GitHub Desktop.
esp32s3 xiao sense OV5640 cam
import network
import urequests
import utime as time
from camera import Camera, GrabMode, PixelFormat, FrameSize
from machine import Pin, RTC, unique_id, deepsleep, sleep
import machine
import ubinascii
import sys
import time
import gc
# ================================
# Configuration
# ================================
WIFI_SSID = "redacted"
WIFI_PASSWORD = "redacted"
SERVER_URL = "http://redacted"
MAX_WIFI_RETRIES = 10
WIFI_RETRY_DELAY = 5 # seconds
# ================================
# Utility Functions
# ================================
def log(msg, level="INFO"):
"""Basic structured logger with timestamp."""
ts = time.localtime()
timestamp = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(*ts[:6])
print("[{}] [{}] {}".format(timestamp, level, msg))
def safe_deinit(cam):
"""Ensure camera is safely deinitialized."""
try:
cam.deinit()
gc.collect()
log("Camera deinitialized.")
except Exception as e:
log("Camera deinit failed: {}".format(e), "WARN")
def get_device_info():
"""Collect useful ESP32 device/system information."""
device_id = ubinascii.hexlify(unique_id()).decode()
mac = ubinascii.hexlify(network.WLAN().config('mac')).decode()
info = {
"device_id": device_id,
"mac_address": mac,
"cpu_freq_mhz": machine.freq() // 1_000_000,
"free_heap": gc.mem_free(),
"reset_cause": machine.reset_cause(),
"uptime_sec": time.ticks_ms() // 1000,
}
# ESP32 hall sensor (not always accurate, only works if not using WiFi/BT at the same time)
try:
info["hall_sensor"] = esp32.hall_sensor()
except Exception:
info["hall_sensor"] = "N/A"
# ESP32 temperature sensor (raw value, in °C)
try:
info["temperature_c"] = esp32.raw_temperature()
except Exception:
info["temperature_c"] = "N/A"
# Firmware version
try:
info["firmware"] = os.uname().release
except Exception:
info["firmware"] = "N/A"
return info
# ================================
# Networking
# ================================
def wifi_connect():
"""Connect to Wi-Fi with retries and logging."""
station = network.WLAN(network.STA_IF)
station.active(True)
if station.isconnected():
log("Already connected. IP: {}".format(station.ifconfig()[0]))
return station
retries = 0
while not station.isconnected() and retries < MAX_WIFI_RETRIES:
log("Connecting to Wi-Fi (attempt {}/{})...".format(retries+1, MAX_WIFI_RETRIES))
try:
station.connect(WIFI_SSID, WIFI_PASSWORD)
except Exception as e:
log("Wi-Fi connect error: {}".format(e), "ERROR")
time.sleep(WIFI_RETRY_DELAY)
retries += 1
if station.isconnected():
log("Connected to Wi-Fi. IP: {}".format(station.ifconfig()[0]))
return station
else:
log("Failed to connect to Wi-Fi after {} attempts.".format(MAX_WIFI_RETRIES), "ERROR")
sys.exit(1)
# ================================
# Camera Capture
# ================================
def capture_image():
"""Capture a JPEG image from the camera safely."""
cam = Camera()
try:
cam.init()
cam.reconfigure(
pixel_format=PixelFormat.JPEG,
frame_size=FrameSize.QSXGA,
grab_mode=GrabMode.LATEST,
fb_count=2
)
log("Camera configured for JPEG/QSXGA.")
img = cam.capture()
log("Image captured. Size: {} bytes".format(len(img)))
return img
except Exception as e:
log("Camera capture failed: {}".format(e), "ERROR")
return None
finally:
safe_deinit(cam)
# ================================
# Send Image
# ================================
def send_image(img):
"""Send captured image to server with detailed headers."""
if img is None:
log("No image to send.", "WARN")
return
device_id = ubinascii.hexlify(unique_id()).decode()
ts = time.localtime()
timestamp = "{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}".format(*ts[:6])
device_info = get_device_info()
headers = {
"Title": "ESP32 Camera Snapshot",
"Message": "ESP32 Snapshot | Temp: {}°C".format(
device_info["temperature_c"]),
"Tags": "camera,esp32,snapshot",
"X-Filename": "pic.jpg",
"X-Timestamp": timestamp,
"X-Device-ID": device_info["device_id"],
"X-MAC": device_info["mac_address"],
"X-CPU-MHz": str(device_info["cpu_freq_mhz"]),
"X-Free-Heap": str(device_info["free_heap"]),
"X-Reset-Cause": str(device_info["reset_cause"]),
"X-Uptime-Sec": str(device_info["uptime_sec"]),
"X-Hall-Sensor": str(device_info["hall_sensor"]),
"X-Temperature-C": str(device_info["temperature_c"]),
"X-Firmware": str(device_info["firmware"]),
"Content-Type": "image/jpeg",
"Content-Length": str(len(img)),
}
try:
log("Sending image to {}".format(SERVER_URL))
resp = urequests.post(SERVER_URL, data=img, headers=headers)
log("Server response: {} - {}".format(resp.status_code, resp.text))
resp.close()
except Exception as e:
log("Failed to send image: {}".format(e), "ERROR")
# ================================
# Main Execution
# ================================
def main():
wifi_connect()
img = capture_image()
send_image(img)
time.sleep(2)
log("Task completed. Entering sleeping for 4 seconds...")
deepsleep(10_000) # 10 seconds
#deepsleep(60_000) # sleep for 60,000 ms = 60 seconds
if __name__ == "__main__":
while True:
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment