Skip to content

Basic Usage

This guide covers the fundamental usage patterns for each mock_machine component.

Pin (GPIO)

Basic Pin Operations

import mock_machine
mock_machine.register_as_machine()
import machine

# Create output pin
pin_out = machine.Pin(0, machine.Pin.OUT)
pin_out.value(1)  # Set high
pin_out.on()      # Alternative way
pin_out.off()     # Set low

# Create input pin with pull-up
pin_in = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_UP)
value = pin_in.value()  # Read pin state

Pin Modes and Configuration

# Supported modes
pin = machine.Pin(0, machine.Pin.OUT)         # Output
pin = machine.Pin(1, machine.Pin.IN)          # Input
pin = machine.Pin(2, machine.Pin.OPEN_DRAIN)  # Open drain
pin = machine.Pin(3, machine.Pin.ALT)         # Alternate function

# Pull resistors
pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
pin = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_DOWN)

# Reconfigure existing pin
pin.init(mode=machine.Pin.OUT, pull=None)

Accessing Mock Pin State

# Get the mock pin object directly
mock_pin = mock_machine.Pin.pins[0]

# Set value for testing
mock_pin.value(1)

# Check internal state
assert mock_pin._mode == machine.Pin.OUT
assert mock_pin._value == 1

I2C (Inter-Integrated Circuit)

Basic I2C Operations

# Create I2C bus
i2c = machine.I2C(0, scl=machine.Pin(0), sda=machine.Pin(1), freq=400000)

# Scan for devices
devices = i2c.scan()  # Returns list of addresses

# Read from device
data = i2c.readfrom(0x50, 10)  # Read 10 bytes from address 0x50

# Write to device
i2c.writeto(0x50, b'Hello')  # Write bytes to address 0x50

# Memory operations
data = i2c.readfrom_mem(0x50, 0x00, 4)  # Read 4 bytes from register 0x00
i2c.writeto_mem(0x50, 0x00, b'\x01\x02\x03\x04')  # Write to register

Creating Mock I2C Devices

from mock_machine import I2C, I2CDevice

# Create bus and device
i2c = I2C(0)
device = I2CDevice(addr=0x68, i2c=i2c)

# Set up register values
device.register_values[0x0D] = b'\x1A'  # WHO_AM_I register
device.register_values[0x00] = b'\x00\x00'  # Data register

# Device is now visible on bus
assert 0x68 in i2c.scan()

# Read from registers
who_am_i = i2c.readfrom_mem(0x68, 0x0D, 1)
assert who_am_i == b'\x1A'

Advanced I2C Device Behavior

class MockSensor(I2CDevice):
    """Custom I2C device with dynamic behavior."""

    def __init__(self, addr, i2c):
        super().__init__(addr, i2c)
        self.temperature = 25.0

    def readfrom_mem(self, memaddr, nbytes):
        if memaddr == 0x00:  # Temperature register
            # Convert temperature to bytes
            temp_raw = int(self.temperature * 256)
            return bytes([(temp_raw >> 8) & 0xFF, temp_raw & 0xFF])
        return super().readfrom_mem(memaddr, nbytes)

# Use custom device
i2c = I2C(0)
sensor = MockSensor(addr=0x48, i2c=i2c)
sensor.temperature = 26.5

data = i2c.readfrom_mem(0x48, 0x00, 2)
# data contains temperature as bytes

SPI (Serial Peripheral Interface)

Basic SPI Operations

# Create SPI bus
spi = machine.SPI(0)
spi.init(baudrate=1000000, polarity=0, phase=0)

# Read operations
data = spi.read(10)  # Read 10 bytes
buffer = bytearray(10)
spi.readinto(buffer)  # Read into existing buffer

# Write operations
spi.write(b'Hello SPI')  # Write bytes

# Combined read/write
write_buf = b'\x01\x02\x03'
read_buf = bytearray(3)
spi.write_readinto(write_buf, read_buf)

Configuring Mock SPI Responses

# Set up read data
spi.read_buf = b'\x01\x02\x03\x04'
data = spi.read(4)  # Returns b'\x01\x02\x03\x04'

# Multiple different responses
spi.reads = [b'\xAA', b'\xBB', b'\xCC']
data1 = spi.read(1)  # Returns b'\xAA'
data2 = spi.read(1)  # Returns b'\xBB'
data3 = spi.read(1)  # Returns b'\xCC'

# Check what was written
spi.write(b'\x55\xAA')
assert spi.write_buf == b'\x55\xAA'
assert spi.writes == [b'\x55\xAA']  # History of all writes

ADC (Analog to Digital Converter)

Basic ADC Usage

# Create ADC on a pin
adc = machine.ADC(machine.Pin(0))

# Read value (0-65535 for 16-bit)
value = adc.read_u16()

Simulating ADC Values

# Direct access to set ADC values
mock_machine.ADC.pin_adc_map[pin] = 32768  # Mid-scale

# Now reading returns the set value
adc = machine.ADC(pin)
assert adc.read_u16() == 32768

# Simulate changing values
for value in range(0, 65536, 1000):
    mock_machine.ADC.pin_adc_map[pin] = value
    reading = adc.read_u16()
    print(f"ADC reading: {reading}")

UART (Serial Communication)

Basic UART Operations

# Create UART
uart = machine.UART(1)

# Write data
uart.write(b'Hello UART\n')

# Read data
data = uart.read(10)  # Read up to 10 bytes
line = uart.readline()  # Read until newline

# Check available data
if uart.any():
    data = uart.read()

Simulating UART Communication

# Create UART with pre-loaded read data
uart = mock_machine.UART(data_for_read=b'Response\n')

# Read the data
line = uart.readline()
assert line == b'Response\n'

# Check what was written
uart.write(b'Command\n')
uart.write_buf.seek(0)
written = uart.write_buf.read()
assert written == b'Command\n'

Timer

Basic Timer Usage

# Create periodic timer
def timer_callback(timer):
    print("Timer fired!")

timer = machine.Timer(0)
timer.init(mode=machine.Timer.PERIODIC, period=1000, callback=timer_callback)

# Stop timer
timer.deinit()

# One-shot timer
timer.init(mode=machine.Timer.ONE_SHOT, period=5000, callback=timer_callback)

PWM (Pulse Width Modulation)

Basic PWM Usage

# Create PWM on a pin
pwm = machine.PWM(machine.Pin(0), freq=1000, duty_u16=32768)

# Adjust frequency and duty cycle
pwm.freq(2000)  # 2kHz
pwm.duty_u16(16384)  # 25% duty cycle

# Read current values
current_freq = pwm.freq()
current_duty = pwm.duty_u16()

RTC (Real Time Clock)

Basic RTC Usage

# Create RTC
rtc = machine.RTC()

# Set up wakeup alarm
def wakeup_callback():
    print("RTC wakeup!")

rtc.wakeup(timeout=5000, callback=wakeup_callback)

# Get datetime
datetime = rtc.datetime()
# Returns: (year, month, day, weekday, hour, minute, second, microsecond)

Next Steps

Now that you understand the basic usage of each component: - Learn about Testing Patterns for effective test design - Explore Advanced Topics for complex scenarios - See complete Examples for real-world usage