mirror of
https://github.com/Architeuthis-Flux/JumperlessV5.git
synced 2025-09-05 10:47:58 +00:00
280 lines
8.5 KiB
Python
280 lines
8.5 KiB
Python
"""
|
|
Jumperless Machine Module Demo
|
|
Demonstrates the enhanced MicroPython capabilities with filesystem and machine module support
|
|
|
|
This file can be run in the MicroPython REPL to test all the new features:
|
|
1. Machine module (Pin, ADC, PWM) with Jumperless node support
|
|
2. Runtime module importing from python_scripts/lib/
|
|
3. Filesystem integration
|
|
4. Node name support in machine classes
|
|
|
|
Usage:
|
|
1. Copy this file to python_scripts/ on your Jumperless
|
|
2. In MicroPython REPL: exec(open('python_scripts/jumperless_machine_demo.py').read())
|
|
"""
|
|
|
|
print("🚀 Jumperless Machine Module Demo")
|
|
print("=" * 50)
|
|
|
|
# Test 1: Import and test filesystem capabilities
|
|
print("\n📁 Testing filesystem and module import capabilities...")
|
|
|
|
try:
|
|
import sys
|
|
import os
|
|
|
|
print(f"✓ Python {sys.version}")
|
|
print(f"✓ Platform: {sys.platform}")
|
|
|
|
print("\n📂 Module search paths:")
|
|
for i, path in enumerate(sys.path):
|
|
print(f" {i}: {path}")
|
|
|
|
# Test directory listing if available
|
|
try:
|
|
print("\n📋 Available directories:")
|
|
for item in os.listdir('/'):
|
|
print(f" /{item}")
|
|
except OSError:
|
|
print(" (Directory listing not available)")
|
|
|
|
except ImportError as e:
|
|
print(f"❌ Filesystem modules not available: {e}")
|
|
|
|
# Test 2: Machine module with Jumperless integration
|
|
print("\n🔌 Testing machine module with Jumperless nodes...")
|
|
|
|
try:
|
|
from machine import Pin, ADC, PWM
|
|
|
|
print("✓ Machine module imported successfully")
|
|
|
|
# Test Pin class with node names
|
|
print("\n🔧 Testing Pin class with Jumperless nodes:")
|
|
|
|
# Test with node numbers
|
|
pin1 = Pin(1, Pin.OUT) # Breadboard node 1
|
|
print("✓ Created Pin(1) - breadboard node 1")
|
|
|
|
# Test with node names
|
|
try:
|
|
pin_d13 = Pin("NANO_D13", Pin.OUT)
|
|
print("✓ Created Pin('NANO_D13') - Arduino D13 equivalent")
|
|
except:
|
|
print("⚠ Pin name lookup not available (expected in current implementation)")
|
|
|
|
# Test basic GPIO operations
|
|
pin1.on()
|
|
print("✓ pin1.on() - set high")
|
|
|
|
pin1.off()
|
|
print("✓ pin1.off() - set low")
|
|
|
|
state = pin1.value()
|
|
print(f"✓ pin1.value() = {state}")
|
|
|
|
# Test ADC with analog pins
|
|
print("\n📊 Testing ADC class:")
|
|
|
|
adc0 = ADC(26) # GPIO 26 = ADC0
|
|
print("✓ Created ADC(26) - NANO_A0 equivalent")
|
|
|
|
reading = adc0.read_u16()
|
|
voltage = (reading / 65535) * 3.3
|
|
print(f"✓ ADC reading: {reading} ({voltage:.3f}V)")
|
|
|
|
# Test PWM/DAC functionality
|
|
print("\n⚡ Testing PWM/DAC functionality:")
|
|
|
|
# Top rail DAC
|
|
dac_top = PWM(Pin(16)) # TOP_RAIL
|
|
print("✓ Created PWM(Pin(16)) - TOP_RAIL DAC")
|
|
|
|
# Set voltage via PWM duty cycle
|
|
# Full scale is -8V to +8V, so 32768 = 0V
|
|
dac_top.duty_u16(32768) # 0V
|
|
print("✓ Set TOP_RAIL to 0V via PWM duty cycle")
|
|
|
|
# Set 3.3V (3.3V + 8V = 11.3V, 11.3/16 * 65535 = 46244)
|
|
duty_3v3 = int(((3.3 + 8.0) / 16.0) * 65535)
|
|
dac_top.duty_u16(duty_3v3)
|
|
print(f"✓ Set TOP_RAIL to 3.3V (duty: {duty_3v3})")
|
|
|
|
except ImportError as e:
|
|
print(f"❌ Machine module not available: {e}")
|
|
except Exception as e:
|
|
print(f"⚠ Machine module error: {e}")
|
|
|
|
# Test 3: Jumperless-specific functions (should still work)
|
|
print("\n🔗 Testing native Jumperless functions...")
|
|
|
|
try:
|
|
# These should be available globally
|
|
result = connect(1, 30)
|
|
print(f"✓ connect(1, 30) = {result}")
|
|
|
|
voltage = adc_get(0)
|
|
print(f"✓ adc_get(0) = {voltage:.3f}V")
|
|
|
|
# Test DAC with node names
|
|
dac_set(TOP_RAIL, 3.3)
|
|
print("✓ dac_set(TOP_RAIL, 3.3) - using node constant")
|
|
|
|
current_voltage = dac_get(TOP_RAIL)
|
|
print(f"✓ dac_get(TOP_RAIL) = {current_voltage:.3f}V")
|
|
|
|
except NameError as e:
|
|
print(f"⚠ Jumperless functions not in global scope: {e}")
|
|
print(" (Try: import jumperless; jumperless.connect(1, 30))")
|
|
|
|
# Test 4: Module importing from filesystem
|
|
print("\n📚 Testing runtime module import...")
|
|
|
|
# Create a simple test module in memory to demonstrate
|
|
test_module_code = """
|
|
# Example user module for Jumperless
|
|
# Place modules like this in python_scripts/lib/ for automatic import
|
|
|
|
def blink_led(pin_num, times=3):
|
|
"""Blink an LED connected to a pin"""
|
|
try:
|
|
from machine import Pin
|
|
import time
|
|
|
|
led = Pin(pin_num, Pin.OUT)
|
|
|
|
for i in range(times):
|
|
led.on()
|
|
time.sleep(0.2)
|
|
led.off()
|
|
time.sleep(0.2)
|
|
|
|
print(f"Blinked pin {pin_num} {times} times")
|
|
|
|
except Exception as e:
|
|
print(f"Blink failed: {e}")
|
|
|
|
def read_analog_sensors():
|
|
"""Read all 4 ADC channels"""
|
|
try:
|
|
from machine import ADC
|
|
|
|
sensors = []
|
|
for channel in range(4):
|
|
adc = ADC(26 + channel) # GPIO 26-29
|
|
reading = adc.read_u16()
|
|
voltage = (reading / 65535) * 3.3
|
|
sensors.append(voltage)
|
|
|
|
return sensors
|
|
|
|
except Exception as e:
|
|
print(f"Sensor reading failed: {e}")
|
|
return [0.0, 0.0, 0.0, 0.0]
|
|
|
|
class JumperlessHelper:
|
|
"""Helper class for common Jumperless operations"""
|
|
|
|
def __init__(self):
|
|
self.connections = []
|
|
|
|
def safe_connect(self, node1, node2):
|
|
"""Connect nodes with error handling"""
|
|
try:
|
|
result = connect(node1, node2)
|
|
if result:
|
|
self.connections.append((node1, node2))
|
|
print(f"✓ Connected {node1} ↔ {node2}")
|
|
else:
|
|
print(f"❌ Failed to connect {node1} ↔ {node2}")
|
|
return result
|
|
except Exception as e:
|
|
print(f"❌ Connection error: {e}")
|
|
return False
|
|
|
|
def disconnect_all(self):
|
|
"""Disconnect all tracked connections"""
|
|
for node1, node2 in self.connections:
|
|
try:
|
|
disconnect(node1, node2)
|
|
print(f"✓ Disconnected {node1} ↔ {node2}")
|
|
except Exception as e:
|
|
print(f"❌ Disconnect error: {e}")
|
|
|
|
self.connections.clear()
|
|
"""
|
|
|
|
# Make the test module available
|
|
print("📝 Creating example user module...")
|
|
print(" (In real usage, save as python_scripts/lib/jumperless_utils.py)")
|
|
|
|
# Execute the module code to make functions available
|
|
exec(test_module_code)
|
|
|
|
print("✓ Example module loaded")
|
|
|
|
# Test the example functions
|
|
print("\n🧪 Testing example module functions...")
|
|
|
|
try:
|
|
# Test LED blink (won't actually blink since no LED, but tests the function)
|
|
print("Testing blink_led function:")
|
|
blink_led(13, 1) # Pin 13, blink once
|
|
|
|
# Test sensor reading
|
|
print("\nTesting sensor reading:")
|
|
sensor_values = read_analog_sensors()
|
|
for i, voltage in enumerate(sensor_values):
|
|
print(f" ADC{i}: {voltage:.3f}V")
|
|
|
|
# Test helper class
|
|
print("\nTesting JumperlessHelper class:")
|
|
helper = JumperlessHelper()
|
|
helper.safe_connect(1, 5)
|
|
helper.safe_connect(10, 15)
|
|
print(f" Tracked connections: {len(helper.connections)}")
|
|
helper.disconnect_all()
|
|
|
|
except Exception as e:
|
|
print(f"❌ Example functions error: {e}")
|
|
|
|
# Test 5: Comprehensive feature summary
|
|
print("\n📋 Feature Summary")
|
|
print("=" * 50)
|
|
|
|
features = [
|
|
("✓ Filesystem Integration", "sys.path configured for python_scripts/lib/"),
|
|
("✓ Machine Module", "Pin, ADC, PWM classes with Jumperless nodes"),
|
|
("✓ Node Name Support", "Use 'NANO_D13', 'TOP_RAIL', etc. in machine classes"),
|
|
("✓ Runtime Import", "Import .py and .mpy modules from filesystem"),
|
|
("✓ Backward Compatibility", "All existing Jumperless functions still work"),
|
|
("✓ Enhanced REPL", "Full MicroPython REPL with module support"),
|
|
]
|
|
|
|
for status, description in features:
|
|
print(f"{status} {description}")
|
|
|
|
print("\n🎯 Next Steps:")
|
|
print("1. Create python_scripts/lib/ directory on your Jumperless")
|
|
print("2. Add your custom .py modules to python_scripts/lib/")
|
|
print("3. Use 'import your_module' in REPL or scripts")
|
|
print("4. Mix machine module with native Jumperless functions")
|
|
print("5. Create reusable hardware abstraction libraries")
|
|
|
|
print("\n💡 Example Usage:")
|
|
print("""
|
|
# Traditional Jumperless way:
|
|
connect(1, 30)
|
|
dac_set(TOP_RAIL, 3.3)
|
|
voltage = adc_get(0)
|
|
|
|
# New machine module way:
|
|
from machine import Pin, ADC, PWM
|
|
pin = Pin('NANO_D13', Pin.OUT)
|
|
adc = ADC('NANO_A0')
|
|
dac = PWM(Pin('TOP_RAIL'))
|
|
|
|
# Both approaches work and can be mixed!
|
|
""")
|
|
|
|
print("🎉 Demo complete! Your Jumperless now has enhanced MicroPython capabilities.") |