Closed ghost closed 9 years ago
I'm open to this but, how can we tell which /dev/tty devices are serialports?
would the ability to provide a target directory as an option be sufficient?
USB serial devices can be found by looking at /sys/bus/usb-serial/devices//tty/, that plus /dev/ttyS would possibly be a good default set.
I'm having the same issue, is there a way to work around it? I'm trying to use johnny-five inside the yun, which relies on serialport.
serialPort.list only returns ttyUSB0 for me...
I can confirm this works on Ubuntu:
$ ls /sys/bus/usb-serial/devices/
ttyUSB0 ttyUSB1
Is there something additional that needs to be installed to have the links in /dev/bus/usb-serial/devices? I am looking at Ubuntu (14.04.1 LTS) and Raspberry Pi. They both seem to have slightly different folder /dev/bus/usb/devices
I am having a play to see if I can get
exec('ls /dev/*/by-id/*usb*', function (err, output) {
working, in place of
fs.readdir("/dev/serial/by-id", function (err, files) {
I don't have enough time to look into this, maybe it will help someone else work it out. The code below finds the devices and calls the exec. The calling code doesn't seem to be able to process "ports"
Here are the changes I made
serialport.js
At the end, I added a check for linux
if (process.platform === 'win32') {
factory.list = SerialPortBinding.list;
} else if (process.platform === 'darwin') {
factory.list = SerialPortBinding.list;
} else if (process.platform === 'linux') {
factory.list = listLinux;
} else {
factory.list = listUnix;
}
I also added a "listLilnux" method just below the "listUnix" method
function listLinux(callback) {
function udev_parser(udev_output, callback) {
function udev_output_to_json(output) {
var result = {};
var lines = output.split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line !== "") {
var line_parts = lines[i].split("=");
result[line_parts[0].trim()] = line_parts[1].trim();
}
}
return result;
}
var as_json = udev_output_to_json(udev_output);
var pnpId = as_json.DEVLINKS.split(" ")[0];
pnpId = pnpId.substring(pnpId.lastIndexOf("/") + 1);
var port = {
comName: as_json.DEVNAME,
manufacturer: as_json.ID_VENDOR,
serialNumber: as_json.ID_SERIAL,
pnpId: pnpId,
vendorId: "0x" + as_json.ID_VENDOR_ID,
productId: "0x" + as_json.ID_MODEL_ID
};
console.log("port: %j", port);
callback(null, port);
}
exec('ls /dev/*/by-id/*usb*', function (err, output) {
if (err) {
console.log(err);
// if this directory is not found this could just be because it's not plugged in
if (err.errno === 34) {
return callback(null, []);
}
if (callback) {
callback(err);
} else {
factory.emit('error', err);
}
return;
}
var files = output.split('\n');
for (var i = 0; i < files.length; i++) {
var file = files[i].trim();
if (file !== "") {
console.log("exec: " + file);
exec('/sbin/udevadm info --query=property -p $(/sbin/udevadm info -q path -n ' + file + ')', function (err, stdout) {
if (err) {
if (callback) {
callback(err);
} else {
factory.emit('error', err);
}
return;
}
udev_parser(stdout, callback);
});
}
}
});
}
if I create a test file and just put this in it
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
// list serial ports:
serialport.list(function (err, ports) {
console.log("list");
console.log("err: " + err);
});
This is what I see logged to the console
exec: /dev/disk/by-id/usb-Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0
exec: /dev/disk/by-id/usb-Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0-part1
exec: /dev/snd/by-id/usb-046d_08d7-01
exec: /dev/v4l/by-id/usb-046d_08d7-video-index0
port: {"comName":"/dev/sdb","manufacturer":"Kingston","serialNumber":"Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0","pnpId":"8:16","vendorId":"0x0951","productId":"0x1666"}
list
err: null
port: {"comName":"/dev/sdb1","manufacturer":"Kingston","serialNumber":"Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0","pnpId":"8:17","vendorId":"0x0951","productId":"0x1666"}
list
err: null
port: {"comName":"/dev/snd/controlC0","manufacturer":"046d","serialNumber":"046d_08d7","pnpId":"116:4","vendorId":"0x046d","productId":"0x08d7"}
list
err: null
port: {"comName":"/dev/video0","manufacturer":"046d","serialNumber":"046d_08d7","pnpId":"81:0","vendorId":"0x046d","productId":"0x08d7"}
list
err: null
If I try the normal test code for listing
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
// list serial ports:
serialport.list(function (err, ports) {
console.log("list");
console.log("err: " + err);
ports.forEach(function(port) {
console.log(port.comName);
});
});
I see this logged to the console
exec: /dev/disk/by-id/usb-Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0
exec: /dev/disk/by-id/usb-Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0-part1
exec: /dev/snd/by-id/usb-046d_08d7-01
exec: /dev/v4l/by-id/usb-046d_08d7-video-index0
port: {"comName":"/dev/sdb","manufacturer":"Kingston","serialNumber":"Kingston_DataTraveler_3.0_60A44C41382CBDA15B5731B6-0:0","pnpId":"8:16","vendorId":"0x0951","productId":"0x1666"}
list
err: null
/opt/projects/nodejs/serial_test/testit.js:8
ports.forEach(function(port) {
^
TypeError: Object #<Object> has no method 'forEach'
at /opt/projects/nodejs/serial_test/testit.js:8:11
at udev_parser (/opt/projects/nodejs/serial_test/node_modules/serialport/serialport.js:582:6)
at /opt/projects/nodejs/serial_test/node_modules/serialport/serialport.js:617:4
at ChildProcess.exithandler (child_process.js:603:7)
at ChildProcess.EventEmitter.emit (events.js:98:17)
at maybeClose (child_process.js:703:16)
at Socket.<anonymous> (child_process.js:916:11)
at Socket.EventEmitter.emit (events.js:95:17)
at Pipe.close (net.js:451:12)
Thanks, @haydockjp. Seem to be working fine on Ubuntu 14.04. Is there a pull request for this?
Ops. You removed the async call, so the listLinux() callback is getting called multiple times.
Sorry for the spam. This is the fix:
function listLinux(callback) {
function udev_parser(udev_output, callback) {
function udev_output_to_json(output) {
var result = {};
var lines = output.split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line !== "") {
var line_parts = lines[i].split("=");
result[line_parts[0].trim()] = line_parts[1].trim();
}
}
return result;
}
var as_json = udev_output_to_json(udev_output);
var pnpId = as_json.DEVLINKS.split(" ")[0];
pnpId = pnpId.substring(pnpId.lastIndexOf("/") + 1);
var port = {
comName: as_json.DEVNAME,
manufacturer: as_json.ID_VENDOR,
serialNumber: as_json.ID_SERIAL,
pnpId: pnpId,
vendorId: "0x" + as_json.ID_VENDOR_ID,
productId: "0x" + as_json.ID_MODEL_ID
};
callback(null, port);
}
exec('ls /dev/*/by-id/*usb*', function(err, output) {
if (err) {
console.log(err);
// if this directory is not found this could just be because it's not plugged in
if (err.errno === 34) {
return callback(null, []);
}
if (callback) {
callback(err);
} else {
factory.emit('error', err);
}
return;
}
var files = output.split('\n');
async.map(files, function(file, callback) {
file = file.trim();
if (file === "") {
callback('');
return;
}
console.log("exec: " + file);
exec('/sbin/udevadm info --query=property -p $(/sbin/udevadm info -q path -n ' + file + ')', function(err, stdout) {
if (err) {
if (callback) {
callback(err);
} else {
factory.emit('error', err);
}
return;
}
udev_parser(stdout, callback);
});
}, callback)
});
}
Hi!
Is there any pull request to fix this? I'm having the same problem. If there isn't any I can create one with the fix from @f03lipe
To my knowledge there isnt a PR out there , I encourage you to make and submit it!
Cheers
On Sunday, April 19, 2015, Sergio Orbe notifications@github.com wrote:
Hi!
Is there any pull request to fix this? I'm having the same problem. If there isn't any I can create one with the fix from @f03lipe https://github.com/f03lipe
— Reply to this email directly or view it on GitHub https://github.com/voodootikigod/node-serialport/issues/343#issuecomment-94311685 .
Chris Williams
@voodootikigod http://twitter.com/voodootikigod | GitHub http://github.com/voodootikigod
The things I make that you should check out: SaferAging http://www.saferaging.com/ | JSConf http://jsconf.com/ | RobotsConf http://robotsconf.com/ | RobotsWeekly http://robotsweekly.com/
Help me end the negativity on the internet, share this http://jsconf.eu/2011/an_end_to_negativity.html.
Hi!
I've tested it with serialport v. 1.6.3 and node 0.12.2 on debian and ubuntu and the problem seems to be gone.
Yay!
Chris Williams
@voodootikigod http://twitter.com/voodootikigod | GitHub http://github.com/voodootikigod
The things I make that you should check out: SaferAging http://www.saferaging.com/ | JSConf http://jsconf.com/ | RobotsConf http://robotsconf.com/ | RobotsWeekly http://robotsweekly.com/
Help me end the negativity on the internet, share this http://jsconf.eu/2011/an_end_to_negativity.html.
On Fri, May 1, 2015 at 1:41 AM, Sergio Orbe notifications@github.com wrote:
Hi!
I've tested it with serialport v. 1.6.3 and node 0.12.2 on debian and ubuntu and the problem seems to be gone.
— Reply to this email directly or view it on GitHub https://github.com/voodootikigod/node-serialport/issues/343#issuecomment-98049596 .
Running 1.7.4, still having this issue here
Guys having same issues can anyone help new to this part..
I'm having issues too
/home/christian/node_modules/johnny-five/node_modules/serialport/serialport.js:541
var pnpId = as_json.DEVLINKS.split(' ')[0];
^
TypeError: Cannot call method 'split' of undefined
I finally decided to fix the problem the other way around: adding a /dev/serial tree on a distribution that does not do it by default is actually very easy, so rather than fix node-serialport, I decided to add the udev entry on my system. I documented this on the build instructions of the project I'm working on ('Node-serialport issues on Linux' section) : http://wizkers.github.io/wizkers-doc/building/
lmk if this helps !
TL;DR; : create the following file: /etc/udev/rules.d/60-ed-persistent-serial.rules and put the two lines below in it:
ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"
ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"
Same error for me... any solution ?
@amuchembled does the solution I described just above work for you?
No sorry, I'm on a Rpi, raspbian jessie. File doesn't seems to exists :
cat /etc/udev/rules.d/60-ed-persistent-serial.rules cat: /etc/udev/rules.d/60-ed-persistent-serial.rules: No such file or directory
But the folder contains :
40-scratch.rules 99-com.rules
well of course: you need to create that file and put those two lines in it :) then reboot
@elafargue Thank you, your solution works ! ;D
Awesome! Thanks for letting us know. Maybe this should be added in the README.md of the node-serialport package...
@elafargue unfortunately, that solution is not working for me.
cat /etc/udev/rules.d/60-ed-persistent-serial.rules
D_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"
ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"
error:
/home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:541
var pnpId = as_json.DEVLINKS.split(' ')[0];
^
TypeError: Cannot read property 'split' of undefined
at udev_parser (/home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:541:35)
at /home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:592:11
at ChildProcess.exithandler (child_process.js:194:7)
at emitTwo (events.js:87:13)
at ChildProcess.emit (events.js:172:7)
at maybeClose (internal/child_process.js:818:16)
at Socket.<anonymous> (internal/child_process.js:319:11)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at Pipe._onclose (net.js:469:12)
DEVLINKS.split issue is fixed in 2.0.5.
On Thu, Nov 12, 2015 at 5:53 AM, JOHNNY notifications@github.com wrote:
@elafargue https://github.com/elafargue unfortunately, that solution is not working for me.
cat /etc/udev/rules.d/60-ed-persistent-serial.rules D_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}" ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"
error:
/home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:541 var pnpId = as_json.DEVLINKS.split(' ')[0]; ^
TypeError: Cannot read property 'split' of undefined at udev_parser (/home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:541:35) at /home/johnny/projects/arduino/node_modules/johnny-five/node_modules/serialport/serialport.js:592:11 at ChildProcess.exithandler (child_process.js:194:7) at emitTwo (events.js:87:13) at ChildProcess.emit (events.js:172:7) at maybeClose (internal/child_process.js:818:16) at Socket.
(internal/child_process.js:319:11) at emitOne (events.js:77:13) at Socket.emit (events.js:169:7) at Pipe._onclose (net.js:469:12) — Reply to this email directly or view it on GitHub https://github.com/voodootikigod/node-serialport/issues/343#issuecomment-156071809 .
Anyone still having this issue? I solved it by running the node script where I use the serial port as sudo.
If sudo works than it's a permission problem and not related to this. Try adding your user to the dialout group and open a new issue with details if you're still having problems.
We eventually moved away from node-serialport and wrote our own serial implementation in C++ for our 3D printing drivers. Repo available here for anyone that's interested: https://github.com/PRINTR3D/formide-drivers. The code where we scan for devices is here: https://github.com/PRINTR3D/formide-drivers/blob/e87371e3b0e2b67d2302321f10587172ff1b5c84/src/utils/find_devices.hpp.
Edit: our drivers were made to only work on Unix systems, hence the hardcoded /dev stuff.
On the Linux distro i'm using (OpenWRT), there is no /dev/serial directory. To my understanding, it exists only on certain Linux distros, and may be missing on others too (depending on the type of device manager being used, i.e hotplug, udev, etc... I guess).
When trying to list serialport on unix/linux (listUnix function in serialport.js), you use this directory. This means that on some Linux distros, serialports cannot be listed.
I can connect directly to the serialport, using /dev/ttyUSB0 for example. Fixing this would greatly improve the generic use of serialport by other nodejs modules, that use the serialport.list function to automatically find a device, such as in firmata/johnny-five.
Thanks