or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbluetooth-communication.mdcore-protocol.mdgui-components.mdindex.mdmessage-handling.mdserial-communication.md

advanced-features.mddocs/

0

# Advanced Arduino Features

1

2

Specialized Arduino functionality including interrupts, tone generation, pulse measurement, and EEPROM operations for advanced hardware control. These features enable sophisticated Arduino applications with real-time event handling, audio output, timing measurements, and persistent data storage.

3

4

## Capabilities

5

6

### External Interrupts

7

8

Hardware interrupt support for real-time event handling on Arduino interrupt-capable pins.

9

10

```java { .api }

11

enum InterruptPin {

12

PIN_2_INT0, // Arduino Uno pin 2 (interrupt 0)

13

PIN_3_INT1; // Arduino Uno pin 3 (interrupt 1)

14

15

byte getValue();

16

static InterruptPin fromValue(byte b);

17

}

18

19

enum InterruptTrigger {

20

CHANGE, // Trigger on any logic change

21

RISING, // Trigger on rising edge (LOW to HIGH)

22

FALLING, // Trigger on falling edge (HIGH to LOW)

23

LOW; // Trigger when pin is LOW

24

}

25

26

// Interrupt management commands

27

static FixedSizePacket createAttachInterrupt(InterruptPin interrupt, InterruptTrigger mode);

28

static FixedSizePacket createDetachInterrupt(InterruptPin interrupt);

29

30

// Interrupt notification message

31

class InterruptNotificationMsg extends JArduinoProtocolPacket {

32

InterruptPin getInterrupt();

33

}

34

```

35

36

### Tone Generation

37

38

Audio tone generation capability for buzzers, speakers, and audio feedback.

39

40

```java { .api }

41

// Tone generation commands

42

static FixedSizePacket createTone(DigitalPin pin, short frequency, short duration);

43

static FixedSizePacket createNoTone(DigitalPin pin);

44

45

// Tone command messages

46

class ToneMsg extends JArduinoProtocolPacket {

47

DigitalPin getPin();

48

short getFrequency(); // Hz (20 - 20000)

49

short getDuration(); // milliseconds (0 = continuous)

50

}

51

52

class NoToneMsg extends JArduinoProtocolPacket {

53

DigitalPin getPin();

54

}

55

```

56

57

### Pulse Measurement

58

59

Precise timing measurement for ultrasonic sensors, encoders, and timing-critical applications.

60

61

```java { .api }

62

// Pulse measurement command

63

static FixedSizePacket createPulseIn(DigitalPin pin, DigitalState state);

64

65

// Pulse measurement messages

66

class PulseInMsg extends JArduinoProtocolPacket {

67

DigitalPin getPin();

68

DigitalState getState(); // HIGH or LOW pulse to measure

69

}

70

71

class PulseInResultMsg extends JArduinoProtocolPacket {

72

int getValue(); // Pulse duration in microseconds

73

}

74

```

75

76

### EEPROM Operations

77

78

Non-volatile memory operations for persistent configuration and data storage.

79

80

```java { .api }

81

// EEPROM commands

82

static FixedSizePacket createEeprom_read(short address);

83

static FixedSizePacket createEeprom_write(short address, byte value);

84

static FixedSizePacket createEeprom_sync_write(short address, byte value);

85

86

// EEPROM messages

87

class Eeprom_readMsg extends JArduinoProtocolPacket {

88

short getAddress(); // EEPROM address (0-1023 for Arduino Uno)

89

}

90

91

class Eeprom_writeMsg extends JArduinoProtocolPacket {

92

short getAddress();

93

byte getValue();

94

}

95

96

class Eeprom_sync_writeMsg extends JArduinoProtocolPacket {

97

short getAddress();

98

byte getValue();

99

}

100

101

// EEPROM result messages

102

class Eeprom_valueMsg extends JArduinoProtocolPacket {

103

short getAddress();

104

byte getValue();

105

}

106

107

class Eeprom_write_ackMsg extends JArduinoProtocolPacket {

108

short getAddress();

109

}

110

```

111

112

### Communication Testing

113

114

Built-in connectivity testing for Arduino communication reliability.

115

116

```java { .api }

117

// Ping/pong commands for connection testing

118

static FixedSizePacket createPing();

119

static FixedSizePacket createPong();

120

121

// Ping/pong messages

122

class PingMsg extends JArduinoProtocolPacket;

123

class PongMsg extends JArduinoProtocolPacket;

124

```

125

126

## Usage Examples

127

128

### External Interrupt Handling

129

130

```java

131

import org.sintef.jarduino.*;

132

import org.sintef.jarduino.observer.JArduinoObserver;

133

134

public class InterruptExample implements JArduinoObserver {

135

private Serial4JArduino arduino;

136

137

public void setupInterrupts() {

138

arduino = new Serial4JArduino("COM3");

139

arduino.register(this);

140

141

// Attach interrupt on pin 2 for button press detection

142

FixedSizePacket attachBtn = JArduinoProtocol.createAttachInterrupt(

143

InterruptPin.PIN_2_INT0,

144

InterruptTrigger.RISING

145

);

146

arduino.receiveMsg(attachBtn.getPacket());

147

148

// Attach interrupt on pin 3 for motion sensor

149

FixedSizePacket attachMotion = JArduinoProtocol.createAttachInterrupt(

150

InterruptPin.PIN_3_INT1,

151

InterruptTrigger.CHANGE

152

);

153

arduino.receiveMsg(attachMotion.getPacket());

154

}

155

156

@Override

157

public void receiveMsg(byte[] msg) {

158

FixedSizePacket packet = JArduinoProtocol.createMessageFromPacket(msg);

159

160

if (packet instanceof InterruptNotificationMsg) {

161

InterruptNotificationMsg notification = (InterruptNotificationMsg) packet;

162

InterruptPin interrupt = notification.getInterrupt();

163

164

switch (interrupt) {

165

case PIN_2_INT0:

166

handleButtonPress();

167

break;

168

case PIN_3_INT1:

169

handleMotionDetected();

170

break;

171

}

172

}

173

}

174

175

private void handleButtonPress() {

176

System.out.println("Button pressed!");

177

// Trigger LED or other response

178

FixedSizePacket ledOn = JArduinoProtocol.createDigitalWrite(

179

DigitalPin.PIN_13, DigitalState.HIGH

180

);

181

arduino.receiveMsg(ledOn.getPacket());

182

}

183

184

private void handleMotionDetected() {

185

System.out.println("Motion detected!");

186

// Trigger alarm or recording

187

}

188

189

public void cleanup() {

190

// Detach interrupts

191

FixedSizePacket detach1 = JArduinoProtocol.createDetachInterrupt(InterruptPin.PIN_2_INT0);

192

FixedSizePacket detach2 = JArduinoProtocol.createDetachInterrupt(InterruptPin.PIN_3_INT1);

193

194

arduino.receiveMsg(detach1.getPacket());

195

arduino.receiveMsg(detach2.getPacket());

196

arduino.close();

197

}

198

}

199

```

200

201

### Tone Generation for Audio Feedback

202

203

```java

204

public class AudioFeedbackExample {

205

private Serial4JArduino arduino;

206

207

public AudioFeedbackExample(Serial4JArduino arduino) {

208

this.arduino = arduino;

209

}

210

211

public void playStartupSound() {

212

// Play a sequence of tones

213

playTone(DigitalPin.PIN_8, 440, 200); // A4 for 200ms

214

sleep(50);

215

playTone(DigitalPin.PIN_8, 554, 200); // C#5 for 200ms

216

sleep(50);

217

playTone(DigitalPin.PIN_8, 659, 400); // E5 for 400ms

218

}

219

220

public void playErrorSound() {

221

// Play error tone

222

playTone(DigitalPin.PIN_8, 200, 500); // Low frequency, 500ms

223

}

224

225

public void playSuccessSound() {

226

// Play success chime

227

playTone(DigitalPin.PIN_8, 800, 100); // High frequency, short

228

sleep(50);

229

playTone(DigitalPin.PIN_8, 1000, 100);

230

}

231

232

public void startAlarm() {

233

// Continuous alarm tone

234

FixedSizePacket alarm = JArduinoProtocol.createTone(

235

DigitalPin.PIN_8,

236

(short) 1000,

237

(short) 0 // 0 = continuous

238

);

239

arduino.receiveMsg(alarm.getPacket());

240

}

241

242

public void stopAlarm() {

243

FixedSizePacket stopTone = JArduinoProtocol.createNoTone(DigitalPin.PIN_8);

244

arduino.receiveMsg(stopTone.getPacket());

245

}

246

247

private void playTone(DigitalPin pin, int frequency, int duration) {

248

FixedSizePacket tone = JArduinoProtocol.createTone(

249

pin,

250

(short) frequency,

251

(short) duration

252

);

253

arduino.receiveMsg(tone.getPacket());

254

}

255

256

private void sleep(int ms) {

257

try { Thread.sleep(ms); } catch (InterruptedException e) {}

258

}

259

}

260

```

261

262

### Ultrasonic Distance Sensor

263

264

```java

265

public class UltrasonicSensor implements JArduinoObserver {

266

private Serial4JArduino arduino;

267

private DigitalPin triggerPin = DigitalPin.PIN_7;

268

private DigitalPin echoPin = DigitalPin.PIN_8;

269

270

public UltrasonicSensor(Serial4JArduino arduino) {

271

this.arduino = arduino;

272

arduino.register(this);

273

setupPins();

274

}

275

276

private void setupPins() {

277

// Set trigger pin as output, echo pin as input

278

FixedSizePacket triggerMode = JArduinoProtocol.createPinMode(triggerPin, PinMode.OUTPUT);

279

FixedSizePacket echoMode = JArduinoProtocol.createPinMode(echoPin, PinMode.INPUT);

280

281

arduino.receiveMsg(triggerMode.getPacket());

282

arduino.receiveMsg(echoMode.getPacket());

283

}

284

285

public void measureDistance() {

286

// Send 10μs trigger pulse

287

FixedSizePacket triggerHigh = JArduinoProtocol.createDigitalWrite(triggerPin, DigitalState.HIGH);

288

arduino.receiveMsg(triggerHigh.getPacket());

289

290

try { Thread.sleep(1); } catch (InterruptedException e) {} // 1ms delay

291

292

FixedSizePacket triggerLow = JArduinoProtocol.createDigitalWrite(triggerPin, DigitalState.LOW);

293

arduino.receiveMsg(triggerLow.getPacket());

294

295

// Measure HIGH pulse duration on echo pin

296

FixedSizePacket pulseIn = JArduinoProtocol.createPulseIn(echoPin, DigitalState.HIGH);

297

arduino.receiveMsg(pulseIn.getPacket());

298

}

299

300

@Override

301

public void receiveMsg(byte[] msg) {

302

FixedSizePacket packet = JArduinoProtocol.createMessageFromPacket(msg);

303

304

if (packet instanceof PulseInResultMsg) {

305

PulseInResultMsg result = (PulseInResultMsg) packet;

306

int duration = result.getValue(); // Duration in microseconds

307

308

// Calculate distance in centimeters

309

// Speed of sound = 343 m/s = 0.0343 cm/μs

310

// Distance = (duration * 0.0343) / 2 (divide by 2 for round trip)

311

double distance = (duration * 0.0343) / 2.0;

312

313

System.out.println("Distance: " + distance + " cm");

314

handleDistanceMeasurement(distance);

315

}

316

}

317

318

private void handleDistanceMeasurement(double distance) {

319

if (distance < 10.0) {

320

System.out.println("Object too close!");

321

// Trigger warning

322

} else if (distance > 200.0) {

323

System.out.println("Object out of range");

324

} else {

325

System.out.println("Distance measured: " + distance + " cm");

326

}

327

}

328

}

329

```

330

331

### EEPROM Configuration Management

332

333

```java

334

public class ConfigurationManager implements JArduinoObserver {

335

private Serial4JArduino arduino;

336

private Map<Short, Byte> configCache = new HashMap<>();

337

338

// Configuration addresses

339

private static final short SENSOR_THRESHOLD_ADDR = 0;

340

private static final short LED_BRIGHTNESS_ADDR = 1;

341

private static final short ALARM_ENABLED_ADDR = 2;

342

private static final short CALIBRATION_ADDR = 10; // Multiple bytes starting at 10

343

344

public ConfigurationManager(Serial4JArduino arduino) {

345

this.arduino = arduino;

346

arduino.register(this);

347

}

348

349

public void loadConfiguration() {

350

// Read configuration values from EEPROM

351

readEEPROM(SENSOR_THRESHOLD_ADDR);

352

readEEPROM(LED_BRIGHTNESS_ADDR);

353

readEEPROM(ALARM_ENABLED_ADDR);

354

355

// Read calibration data (multiple bytes)

356

for (short addr = CALIBRATION_ADDR; addr < CALIBRATION_ADDR + 10; addr++) {

357

readEEPROM(addr);

358

}

359

}

360

361

public void saveConfiguration() {

362

// Save current configuration to EEPROM

363

writeEEPROM(SENSOR_THRESHOLD_ADDR, (byte) 128); // Default threshold

364

writeEEPROM(LED_BRIGHTNESS_ADDR, (byte) 255); // Max brightness

365

writeEEPROM(ALARM_ENABLED_ADDR, (byte) 1); // Alarm enabled

366

}

367

368

public void setSensorThreshold(int threshold) {

369

byte value = (byte) Math.min(255, Math.max(0, threshold));

370

writeEEPROM(SENSOR_THRESHOLD_ADDR, value);

371

}

372

373

public void setLEDBrightness(int brightness) {

374

byte value = (byte) Math.min(255, Math.max(0, brightness));

375

writeEEPROM(LED_BRIGHTNESS_ADDR, value);

376

}

377

378

public void setAlarmEnabled(boolean enabled) {

379

writeEEPROM(ALARM_ENABLED_ADDR, (byte) (enabled ? 1 : 0));

380

}

381

382

public void saveCalibrationData(byte[] calibrationData) {

383

for (int i = 0; i < calibrationData.length && i < 10; i++) {

384

writeEEPROM((short) (CALIBRATION_ADDR + i), calibrationData[i]);

385

}

386

}

387

388

private void readEEPROM(short address) {

389

FixedSizePacket read = JArduinoProtocol.createEeprom_read(address);

390

arduino.receiveMsg(read.getPacket());

391

}

392

393

private void writeEEPROM(short address, byte value) {

394

FixedSizePacket write = JArduinoProtocol.createEeprom_sync_write(address, value);

395

arduino.receiveMsg(write.getPacket());

396

}

397

398

@Override

399

public void receiveMsg(byte[] msg) {

400

FixedSizePacket packet = JArduinoProtocol.createMessageFromPacket(msg);

401

402

if (packet instanceof Eeprom_valueMsg) {

403

Eeprom_valueMsg result = (Eeprom_valueMsg) packet;

404

short address = result.getAddress();

405

byte value = result.getValue();

406

407

configCache.put(address, value);

408

System.out.println("EEPROM[" + address + "] = " + (value & 0xFF));

409

410

handleConfigurationValue(address, value);

411

412

} else if (packet instanceof Eeprom_write_ackMsg) {

413

Eeprom_write_ackMsg ack = (Eeprom_write_ackMsg) packet;

414

System.out.println("EEPROM write confirmed at address: " + ack.getAddress());

415

}

416

}

417

418

private void handleConfigurationValue(short address, byte value) {

419

switch (address) {

420

case SENSOR_THRESHOLD_ADDR:

421

System.out.println("Sensor threshold: " + (value & 0xFF));

422

break;

423

case LED_BRIGHTNESS_ADDR:

424

System.out.println("LED brightness: " + (value & 0xFF));

425

break;

426

case ALARM_ENABLED_ADDR:

427

System.out.println("Alarm enabled: " + (value != 0));

428

break;

429

default:

430

if (address >= CALIBRATION_ADDR && address < CALIBRATION_ADDR + 10) {

431

System.out.println("Calibration[" + (address - CALIBRATION_ADDR) + "] = " + (value & 0xFF));

432

}

433

break;

434

}

435

}

436

437

public byte getCachedValue(short address) {

438

return configCache.getOrDefault(address, (byte) 0);

439

}

440

}

441

```

442

443

### Connection Monitoring

444

445

```java

446

public class ConnectionMonitor implements JArduinoObserver {

447

private Serial4JArduino arduino;

448

private boolean isConnected = false;

449

private Timer pingTimer;

450

451

public ConnectionMonitor(Serial4JArduino arduino) {

452

this.arduino = arduino;

453

arduino.register(this);

454

startPeriodicPing();

455

}

456

457

private void startPeriodicPing() {

458

pingTimer = new Timer(5000, e -> sendPing()); // Ping every 5 seconds

459

pingTimer.start();

460

}

461

462

private void sendPing() {

463

FixedSizePacket ping = JArduinoProtocol.createPing();

464

arduino.receiveMsg(ping.getPacket());

465

466

// Set timeout to detect disconnection

467

Timer timeoutTimer = new Timer(2000, e -> handlePingTimeout());

468

timeoutTimer.setRepeats(false);

469

timeoutTimer.start();

470

}

471

472

@Override

473

public void receiveMsg(byte[] msg) {

474

FixedSizePacket packet = JArduinoProtocol.createMessageFromPacket(msg);

475

476

if (packet instanceof PongMsg) {

477

if (!isConnected) {

478

System.out.println("Arduino connection established");

479

isConnected = true;

480

notifyConnectionRestored();

481

}

482

}

483

}

484

485

private void handlePingTimeout() {

486

if (isConnected) {

487

System.out.println("Arduino connection lost");

488

isConnected = false;

489

notifyConnectionLost();

490

}

491

}

492

493

private void notifyConnectionRestored() {

494

// Notify application that Arduino is connected

495

}

496

497

private void notifyConnectionLost() {

498

// Notify application that Arduino is disconnected

499

// Could trigger reconnection attempts

500

}

501

502

public boolean isConnected() {

503

return isConnected;

504

}

505

506

public void cleanup() {

507

if (pingTimer != null) {

508

pingTimer.stop();

509

}

510

}

511

}

512

```

513

514

## Advanced Features Summary

515

516

### Interrupt Capabilities

517

- **Real-time event handling**: Sub-millisecond response to external events

518

- **Multiple trigger modes**: Rising, falling, change, and level detection

519

- **Two interrupt pins**: PIN_2_INT0 and PIN_3_INT1 on Arduino Uno

520

- **Automatic notifications**: Asynchronous interrupt messages to observers

521

522

### Audio Features

523

- **Frequency range**: 20 Hz to 20 kHz tone generation

524

- **Precise timing**: Millisecond-accurate duration control

525

- **Continuous tones**: Zero duration for ongoing audio

526

- **Multiple pins**: Any digital pin can generate tones

527

528

### Timing Measurements

529

- **Microsecond precision**: High-resolution pulse measurement

530

- **Ultrasonic sensors**: Perfect for HC-SR04 distance sensors

531

- **Encoder support**: Measure pulse widths from rotary encoders

532

- **Timeout handling**: Prevents blocking on missing pulses

533

534

### EEPROM Storage

535

- **1024 bytes**: Full Arduino Uno EEPROM capacity (addresses 0-1023)

536

- **Synchronous/asynchronous**: Choice of write modes

537

- **Wear leveling**: Minimize EEPROM wear with strategic addressing

538

- **Configuration management**: Perfect for persistent settings

539

540

### Connection Reliability

541

- **Ping/pong protocol**: Built-in connectivity testing

542

- **Automatic detection**: Observer-based connection monitoring

543

- **Timeout handling**: Configurable connection timeouts

544

- **Reconnection support**: Framework for automatic reconnection