or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

character-displays.mdcolor-displays.mdgreyscale-displays.mdindex.mdinterfaces.mdmonochrome-displays.md

interfaces.mddocs/

0

# Communication Interfaces

1

2

Serial communication interfaces provided by luma.core for connecting to OLED displays via I2C, SPI, and parallel protocols. These interfaces handle low-level communication while providing a consistent API across different hardware connections.

3

4

## Capabilities

5

6

### I2C Interface

7

8

Two-wire serial communication interface commonly used for OLED displays, requiring only clock and data lines plus power.

9

10

```python { .api }

11

class i2c:

12

def __init__(self, port=1, address=0x3C, **kwargs):

13

"""

14

Initialize I2C serial interface.

15

16

Parameters:

17

- port: I2C bus number (default: 1)

18

- address: I2C device address (default: 0x3C)

19

- **kwargs: Additional interface options

20

"""

21

22

def command(self, cmd, *args):

23

"""Send command byte(s) to the device."""

24

25

def data(self, values):

26

"""Send data byte(s) to the device."""

27

```

28

29

**Common I2C Addresses**:

30

- `0x3C` (60) - Most common for OLED displays

31

- `0x3D` (61) - Alternative address when multiple displays

32

33

Usage example:

34

35

```python

36

from luma.core.interface.serial import i2c

37

from luma.oled.device import ssd1306

38

39

# Standard I2C configuration

40

serial = i2c(port=1, address=0x3C)

41

device = ssd1306(serial)

42

43

# For multiple displays or address conflicts

44

serial2 = i2c(port=1, address=0x3D)

45

device2 = ssd1306(serial2)

46

47

# Using different I2C bus

48

serial3 = i2c(port=0, address=0x3C) # Bus 0 instead of 1

49

```

50

51

### SPI Interface

52

53

Four-wire serial peripheral interface providing faster communication speeds, commonly used for color and high-resolution displays.

54

55

```python { .api }

56

class spi:

57

def __init__(self, port=0, device=0, bus_speed_hz=8000000, **kwargs):

58

"""

59

Initialize SPI serial interface.

60

61

Parameters:

62

- port: SPI bus number (default: 0)

63

- device: SPI device number (default: 0)

64

- bus_speed_hz: SPI bus speed in Hz (default: 8MHz)

65

- **kwargs: Additional SPI options (CS_ACTIVE_LOW, etc.)

66

"""

67

68

def command(self, cmd, *args):

69

"""Send command byte(s) to the device."""

70

71

def data(self, values):

72

"""Send data byte(s) to the device."""

73

```

74

75

**Typical SPI Connections**:

76

- **SCLK/SCK**: Serial clock

77

- **MOSI/SDA**: Master Out Slave In (data)

78

- **CS/SS**: Chip Select (device selection)

79

- **DC/RS**: Data/Command selection

80

- **RST**: Reset (optional)

81

82

Usage example:

83

84

```python

85

from luma.core.interface.serial import spi

86

from luma.oled.device import ssd1351, ssd1322

87

88

# Standard SPI configuration for color displays

89

serial = spi(port=0, device=0, bus_speed_hz=8000000)

90

device = ssd1351(serial)

91

92

# Higher speed for large greyscale displays

93

serial_fast = spi(port=0, device=0, bus_speed_hz=16000000)

94

device_large = ssd1322(serial_fast, width=256, height=64)

95

96

# Multiple SPI devices

97

serial1 = spi(port=0, device=0) # CS0

98

serial2 = spi(port=0, device=1) # CS1

99

device1 = ssd1351(serial1)

100

device2 = ssd1351(serial2)

101

```

102

103

### Parallel Interface

104

105

Multi-wire parallel interface used primarily for character displays and some specialized OLED controllers.

106

107

```python { .api }

108

class parallel:

109

def __init__(self, RS=7, E=8, PINS=[25, 24, 23, 18], **kwargs):

110

"""

111

Initialize parallel serial interface.

112

113

Parameters:

114

- RS: Register Select pin number (default: 7)

115

- E: Enable pin number (default: 8)

116

- PINS: Data pin numbers list (default: [25, 24, 23, 18])

117

- **kwargs: Additional parallel options

118

"""

119

120

def command(self, cmd, *args):

121

"""Send command byte(s) to the device."""

122

123

def data(self, values):

124

"""Send data byte(s) to the device."""

125

```

126

127

**Pin Functions**:

128

- **RS (Register Select)**: Command (0) or Data (1) mode

129

- **E (Enable)**: Strobe signal for data transfer

130

- **D0-D7**: 8-bit data bus (or D4-D7 for 4-bit mode)

131

132

Usage example:

133

134

```python

135

from luma.core.interface.serial import parallel

136

from luma.oled.device import ws0010, winstar_weh

137

138

# 4-bit parallel mode (most common)

139

serial = parallel(

140

RS=7, # Register Select

141

E=8, # Enable

142

PINS=[25, 24, 23, 18] # D4, D5, D6, D7

143

)

144

device = ws0010(serial)

145

146

# 8-bit parallel mode (if supported)

147

serial_8bit = parallel(

148

RS=7, E=8,

149

PINS=[25, 24, 23, 18, 17, 16, 15, 14] # D0-D7

150

)

151

152

# Character display

153

device_char = winstar_weh(serial, width=16, height=2)

154

```

155

156

## Interface Selection Guidelines

157

158

### Choose I2C When:

159

- **Simple connections**: Only 2 wires plus power needed

160

- **Multiple devices**: Easy to chain multiple displays

161

- **Limited GPIO pins**: Minimal pin usage

162

- **Monochrome displays**: Adequate speed for simple graphics

163

164

```python

165

# I2C - Best for simple monochrome displays

166

serial = i2c(port=1, address=0x3C)

167

device = ssd1306(serial) # Simple setup

168

```

169

170

### Choose SPI When:

171

- **High performance**: Faster data transfer rates

172

- **Color displays**: Large amounts of data to transfer

173

- **Large displays**: High resolution or frequent updates

174

- **Dedicated connections**: Each display needs separate CS line

175

176

```python

177

# SPI - Best for color and large displays

178

serial = spi(port=0, device=0, bus_speed_hz=16000000)

179

device = ssd1351(serial) # Color display with high speed

180

```

181

182

### Choose Parallel When:

183

- **Character displays**: Required for WS0010-based displays

184

- **Legacy compatibility**: Working with older display modules

185

- **Specialized controllers**: Some displays only support parallel

186

187

```python

188

# Parallel - Required for character displays

189

serial = parallel(RS=7, E=8, PINS=[25, 24, 23, 18])

190

device = ws0010(serial) # Character display

191

```

192

193

## Hardware Configuration

194

195

### Raspberry Pi GPIO

196

197

Common GPIO pin assignments for Raspberry Pi:

198

199

```python

200

# I2C (uses dedicated I2C pins)

201

serial = i2c(port=1, address=0x3C) # GPIO 2 (SDA), GPIO 3 (SCL)

202

203

# SPI (uses dedicated SPI pins)

204

serial = spi(port=0, device=0) # GPIO 10 (MOSI), GPIO 11 (SCLK), GPIO 8 (CS0)

205

206

# Parallel (uses general GPIO pins)

207

serial = parallel(

208

RS=7, # GPIO 7

209

E=8, # GPIO 8

210

PINS=[25, 24, 23, 18] # GPIO 25, 24, 23, 18

211

)

212

```

213

214

### Multiple Displays

215

216

```python

217

# Multiple I2C displays (different addresses)

218

serial1 = i2c(port=1, address=0x3C)

219

serial2 = i2c(port=1, address=0x3D)

220

device1 = ssd1306(serial1)

221

device2 = ssd1306(serial2)

222

223

# Multiple SPI displays (different CS pins)

224

serial1 = spi(port=0, device=0) # CS0

225

serial2 = spi(port=0, device=1) # CS1

226

device1 = ssd1351(serial1)

227

device2 = ssd1351(serial2)

228

229

# Multiple parallel displays (different pin sets)

230

serial1 = parallel(RS=7, E=8, PINS=[25, 24, 23, 18])

231

serial2 = parallel(RS=12, E=13, PINS=[21, 20, 19, 16])

232

device1 = ws0010(serial1)

233

device2 = ws0010(serial2)

234

```

235

236

## Troubleshooting

237

238

### I2C Issues

239

240

```python

241

# Check I2C device detection

242

# Run: i2cdetect -y 1

243

244

# Try different address

245

serial = i2c(port=1, address=0x3D) # Instead of 0x3C

246

247

# Check I2C bus number

248

serial = i2c(port=0, address=0x3C) # Try bus 0

249

```

250

251

### SPI issues

252

253

```python

254

# Reduce bus speed for troubleshooting

255

serial = spi(port=0, device=0, bus_speed_hz=1000000) # 1MHz instead of 8MHz

256

257

# Check SPI device

258

serial = spi(port=0, device=1) # Try CS1 instead of CS0

259

```

260

261

### Parallel Issues

262

263

```python

264

# Verify pin assignments

265

serial = parallel(RS=7, E=8, PINS=[25, 24, 23, 18])

266

267

# Add execution delay if needed

268

device = ws0010(serial, exec_time=1e-6 * 100) # 100µs instead of 50µs

269

```

270

271

## Performance Considerations

272

273

### Bus Speed Optimization

274

275

```python

276

# Conservative speeds (reliable)

277

i2c_slow = i2c(port=1, address=0x3C) # ~100kHz (I2C standard)

278

spi_slow = spi(port=0, device=0, bus_speed_hz=1000000) # 1MHz

279

280

# Optimized speeds (faster updates)

281

spi_fast = spi(port=0, device=0, bus_speed_hz=16000000) # 16MHz

282

spi_max = spi(port=0, device=0, bus_speed_hz=32000000) # 32MHz (if supported)

283

```

284

285

### Interface Comparison

286

287

| Interface | Speed | Pins | Multiple Devices | Best For |

288

|-----------|----------|------|------------------|----------|

289

| I2C | ~400kHz | 2 | Easy (addresses) | Monochrome |

290

| SPI | 1-32MHz | 4+ | Medium (CS pins) | Color/Large |

291

| Parallel | Variable | 6-10 | Hard (pin sets) | Character |