Serial-port access using Flutter/dart

Hi, I have the flutterdemo app running on Ubuntu Core 22, I have built the Gadget snap and added serial a serial port slot. This image is installed and working. I have modified the snapcraft.yaml for the Flutter project to enable the plug. I have connected the plug to the slot. This all seems to be working:

~$ snap connections
Interface                 Plug                                        Slot                         Notes
content[graphics-core22]  iot-example-graphical-snap:graphics-core22  mesa-core22:graphics-core22  -
content[graphics-core22]  ubuntu-frame:graphics-core22                mesa-core22:graphics-core22  -
hardware-observe          ubuntu-frame:hardware-observe               :hardware-observe            -
network-bind              ubuntu-frame:network-bind                   :network-bind                -
opengl                    iot-example-graphical-snap:opengl           :opengl                      -
opengl                    ubuntu-frame:opengl                         :opengl                      -
serial-port               iot-example-graphical-snap:serial0          pc:serial0                   manual
wayland                   iot-example-graphical-snap:wayland          ubuntu-frame:wayland         -    

snap interface serial-port
name:    serial-port
summary: allows accessing a specific serial port
plugs:
  - iot-example-graphical-snap:serial0
slots:
  - pc:serial0  

How do I now read and write to the serial port from my Flutter app. Does anyone have any Dart/Flutter examples of using the serial-port plug ?

Thanks

I have now almost solved this problem. I found this (https://kyrofa.com/posts/ros-production-obtaining-confined-access-to-the-turtlebot-4-5/) which said to set the usb-vendor and usb-product numbers in the gadget snapcraft.yaml. I didn’t think these were necessary as the FTDI serial device was showing up as /dev/ttyUSB0 and I expected the OS/driver to emulate a serial port so I thought the USB details were not necessary. Turns out they are necessary. I also changed the path from /dev/ttyUSB0 to /dev/serial-port-xxxx. This is the name of a symbolic link that is created in the /dev/ folder. Not sure is this has to start with serial-port-, but I changed the path and added the usb parameters at the same time and I haven’t had a chance to see if it’s important.

So, in the gadget snapcraft.yaml, I changed:

slots:
  serial0:
  interface: serial-port
  path: /dev/ttyUSB0

to:

slots:
  serial0:
  interface: serial-port
  path: /dev/serial-port-xxxx
  usb-vendor: 0x0403
  usb-product: 0x6001

I built the Ubuntu core image and installed it. Then in the flutter/dart code, I used:

SerialPort? _serialPort = SerialPort('/dev/serial-port-xxxx');
_serialPort!.openReadWrite();

List<int> list = 'UUUUUUUUUU'.codeUnits;
Uint8List bytes = Uint8List.fromList(list);
String string = String.fromCharCodes(bytes);
_serialPort!.write(bytes);
_serialPort!.close();

It worked! I could actually see data on the oscilloscope. Then (in the flutter code) I tried to set the BAUD rate using:

final configu = SerialPortConfig();
configu.baudRate = 19200;
configu.bits = 8;
configu.parity = 0;
_serialPort!.config = configu;

and this is where I spent a few hours trying to make it work. I read somewhere that the port has to be open before changing the settings, so I did this. More often than not, setting the configuration data would throw an exception, but occasionally it would work. I tried many sequences of rebooting/restarting the snap, re-installing the snap until I eventually realised that it was just intermittent, none of the rebooting/re-installing or restarting affected it. Then I put the configuration setting in a loop to retry like this:

void _setBaudRate(int baud){
  for (;;)  {
    SerialPort? _serialPort = SerialPort('/dev/serial-port-xxxx');

    try    {  
        _serialPort!.openReadWrite();
        final configu = SerialPortConfig();
        configu.baudRate = baud;
        configu.bits = 8;
        configu.parity = 0;
        _serialPort!.config = configu;
      }
      catch(e) {
        _serialPort!.close();
        continue;
      }

      _serialPort!.close();
      break;
    }
  }

and this consistently worked. I can now change the serial port settings reliably. I would really like to know what is causing these retries to be necessary. I must be doing something wrong, but it can’t be that wrong as it works some of the time. Perhaps it’s a timing issue ?

Any help or additional info would be welcome.

Thanks

1 Like