Closed folksman closed 2 years ago
Is the master node driven by c++ or by circuitpython?
I had trouble getting consistent results with mesh networking. There are commented out lines that I use to debug the problem, but calling print()
while the mesh network layer is executing tends to slow things down significantly.
i use circuitpython on device. BTW i tested now as well Network mode and i see that only send 2-3 messages ok then it failed. this is on both sides
complete using circuitpython example
oh forget the issue on Network mode. looks like it was my mistake. i must idle on 1 node, correct? ohterwise the sender sends just 2-3 message and the failed But mesh issue still there :(
Yes all nodes in the network/mesh (including master) must be idling if they are not emitting. The first 2 or 3 messages might be acknowledged by the radio itself, but the MCU must call network.update()
(or mesh.update()
) to keep the radio's RX FIFO unoccupied.
The mesh connecting process is very sensitive to timing because it doesn't really use the radio's auto_ack feature. What hardware are you using? RPi is somewhat faster than MCUs driven by circuitpython firmware.
Yeah network works fine as i see - no problems so far :)
Mesh: I use a Adafruit Express father board and a Adafruit RP2040 father board. both drive with actual firmware and your lib by simple use your nrf24l01_network_test.py example. I really don´t know why just only this example with mesh not working :/
ohhhh please excuse my issue. i found out what happened. on mesh after create the master i must start as well idle to get it working. now all works fine :))
btw: impressive fast reply from you! love this kind of help
When testing this mesh layer, I mainly used a RPi as mesh master and my feather RP2040 board as a child node. I should note that it was better when there was already a mesh node connected to the mesh master because the middle-man node would allow auto_ack to be used for msg forwarding.
It's 7am here so, I'm going to try and get some sleep, but I'll spin up some MCUs to test when I'm fully awake.
i found already the problem as i mentioned. i not started idle before connect a child node.. now it works well :) Only 1 question more.. how i can get the RX open always to not have any timeout for idle? in my project i not want interact with console
Oops. Didn't see that post while I was writing mine. Good to hear you got it working! I suppose I should add something to the example prompts to make it clear that idle()
must be called... If you have any suggestions, I'd be very thankful.
how i can get the RX open always to not have any timeout for idle? in my project i not want interact with console
while True:
idle()
There are other ways to do it, but this was the first idea that came to mind. The importance of using idle()
is the network.update()
call. So, you could do
while True:
network.update()
As long as you don't want to emit()
anything from that node.
Only 1 question more.. how i can get the RX open always to not have any timeout for idle? in my project i not want interact with console
You could pass idle()
an enormous number...
idle(5000)
will put the node in idle for 5000 seconds.
I use timeouts in the examples because a keyboard interrupt (like ctrl + c
) can leave the SPI bus in a locked state (which would then require a hard reset to unlock).
not easy to understand. lets say i have a master node which always want receive messages without any timeout or initiation to listen. the other node as example send a button command to the master. how i can then make that without set any timeout for RX?
oh i see your reply bit too late. you already answered my question. Does it mean it can´t send and receive dual in same time ?
Does it mean it can´t send and receive dual in same time ?
It all depends on how you write your application. Using the examples: no, because they were designed to show 2 basic roles (emit and idle) separately. In practice, you could write an app that uses these roles however you want. Just remember that the network layers (including mesh) need to be updated regularly (using network.update()
). So, you can send()
whenever you need to, and the message received (after calling network.update()
) can be acted upon accordingly.
ok understand. how many nodes can be handle into the Mesh Network with 1 master?
I've written some very in-depth docs, but the info is rather spread out.
how many nodes can be handle into the Mesh Network with 1 master?
Answer is found in docs' topology page. TL;DR - "A single network can potentially have a maximum of 781 nodes (all operating on the same channel)"
oh yes ..i see. sorry!
Since i have as well a Esp32 (which not support circuitpython BUT micropython), can this libs (py code) also used in Micropython of is there a MESH compatible version somewhere available?
It takes some doing, but this lib should work with microPython if you can get all the files into the ESP32 file system (in a lib folder preferably located at the root of the file system). I haven't tested this though because I don't know a good way of transferring multiple files (using a mandatory directory structure) into my ESP32 (tiny Pico board). As far as I know, there is no microPython equivalent lib that can do everything this lib does. Let me know if you attempt this; I can offer guidance on differences with instantiating the radio object in microPython (the examples won't work in microPython as they are currently written).
There are ESP32-S2 boards that run CircuitPython. I have my eye on Adafruit's new QtPy ESP32-S2 (which sells for $10 American). 😍
using my M5 Atom Esp32 and Thonny Editor its easy to create lib folder and upload multiple files. It would be great if you can help me with Micropython. It would be really nice if we can get this running in mesh too. That opens a lot new possiblities then. As example using a websocket server interacting with ;)
The QtPy ESP32-S2 looks promising but i have a lot of the mentioned devices which i would be use to.
ok, I'd just like to remind you: you're in untested territory here.
from digitalio import DigitalInOut
with
from circuitpython_nrf24l01.wrapper import DigitalInOut
Now you can declare the CE & CSN pin using the pin number like you would when using machine.Pin
.
# change these (digital output) pins accordingly
CE_PIN = DigitalInOut(4)
CSN_PIN = DigitalInOut(5)
replace SPI_BUS = busio.SPI()
with
SPI_BUS = machine.SPI(0) # could pass `1` if you're using a secondary HW SPI bus
Keep in mind that this line will also require import machine
at the top of the script.
you should be able to declare the radio obj like normal now:
nrf = Network(SPI_BUS, CSN_PIN, CE_PIN, THIS_NODE)
# or if you need to change the baudrate
baudrate = 4000000 # a safe default value for troubleshooting
nrf = Network(SPI_BUS, CSN_PIN, CE_PIN, THIS_NODE, spi_frequency=baudrate)
import time
import struct
import machine
from circuitpython_nrf24l01.wrapper import DigitalInOut
from circuitpython_nrf24l01.network.constants import MAX_FRAG_SIZE, NETWORK_DEFAULT_ADDR
IS_MESH = (
input(
" nrf24l01_network_test example\n"
"Would you like to run as a mesh network node (y/n)? Defaults to 'Y' "
) or "Y"
).upper().startswith("Y")
# to use different addresses on a set of radios, we need a variable to
# uniquely identify which address this radio will use
THIS_NODE = 0
print(
"Remember, the master node always uses `0` as the node_address and node_id."
"\nWhich node is this? Enter",
end=" ",
)
if IS_MESH:
# node_id must be less than 255
THIS_NODE = int(input("a unique int. Defaults to '0' ") or "0") & 0xFF
else:
# logical node_address is in octal
THIS_NODE = int(input("an octal int. Defaults to '0' ") or "0", 8)
if IS_MESH:
if THIS_NODE: # if this is not a mesh network master node
from circuitpython_nrf24l01.rf24_mesh import RF24MeshNoMaster as Network
else:
from circuitpython_nrf24l01.rf24_mesh import RF24Mesh as Network
print("Using RF24Mesh{} class".format("" if not THIS_NODE else "NoMaster"))
else:
from circuitpython_nrf24l01.rf24_network import RF24Network as Network
# we need to construct frame headers for RF24Network.send()
from circuitpython_nrf24l01.network.structs import RF24NetworkHeader
# we need to construct entire frames for RF24Network.write() (not for this example)
# from circuitpython_nrf24l01.network.structs import RF24NetworkFrame
print("Using RF24Network class")
# change these (digital output) pins accordingly
CE_PIN = DigitalInOut(4)
CSN_PIN = DigitalInOut(5)
SPI_BUS = machine.SPI(0) # could pass `1` if you're using a secondary HW SPI bus
# initialize this node as the network
nrf = Network(SPI_BUS, CSN_PIN, CE_PIN, THIS_NODE)
# the rest of the example remains the same
I tried using Thonny to get the lib onto my tinyPico... Thonny only allows installing python libs from pypi to the microPython board's file system (using a tool called minipip). Unfortunately, this does not help when trying to test an unreleased development version of the lib ☹️ . Digging deeper, I found rshell now supports recursive copying of files to the microPython file system 😄 .
I tried running the code I suggested above on my tinyPico with the current release of this lib copied to the microPython file system. Unfortunately, I got a SyntaxError on line 221 of mixins.py. https://github.com/nRF24/CircuitPython_nRF24L01/blob/c800869415275f960f97605c28529f9fa5e679b9/circuitpython_nrf24l01/network/mixins.py#L221
I'm guessing the latest version of microPython (v1.17) does not fully support f-strings; v1.17 release notes say:
This release of MicroPython adds support for f-strings (PEP-498), with a few limitations compared to normal Python. F-strings are essentially syntactic sugar for "".format() and make formatting strings a lot more convenient.
So, I'm going to start changing the lib to not use f-strings and try again using rshell... @folksman Any success on your end? You're the first one to provide feedback since I released the networking features, so I'm eager to hear about your experience.
It looks like I'll have to write a wrapper for micropython's utime
module as it is not compatible with CPython's and CircuitPython's time
module... TBH, MicroPython support seems like more trouble than its worth; I generally don't like MicroPython because it tries too hard to support processors with very little memory or no native USB support.
I already had to ignore support for CircuitPython on ATSAMD21 based boards due to not enough memory, and that was before I started porting the C++ network libs.
@folksman You might be better off using TMRh20's RF24Mesh lib (written in C++ for arduino like boards) on the ESP32 boards. This python lib was written to be OTA compatible with nodes running the original C++ libs for the nrf24l01.
hi! i tested today but got this:
MPY: soft reboot
nrf24l01_network_test example
Would you like to run as a mesh network node (y/n)? Defaults to 'Y'
Remember, the master node always uses 0
as the node_address and node_id.
Which node is this? Enter a unique int. Defaults to '0'
Traceback (most recent call last):
File "boot.py", line 33, in
Are you still work on it?
The error that you're seeming is the first of many I found when trying to get this lib to work on ESP32. At the end of the day, microPython is too different from normal CPython. At least CircuitPython tries to be compatible with CPython... You'll have to use C++ on the ESP32 boards.
Unfortunately, this lib's API has to be a little different from the C++ API because of differences in C++ vs Python syntax/features.
I'll probably just drop microPython support since I'd have to write wrappers for the entire microPython API (which could change for different boards or future versions).
ok i see. very harm but may usage of other boards (as you mentioned) is may a option. Well, thank you for the great help! During this time i also got running the C++ samples on my boards and its working well with your library :) Its not so nice as work with python but should be good for my usage too.
HI, i tested almost all examples and they working great except the nrf24l01_network_test.py. i started 1 node as master by default settings and the 2nd i do Y > node '1' and on try connecting Mesh Network it always fail. The master node is acting as master node so ther should be no problem. Any fast help would be great!