I've been looking around for an answer on this...
Basically, I want to read data from the serial port (in this case, over USB). I've looked into the node-serialport module but it keeps stalling after the first result form the serial port. I expected it to just spit out the data when it received it. It's as if a buffer is filling up and needs to be flushed somehow?
I've slightly modified the code from the demos I found here - https://github.com/voodootikigod/node-serialport/tree/master/tests
Here's my code:
var sys = require("sys"),
repl = require("repl"),
serialPort = require("serialport").SerialPort;
// Create new serialport pointer
var serial = new serialPort("/dev/tty.usbmodem1d11" , { baudrate : 9600 });
// Add data read event listener
serial.on( "data", function( chunk ) {
sys.puts(chunk);
});
serial.on( "error", function( msg ) {
sys.puts("error: " + msg );
});
repl.start( "=>" );
I'm using an Arduino hence the 9600 baudrate.
Any help would be awesome, cheers,
James
Author of node-serialport. I have tracked down the issue and it is due to a compilation issue with IOWatcher in node.js. I have revised the strategy for reading from the serial port and it now should function as designed in all cases. Please ensure you are using node-serialport 0.2.6 and greater.
Now go out and build JS controlled robots!!!
I also experienced problems with the serial port read.
This is due to a bug in node.js v4.7 (see this issue)
However it worked after switching to an older version of Node.js (v4.0).
It might work with versions up to v4.6 also, but I haven't verified that yet.
Related
as the title suggests, I made a simple program made with Node.js and Noble to scan for devices with Bluetooth LE. My end goal here is to connect to my daydream view controller and receive information from it.
My problem is that whenever I run the file the state is set to "poweredOff" even though I set it to "poweredOn". When the state is set to "poweredOff" it stops scanning so I am never able to find devices.
Here is my code:
const noble = require('noble')
noble.on('stateChange', function(state) {
console.log("[STATE] State changed to: ", state)
if (state === 'poweredOn') {
console.log("[STATE] Powered on, now scanning")
noble.startScanning();
} else {
console.log("[STATE] Powered off, stopped scanning")
noble.stopScanning();
}
})
noble.state = "poweredOn"
// we found something
noble.on("discover", function(peripheral){
console.log(peripheral)
})
Here is the output I get after running that:
[STATE] State changed to: poweredOff
[STATE] Powered off, stopped scanning
What have I tried?
I have checked that I have all the prerequisites for Noble.
I have tried to run the examples provided by Noble. (same thing happens)
And I have tried moving noble.state = "poweredOn" above and below the noble.on('stateChange') event
I also figured out the problem is not in the daydream controller because I downloaded the LightBlue app on my phone and it detects and connects to the daydream controller just fine. I get no errors or anything at all. This is very strange to me and I hope that anyone could help me.
Thanks in advance.
I'm working on node-midi, a node.js wrapper for the RtMidi C++ library that provides realtime MIDI I/O, and its simplified wrapper node-easymidi.
The library is working great, but one thing, I wanted to read the midi piano keyboard input from not only the easymidi, but also from an other application, FL studio, to play the midi input sounds. If I try to connect to easymidi while FL studio, I get an error MidiInWinMM::initialize: no MIDI input devices currently available.. So I needed to exit FL studio before running the node app.
So, how can I modify the code to work with multiple applications aside from the node app? Or I need to install other libraries or change Windows settings? I read google, stackoverflow, github issue, but couldn't find a solution by myself. So I want your help here. Thank you.
Here's the code.
var easymidi = require('easymidi');
var inputs = easymidi.getInputs();
var outputs = easymidi.getOutputs();
console.log(inputs, outputs ) ;
// [ 'CASIO USB-MIDI 0' ] [ 'Microsoft GS Wavetable Synth 0', 'CASIO USB-MIDI 1' ]
var input = new easymidi.Input('CASIO USB-MIDI 0');
input.on('noteon', function (msg) {
console.log(msg ) ;
});
input.on('noteoff', function (msg) {
console.log(msg ) ;
});
Unfortunately, MIDI instruments cannot be shared in Windows.
If the port is used by one application, another application cannot connect to it.
I'm trying figure out how to control multiple temperature sensors.
THE SETUP:
2 ESP8266 Micro Controllers
2 MCP9808 Temperature Sensors
1 Machine controlling both ESPs using Johnny-Five.
NOTE: Each ESP8266 micro controller handles one MCP9808 Temperature Sensor.
THE GOAL:
The central machine (MacOS running Johnny-Five) handles both microcontrollers under one Node JS script.
THE PROBLEM:
I can control one Micro Controller / Temperature pairing, but not both under the same script.
Apparently the key to handling both at once lies in knowing how to handle the IC2 addressing.
So far I haven't been able to find any pages, forums, instructions or combinations thereof that clearly explain the logic in terms that I can understand.
THE QUESTION:
How to handle I2C using Johnny-Five to control multiple devices
THE CODE:
It only works when handling one Sensor, not both
In other words with the 4th line commented out it works. Uncommented, it doesn't.
var five = require("johnny-five");
var {EtherPortClient}=require("etherport-client");
var Thermometers=[
//{Name:"Thermometer1", Ip:"192.168.1.101"}, //Uncommenting causes fail.
{Name:"Thermometer2", Ip:"192.168.1.102"}
];
TrackThermometers();
function TrackThermometers(){
Thermometers.forEach(function(ThisThermometer, ThermometerCount){
ThisThermometer.Board=new five.Board({
port: new EtherPortClient({
host: ThisThermometer.Ip,
port: 3030
}),
repl: false
});
ThisThermometer.Board.on("ready", function(){
ThisThermometer.Controller=new five.Thermometer({ //This cmd triggers the error
controller:"MCP9808"
});
ThisThermometer.Controller.on("change", function(){
console.log(this.id, this.fahrenheit);
});
})
});
}
SOLUTION
There is a board property (undocumented as of this post) under the J5's Thermometer API. Assigning the Board instance in question to that property associates the Thermometer instance with that board.
By way of example the above code would be edited as follows...
ThisThermometer.Controller=new five.Thermometer({
board: ThisThermometer.Board, //<-- the missing magic
controller:"MCP9808"
});
Thanks to Donovan Buck for figuring this out. May be documented soon.
To be as concise as possible, I am connecting to a telit ME910c1-nv socket modem made by multitech. It's not really relevant but I know someone will think this issue is hardware related when it's not.
The device has both a 4g cat m-1 modem and a gps module built in. I connect to these over UART to a raspberry pi.
The issue is that when I send AT commands to get the GPS location, eventually the module will stop sending and/or my code can no longer read from the serial port.
I am using node js to communicate with the module but I have also had the same issue with python. I have no issues in C though, which makes me think it is a higher level programming issue and timing issue.
An basic example is:
getGpsData=(modem, callback)=>{
modem.write("AT$GPSACP\r");
const timer = setTimeout( ()=>{
callback(null);
}, 5000); //wait 5 sec before returning null
modem.on('readable', readRaw=()=>{
let data = modem.read();
let output = "";
if(data){
data = data.toString();
output += data;
if(data.includes(escape_character)){ //escape character is "OK" or "ERROR"
clearTimeout(timer);
callback(output);
}
}
});
}
//connect to serial port
modem = new serialport("/dev/serial0");
on.('connect', ()=>{
//on connect read gps data at constant interval
setInterval(()=>{
getGpsData(modem, (data)=>{
modem.removeListener('readable', rawRead);
console.log(data);
}
}, 10000); //loop every 10 sec
});
When I run this, I will get about 10 - 20 gps readings and then all nulls. When I stop my code and start it again, it works fine. Sometimes it runs for an hour or more without any issues and then starts producing nulls and never recovers. If I connect directly to the modem and send it AT commands, I don't get this issue at all. It's as if my reads are out of sync with what the module it writing to the serial port.
The output from the module comes as:
$gpsacp: "gpsdata..........."
OK
I get null data reads because it times out and my escape character is never read. Sometimes I'll get the "OK" escape character and null data also.
I've rewritten my command and read function multiple times but always suffer the same issue. Anyone have any idea why this is happening or had similar experience?
I try to connect to a serial-usb interface (FT232) but can't find anything on how to configure it...
What I've got :
A serial to USB interface from FTDI, it's a TTL-232RG-VSW5V-WE from this page
A custom board sending messages through RS232
What I need :
I need to connect to this interface using WebUSB, send messages, read messages.
What I've achieved :
Right now, I can connect to the interface and "read" something.
My problem :
I can't find anything on the web on how to configure the USB interface, the serial port configuration must be 57600 baud/s, E, 8, 1 but nothing I could find told how to configure these values...
See the following code, from what I understood, I've got to put some value in the controlTransferOut but I can't find what to put and why..
device = await navigator.usb.requestDevice({ 'filters': [] });
console.log(device);
await device.open();
if (device.configuration === null) {
await device.selectConfiguration(1);
}
await device.claimInterface(0);
await device.selectAlternateInterface(0, 0);
await device.controlTransferOut({ /* WHAT DO I PUT HERE?? */ });
let result = await device.transferIn(1, 64);
console.log((new TextDecoder).decode(result.data));
What I can read from the "What I've achieved" section is single chars because the serial is not well configured.
I tweaked it though to kindda make it work, I've opened the serial port with another software, configured it, closed the other software, then connect to the USB interface with webusb and read messages. That worked, but way to complicated...
Any help would be REALLY appreciated :)
According to the datasheet your TTL-232RG-VSW5V-WE cable contains a FT232R chip. The datasheet for that is here. I was hoping to discover a description of the protocol that the chip supports but all I found was documentation for their proprietary drivers.
On the other hand I know that Linux supports these chips so there must be code in the kernel driver for setting baud rate. The function in question is change_speed() in ftdi_sio.c.
From this it appears that the control transfer you need to send is,
device.controlTransferOut({ requestType: 'vendor',
recipient: 'device',
request: 3 /* FTDI_SIO_SET_BAUDRATE_REQUEST */,
value: divisor_value,
index: divisor_index });
divisor_value and divisor_index are the lower and upper 16 bits of the chip's clock divisor which is calculated by the ftdi_232bm_baud_to_divisor function based on the baud rate requested.
Hopefully this is a good start towards reading the code and figuring out what you need.
Thank you, very much. It works like a charm.
I figured out for baud rate 9600:
device.controlTransferOut({
requestType: "vendor",
recipient: "device",
request: 3 /* FTDI_SIO_SET_BAUDRATE_REQUEST */,
value: 16696, // divisor_value
index: 48000000 // divisor_index
});