767 lines
20 KiB
Markdown
767 lines
20 KiB
Markdown
---
|
|
name: badger-diagnostics
|
|
description: System diagnostics, verification, and troubleshooting for Badger 2350. Use when checking firmware version, verifying installations, diagnosing hardware issues, troubleshooting errors, or performing system health checks on Badger 2350.
|
|
---
|
|
|
|
# Badger 2350 Diagnostics and Troubleshooting
|
|
|
|
Comprehensive diagnostics and troubleshooting tools for verifying your Badger 2350 setup, checking installations, and resolving common issues.
|
|
|
|
## ⚠️ When to Use This Skill
|
|
|
|
**Use this skill FIRST** in these situations:
|
|
1. **Starting a new session** - Verify everything works before coding
|
|
2. **After setup** - Confirm installation completed correctly
|
|
3. **Before debugging** - Rule out environment issues
|
|
4. **When errors occur** - Diagnose the root cause
|
|
5. **After firmware updates** - Verify everything still works
|
|
|
|
**Best Practice**: Run diagnostics at the start of EVERY development session. It takes 30 seconds and prevents hours of debugging.
|
|
|
|
## Quick Verification Command
|
|
|
|
**Run this FIRST every session** (doesn't require any files to exist):
|
|
|
|
### Level 1: Basic Connection Test
|
|
```bash
|
|
# Simplest test - just verify badge responds
|
|
mpremote exec "print('Badge connected!')"
|
|
# Should print: Badge connected!
|
|
|
|
# If this fails, badge isn't connected or mpremote not installed
|
|
```
|
|
|
|
### Level 2: Full Verification
|
|
```bash
|
|
# Complete verification (auto-detects port on macOS/Linux)
|
|
mpremote exec "import sys, gc; from badgeware import screen, brushes, shapes, io; print('=== VERIFICATION ==='); print('✓ MicroPython:', sys.version[:30]); print('✓ Memory:', gc.mem_free(), 'bytes'); print('✓ badgeware: loaded'); print('✓ Display: 160x120'); print('=== ALL OK ===')"
|
|
```
|
|
|
|
**Expected output**: All checks with ✓ marks and no errors.
|
|
|
|
**With explicit port** (if auto-detect fails):
|
|
```bash
|
|
mpremote connect /dev/cu.usbmodem1101 exec "from badgeware import screen; print('✓ Badge OK')"
|
|
# Replace /dev/cu.usbmodem1101 with your port
|
|
```
|
|
|
|
**If this fails**: Continue with detailed diagnostics below.
|
|
|
|
## Quick System Check
|
|
|
|
Run this complete system diagnostic in REPL:
|
|
|
|
```python
|
|
# diagnostic.py - Complete system check
|
|
import sys
|
|
import gc
|
|
import os
|
|
from machine import freq, unique_id
|
|
import ubinascii
|
|
|
|
def system_info():
|
|
"""Display complete system information"""
|
|
print("=" * 50)
|
|
print("BADGER 2350 SYSTEM DIAGNOSTICS")
|
|
print("=" * 50)
|
|
|
|
# MicroPython version
|
|
print(f"\n[MicroPython]")
|
|
print(f" Version: {sys.version}")
|
|
print(f" Implementation: {sys.implementation}")
|
|
print(f" Platform: {sys.platform}")
|
|
|
|
# Hardware info
|
|
print(f"\n[Hardware]")
|
|
print(f" CPU Frequency: {freq():,} Hz ({freq() / 1_000_000:.0f} MHz)")
|
|
uid = ubinascii.hexlify(unique_id()).decode()
|
|
print(f" Unique ID: {uid}")
|
|
|
|
# Memory
|
|
gc.collect()
|
|
print(f"\n[Memory]")
|
|
print(f" Free: {gc.mem_free():,} bytes ({gc.mem_free() / 1024:.1f} KB)")
|
|
print(f" Allocated: {gc.mem_alloc():,} bytes ({gc.mem_alloc() / 1024:.1f} KB)")
|
|
total = gc.mem_free() + gc.mem_alloc()
|
|
print(f" Total: {total:,} bytes ({total / 1024:.1f} KB)")
|
|
|
|
# File system
|
|
print(f"\n[File System]")
|
|
try:
|
|
stat = os.statvfs('/')
|
|
block_size = stat[0]
|
|
total_blocks = stat[2]
|
|
free_blocks = stat[3]
|
|
total_bytes = block_size * total_blocks
|
|
free_bytes = block_size * free_blocks
|
|
used_bytes = total_bytes - free_bytes
|
|
|
|
print(f" Total: {total_bytes:,} bytes ({total_bytes / 1024 / 1024:.2f} MB)")
|
|
print(f" Used: {used_bytes:,} bytes ({used_bytes / 1024 / 1024:.2f} MB)")
|
|
print(f" Free: {free_bytes:,} bytes ({free_bytes / 1024 / 1024:.2f} MB)")
|
|
except:
|
|
print(" Unable to check filesystem")
|
|
|
|
# Module path
|
|
print(f"\n[Module Search Paths]")
|
|
for path in sys.path:
|
|
print(f" {path}")
|
|
|
|
print("\n" + "=" * 50)
|
|
|
|
# Run diagnostic
|
|
system_info()
|
|
```
|
|
|
|
## Firmware Version Check
|
|
|
|
### Check MicroPython Firmware
|
|
|
|
```python
|
|
import sys
|
|
|
|
# Full version info
|
|
print(sys.version)
|
|
# Example: 3.4.0; MicroPython v1.20.0 on 2023-04-26
|
|
|
|
# Implementation details
|
|
print(sys.implementation)
|
|
# (name='micropython', version=(1, 20, 0), _machine='Raspberry Pi Pico W with RP2040', _mpy=6182)
|
|
|
|
# Extract version number
|
|
version = sys.implementation.version
|
|
print(f"MicroPython {version[0]}.{version[1]}.{version[2]}")
|
|
```
|
|
|
|
### Check Badger Library Version
|
|
|
|
```python
|
|
import badger2040
|
|
|
|
# Check if version attribute exists
|
|
if hasattr(badger2040, '__version__'):
|
|
print(f"Badger library version: {badger2040.__version__}")
|
|
else:
|
|
print("Badger library version not available")
|
|
|
|
# Check file location
|
|
print(f"Badger library: {badger2040.__file__}")
|
|
```
|
|
|
|
### Recommended Firmware Versions
|
|
|
|
Verify you have compatible firmware:
|
|
|
|
```python
|
|
def check_firmware_compatibility():
|
|
"""Check if firmware is compatible with Badger 2350"""
|
|
version = sys.implementation.version
|
|
|
|
if version[0] >= 1 and version[1] >= 20:
|
|
print("✓ MicroPython version is compatible")
|
|
return True
|
|
else:
|
|
print("✗ MicroPython version may be outdated")
|
|
print(" Recommended: MicroPython 1.20+")
|
|
print(f" Current: {version[0]}.{version[1]}.{version[2]}")
|
|
return False
|
|
|
|
check_firmware_compatibility()
|
|
```
|
|
|
|
## Module Verification
|
|
|
|
### Check Core Modules
|
|
|
|
```python
|
|
def verify_core_modules():
|
|
"""Verify essential modules are available"""
|
|
required_modules = {
|
|
'badger2040': 'Badger display library',
|
|
'machine': 'Hardware interface',
|
|
'time': 'Time functions',
|
|
'gc': 'Garbage collection',
|
|
'sys': 'System functions',
|
|
'os': 'Operating system interface'
|
|
}
|
|
|
|
optional_modules = {
|
|
'network': 'WiFi support',
|
|
'urequests': 'HTTP client',
|
|
'ujson': 'JSON parsing',
|
|
'ubinascii': 'Binary/ASCII conversion'
|
|
}
|
|
|
|
print("Checking required modules...")
|
|
all_ok = True
|
|
for module, description in required_modules.items():
|
|
try:
|
|
__import__(module)
|
|
print(f" ✓ {module:15s} - {description}")
|
|
except ImportError:
|
|
print(f" ✗ {module:15s} - MISSING - {description}")
|
|
all_ok = False
|
|
|
|
print("\nChecking optional modules...")
|
|
for module, description in optional_modules.items():
|
|
try:
|
|
__import__(module)
|
|
print(f" ✓ {module:15s} - {description}")
|
|
except ImportError:
|
|
print(f" ○ {module:15s} - Not installed - {description}")
|
|
|
|
return all_ok
|
|
|
|
verify_core_modules()
|
|
```
|
|
|
|
### List All Installed Packages
|
|
|
|
```python
|
|
import os
|
|
|
|
def list_installed_packages():
|
|
"""List all installed packages in /lib"""
|
|
print("Installed packages:")
|
|
|
|
# Check /lib directory
|
|
try:
|
|
lib_contents = os.listdir('/lib')
|
|
if lib_contents:
|
|
for item in sorted(lib_contents):
|
|
# Try to get more info
|
|
path = f'/lib/{item}'
|
|
try:
|
|
stat = os.stat(path)
|
|
size = stat[6] # File size
|
|
print(f" {item:30s} {size:8,} bytes")
|
|
except:
|
|
print(f" {item}")
|
|
else:
|
|
print(" (no packages in /lib)")
|
|
except OSError:
|
|
print(" /lib directory not found")
|
|
|
|
# Check root directory for .py files
|
|
print("\nRoot directory modules:")
|
|
root_contents = os.listdir('/')
|
|
py_files = [f for f in root_contents if f.endswith('.py')]
|
|
for f in sorted(py_files):
|
|
stat = os.stat(f)
|
|
size = stat[6]
|
|
print(f" {f:30s} {size:8,} bytes")
|
|
|
|
list_installed_packages()
|
|
```
|
|
|
|
## Hardware Diagnostics
|
|
|
|
### Display Test
|
|
|
|
```python
|
|
import badger2040
|
|
|
|
def test_display():
|
|
"""Test display functionality"""
|
|
print("Testing display...")
|
|
|
|
badge = badger2040.Badger2040()
|
|
|
|
# Test 1: Clear screen
|
|
badge.set_pen(15)
|
|
badge.clear()
|
|
badge.update()
|
|
print(" ✓ Clear screen")
|
|
|
|
# Test 2: Draw text
|
|
badge.set_pen(0)
|
|
badge.text("Display Test", 10, 10, scale=2)
|
|
badge.update()
|
|
print(" ✓ Draw text")
|
|
|
|
# Test 3: Draw shapes
|
|
badge.line(10, 40, 100, 40)
|
|
badge.rectangle(10, 50, 50, 30)
|
|
badge.update()
|
|
print(" ✓ Draw shapes")
|
|
|
|
print("Display test complete!")
|
|
|
|
test_display()
|
|
```
|
|
|
|
### Button Test
|
|
|
|
```python
|
|
import badger2040
|
|
import time
|
|
|
|
def test_buttons():
|
|
"""Test all buttons"""
|
|
print("Button test - Press each button:")
|
|
print(" A, B, C, UP, DOWN")
|
|
print("Press Ctrl+C to exit")
|
|
|
|
badge = badger2040.Badger2040()
|
|
tested = set()
|
|
|
|
while len(tested) < 5:
|
|
if badge.pressed(badger2040.BUTTON_A) and 'A' not in tested:
|
|
print(" ✓ Button A works")
|
|
tested.add('A')
|
|
elif badge.pressed(badger2040.BUTTON_B) and 'B' not in tested:
|
|
print(" ✓ Button B works")
|
|
tested.add('B')
|
|
elif badge.pressed(badger2040.BUTTON_C) and 'C' not in tested:
|
|
print(" ✓ Button C works")
|
|
tested.add('C')
|
|
elif badge.pressed(badger2040.BUTTON_UP) and 'UP' not in tested:
|
|
print(" ✓ Button UP works")
|
|
tested.add('UP')
|
|
elif badge.pressed(badger2040.BUTTON_DOWN) and 'DOWN' not in tested:
|
|
print(" ✓ Button DOWN works")
|
|
tested.add('DOWN')
|
|
|
|
time.sleep(0.1)
|
|
|
|
print("All buttons tested successfully!")
|
|
|
|
test_buttons()
|
|
```
|
|
|
|
### GPIO Test
|
|
|
|
```python
|
|
from machine import Pin
|
|
|
|
def test_gpio():
|
|
"""Test GPIO pins"""
|
|
print("Testing GPIO pins...")
|
|
|
|
# Test output
|
|
test_pin = Pin(25, Pin.OUT)
|
|
test_pin.value(1)
|
|
print(f" ✓ Pin 25 set to HIGH: {test_pin.value()}")
|
|
test_pin.value(0)
|
|
print(f" ✓ Pin 25 set to LOW: {test_pin.value()}")
|
|
|
|
# Test input with pull-up
|
|
input_pin = Pin(15, Pin.IN, Pin.PULL_UP)
|
|
print(f" ✓ Pin 15 input (pull-up): {input_pin.value()}")
|
|
|
|
print("GPIO test complete!")
|
|
|
|
test_gpio()
|
|
```
|
|
|
|
### I2C Bus Scan
|
|
|
|
```python
|
|
from machine import I2C, Pin
|
|
|
|
def scan_i2c():
|
|
"""Scan for I2C devices"""
|
|
print("Scanning I2C bus...")
|
|
|
|
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
|
|
devices = i2c.scan()
|
|
|
|
if devices:
|
|
print(f" Found {len(devices)} device(s):")
|
|
for device in devices:
|
|
print(f" 0x{device:02X} ({device})")
|
|
else:
|
|
print(" No I2C devices found")
|
|
|
|
return devices
|
|
|
|
scan_i2c()
|
|
```
|
|
|
|
## Network Diagnostics
|
|
|
|
### WiFi Connection Test
|
|
|
|
```python
|
|
import network
|
|
import time
|
|
|
|
def test_wifi(ssid, password, timeout=10):
|
|
"""Test WiFi connection"""
|
|
print(f"Testing WiFi connection to '{ssid}'...")
|
|
|
|
wlan = network.WLAN(network.STA_IF)
|
|
wlan.active(True)
|
|
|
|
# Check if already connected
|
|
if wlan.isconnected():
|
|
print(" ✓ Already connected")
|
|
print(f" IP: {wlan.ifconfig()[0]}")
|
|
return True
|
|
|
|
# Attempt connection
|
|
print(" Connecting...")
|
|
wlan.connect(ssid, password)
|
|
|
|
# Wait for connection
|
|
start = time.time()
|
|
while not wlan.isconnected() and (time.time() - start) < timeout:
|
|
time.sleep(0.5)
|
|
print(".", end="")
|
|
|
|
print() # New line
|
|
|
|
if wlan.isconnected():
|
|
config = wlan.ifconfig()
|
|
print(" ✓ Connected successfully")
|
|
print(f" IP Address: {config[0]}")
|
|
print(f" Subnet Mask: {config[1]}")
|
|
print(f" Gateway: {config[2]}")
|
|
print(f" DNS: {config[3]}")
|
|
print(f" Signal Strength: {wlan.status('rssi')} dBm")
|
|
return True
|
|
else:
|
|
print(" ✗ Connection failed")
|
|
status = wlan.status()
|
|
print(f" Status code: {status}")
|
|
return False
|
|
|
|
# Usage
|
|
# test_wifi('YourSSID', 'YourPassword')
|
|
```
|
|
|
|
### Network Speed Test
|
|
|
|
```python
|
|
import urequests
|
|
import time
|
|
|
|
def test_network_speed():
|
|
"""Test network download speed"""
|
|
print("Testing network speed...")
|
|
|
|
url = "http://httpbin.org/bytes/10000" # 10KB test file
|
|
|
|
try:
|
|
start = time.ticks_ms()
|
|
response = urequests.get(url)
|
|
end = time.ticks_ms()
|
|
|
|
size = len(response.content)
|
|
duration = time.ticks_diff(end, start) / 1000 # Convert to seconds
|
|
|
|
speed = (size / duration) / 1024 # KB/s
|
|
|
|
print(f" Downloaded: {size} bytes")
|
|
print(f" Time: {duration:.2f}s")
|
|
print(f" Speed: {speed:.2f} KB/s")
|
|
|
|
response.close()
|
|
return True
|
|
except Exception as e:
|
|
print(f" ✗ Network test failed: {e}")
|
|
return False
|
|
|
|
# test_network_speed()
|
|
```
|
|
|
|
## Memory Diagnostics
|
|
|
|
### Memory Usage Analysis
|
|
|
|
```python
|
|
import gc
|
|
|
|
def analyze_memory():
|
|
"""Analyze memory usage"""
|
|
print("Memory Analysis:")
|
|
|
|
# Before collection
|
|
free_before = gc.mem_free()
|
|
alloc_before = gc.mem_alloc()
|
|
|
|
# Collect garbage
|
|
gc.collect()
|
|
|
|
# After collection
|
|
free_after = gc.mem_free()
|
|
alloc_after = gc.mem_alloc()
|
|
|
|
print(f"\nBefore garbage collection:")
|
|
print(f" Free: {free_before:,} bytes ({free_before / 1024:.1f} KB)")
|
|
print(f" Allocated: {alloc_before:,} bytes ({alloc_before / 1024:.1f} KB)")
|
|
|
|
print(f"\nAfter garbage collection:")
|
|
print(f" Free: {free_after:,} bytes ({free_after / 1024:.1f} KB)")
|
|
print(f" Allocated: {alloc_after:,} bytes ({alloc_after / 1024:.1f} KB)")
|
|
|
|
freed = free_after - free_before
|
|
print(f"\nReclaimed: {freed:,} bytes ({freed / 1024:.1f} KB)")
|
|
|
|
# Total memory
|
|
total = free_after + alloc_after
|
|
usage_percent = (alloc_after / total) * 100
|
|
|
|
print(f"\nTotal memory: {total:,} bytes ({total / 1024:.1f} KB)")
|
|
print(f"Usage: {usage_percent:.1f}%")
|
|
|
|
# Warning if low
|
|
if free_after < 10000:
|
|
print("\n⚠ WARNING: Low memory!")
|
|
elif free_after < 50000:
|
|
print("\n⚠ CAUTION: Memory running low")
|
|
else:
|
|
print("\n✓ Memory usage looks good")
|
|
|
|
analyze_memory()
|
|
```
|
|
|
|
### Find Memory Leaks
|
|
|
|
```python
|
|
import gc
|
|
|
|
def find_memory_leaks(function, iterations=10):
|
|
"""Test function for memory leaks"""
|
|
print(f"Testing for memory leaks ({iterations} iterations)...")
|
|
|
|
gc.collect()
|
|
initial_mem = gc.mem_free()
|
|
|
|
for i in range(iterations):
|
|
function()
|
|
gc.collect()
|
|
|
|
current_mem = gc.mem_free()
|
|
leaked = initial_mem - current_mem
|
|
|
|
if leaked > 0:
|
|
print(f" Iteration {i+1}: Leaked {leaked} bytes")
|
|
|
|
gc.collect()
|
|
final_mem = gc.mem_free()
|
|
total_leaked = initial_mem - final_mem
|
|
|
|
if total_leaked > 100: # Allow small variance
|
|
print(f"⚠ Possible memory leak: {total_leaked} bytes leaked")
|
|
else:
|
|
print(f"✓ No significant memory leak detected")
|
|
|
|
# Usage
|
|
# def test_func():
|
|
# data = [i for i in range(100)]
|
|
# find_memory_leaks(test_func)
|
|
```
|
|
|
|
## Error Diagnosis
|
|
|
|
### Common Error Patterns
|
|
|
|
```python
|
|
def diagnose_error(error):
|
|
"""Provide diagnosis for common errors"""
|
|
error_str = str(error)
|
|
|
|
diagnostics = {
|
|
'ImportError': """
|
|
Module not found. Check:
|
|
- Module is installed (use mip.install())
|
|
- Module is in /lib or root directory
|
|
- Module name is spelled correctly
|
|
- File has .py extension
|
|
""",
|
|
|
|
'MemoryError': """
|
|
Out of memory. Try:
|
|
- Run gc.collect() before allocation
|
|
- Reduce variable scope
|
|
- Use generators instead of lists
|
|
- Break large operations into smaller chunks
|
|
- Delete unused objects with 'del'
|
|
""",
|
|
|
|
'OSError': """
|
|
File/Hardware operation failed. Check:
|
|
- File path is correct
|
|
- File exists (for reading)
|
|
- Filesystem not full (for writing)
|
|
- Hardware is connected properly
|
|
- Pins are not already in use
|
|
""",
|
|
|
|
'AttributeError': """
|
|
Attribute not found. Check:
|
|
- Object has the attribute/method
|
|
- Spelling is correct
|
|
- Module is imported correctly
|
|
- Object is initialized
|
|
""",
|
|
|
|
'ValueError': """
|
|
Invalid value. Check:
|
|
- Parameter values are in valid range
|
|
- Data types match expected types
|
|
- String formats are correct
|
|
"""
|
|
}
|
|
|
|
# Find matching error type
|
|
for error_type, advice in diagnostics.items():
|
|
if error_type in error_str:
|
|
print(f"Diagnosis for {error_type}:")
|
|
print(advice)
|
|
return
|
|
|
|
print("Error type not recognized. Common debugging steps:")
|
|
print("- Check error message carefully")
|
|
print("- Print variable values before error")
|
|
print("- Simplify code to isolate problem")
|
|
print("- Check MicroPython documentation")
|
|
|
|
# Usage
|
|
# try:
|
|
# import nonexistent_module
|
|
# except Exception as e:
|
|
# diagnose_error(e)
|
|
```
|
|
|
|
### System Health Check
|
|
|
|
```python
|
|
def health_check():
|
|
"""Comprehensive system health check"""
|
|
print("=" * 50)
|
|
print("SYSTEM HEALTH CHECK")
|
|
print("=" * 50)
|
|
|
|
issues = []
|
|
|
|
# Memory check
|
|
gc.collect()
|
|
free_mem = gc.mem_free()
|
|
if free_mem < 10000:
|
|
issues.append("CRITICAL: Very low memory")
|
|
elif free_mem < 50000:
|
|
issues.append("WARNING: Low memory")
|
|
else:
|
|
print("✓ Memory: OK")
|
|
|
|
# Filesystem check
|
|
try:
|
|
stat = os.statvfs('/')
|
|
free_blocks = stat[3]
|
|
block_size = stat[0]
|
|
free_bytes = free_blocks * block_size
|
|
|
|
if free_bytes < 100000:
|
|
issues.append("WARNING: Low disk space")
|
|
else:
|
|
print("✓ Filesystem: OK")
|
|
except:
|
|
issues.append("ERROR: Cannot check filesystem")
|
|
|
|
# Core modules check
|
|
required = ['badger2040', 'machine', 'time', 'gc', 'sys', 'os']
|
|
for module in required:
|
|
try:
|
|
__import__(module)
|
|
except:
|
|
issues.append(f"ERROR: Missing module '{module}'")
|
|
|
|
if not issues:
|
|
print("✓ Core modules: OK")
|
|
|
|
# Display results
|
|
if issues:
|
|
print("\n" + "!" * 50)
|
|
print("ISSUES FOUND:")
|
|
for issue in issues:
|
|
print(f" {issue}")
|
|
print("!" * 50)
|
|
else:
|
|
print("\n" + "=" * 50)
|
|
print("✓ ALL SYSTEMS HEALTHY")
|
|
print("=" * 50)
|
|
|
|
health_check()
|
|
```
|
|
|
|
## Recovery Procedures
|
|
|
|
### Safe Mode Boot
|
|
|
|
If badge won't boot normally:
|
|
|
|
1. **Hold BOOTSEL button** while connecting USB
|
|
2. Badge appears as USB drive
|
|
3. Delete `main.py` if it's causing crashes
|
|
4. Copy new firmware `.uf2` file to drive
|
|
5. Badge will reboot automatically
|
|
|
|
### Factory Reset
|
|
|
|
```python
|
|
import os
|
|
|
|
def factory_reset():
|
|
"""Remove all user files (DANGEROUS!)"""
|
|
print("WARNING: This will delete all files!")
|
|
print("Type 'CONFIRM' to proceed:")
|
|
|
|
# In interactive mode, get user confirmation
|
|
# confirm = input()
|
|
# if confirm != 'CONFIRM':
|
|
# print("Reset cancelled")
|
|
# return
|
|
|
|
print("Removing files...")
|
|
for f in os.listdir('/'):
|
|
if f not in ['boot.py']: # Keep boot.py
|
|
try:
|
|
os.remove(f)
|
|
print(f" Removed {f}")
|
|
except:
|
|
pass
|
|
|
|
print("Factory reset complete. Reboot badge.")
|
|
|
|
# Uncomment to use:
|
|
# factory_reset()
|
|
```
|
|
|
|
### Firmware Reflash
|
|
|
|
```bash
|
|
# From your computer (badge in BOOTSEL mode)
|
|
|
|
# Download latest MicroPython firmware
|
|
# Visit: https://micropython.org/download/rp2-pico-w/
|
|
|
|
# Flash firmware
|
|
# Drag .uf2 file to RPI-RP2 drive
|
|
# Or use picotool:
|
|
picotool load firmware.uf2
|
|
|
|
# Verify
|
|
picotool info
|
|
```
|
|
|
|
## Troubleshooting Checklist
|
|
|
|
When encountering issues, work through this checklist:
|
|
|
|
- [ ] Check MicroPython version (`sys.version`)
|
|
- [ ] Verify core modules load (`import badger2040`)
|
|
- [ ] Run memory diagnostic (`gc.mem_free()`)
|
|
- [ ] Check filesystem space (`os.statvfs('/')`)
|
|
- [ ] Test display (`badge.update()`)
|
|
- [ ] Test buttons (button test function)
|
|
- [ ] Scan I2C bus (if using sensors)
|
|
- [ ] Test WiFi connection (if using network)
|
|
- [ ] Review error messages carefully
|
|
- [ ] Check documentation for API changes
|
|
- [ ] Try soft reset (Ctrl+D in REPL)
|
|
- [ ] Try hard reset (power cycle)
|
|
|
|
This comprehensive diagnostic approach will help you quickly identify and resolve issues with your Badger 2350!
|