Skip to content

serialport/bindings-cpp/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] #2787

Open
@semireg

Description

@semireg

SerialPort Version

Tested 10-12

Node Version

Electron main

Electron Version

Tested 26-30

Platform

Sonoma 14.14.1 - Darwin Kernel Version 23.4.0 macOS

Architecture

ARM

Hardware or chipset of serialport

FTDI FT232R USB UART (PID: 0x6001)

What steps will reproduce the bug?

I have a weight scale that responds to a simple "W\r\n". This works fine using screen /dev/tty.usbserial-AI04V9SR 9600, here's the expected output:

CleanShot 2024-04-19 at 10 55 13

I'm no stranger to USB devices, Electron, native modules, TypeScript, etc. I'm unable to get serialport to work as I'd expect.

What happens?

Here's the output from electron 26.6.9 main when DEBUG=*

  serialport/bindings-cpp list +0ms
  serialport/stream opening path: /dev/tty.usbserial-AI04V9SR +0ms
  serialport/bindings-cpp open +1ms
  serialport/stream _read queueing _read for after open +0ms
  serialport/bindings-cpp/poller Creating poller +0ms
  serialport/stream opened path: /dev/tty.usbserial-AI04V9SR +27ms
  serialport/stream _read reading { start: 0, toRead: 65536 } +0ms
  serialport/bindings-cpp read +27ms
  serialport/bindings-cpp/unixRead Starting read +0ms
10:50:45.861 ›   28 | ScaleManager opening path /dev/tty.usbserial-AI04V9SR
  serialport/bindings-cpp/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] {
  errno: -35,
  code: 'EAGAIN',
  syscall: 'read'
} +0ms
  serialport/bindings-cpp/unixRead waiting for readable because of code: EAGAIN +0ms
  serialport/bindings-cpp/poller Polling for "readable" +1ms
  serialport/bindings-cpp list +2s
10:50:47.841 ›    3 | ScaleManager write (AI04V9SR at path /dev/tty.usbserial-AI04V9SR): W

  serialport/stream _write 3 bytes of data +2s
  serialport/bindings-cpp write 3 bytes +4ms
  serialport/bindings-cpp/unixWrite Starting write 3 bytes offset 0 bytesToWrite 3 +0ms
...

My calling code is fairly vanilla. I've tried with autoOpen:true/false, with/without a parser. Here's a code sample:

            const port = new SerialPort({ path, baudRate: 9600, autoOpen: false });
            port.open((openError) => {
              log.info(`ScaleManager opening path ${path}`);
              if (openError) {
                log.error(`ScaleManager portInfo:${JSON.stringify(portInfo)} openError:${openError}`);
                return;
              }
              deviceWrapper.ready = true;
            });

            const newParser = port.pipe(new InterByteTimeoutParser({ interval: 50 }));
            newParser.on('data', (data: Buffer) => {
              log.info('Data:', data);
            });

My writing looks like:

port.write(Buffer.from('W\r\n'), 'utf-8', (writeError) => {
                  if (writeError) {
                    log.error(`ScaleManager writeError:${writeError}`);
                    port.close();
                  }
                });

My goal is to keep targeting Electron 26 due to macOS 10.13/10.14, along with other native module compatibility.

Here's the DEBUG repl using node v18.17.1.

% DEBUG=serialport* npx @serialport/repl /dev/tty.usbserial-AI04V9SR
  serialport/bindings-cpp loading DarwinBinding +0ms
DEBUG=serialport* # enable debugging with DEBUG=serialport*
port = SerialPort({ path: "/dev/tty.usbserial-AI04V9SR", baudRate: 9600, autoOpen: false })
globals { SerialPort, SerialPortMock, path, port }
> port.open()
  serialport/stream opening path: /dev/tty.usbserial-AI04V9SR +0ms
  serialport/bindings-cpp open +0ms
undefined
>   serialport/bindings-cpp/poller Creating poller +0ms
  serialport/stream opened path: /dev/tty.usbserial-AI04V9SR +30ms

undefined
> port.write('W\r\n');
  serialport/stream _write 3 bytes of data +7s
  serialport/bindings-cpp write 3 bytes +7s
  serialport/bindings-cpp/unixWrite Starting write 3 bytes offset 0 bytesToWrite 3 +0ms
true
>   serialport/bindings-cpp/unixWrite write returned: wrote 3 bytes +1ms
  serialport/bindings-cpp/unixWrite Finished writing 3 bytes +0ms
  serialport/stream binding.write write finished +2ms

undefined
> port.read()
  serialport/stream _read reading { start: 0, toRead: 65536 } +3s
  serialport/bindings-cpp read +3s
  serialport/bindings-cpp/unixRead Starting read +0ms
null
>   serialport/bindings-cpp/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] {
  errno: -35,
  code: 'EAGAIN',
  syscall: 'read'
} +1ms
  serialport/bindings-cpp/unixRead waiting for readable because of code: EAGAIN +0ms
  serialport/bindings-cpp/poller Polling for "readable" +11s

undefined

Immediately after this I can type screen /dev/tty.usbserial-AI04V9SR 9600 and press W and receive a response from the scale.

Oh, and here's the stty/permission settings.

% ls -lah /dev/tty.usbserial-AI04V9SR    
crw-rw-rw-  1 root  wheel  0x9000002 Apr 19 11:07 /dev/tty.usbserial-AI04V9SR

% stty -a -f /dev/tty.usbserial-AI04V9SR
speed 9600 baud; 0 rows; 0 columns;
lflags: -icanon -isig -iexten -echo -echoe -echok -echoke -echonl
	-echoctl -echoprt -altwerase -noflsh -tostop -flusho -pendin
	-nokerninfo -extproc
iflags: -istrip -icrnl -inlcr -igncr -ixon -ixoff -ixany -imaxbel -iutf8
	-ignbrk -brkint -inpck -ignpar -parmrk
oflags: -opost -onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
	-dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
	eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
	min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
	stop = ^S; susp = ^Z; time = 0; werase = ^W;

What should have happened?

I'd just like to see the output of the weight scale.

Additional information

I've unplug/replugged the USB device multiple times to ensure it's a clean/fresh interface. No difference, unfortunately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions