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

spi-devices.mddocs/

0

# SPI Devices

1

2

SPI-connected devices including analog-to-digital converters (ADCs) from the MCP3xxx family. These devices enable reading analog sensor values and can be used as sources for other devices.

3

4

## Base Classes

5

6

### SPIDevice

7

8

Base class for all SPI-connected devices.

9

10

```python { .api }

11

class SPIDevice(Device):

12

def __init__(self, *, port=0, device=0, pin_factory=None):

13

"""

14

Base class for SPI devices.

15

16

Parameters:

17

- port: int - SPI port number (usually 0)

18

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

19

- pin_factory: Factory or None - Pin factory for advanced usage

20

"""

21

22

@property

23

def closed(self) -> bool:

24

"""Returns True if device is closed."""

25

26

def close(self):

27

"""Close the device and release resources."""

28

```

29

30

### AnalogInputDevice

31

32

Base class for analog-to-digital converter devices.

33

34

```python { .api }

35

class AnalogInputDevice(SPIDevice):

36

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

37

"""

38

Base class for ADC devices.

39

40

Parameters:

41

- channel: int - ADC channel number to read from

42

- differential: bool - True for differential reading, False for single-ended

43

- max_voltage: float - Maximum input voltage for scaling

44

- **spi_args: Additional SPI configuration arguments

45

"""

46

47

@property

48

def value(self) -> float:

49

"""Current analog reading scaled to 0.0-1.0 range."""

50

51

@property

52

def voltage(self) -> float:

53

"""Current reading as voltage (0.0 to max_voltage)."""

54

55

@property

56

def raw_value(self) -> int:

57

"""Raw ADC reading as integer."""

58

59

@property

60

def channel(self) -> int:

61

"""ADC channel being read."""

62

63

@property

64

def differential(self) -> bool:

65

"""True if using differential reading mode."""

66

67

@property

68

def max_voltage(self) -> float:

69

"""Maximum input voltage for scaling."""

70

```

71

72

## MCP30xx Series (10-bit ADCs)

73

74

### MCP3001

75

76

Single-channel 10-bit ADC.

77

78

```python { .api }

79

class MCP3001(AnalogInputDevice):

80

def __init__(self, *, max_voltage=3.3, **spi_args):

81

"""

82

MCP3001 10-bit single-channel ADC.

83

84

Parameters:

85

- max_voltage: float - Maximum input voltage (default 3.3V)

86

- **spi_args: SPI configuration (port, device, etc.)

87

"""

88

```

89

90

### MCP3002

91

92

Dual-channel 10-bit ADC.

93

94

```python { .api }

95

class MCP3002(AnalogInputDevice):

96

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

97

"""

98

MCP3002 10-bit dual-channel ADC.

99

100

Parameters:

101

- channel: int - Channel number (0 or 1)

102

- differential: bool - True for differential mode

103

- max_voltage: float - Maximum input voltage

104

- **spi_args: SPI configuration

105

"""

106

```

107

108

### MCP3004

109

110

4-channel 10-bit ADC.

111

112

```python { .api }

113

class MCP3004(AnalogInputDevice):

114

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

115

"""

116

MCP3004 10-bit 4-channel ADC.

117

118

Parameters:

119

- channel: int - Channel number (0-3)

120

- differential: bool - True for differential mode

121

- max_voltage: float - Maximum input voltage

122

- **spi_args: SPI configuration

123

"""

124

```

125

126

### MCP3008

127

128

8-channel 10-bit ADC (most commonly used).

129

130

```python { .api }

131

class MCP3008(AnalogInputDevice):

132

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

133

"""

134

MCP3008 10-bit 8-channel ADC.

135

136

Parameters:

137

- channel: int - Channel number (0-7)

138

- differential: bool - True for differential mode

139

- max_voltage: float - Maximum input voltage

140

- **spi_args: SPI configuration (port=0, device=0)

141

"""

142

```

143

144

## MCP32xx Series (12-bit ADCs)

145

146

### MCP3201

147

148

Single-channel 12-bit ADC.

149

150

```python { .api }

151

class MCP3201(AnalogInputDevice):

152

def __init__(self, *, max_voltage=3.3, **spi_args):

153

"""

154

MCP3201 12-bit single-channel ADC.

155

156

Parameters:

157

- max_voltage: float - Maximum input voltage

158

- **spi_args: SPI configuration

159

"""

160

```

161

162

### MCP3202

163

164

Dual-channel 12-bit ADC.

165

166

```python { .api }

167

class MCP3202(AnalogInputDevice):

168

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

169

"""

170

MCP3202 12-bit dual-channel ADC.

171

172

Parameters:

173

- channel: int - Channel number (0 or 1)

174

- differential: bool - True for differential mode

175

- max_voltage: float - Maximum input voltage

176

- **spi_args: SPI configuration

177

"""

178

```

179

180

### MCP3204

181

182

4-channel 12-bit ADC.

183

184

```python { .api }

185

class MCP3204(AnalogInputDevice):

186

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

187

"""

188

MCP3204 12-bit 4-channel ADC.

189

190

Parameters:

191

- channel: int - Channel number (0-3)

192

- differential: bool - True for differential mode

193

- max_voltage: float - Maximum input voltage

194

- **spi_args: SPI configuration

195

"""

196

```

197

198

### MCP3208

199

200

8-channel 12-bit ADC.

201

202

```python { .api }

203

class MCP3208(AnalogInputDevice):

204

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

205

"""

206

MCP3208 12-bit 8-channel ADC.

207

208

Parameters:

209

- channel: int - Channel number (0-7)

210

- differential: bool - True for differential mode

211

- max_voltage: float - Maximum input voltage

212

- **spi_args: SPI configuration

213

"""

214

```

215

216

## MCP33xx Series (13-bit Signed ADCs)

217

218

### MCP3301

219

220

Single-channel 13-bit signed ADC.

221

222

```python { .api }

223

class MCP3301(AnalogInputDevice):

224

def __init__(self, *, max_voltage=3.3, **spi_args):

225

"""

226

MCP3301 13-bit single-channel signed ADC.

227

228

Parameters:

229

- max_voltage: float - Maximum input voltage

230

- **spi_args: SPI configuration

231

"""

232

```

233

234

### MCP3302

235

236

4-channel 13-bit signed ADC.

237

238

```python { .api }

239

class MCP3302(AnalogInputDevice):

240

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

241

"""

242

MCP3302 13-bit 4-channel signed ADC.

243

244

Parameters:

245

- channel: int - Channel number (0-3)

246

- differential: bool - True for differential mode

247

- max_voltage: float - Maximum input voltage

248

- **spi_args: SPI configuration

249

"""

250

```

251

252

### MCP3304

253

254

8-channel 13-bit signed ADC.

255

256

```python { .api }

257

class MCP3304(AnalogInputDevice):

258

def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):

259

"""

260

MCP3304 13-bit 8-channel signed ADC.

261

262

Parameters:

263

- channel: int - Channel number (0-7)

264

- differential: bool - True for differential mode

265

- max_voltage: float - Maximum input voltage

266

- **spi_args: SPI configuration

267

"""

268

```

269

270

## Usage Examples

271

272

### Basic Analog Reading

273

274

```python

275

from gpiozero import MCP3008

276

from time import sleep

277

278

# Single channel reading

279

adc = MCP3008(channel=0)

280

281

while True:

282

value = adc.value # 0.0 to 1.0

283

voltage = adc.voltage # 0.0 to 3.3V (or max_voltage)

284

raw = adc.raw_value # Raw ADC counts

285

286

print(f"Value: {value:.3f}, Voltage: {voltage:.2f}V, Raw: {raw}")

287

sleep(0.5)

288

```

289

290

### Multiple Channel Reading

291

292

```python

293

from gpiozero import MCP3008

294

295

# Create ADC objects for different channels

296

channels = [MCP3008(channel=i) for i in range(4)]

297

298

while True:

299

readings = [adc.value for adc in channels]

300

print(f"Channels 0-3: {readings}")

301

sleep(0.1)

302

```

303

304

### Potentiometer Control

305

306

```python

307

from gpiozero import MCP3008, PWMLED

308

from signal import pause

309

310

pot = MCP3008(channel=0)

311

led = PWMLED(17)

312

313

# LED brightness follows potentiometer

314

led.source = pot

315

316

pause()

317

```

318

319

### Analog Sensor with Thresholds

320

321

```python

322

from gpiozero import MCP3008, LED

323

from time import sleep

324

325

sensor = MCP3008(channel=0)

326

warning_led = LED(17)

327

alarm_led = LED(18)

328

329

while True:

330

value = sensor.value

331

332

if value > 0.8:

333

warning_led.off()

334

alarm_led.on()

335

print("ALARM: High reading!")

336

elif value > 0.6:

337

warning_led.on()

338

alarm_led.off()

339

print("Warning: Elevated reading")

340

else:

341

warning_led.off()

342

alarm_led.off()

343

print(f"Normal: {value:.3f}")

344

345

sleep(0.5)

346

```

347

348

### Temperature Sensor (TMP36)

349

350

```python

351

from gpiozero import MCP3008

352

from time import sleep

353

354

# TMP36 temperature sensor on channel 0

355

temp_sensor = MCP3008(channel=0)

356

357

while True:

358

voltage = temp_sensor.voltage

359

# TMP36: 10mV per degree C, 500mV offset, 0°C = 0.5V

360

temperature_c = (voltage - 0.5) * 100

361

temperature_f = temperature_c * 9/5 + 32

362

363

print(f"Temperature: {temperature_c:.1f}°C ({temperature_f:.1f}°F)")

364

sleep(1)

365

```

366

367

### Light Sensor (Photoresistor)

368

369

```python

370

from gpiozero import MCP3008, LED

371

from signal import pause

372

373

# Photoresistor voltage divider on channel 0

374

light_sensor = MCP3008(channel=0)

375

night_light = LED(17)

376

377

def update_light():

378

light_level = light_sensor.value

379

# Turn on LED when it's dark (low light reading)

380

night_light.value = 1 - light_level

381

382

# Update every 100ms

383

light_sensor.when_changed = update_light

384

385

pause()

386

```

387

388

### Differential Reading

389

390

```python

391

from gpiozero import MCP3008

392

393

# Differential reading between channels 0 and 1

394

diff_adc = MCP3008(channel=0, differential=True)

395

396

while True:

397

# This reads the voltage difference between CH0+ and CH0- (CH1)

398

diff_voltage = diff_adc.voltage

399

print(f"Differential voltage: {diff_voltage:.3f}V")

400

sleep(0.1)

401

```

402

403

### Data Logging

404

405

```python

406

from gpiozero import MCP3008

407

import csv

408

import time

409

410

sensors = [MCP3008(channel=i) for i in range(3)]

411

412

with open('sensor_data.csv', 'w', newline='') as csvfile:

413

writer = csv.writer(csvfile)

414

writer.writerow(['timestamp', 'channel_0', 'channel_1', 'channel_2'])

415

416

try:

417

while True:

418

timestamp = time.time()

419

readings = [sensor.voltage for sensor in sensors]

420

writer.writerow([timestamp] + readings)

421

print(f"Logged: {readings}")

422

time.sleep(1)

423

except KeyboardInterrupt:

424

print("Data logging stopped")

425

```

426

427

### Custom Voltage Reference

428

429

```python

430

from gpiozero import MCP3008

431

432

# Using 5V reference instead of default 3.3V

433

adc_5v = MCP3008(channel=0, max_voltage=5.0)

434

435

while True:

436

voltage = adc_5v.voltage # Now scaled to 0-5V range

437

print(f"Voltage (5V ref): {voltage:.2f}V")

438

sleep(0.5)

439

```

440

441

## SPI Configuration

442

443

All MCP3xxx devices support additional SPI configuration parameters:

444

445

```python

446

# Custom SPI configuration

447

adc = MCP3008(

448

channel=0,

449

port=0, # SPI port (usually 0)

450

device=1, # Chip select (CE1 instead of CE0)

451

max_voltage=5.0, # Voltage reference

452

differential=False # Single-ended reading

453

)

454

```

455

456

Common SPI connections on Raspberry Pi:

457

- **MOSI**: GPIO 10 (Pin 19)

458

- **MISO**: GPIO 9 (Pin 21)

459

- **SCLK**: GPIO 11 (Pin 23)

460

- **CE0**: GPIO 8 (Pin 24) - device=0

461

- **CE1**: GPIO 7 (Pin 26) - device=1