Application Development Example with Flutter and Arduino

Application Development Example with Flutter and Arduino

Building a Bridge Between Mobile Devices and Embedded Systems

The integration of mobile technologies and embedded systems offers a wide range of applications. This integration can be used in industrial automation, healthcare, agriculture, smart home systems and more. In this article, we will present an example of combining technologies such as Flutter and Arduino to create a bridge between mobile devices and embedded systems.

Usage areas:
1. Industrial Automation: It can be used in factory automation and data monitoring systems to establish data communication between mobile devices and hardware. For example, monitoring and controlling the sensor data of a facility via a mobile application.

2. Smart Agriculture: In the agricultural sector, embedded systems integrated with mobile devices can be used in areas such as land monitoring, irrigation systems control, soil fertility monitoring. Mobile applications allow farmers to manage their land remotely and analyze agricultural data.

3. Health Services: Embedded systems integrated with mobile devices are widely used in areas such as data collection and monitoring with portable health devices, patient monitoring and medical imaging. Mobile applications offer users the ability to track personal health data and share it with healthcare professionals.

4. Education and Learning: Educational applications can provide interactive experiences with embedded systems. For example, it can provide children with programming and engineering skills by communicating between robotics training sets and mobile devices.

Such applications become more efficient, accessible and user-friendly thanks to the integration of embedded systems with mobile devices. In this article, we aim to demonstrate the potential of these technologies by developing a simple example using Flutter and Arduino.

Click to read the previous related article:

ADS1115 Connection and Data Reading with Arduino Nano

First, let's update the codes in the previous MCU+ADS1115 implementation:

#include <Wire.h>
#include <Adafruit_ADS1015.h>

// Pins to which the Bluetooth module is connected
#define RX_PIN 10
#define TX_PIN 11

Adafruit_ADS1115 ads; //Create ADS1115 object

void setup(void)
{
   Serial.begin(9600);
   Serial.println("Sample reading with ADS1115:");
  
   // initialize ADS1115
   if (!ads.begin())
   {
     Serial.println("Failed to initialize ADS1115!");
     while(1);
   }

   //start Bluetooth communication
   Serial1.begin(9600);
}

void loop(void)
{
   int16_t adc0;

   adc0 = ads.readADC_SingleEnded(0); // read data from channel 0
   Serial.print("ADC 0 Value: "); Serial.println(adc0);

   // Send data via Bluetooth module
   Serial1.print("ADC 0 Value: ");
   Serial1.println(adc0);

   delay(1000);
}

In these codes, we assumed that the RX and TX pins of the Bluetooth module are connected to pins 10 and 11 of the Arduino.

Let's add dependencies such as flutter_blue and fl_chart to the project you created. Open the pubspec.yaml file and edit it as follows:

dependencies:
   flutter:
     sdk:flutter
   flutter_blue: ^0.7.3
   fl_chart: ^0.35.0


To add the necessary permissions for Bluetooth operations, open android/app/src/main/AndroidManifest.xml and add the following permissions:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.flutter_bluetooth_adc">
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     ...
</manifest>


We will create a service for Bluetooth operations and a widget for the line chart. Create two files named bluetooth_service.dart and line_chart.dart in the lib folder.

 

bluetooth_service.dart file:

import 'package:flutter_blue/flutter_blue.dart';

class BluetoothService {
   FlutterBlue flutterBlue = FlutterBlue.instance;
   BluetoothDevice _device;
   BluetoothCharacteristic _characteristic;

   Future<void> connectToBluetoothDevice() async {
     flutterBlue.scanResults.listen((results) {
       for (ScanResult result in results) {
         if (result.device.name == 'YourDeviceName') { // Enter device name here
           _device = result.device;
           break;
         }
       }
     });

     await flutterBlue.startScan(timeout: Duration(seconds: 4));
     await _device.connect();
     List<BluetoothService> services = await _device.discoverServices();
     services.forEach((service) {
       service.characteristics.forEach((characteristic) {
         if (characteristic.uuid.toString() == 'yourCharacteristicUUID') { // Enter feature UUID here
           _characteristic = characteristic;
         }
       });
     });
   }

   Stream<List<int>> getBluetoothDataStream() {
     return _characteristic.value;
   }
}


line_chart.dart file:

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

class LineChartWidget extends StatelessWidget {
   final List<FlSpot> spots;

   LineChartWidget({this.spots});

   @override
   Widget build(BuildContext context) {
     return LineChart(
       LineChartData(
         lineBarsData: [
           LineChartBarData(
             spots: spots,
             isCurved: true,
             belowBarData: BarAreaData(show: false),
           ),
         ],
         minY:0,
         titlesData: FlTitlesData(
           leftTitles: SideTitles(showTitles: true),
           bottomTitles: SideTitles(showTitles: true),
         ),
       ),
     );
   }
}


Finally, let's create a widget on the main application screen that will retrieve the data using this service and convert it into a line chart. Edit the main.dart file as follows:

import 'package:flutter/material.dart';
import 'bluetooth_service.dart';
import 'line_chart.dart';

void main() {
   runApp(MyApp());
}

class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return MaterialApp(
       title: 'Bluetooth ADC',
       theme: ThemeData(
         primarySwatch: Colors.blue,
         visualDensity: VisualDensity.adaptivePlatformDensity,
       ),
       home:MyHomePage(),
     );
   }
}

class MyHomePage extends StatefulWidget {
   @override
   _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
   List<FlSpot> spots = [];

   @override
   void initState() {
     super.initState();
     connectToBluetoothDevice();
   }

   void connectToBluetoothDevice() async {
     BluetoothService bluetoothService = BluetoothService();
     await bluetoothService.connectToBluetoothDevice();

     bluetoothService.getBluetoothDataStream().listen((data) {
       setState(() {
         spots.add(FlSpot(spots.length.toDouble(), data.toDouble()));
       });
     });
   }

   @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
         title: Text('Bluetooth ADC'),
       ),
       body: Center(
         child: LineChartWidget(spots: spots),
       ),
     );
   }
}

Your Flutter application will receive the data from Arduino via Bluetooth and convert it into a line graph and display it to the user.