sphero.js icon indicating copy to clipboard operation
sphero.js copied to clipboard

Connection issues... Possible workaround/hack

Open tvl83 opened this issue 7 years ago • 2 comments

I have worked with the Sprk+ for a while for my job and I found out a weird hack. I have to issue a disconnect command FIRST then connect and it seems to work fine. I also, when disconnecting via the script have to kill the process and restart the script to let me connect to it again.

Here is a snippet of my code:


// I am using socket.io so this is a socket message from a web page that tells it to connectSphero

socket.on("connectSphero", function (data) {

// if the sphero object is not null, i disconnect and proceed.
        if (sphero !== null) {
            console.log("sphero not null... disconnecting ");
            sphero.disconnect(function () {
                console.log("disconnecting first... for some reason it works");
            });
        }
// we have multiple spheros so in the socket message payload i am telling it which to connect to
        if (data.sphero === 'a') {
            console.log('Chose Sphero A');
            currentSpheroMAC = "C7:CB:11:51:A8:DB";
            sphero = Sphero(currentSpheroMAC, {emitPacketErrors: true, timeout: 2000});
            spheroName = 'a';
        } else if (data.sphero === 'b') {
            console.log('Chose Sphero B');
            currentSpheroMAC = "D8:C1:9C:58:77:71";
            sphero = Sphero(currentSpheroMAC, {emitPacketErrors: true});
            spheroName = 'b';
        }

        // Setting voltage low point to 7.25v and critical to 6.75v
        sphero.setVoltageTripPoints(725,675, function(err, data){
            console.log(err || "data: " + data);
        });

// i issue the disconnect command again
    sphero.disconnect(function () {
        console.log("disconnecting first... for some reason it works");
    });
// i connect to the sphero here
    sphero.connect(function () {
        sphero.setInactivityTimeout(36000, function (err, data) {
            console.log(err || "data: ");
            console.log("setting inactivity timeout to 3600 seconds (1hr)");
        });
    });
});

it's a bit hacky to issue the disconnect first then connect to it but that is the only way I have found it to work. I hope this is helpful to someone.

Here is how I kill the script on disconnect.

// again with socket.io message i send disconnectSphero and it does this
socket.on("disconnectSphero", function () {
        if (sphero !== null) {
// tell it to sleep after 60 seconds
            sphero.setInactivityTimeout(60, function (err, data) {
                console.log(err || "data: ");
                console.log("setting inactivity timeout to 60 seconds");
issue disconnect command                
                sphero.disconnect(function () {
                    console.log("Now disconnected from Sphero");
                    sphero = null;
                    console.log("sphero == null");
                    io.emit("spheroDisconnected", {
                        spheroName: spheroName
                    });
// this actually kills the process of the script
                    process.exit(1);
                })
            });
        }
    });

I then use a process manager called pm2 which can watch the process and automatically restart it when it gets killed or crashes or what ever so then my script automatically restarts and i am able to connect to the sphero again.

it's extremely weird that this is required, i admit but again it's the only way it has worked for me.

tvl83 avatar Feb 06 '18 16:02 tvl83

I'm not entirely certain why you'd need to call a disconnect before you can connect but I can tell you that when you call disconnect it never makes it far enough back down the stack to actually do a call to noble to handle the actual disconnection.

In ble.js from the sphero.js npm in adaptors, here's the original code at the end of the function when you try a disconnect:

Adaptor.prototype.close = function close(callback) { callback(); };

I modified it a bit to actually call into noble and complete the disconnect.

Adaptor.prototype.close = function close(callback) {

var p = this._connectedPeripheral();

var self = this;

p.disconnect(function() {
	console.log("///////// Here in the disconnect call");
	console.log(self.uuid);
	console.log(self.connectedPeripherals);

	delete self.connectedPeripherals[self.uuid];

	self.noblePeripheral = null;
	self.isConnected = false;
	
	callback();
});

}; ` in the same file it fails when calling the connect again. Everything I've tried to restart the part to enable the scanning has ended in frustration. Maybe someone a bit more familiar with noble could help explain.

xocialize avatar Mar 07 '18 22:03 xocialize

Yea like I said it is extremely weird but it works. I also have to kill the original process too and have it restarted to be able to reconnect again. Extremely bizarre stuff but it's my workaround to make things work consistently.

tvl83 avatar Mar 12 '18 21:03 tvl83