From f896e057f8573c318c990665035465ec3a8bc1af Mon Sep 17 00:00:00 2001 From: Gerrit Balindt Date: Tue, 15 Oct 2024 18:23:17 +0200 Subject: [PATCH] add basic serial port windows --- lib/screens/settings.dart | 4 +- lib/widgets/gnss-serial-selection.dart | 118 +++++++++++++++++++------ 2 files changed, 95 insertions(+), 27 deletions(-) diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 3014cb5..636d73e 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -53,7 +53,7 @@ class _SettingsState extends State { margin: EdgeInsets.all(10.0), child: GnssSettings(), ), - Container( + /*Container( margin: EdgeInsets.only(top: 20.0, left: 30.0, right: 30.0), child: Text( 'Bluetooth', @@ -63,7 +63,7 @@ class _SettingsState extends State { Card( margin: EdgeInsets.all(10.0), child: GNSSBluetooth(), - ), + ),*/ Container( margin: EdgeInsets.only(top: 20.0, left: 30.0, right: 30.0), child: Text( diff --git a/lib/widgets/gnss-serial-selection.dart b/lib/widgets/gnss-serial-selection.dart index 181f4e3..aba2ac0 100644 --- a/lib/widgets/gnss-serial-selection.dart +++ b/lib/widgets/gnss-serial-selection.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:terrestrial_forest_monitor/polyfill/libserial.dart' if (dart.library.html) 'package:terrestrial_forest_monitor/polyfill/libserial.dart' if (dart.library.io) 'package:flutter_libserialport/flutter_libserialport.dart'; //import 'package:flutter_libserialport/flutter_libserialport.dart'; @@ -34,6 +35,7 @@ class _GnssSerialSelectionState extends State { String selectedPort = ''; bool tested = false; bool testing = false; + List nmeaSentences = []; var serialPort; @override @@ -51,20 +53,30 @@ class _GnssSerialSelectionState extends State { _closePort() { if (serialPort != null && serialPort!.isOpen) { - serialPort?.close(); + serialPort.close(); + serialPort.dispose(); + print('CLOSE'); } } _getAvailablePorts() { try { availablePorts = SerialPort.availablePorts; + setState(() { + // make unique + availablePorts = availablePorts.toSet().toList(); + // Make sure to set the selected port to the first available port + if (availablePorts.isNotEmpty) { + selectedPort = availablePorts[0].toString(); + } + }); } catch (e) { if (e is SerialPortError) { // TODO: Show error - print('${e}'); + print('availablePorts: ${e}'); // Handle the error, e.g., show a dialog or a snackbar } else { - print('Error: $e'); + print('Error Get Ports: $e'); } } setState(() { @@ -83,34 +95,46 @@ class _GnssSerialSelectionState extends State { _cancelTesting() { _closePort(); + setState(() { testing = false; }); } - void parseReceiveData(String nmeaData) { - double latitude; - double longitude; + void _getLatLonFromGNRMC(String line) { + // Step 5: Split the line by commas + List parts = line.split(','); - var nmeaDataArray = nmeaData.split(","); - - if (nmeaDataArray[0].startsWith('\$GNRMC') && nmeaDataArray[3].isNotEmpty && nmeaDataArray[5].isNotEmpty) { - print('parse'); - //latitude = parseToDecimal(nmeaDataArray[3], nmeaDataArray[4]); - //longitude = parseToDecimal(nmeaDataArray[5], nmeaDataArray[6]); + // Step 6: Check if the line has enough parts + if (parts.length < 7) { + return; } + + // Step 7: Get the latitude and longitude + String lat = parts[3]; + String lon = parts[5]; + + // Lat and Lon to double + //double latD = double.parse(lat); + //double lonD = double.parse(lon); + + // Step 8: Print the latitude and longitude + print('Latitude: $lat, Longitude: $lon'); + /*return Position( + latitude: double.parse(lat), + longitude: double.parse(lon), + );*/ } Future _testConnection() async { + _closePort(); + nmeaSentences = []; + if (selectedPort.isEmpty) { return; } - setState(() { - testing = true; - }); - serialPort = SerialPort(selectedPort); if (serialPort == null || baudeRate == null) { @@ -118,30 +142,60 @@ class _GnssSerialSelectionState extends State { return; } + setState(() { + testing = true; + }); + try { var config = serialPort!.config; print(baudeRate); config.baudRate = baudeRate!; serialPort!.config = config; - if (serialPort!.openRead()) { + if (serialPort.openRead()) { print('Port opened'); tested = true; } else { print('Port not opened'); + setState(() { + testing = false; + }); + return; } var reader = SerialPortReader(serialPort!); reader!.stream.listen((data) { - //print('Data: $data'); - String utfDAta = String.fromCharCodes(data); - if (utfDAta.startsWith('\$GNRMC')) parseReceiveData(utfDAta); + + String nmeaSentence = String.fromCharCodes(data); + + // split nmeaSentances in Lines + List lines = nmeaSentence.split('\$'); + + // Clear empty lines + lines.removeWhere((element) => element.isEmpty); + + setState(() { + nmeaSentences.addAll(lines); + }); + + // Step 2: Iterate through each line + for (String line in lines) { + + // Step 3: Check if the line starts with "GNRMC" + if (line.startsWith('GNRMC')) { + print(line); + // Step 4: Parse the line + _getLatLonFromGNRMC(line); + } + } + }, onDone: () { print('Done'); + + }, onError: (e) { + print('$e'); setState(() { - tested = true; + testing = false; }); - }, onError: (e) { - print('Error: $e'); }); print('read start'); } catch (e) { @@ -162,7 +216,7 @@ class _GnssSerialSelectionState extends State { DropdownButton( value: selectedPort, onChanged: (String? value) { - if (value == null) return; + if (value == null || testing) return; setState(() { selectedPort = value; }); @@ -216,7 +270,21 @@ class _GnssSerialSelectionState extends State { child: Text('SAVE'), ) ], - ) + ), + Divider(), + // nmeaSentences + if (nmeaSentences.isNotEmpty) + Container( + height: 200, + child: ListView.builder( + itemCount: nmeaSentences.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(nmeaSentences[index].toString()), + ); + }, + ), + ) ], ); }