-
-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow multiple LoRa modules to use onReceive #367
Comments
Hmm, I'm finding information that says that |
Trying to think through possible work-arounds. The best thing I can think of is to keep a global key-value map of all created LoRa objects keyed by the interrupt pin they are attached to, you should then be able to get that interrupt pin during ISR and select the correct object on which to call I also saw one idea to use a macro to define a function that takes takes a variable, but acts like it doesn't. See this forum discussion, https://forum.arduino.cc/index.php?topic=267380.0 |
I saw a similar error while trying a variation this morning.
There has to be something in the realm of C++ that provides this kind of functionality. I'm going to read up on static functions in C++ and see if that turns anything up. |
@morganrallen you are correct that there is a key-value map option in C++. We use it in disaster radio for handling multiple websocket connections, it's called an unordered map. See this line in our WebsocketClient code. We map a pointer to the WebsocketClient object to a hash that corresponds to a client id. I'm imagining something similar could be done with LoRaClass objects mapped to interrupt pins. I'll hack a bit on it myself in the next few days to see if I can come up with anything. |
How you specify SS of each LoRa in this case for one 1 SPI? Thanks a lot. |
You would specify the CS pins using the
However, setting this chip select is irrelevant to the Really this is a flaw in the design of this library. I got distracted and started trying to use RadioLib to solve my problem. It is able to initialize two LoRa modules successfully because it does not rely on a global class object, instead it forces users to create their own module objects. Their solution to the I'm not sure of a good solution that isn't just a hack, Arduino isn't meant for async tasks, and the more things you add to the ISR, the more likely it is to crash your microcontroller. |
@paidforby Thanks for your comprehensive reply. Now I realize about the global LoRa object. Setting two CSs may not be sufficient. Let me look at RadioLib for any hint to move on. Thanks a lot again. |
I believe the only thing to solve is the global LoRa object. The callback in this library can be use to set flag only too. This library has the beauty of simplicity. |
The I agree that simplicity is of this library is beautiful, but it is also deceiving. However, I'm thinking that I may be able to solve my complaint by avoiding the |
parsePacket is to use Single RX mode. The mode is in the datasheet. |
Got it. Thanks for explaining that. So using parsePacket probably isn't a viable solution. It seems to me that the best solution would be to change the suggested usage of the library and have a user check an interrupt flag during
and to use With this the only changes that need to be made is for |
Can we have two or more global LoRa objects instead? Haha By right, it should be simple to fix to LoRaClass.this or make this object private to the instance. I also dont know how one SPI takes turn to Low/high two SSs of two LoRa modules. |
@morganrallen Any idea on @paidforby recommendation? |
@paidforby After trying to fix here and there a bit. The main problem is with this line. So the limitation of attachInterrupt is the main root cause. |
Sure, I mentioned that in an earlier comment, #367 (comment). This is what I was saying about "technically" being able to set a flag with With this knowledge there are two ways to solve the problem, A) Fix the attachInterrupt side by allowing the user to pass their own static ISR function into OR B) Fix the I'm in favor of option A because it is more honest about how the library is operating and is the more correct usage of an ISR function. Option B seems messy and hacky for only a small pay off. I haven't pursued either solution very far because I am currently satisfied with my RadioLib solution. If anyone is interested in taking a look at how I have used RadioLib to do this, you can see the LoRaLayer2 library portion in Layer1_SX1276.cpp and the relevant main.ino code, here and here. Apologies if it is a little messy, I haven't had time to clean it up and add comments. |
I checked RadioLib. Will be useful if two LoRa modules are put into two different SPI interfaces. |
See the commit in which I referenced this issue. paidforby@92177e0 In it, I implemented Option A. The only added syntax is that the user must execute I left If @morganrallen and/or @sandeepmistry think this change is worth adding to the library, I'm happy to open a merge request. |
Multiple LoRa modules can not use other interrupt functions such as OnTxDone too. Thinking to merge @paidforby 's code into my own Repository. |
Go for it! I have not done anything for onTxDone, but since it involves that global Lora object I'm guessing it would have the same problem as onReceive and probably can be solved in a similar fashion. |
This library seems less active recently. But nevermind, let me try based on your work. |
Based on discussion in #279, this library currently does not support the use of a local
LoRa
object as a receiver. This prevents the use of multiple LoRa modules in which more than one module is able to receive packets.Problem
The function that handles the onReceive callback,
onDio0Rise
, contains a reference to the globalLoRa
object when it callshandleDio0Rise
, see LoRa.cpp line 715. Regardless of theLoRaClass
object on which you call theonReceive
function, the globalLoRa
object is always the object on whichhandleDio0Rise
is called. If you then tried to read from a local LoRa object, the buffer for that object would never be properly cleared and reset becausehandleDio0Rise
is never called on that object.I imagine that the
onDio0Rise
function was written this way because it is a callback and, therefore, cannot contain references tothis
or other non-static members, so a quick fix was to use the global object.Solution
The "right" way to handle this non-static member inside of a callback is to pass the LoRaClass object down to
onDio0Rise
from where the callback is set inonReceive
here.I suppose something like this should work,
and then rewrite
onDio0Rise
like so,I haven't tested to see if this will actually work, but it seems like the best solution since it should keep the syntax of
onReceive
the same and only actually makes a difference when you call it on a local LoRa object. I'll test and report back.The text was updated successfully, but these errors were encountered: