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.
Related
I have spent the last couple of days researching and understanding GATT to control my new adjustable bed which I can currently only control via Manufacturer's app but I want to control via my smart home setup.
I am able to get characteristics which are read and write with/without response so I know I am on right track and I have used PacketLogger on OSX to get values which I now know are acceptable when sent by myself using an IOS app called BLE Scanner which just asks for a Hex or Text Value to send to the characteristics for the device (bed) and I have sent the values I extracted from PacketLogger when using the manufacturer's app (5212 006E 0100 4EBD) as Hex separately and it vibrates the bed!
I just need to be able to this myself now with Noble by sending either straight to the peripheral.writeHandle function or via the characteristic.write function. I have tried many different things but I don't get the same effect as BLE Scanner app when it sends the values individually as Hex so I know the device isn't happy with what i'm sending. I noticed there is some padding added for what I think is L2CAP but as I say BLE Scanner just works for (5212 006E 0100 4EBD) as long as they are sent separately as Hex.
Would really appreciate some help to get me over the line.
I have tried so far to write to the characteristic and also tried direct to the periphel as there is no mention of the characteristic UUID in the PacketLogger logs when writing via BLE Scanner whereas when using the Manaufacturer app PacketLogger shows the write characteristic UUID so both I think will work.
I have tried many variations of
peripheral.writeHandle(18, Buffer.from("5212006E01004EBD", "hex"),
true, function(err) { console.log('writehandle'+err) });
and
characteristic.write(Buffer.from("5212006E01004EBD", "hex"), true,
function (error) {
if (!error) {
console.log("write succesful");
} else {
console.log("write unsuccesful");
}
}.bind(this));
I do see a difference in the ATT Send PacketLogger entry for the BLE Scanner App which works and my attempt in Noble which doesn't work - Write Request - Handle:0x0012 - Value: 5212 006E 0100 4EBD Opcode is 0x0012 is the working packetlogger entry for BLE Scanner whereas my attempt shows multiple entries for each attempt and the first entry is always Exchange MTU Request - MTU: 104 and the Opcode is 0x0002. No matter what I change in Noble the Opcode remains the same.
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
});
I've previously had my Arduino kit working on the same hardware with Breakout, but would like to switch to Johnny Five. My hardware is wired with the simple single LED layout from http://weblog.bocoup.com/javascript-arduino-programming-with-nodejs/ but running the basic LED strobing demo isn't working as expected:
var five = require("johnny-five"),
board, led;
board = new five.Board();
board.on("ready", function() {
console.log('ready');
led = new five.Led(13);
led.strobe(100);
});
Returns:
1341154189666 Board Connecting...
1341154189697 Serial Found possible serial port cu.usbmodem621
1341154189699 Board -> Serialport connected cu.usbmodem621
1341154191570 Repl Successfully Connected
I end up straight in the Firmata REPL with no LED strobing, and board.ready is false.
Any suggestions for why the board.ready callback wouldn't be firing?
On Windows, sometimes you have to specify which COM port. I received the following error when flashing firmata:
avrdude: stk500_getsync(): not in sync: resp=0x00
Change the Arduino UI to point to the other COM port (COM4 in my case)
Tools -> Serial Port -> COM4
Add this to your johnny-five startup code:
var five = require("johnny-five");
board = new five.Board({
port: "COM4"
});
board.on("ready", ...);
I was running into this same problem on my Arduino Uno R3 with johnny-five. To fix it, I had to update the StandardFirmata.
Download the latest Arduino software (at time of writing 1.0.2)
Install and open the Arduino application
Connect the Arduino to the computer (through USB)
In the menu, select File > Examples > Firmata > StandardFirmata
Press the upload button
After that completed, I could connect to the board using firmata and the ready event fired as expected. I had to do the same process with all my Arduinos to get them to work.
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.