I'm currently trying to develop a very simple system: send a message to an Arduino when a button is pressed (this message will open a gate). The thing is I still didn't figured out how to connect an Arduino to an Android smartphone.
The code I'm using is as follows (it's almost identical to the example code, the only difference will be mentioned below):
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:usb_serial/transaction.dart';
import 'package:usb_serial/usb_serial.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
UsbPort? _port;
String _status = "Idle";
List<Widget> _ports = [];
final List<Widget> _serialData = [];
StreamSubscription<String>? _subscription;
Transaction<String>? _transaction;
UsbDevice? _device;
final TextEditingController _textController = TextEditingController();
Future<bool> _connectTo(device) async {
_serialData.clear();
if (_subscription != null) {
_subscription!.cancel();
_subscription = null;
}
if (_transaction != null) {
_transaction!.dispose();
_transaction = null;
}
if (_port != null) {
_port!.close();
_port = null;
}
if (device == null) {
_device = null;
setState(() {
_status = "Disconnected";
});
return true;
}
_port = await device.create();
if (await (_port!.open()) != true) {
setState(() {
_status = "Failed to open port";
});
return false;
}
_device = device;
await _port!.setDTR(true);
await _port!.setRTS(true);
await _port!.setPortParameters(115200, UsbPort.DATABITS_8, UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);
_transaction = Transaction.stringTerminated(_port!.inputStream as Stream<Uint8List>, Uint8List.fromList([13, 10]));
_subscription = _transaction!.stream.listen((String line) {
setState(() {
_serialData.add(Text(line));
if (_serialData.length > 20) {
_serialData.removeAt(0);
}
});
});
setState(() {
_status = "Connected";
});
return true;
}
void _getPorts() async {
_ports = [];
List<UsbDevice> devices = await UsbSerial.listDevices();
if (!devices.contains(_device)) {
_connectTo(null);
}
print(devices);
devices.forEach((device) {
_ports.add(ListTile(
leading: Icon(Icons.usb),
title: Text(device.productName!),
trailing: ElevatedButton(
child: Text(_device == device ? "Disconnect" : "Connect"),
onPressed: () {
_connectTo(_device == device ? null : device).then((res) {
_getPorts();
});
},
)));
});
setState(() {
print(_ports);
});
}
@override
void initState() {
super.initState();
UsbSerial.usbEventStream!.listen((UsbEvent event) {
_getPorts();
});
_getPorts();
}
@override
void dispose() {
super.dispose();
_connectTo(null);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('USB Serial Plugin example app'),
),
body: Center(
child: Column(children: <Widget>[
Text(_ports.length > 0 ? "Available Serial Ports" : "No serial devices available", style: Theme.of(context).textTheme.headline6),
..._ports,
Text('Status: $_status\n'),
Text('info: ${_port.toString()}\n'),
ListTile(
title: TextField(
controller: _textController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Text To Send',
),
),
trailing: ElevatedButton(
onPressed: _port == null
? null
: () async {
if (_port == null) {
return;
}
String data = _textController.text + "\r\n";
await _port!.write(Uint8List.fromList(data.codeUnits));
_textController.text = "";
},
child: const Text("Send"),
),
),
Text("Result Data", style: Theme.of(context).textTheme.headline6),
..._serialData,
])),
));
}
}
I'm using the usb_serial library and the example code on my app, but my smartphone doesn't really reconizes Arduino. Actually, it reconizes that something is plugged in, but it doesn't specify what has been plugged.
I've already removed the subtitle line, as suggested by this and some other answers.
Also, I've tried to add the line below on device_filter.xml, but it still doesn't work:
<usb-device vendor-id="2341" product-id="0043" />
Both ids i got from lsusb, as it's possible to see below:
artur@artur-Vostro-3710:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 048: ID 1a2c:6004 China Resource Semico Co., Ltd USB Keyboard
Bus 001 Device 051: ID 413c:250e Dell Computer Corp. Dell Laser Mouse MS3220
Bus 001 Device 004: ID 8087:0032 Intel Corp. AX210 Bluetooth
Bus 001 Device 071: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
One thing to notice is that I've already downloaded USB OTG Checker app and my Android is compatible, also, I've downloaded the USB Serial Console and it works perfectly with my Arduino (It's a java code).