Closed conaito closed 6 months ago
I try the mesh with 2 pico (circuitpython mesh example) and 1x arduino with c++. As soon the arduino is connect to the master then also the 2nd pico can connect. Thats strange. Can you help me to get the example working with just the 2 circuitpython?
The quick answer is that the circuitpython firmware runs slower than the C++ examples.
I documented the connection process in the topology page of the docs. What you're experiencing is a common point of failure (point 2 in the list).
I'm not sure what the best solution is here. Essentially the master node needs to have a slight delay so the child nodes on network level 1 have enough time to switch back to RX mode and complete the pairing process.
Are these nodes not stationary? Is that why RF24Network is insufficient for your application?
It means its not possible to connect 2 picos with circuitpython by Mesh? (1 is master and 2nd is a child)
I want use mesh because i not want setup octal node id´s. it should hold it simple by simple set on a child nodes 1,2,3,4 etc
btw if i not use Mesh (in exmaple 'N' > 0 and 2nd 'N' >1) it works great
RF24Network is much more reliable for nodes that don't physically move around. RF24Mesh is designed for nodes that do physically move around, but the connecting process is flawed because the process doesn't use auto-ack. Transmissions in RF24Mesh will also be slower because the octal address has to be fetched from the master node before any the message can be sent to the actual destination.
The actual line of code that is failing in the master is here: https://github.com/nRF24/CircuitPython_nRF24L01/blob/c73978c954d074cebd1337227dbc7ae08fbda51c/circuitpython_nrf24l01/rf24_mesh.py#L373
You could try doubling that call so it transmits twice:
self._write(self.frame_buf.header.to_node, TX_PHYSICAL)
self._write(self.frame_buf.header.to_node, TX_PHYSICAL)
Hopefully that will give the child enough time to receive the the response from master and complete the process.
ok i will try that tomorrow.
If i use network instead, is there a way to automatically give the child nodes id on connect to master or a similar workaround to not need to set node id on each child into the code?
also, how is the best way to send a message to all childs? just by a loop only possible or exist a function already for? Am 7. Nov. 2022, 17:05 +0100 schrieb Brendan @.***>:
The actual line of code that is failing in the master is here: https://github.com/nRF24/CircuitPython_nRF24L01/blob/c73978c954d074cebd1337227dbc7ae08fbda51c/circuitpython_nrf24l01/rf24_mesh.py#L373 You could try doubling that call so it transmits twice: self._write(self.frame_buf.header.to_node, TX_PHYSICAL) self._write(self.frame_buf.header.to_node, TX_PHYSICAL) Hopefully that will give the child enough time to receive the the response from master and complete the process). — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
is there a way to automatically give the child nodes id on connect to master or a similar workaround to not need to set node id on each child into the code?
No, you need to assign a unique id to each node in the network. There is no way around that.
how is the best way to send a message to all childs?
This is called "multicasting". You can enable multicast_relay
and use multicast()
. Beware that auto-ack is disabled for multicasting, so there is no guarantee that the message is received by all nodes.
on multicast how can i send to all nodes without worry to set the correct level of the child nodes? basically to all childs not depend on level they are Am 7. Nov. 2022, 17:24 +0100 schrieb Brendan @.***>:
is there a way to automatically give the child nodes id on connect to master or a similar workaround to not need to set node id on each child into the code? No, you need to assign a unique id to each node in the network. There is no way around that. how is the best way to send a message to all childs? This is called "multicasting". You can enable multicast_relay and use multicast(). Beware that auto-ack is disabled for multicasting, so there is no guarantee that the message is received by all nodes. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
I suppose there should be an example code snippet in the docs for this...
From master node, you just need to
mesh_node.multicast(payload, 0, level=1)
this broadcasts the payload to all child nodes on level 1. If multicast_relay
is set to True
(on all child nodes in level 1), then the payload is re-broadcasted to all child nodes on level 2. I think you get the idea from there.
Typically you don’t want to enable multicast relay with RF24Mesh it will interfere with mesh functionality. You would need to manually relay multicast packets
On Nov 7, 2022, at 10:55 AM, Brendan @.***> wrote:
I suppose there should be an example code snippet in the docs for this...
From master node, you just need to
mesh_node.multicast(payload, 0, level=1) this broadcasts the payload to all child nodes on level 1. If multicast_relay is set to True (on all child nodes in level 1), then the payload is re-broadcasted to all child nodes on level 2. I think you get the idea from there.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.
it means if i require multicast (what i need) then its better to go with Network instead Mesh?
Is in Network a function available to get a list of all registered childs at master? Am 7. Nov. 2022, 18:55 +0100 schrieb TMRh20 @.***>:
Typically you don’t want to enable multicast relay with RF24Mesh it will interfere with mesh functionality. You would need to manually relay multicast packets
On Nov 7, 2022, at 10:55 AM, Brendan @.***> wrote:
I suppose there should be an example code snippet in the docs for this...
From master node, you just need to
mesh_node.multicast(payload, 0, level=1) this broadcasts the payload to all child nodes on level 1. If multicast_relay is set to True (on all child nodes in level 1), then the payload is re-broadcasted to all child nodes on level 2. I think you get the idea from there.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Yup
On Nov 7, 2022, at 12:07 PM, conaito @.***> wrote:
it means if i require multicast (what i need) then its better to go with Network instead Mesh?
Is in Network a function available to get a list of all registered childs at master? Am 7. Nov. 2022, 18:55 +0100 schrieb TMRh20 @.***>:
Typically you don’t want to enable multicast relay with RF24Mesh it will interfere with mesh functionality. You would need to manually relay multicast packets
On Nov 7, 2022, at 10:55 AM, Brendan @.***> wrote:
I suppose there should be an example code snippet in the docs for this...
From master node, you just need to
mesh_node.multicast(payload, 0, level=1) this broadcasts the payload to all child nodes on level 1. If multicast_relay is set to True (on all child nodes in level 1), then the payload is re-broadcasted to all child nodes on level 2. I think you get the idea from there.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***> — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.
Is in Network a function available to get a list of all registered childs at master?
No. RF24Network doesn't need to keep track of node addresses that correspond to node IDs (the RF24Mesh master node's DHCP list). All logical addresses (octal numbers) are static in RF24Network.
Double the line 373 not help :( any other idea? Am 7. Nov. 2022, 23:21 +0100 schrieb Brendan @.***>:
Is in Network a function available to get a list of all registered childs at master? No. RF24Network doesn't need to keep track of node addresses that correspond to node IDs (the RF24Mesh master node's DHCP list). All logical addresses (octal numbers) are static in RF24Network. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Nope, use C++ for nodes on level 1 or switch to RF24Network. There's nothing I can do to speed up CircuitPython's slow execution which is the problem with nodes connecting to master from level 1. Trust me, I invested a lot of time trying to optimize this lib around that limitation.
Just in case I get the time to reproduce this,
Honestly, your English is hard to read and understand. I will not write code for you - that is what the documentation is supposed to help with.
If by string you mean "some value"
, then that is an invalid data type for a payload. Payloads in this lib should only use bytes or bytearray objects.
Please also read the python docs about using struct.pack()
or struct.unpack()
. I will not teach you on this.
i understand to need follow on sender message = struct.pack("4s", b"cool") but no chance to get it correct unpack on receiver :(
for actual strings, you could use str.encode()
msg = "cool"
nrf.send(msg.encode(encoding="utf-8"))
and then use bytearray.decode()
on the receiver.
rcv = nrf.read()
msg = rcv.decode(encoding="utf-8")
raw bytes objects are easy enough to construct, but the functions exist to deal with data that isn't a simple ASCII character.
>>> b"cool" == "cool".encode(encoding="utf-8")
True
Have you tried using the more basic RF24 examples? This should've been your first step in understanding how to use the library. Once you can get the RF24 examples working, then you know its not a radio hardware problem, and you can graduate to networking usage.
I already know why it isn't working. I documented the problem as a known point of failure. As stated in the docs:
If a master node is able to respond faster than the connecting node can prepare itself to receive, then the process will fail entirely. This failure about faster master nodes often results in some slower RF24Mesh nodes only being able to connect to the network through another non-master node.
The problem isn't so much about the library's code, rather the real problem is with CircuitPython's slow execution. Its not something I can fix until CircuitPython becomes significantly faster which entirely depends on the MCU board.
The RP2040 is dual core, but that doesn't mean it is the fastest processor (actually about 125-133 MHz). The ESP32 can run at about 240 MHz.
This is a complete hack, but I'm curious if using the auto-ack would help resolve this...
Instead of https://github.com/nRF24/CircuitPython_nRF24L01/blob/c73978c954d074cebd1337227dbc7ae08fbda51c/circuitpython_nrf24l01/rf24_mesh.py#L373 try
self._write_to_pipe(self.frame_buf.header.to_node, 1, False)
To be clear, the hack I just posted is meant for the master node, not the child node.
i test it out tomorrow and let you know. thank you Am 8. Nov. 2022, 14:36 +0100 schrieb Brendan @.***>:
To be clear, the hack I just posted is meant for the master node, not the child node. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
EDIT: It is a dirty hack. If we bypass _write()
, then we need to also put the radio back in RX mode for continued operation. So, I change my suggestion to:
self._write_to_pipe(self.frame_buf.header.to_node, 1, False)
self.listen = True
self._rf24.auto_ack = 0x3E
I tested your latest code. Same.. not connected to Mesh :/
It seems there is no way to reliably fix this within the confines of circuitpython. If we make any changes to this lib, then they should also be added to the RF24Mesh C++ lib because the code for this lib's RF24Mesh and RF24Network is directly ported from the C++ libs.
hi, i try the network / mesh example between 2 pico boards but not get the mesh working... i try 1 node with Y > 0 and 2nd with Y > 1.. it will not connect to the mesh master. With 1 node as arduino and c++ code it connect to the mesh mast well. If i try just Network it works well togehter. ANy idea here? May i try it in wrong way using your example?