Skip to content

heyteacher/flutter_antplus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

65 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

flutter_antplus

pub package license

A powerful, high-performance Flutter plugin for connecting to ANT+ devices on Android using the official ANT-Android-SDKs. It allows seamless scanning, connection, and data acquisition from multiple fitness sensors like heart rate monitors, bike power meters, and speed/cadence sensors.


πŸš€ Features

  • Heart Rate Monitor (HRM)
    • Real-time Heart Rate (bpm) stream
  • Bike Power Meter
    • Real-time Power (watts)
    • Real-time Cadence (rpm)
    • Pedal Balance (%)
    • Left & Right Pedal Smoothness (%)
    • Left & Right Torque Effectiveness (%)
    • Battery status tracking
  • Cadence Sensor
    • Real-time Cadence (rpm)
  • Common API (AntplusDeviceViewModel)
    • Universal start/stop scan interface
    • State monitoring (onDeviceStateChangeStream)
    • Subscriptions status tracking (onRequestAccessResultStream)
  • Plugin Logging
    • Integrated debug logging through the AntplusLogging singleton

πŸ› οΈ Requirements


πŸ› οΈ Android Setup

To run ANT+ communication on Android (especially on Android 11+ / API 30+), you must declare package visibility for the ANT+ background services.

Add the following inside the <manifest> tag (outside <application>) in your android/app/src/main/AndroidManifest.xml:

<queries>
  <!-- Declares dependency on the ANT+ Plugin Service -->
  <package android:name="com.dsi.ant.plugins.antplus" />
  <!-- Declares dependency on the ANT Radio Service -->
  <package android:name="com.dsi.ant.service.socket" />
  <intent>
    <action android:name="com.dsi.ant.plugins.antplus.queryalreadyconnecteddevices" />
  </intent>
</queries>

⚑ Quick Start

A comprehensive example app can be found in example.

1. Initialize Logging (Optional)

It is recommended to initialize the logging interface at app startup:

import 'package:flutter_antplus/antplus_logging.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  AntplusLogging.instance.initLog();
  runApp(const MyApp());
}

2. Scanning and Connecting

Each device type has its own view model implementing the AntplusDeviceViewModel interface:

  • AntplusHeartrateViewModel.instance
  • AntplusBikepowerViewModel.instance
  • AntplusCadenceViewModel.instance

Start Scanning

final hrViewModel = AntplusHeartrateViewModel.instance;

// Listen to scan results
final scanSubscription = hrViewModel.onScanResultStream.listen((device) {
  print('Found device: ${device.name} (Number: ${device.number})');
});

// Start the scan
await hrViewModel.startScan();

Connect to a Device

When a device is discovered, you can connect to it using its unique deviceNumber:

// Stop scan before connecting (best practice)
await hrViewModel.stopScan();

// Connect using device number
await hrViewModel.connect(device.number);

Monitor Device Connection State

final stateSubscription = hrViewModel.onDeviceStateChangeStream.listen((state) {
  print('Device state changed to: ${state.name}');
  // States: dead, closed, searching, tracking, processingRequest, unrecognized
});

πŸ“Š Reading Sensor Data

πŸ’“ Heart Rate

final hrSubscription = AntplusHeartrateViewModel.instance.onHeartRateDataStream.listen((bpm) {
  print('Heart Rate: $bpm bpm');
});

🚴 Bike Power

The bike power view model offers multiple specialized telemetry streams:

final powerModel = AntplusBikepowerViewModel.instance;

// Real-time Power output in watts
powerModel.onPowerDataStream.listen((watts) {
  print('Power: $watts W');
});

// Cadence from the power meter
powerModel.onCadenceDataStream.listen((rpm) {
  print('Cadence: $rpm rpm');
});

// Left/Right Pedal Balance
powerModel.onBalanceDataStream.listen((balance) {
  print('Balance: $balance%');
});

// Pedal Smoothness
powerModel.onPedalSmoothnessDataStream.listen((data) {
  print('Smoothness - Left: ${data.leftOrCombinedPedalSmoothness}%, Right: ${data.rightPedalSmoothness}%');
});

// Torque Effectiveness
powerModel.onTorqueEffectivenessDataStream.listen((data) {
  print('Torque - Left: ${data.leftTorqueEffectiveness}%, Right: ${data.rightTorqueEffectiveness}%');
});

// Battery status of the power meter sensor
powerModel.onBatteryStatusDataStream.listen((status) {
  print('Battery Status: ${status.name}');
});

πŸ”„ Cadence

final cadenceSubscription = AntplusCadenceViewModel.instance.onCadenceDataStream.listen((rpm) {
  print('Cadence: $rpm rpm');
});

πŸ› οΈ For developers

Pigeon Code Generation

The pigeon definition files are located in the pigeons/ folder. If you edit these definitions, regenerate the pigeon platform channel implementations using the following commands:

# Bike Power
dart run pigeon --input pigeons/bikepower.dart 
dart run pigeon --input pigeons/bikepower_event_channel.dart 

# Heart Rate
dart run pigeon --input pigeons/heartrate.dart 
dart run pigeon --input pigeons/heartrate_event_channel.dart 

# Cadence
dart run pigeon --input pigeons/cadence.dart 
dart run pigeon --input pigeons/cadence_event_channel.dart 

# Logging
dart run pigeon --input pigeons/logging_event_channel.dart 

# Device
dart run pigeon --input pigeons/device_event_channel.dart 

πŸ“„ License

This project is licensed under the BSD-3-Clause License - see the LICENSE file for details.

About

Flutter plugin for Ant+: search, listen, acquire data from Ant+ sensors like power meters, heart rate and cadence sensors (mirror from codeberg)

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages