Open fredlcore opened 3 years ago
Hi @fredlcore! Connecting to multiple hubs is defenitely possible. Up to now you can have a connection to up to 9 hubs from one esp32. If you want to use more than three hubs, you have to configure the NimBLE-Arduino lib according to the followin procedure: https://github.com/corneliusmunz/legoino#connection-to-more-than-3-hubs
You can find ab example of connections to multiple hubs in the following sketch: https://github.com/corneliusmunz/legoino/blob/master/examples/MultipleTrainHubs/MultipleTrainHubs.ino
Now the issue #46 comes into place. Adding the non blocking scan has some benefits but also some drawbacks and you can "remove" the non blocking change by changing the following line in the Lpf2Hub.cpp
file:
Non blocking scan start: pBLEScan->start(_scanDuration, scanEndedCallback);
Change to blocking scan start: pBLEScan->start(_scanDuration);
With this change the connection procedure should work for multiple hubs and you can check for each hub instance if it is connected with the myHub.isConnected()
method. If you know the Hub Ids, you can specifically connect to a known id and can map that to a specific instance
myTrainHub1.init("90:84:2b:03:19:7f"); // initialize the listening train hub 1 // here you have to use your own device ids
You can find an example in the TwoTrainHub.ino
sketch
Thanks for the detailed feedback!
I'm not sure if I understand the blocking/non-blocking matters correctly, but looking at the code in MultipleTrainHubs.ino
, I'm wondering whether it is not possible to send all three inits at the same time, like I did here: https://github.com/fredlcore/PS3-Lego-Duplo-Train-Control/blob/08bd8fa5e5a7657427cfdf943890201ffecae241/DuploTrainControl/DuploTrainControl.ino#L124-L127
Or is it a must that any subsequent inits can only be started after there has been a successful connection with the previous init?
The reason why I would like to do this with an array of Lpf2Hub
objects is that it is easily scalable. So it does not matter whether it's one, two or three hubs one is using (or up to nine with the changes you mentioned above). And it would not require the nested if
blocks etc. But maybe that's the reason why yours is working and mine is not.
So in case you'd have the time to look at my code, I'd really appreciate it!
I just figured out the reason why my code was not working properly: I assumed that after issuing an init()
, the scan would continuously run until a connection was made. In all these tests, it probably took me more than 10 seconds (the defaul scan duration) to start both Duplo trains, so only the first one got connected. Now that I re-issue init()
every 11 seconds, it works and I can control both trains. Working with an array in that respect makes this matter easily scalable and also does not require one to do nested if
s etc.
@corneliusmunz: I now found a solution that works with non-blocking scan and gives you the freedom to initialize up to nine hubs without adding extra code - just by going through a loop using an array:
#define HUBS 3
for (int x=0; x<HUBS; x++) {
myHubs[x] = new Lpf2Hub;
myHubs[x]->init();
}
Later on, in the loop() function, I can use this to both execute individual code for each train as well as restart scanning after the initial scanning period is over, so that any disconnected device can easily reconnect:
for (int hub=0; hub<HUBS; hub++) {
myHub = myHubs[hub];
if (myHub->isConnected()) {
... *Do train control stuff here* ...
} else { // not connected anymore? Then put this instance in scanning mode again
if (myHub->isScanning() == false && myHub->isConnecting() == false && myHub->isConnected() == false) {
myHub->init();
}
}
}
Maybe this is an (easier) option for your TwoTrainHubs or MultipleTrainHubs examples as well?
First of all, I'm not sure if this is a doublette of #46 - if so, feel free to close this right now. I'm trying to connect my ESP32 to three Lego Duplo trains. The way I'm doing this is that I setup an array of Lfp2Hub objects like this:
and then send all of them into init mode in setup():
Subsequently, I can cycle through them in a for-loop:
However, this only works for the first train to be connected, and this will always be the last element of the myHubs array (2 in this case). Also, once the first connection is made, any subsequent train that is turned on won't connect.
After reading #46, I was wondering if this also has to do with the blocking-/non-blocking approach. But if changing to a blocking model would be necessary to connect multiple hubs, wouldn't that mean that I'd have to a) define how many hubs I want to use and b) make sure that all of these hubs are connected before the code will continue to execute? Because that's what blocking means, isn't it? My goal would be that my kids can decide whether they put 1, 2 or 3 trains on the track and all active ones could be controlled (I would use the PS3 controller's "SELECT" button to switch between them). However, it seems that with blocking mode, they would have to always use the same number of trains, wouldn't it?