or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

composite-devices.mdindex.mdinput-devices.mdoutput-devices.mdpin-factories.mdspi-devices.mdsystem-monitoring.mdtone-system.mdtools.md

pin-factories.mddocs/

0

# Pin Factory System

1

2

The pin factory system provides an abstracted interface for different GPIO backends, board information, and pin management. This enables GPIO Zero to work with multiple underlying GPIO libraries and provides comprehensive hardware abstraction.

3

4

## Core Factory Classes

5

6

### Factory

7

8

Abstract base class for all pin factories.

9

10

```python { .api }

11

class Factory:

12

def __init__(self):

13

"""

14

Abstract base class for pin factories.

15

"""

16

17

def close(self):

18

"""Close the factory and release all resources."""

19

20

def reset(self):

21

"""Reset the factory to its initial state."""

22

23

def pin(self, spec) -> 'Pin':

24

"""

25

Create a pin object for the specified pin.

26

27

Parameters:

28

- spec: Pin specification (int, str, or PinInfo)

29

30

Returns:

31

Pin object for the specified pin

32

"""

33

34

def spi(self, *, port=0, device=0) -> 'SPI':

35

"""

36

Create an SPI interface object.

37

38

Parameters:

39

- port: int - SPI port number

40

- device: int - SPI device (chip select) number

41

42

Returns:

43

SPI interface object

44

"""

45

46

def reserve_pins(self, requester, *pins):

47

"""Reserve pins for exclusive use by requester."""

48

49

def release_pins(self, requester, *pins):

50

"""Release pin reservations for requester."""

51

52

def release_all(self, requester):

53

"""Release all pin reservations for requester."""

54

55

@property

56

def board_info(self) -> 'BoardInfo':

57

"""Information about the current board."""

58

59

@property

60

def ticks(self) -> int:

61

"""Current system tick count."""

62

63

def ticks_diff(self, later: int, earlier: int) -> int:

64

"""Calculate difference between two tick counts."""

65

```

66

67

### Pin

68

69

Abstract base class representing a GPIO pin.

70

71

```python { .api }

72

class Pin:

73

def __init__(self, factory, info):

74

"""

75

Abstract base class for GPIO pins.

76

77

Parameters:

78

- factory: Factory that created this pin

79

- info: PinInfo object describing this pin

80

"""

81

82

def close(self):

83

"""Close the pin and release resources."""

84

85

def output_with_state(self, state: bool):

86

"""Configure pin as output and set initial state."""

87

88

def input_with_pull(self, pull: str):

89

"""Configure pin as input with pull resistor."""

90

91

@property

92

def number(self) -> int:

93

"""Pin number."""

94

95

@property

96

def info(self) -> 'PinInfo':

97

"""Pin information object."""

98

99

@property

100

def factory(self) -> Factory:

101

"""Factory that created this pin."""

102

103

@property

104

def function(self) -> str:

105

"""Current pin function ('input', 'output', 'alt0', etc.)."""

106

107

@function.setter

108

def function(self, value: str): ...

109

110

@property

111

def state(self) -> bool:

112

"""Current pin state (True=HIGH, False=LOW)."""

113

114

@state.setter

115

def state(self, value: bool): ...

116

117

@property

118

def pull(self) -> str:

119

"""Current pull resistor setting ('up', 'down', 'floating')."""

120

121

@pull.setter

122

def pull(self, value: str): ...

123

124

@property

125

def bounce(self) -> float:

126

"""Bounce time in seconds for edge detection."""

127

128

@bounce.setter

129

def bounce(self, value: float): ...

130

131

@property

132

def edges(self) -> str:

133

"""Edge detection setting ('none', 'falling', 'rising', 'both')."""

134

135

@edges.setter

136

def edges(self, value: str): ...

137

138

@property

139

def frequency(self) -> float:

140

"""PWM frequency in Hz."""

141

142

@frequency.setter

143

def frequency(self, value: float): ...

144

145

@property

146

def when_changed(self) -> callable:

147

"""Callback function for pin state changes."""

148

149

@when_changed.setter

150

def when_changed(self, value: callable): ...

151

```

152

153

### SPI

154

155

Abstract base class for SPI interfaces.

156

157

```python { .api }

158

class SPI:

159

def __init__(self, factory, port, device):

160

"""

161

Abstract base class for SPI interfaces.

162

163

Parameters:

164

- factory: Factory that created this interface

165

- port: SPI port number

166

- device: SPI device number

167

"""

168

169

def close(self):

170

"""Close the SPI interface."""

171

172

def transfer(self, data: list) -> list:

173

"""

174

Transfer data over SPI.

175

176

Parameters:

177

- data: List of bytes to send

178

179

Returns:

180

List of bytes received

181

"""

182

183

@property

184

def closed(self) -> bool:

185

"""Returns True if interface is closed."""

186

187

@property

188

def port(self) -> int:

189

"""SPI port number."""

190

191

@property

192

def device(self) -> int:

193

"""SPI device (chip select) number."""

194

```

195

196

## Board Information Classes

197

198

### BoardInfo

199

200

Information about a GPIO board.

201

202

```python { .api }

203

class BoardInfo:

204

def __init__(self, headers, **kwargs):

205

"""

206

Information about a GPIO board.

207

208

Parameters:

209

- headers: Dictionary of HeaderInfo objects

210

- **kwargs: Additional board properties

211

"""

212

213

def find_pin(self, spec) -> list:

214

"""

215

Find pin by specification.

216

217

Parameters:

218

- spec: Pin specification (number, name, or pattern)

219

220

Returns:

221

List of (header, pin_info) tuples matching specification

222

"""

223

224

@property

225

def headers(self) -> dict:

226

"""Dictionary of headers on this board."""

227

228

@property

229

def pins(self) -> dict:

230

"""Dictionary of all pins on this board."""

231

```

232

233

### HeaderInfo

234

235

Information about a pin header.

236

237

```python { .api }

238

class HeaderInfo:

239

def __init__(self, name, rows, columns, **kwargs):

240

"""

241

Information about a pin header.

242

243

Parameters:

244

- name: Header name

245

- rows: Number of rows

246

- columns: Number of columns

247

- **kwargs: Additional header properties

248

"""

249

250

@property

251

def name(self) -> str:

252

"""Header name."""

253

254

@property

255

def rows(self) -> int:

256

"""Number of rows in header."""

257

258

@property

259

def columns(self) -> int:

260

"""Number of columns in header."""

261

262

@property

263

def pins(self) -> dict:

264

"""Dictionary of pins in this header."""

265

```

266

267

### PinInfo

268

269

Information about a specific pin.

270

271

```python { .api }

272

class PinInfo:

273

def __init__(self, number, name, **kwargs):

274

"""

275

Information about a specific pin.

276

277

Parameters:

278

- number: Pin number

279

- name: Pin name

280

- **kwargs: Additional pin properties

281

"""

282

283

@property

284

def number(self) -> int:

285

"""Pin number."""

286

287

@property

288

def name(self) -> str:

289

"""Pin name."""

290

291

@property

292

def function(self) -> str:

293

"""Default pin function."""

294

295

@property

296

def pull(self) -> str:

297

"""Default pull resistor setting."""

298

299

@property

300

def row(self) -> int:

301

"""Header row position."""

302

303

@property

304

def col(self) -> int:

305

"""Header column position."""

306

```

307

308

## Raspberry Pi Specific Classes

309

310

### PiBoardInfo

311

312

Board information specific to Raspberry Pi.

313

314

```python { .api }

315

class PiBoardInfo(BoardInfo):

316

def __init__(self, revision=None, **kwargs):

317

"""

318

Raspberry Pi board information.

319

320

Parameters:

321

- revision: Pi revision string or None for auto-detect

322

- **kwargs: Additional board properties

323

"""

324

325

@property

326

def revision(self) -> str:

327

"""Pi board revision string."""

328

329

@property

330

def model(self) -> str:

331

"""Pi model name."""

332

333

@property

334

def pcb_revision(self) -> str:

335

"""PCB revision."""

336

337

@property

338

def memory(self) -> int:

339

"""Memory size in MB."""

340

341

@property

342

def manufacturer(self) -> str:

343

"""Board manufacturer."""

344

345

@property

346

def storage(self) -> str:

347

"""Storage type."""

348

349

@property

350

def usb(self) -> int:

351

"""Number of USB ports."""

352

353

@property

354

def ethernet(self) -> int:

355

"""Number of Ethernet ports."""

356

357

@property

358

def wifi(self) -> bool:

359

"""True if WiFi is available."""

360

361

@property

362

def bluetooth(self) -> bool:

363

"""True if Bluetooth is available."""

364

365

@property

366

def csi(self) -> int:

367

"""Number of CSI camera connectors."""

368

369

@property

370

def dsi(self) -> int:

371

"""Number of DSI display connectors."""

372

```

373

374

### pi_info Function

375

376

```python { .api }

377

def pi_info(revision=None) -> PiBoardInfo:

378

"""

379

Return board information for current or specified Pi revision.

380

381

Parameters:

382

- revision: str or None - Pi revision string or None for current Pi

383

384

Returns:

385

PiBoardInfo object for the specified Pi

386

"""

387

```

388

389

## Device Configuration

390

391

### Setting Pin Factory

392

393

```python { .api }

394

# Global pin factory configuration

395

from gpiozero import Device

396

from gpiozero.pins.pigpio import PiGPIOFactory

397

398

Device.pin_factory = PiGPIOFactory()

399

```

400

401

### Per-Device Pin Factory

402

403

```python { .api }

404

# Individual device pin factory

405

from gpiozero import LED

406

from gpiozero.pins.native import NativeFactory

407

408

led = LED(17, pin_factory=NativeFactory())

409

```

410

411

## Available Pin Factories

412

413

GPIO Zero includes several pin factory implementations:

414

415

### Default Factory (Auto-Detection)

416

417

The default factory automatically selects the best available backend:

418

419

1. **lgpio** - Preferred modern library

420

2. **RPi.GPIO** - Classic library

421

3. **pigpio** - High-performance library

422

4. **native** - Pure Python fallback

423

424

### Specific Factories

425

426

#### Native Factory

427

428

```python

429

from gpiozero.pins.native import NativeFactory

430

Device.pin_factory = NativeFactory()

431

```

432

433

Pure Python implementation, works on any Pi but limited functionality.

434

435

#### RPi.GPIO Factory

436

437

```python

438

from gpiozero.pins.rpigpio import RPiGPIOFactory

439

Device.pin_factory = RPiGPIOFactory()

440

```

441

442

Uses RPi.GPIO library, good compatibility but limited PWM.

443

444

#### pigpio Factory

445

446

```python

447

from gpiozero.pins.pigpio import PiGPIOFactory

448

Device.pin_factory = PiGPIOFactory()

449

```

450

451

High-performance library with accurate timing and hardware PWM.

452

453

#### lgpio Factory

454

455

```python

456

from gpiozero.pins.lgpio import LGPIOFactory

457

Device.pin_factory = LGPIOFactory()

458

```

459

460

Modern replacement for pigpio with similar features.

461

462

### Mock Factory

463

464

For testing and development without hardware:

465

466

```python

467

from gpiozero.pins.mock import MockFactory

468

Device.pin_factory = MockFactory()

469

```

470

471

## Usage Examples

472

473

### Board Information

474

475

```python

476

from gpiozero import Device

477

478

# Get current board info

479

board = Device.pin_factory.board_info

480

print(f"Board: {board.model}")

481

print(f"Revision: {board.revision}")

482

print(f"Memory: {board.memory}MB")

483

484

# Find pins by name

485

gpio17_pins = board.find_pin("GPIO17")

486

for header, pin_info in gpio17_pins:

487

print(f"Pin {pin_info.number}: {pin_info.name}")

488

489

# List all pins

490

for pin_num, pin_info in board.pins.items():

491

print(f"Pin {pin_num}: {pin_info.name}")

492

```

493

494

### Pin Factory Selection

495

496

```python

497

from gpiozero import LED, Device

498

from gpiozero.pins.pigpio import PiGPIOFactory

499

from gpiozero.pins.rpigpio import RPiGPIOFactory

500

501

# Set global pin factory

502

Device.pin_factory = PiGPIOFactory()

503

504

# All devices now use pigpio

505

led1 = LED(17)

506

led2 = LED(18)

507

508

# Override for specific device

509

led3 = LED(19, pin_factory=RPiGPIOFactory())

510

```

511

512

### Remote GPIO

513

514

```python

515

from gpiozero import LED

516

from gpiozero.pins.pigpio import PiGPIOFactory

517

518

# Connect to remote Pi

519

remote_factory = PiGPIOFactory(host='192.168.1.100', port=8888)

520

led = LED(17, pin_factory=remote_factory)

521

522

led.on()

523

```

524

525

### Mock Pin Testing

526

527

```python

528

from gpiozero import LED, Button

529

from gpiozero.pins.mock import MockFactory, MockPWMPin

530

531

# Set up mock factory

532

mock_factory = MockFactory()

533

Device.pin_factory = mock_factory

534

535

# Create devices (no hardware needed)

536

led = LED(17)

537

button = Button(2)

538

539

# Simulate hardware

540

mock_factory.pin(17).drive_high() # Simulate LED on

541

mock_factory.pin(2).drive_low() # Simulate button press

542

543

# Check device states

544

print(f"LED is {'on' if led.is_lit else 'off'}")

545

print(f"Button is {'pressed' if button.is_pressed else 'released'}")

546

```

547

548

### Custom Pin Factory

549

550

```python

551

from gpiozero.pins import Factory, Pin

552

from gpiozero import Device

553

554

class MyCustomFactory(Factory):

555

def __init__(self):

556

super().__init__()

557

# Initialize custom hardware interface

558

559

def pin(self, spec):

560

# Return custom pin implementation

561

return MyCustomPin(self, spec)

562

563

def _get_board_info(self):

564

# Return custom board information

565

return my_board_info

566

567

# Use custom factory

568

Device.pin_factory = MyCustomFactory()

569

```

570

571

### Pin Reservation

572

573

```python

574

from gpiozero import LED, Device

575

576

# Create device (pins are automatically reserved)

577

led = LED(17)

578

579

# Manual pin reservation

580

factory = Device.pin_factory

581

factory.reserve_pins(led, 17, 18, 19)

582

583

# Check reservations

584

try:

585

led2 = LED(17) # This will fail - pin already reserved

586

except GPIOPinInUse:

587

print("Pin 17 is already in use")

588

589

# Release reservations

590

led.close() # Automatically releases pin 17

591

factory.release_pins(led, 18, 19) # Manual release

592

```

593

594

### SPI Configuration

595

596

```python

597

from gpiozero import MCP3008

598

599

# Default SPI (port=0, device=0)

600

adc = MCP3008(channel=0)

601

602

# Custom SPI configuration

603

adc2 = MCP3008(channel=0, port=0, device=1) # Use CE1 instead of CE0

604

605

# Access underlying SPI interface

606

spi = Device.pin_factory.spi(port=0, device=0)

607

response = spi.transfer([0x01, 0x80, 0x00]) # Raw SPI transfer

608

spi.close()

609

```