-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Pico SDK] using multiple multiple radios on a single RPi Pico board #912
Comments
After looking at the code, I noticed a few things that weren't mentioned in the OP:
|
But still not OK, here is the refactored code to work on a single core (including remarks): #include <stdio.h>
#include <pico/stdlib.h>
#include <pico/unique_id.h>
#include "pico/multicore.h"
#include <hardware/adc.h>
#include <tusb.h>
#include <RF24.h>
const int GPIO_MODE = 1;
#define SPI0_MISO 4
#define SPI0_MOSI 3
#define SPI0_SCK 2
#define SPI0_CSN 5
#define SPI0_CE 6
#define SPI1_MISO 12
#define SPI1_MOSI 11
#define SPI1_SCK 10
#define SPI1_CSN 13
#define SPI1_CE 14
int cnt = 1;
char sid[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = {0};
pico_unique_board_id_t id;
SPI spi_0;
SPI spi_1;
RF24 radio_tx(SPI0_CE, SPI0_CSN);
RF24 radio_rx(SPI1_CE, SPI1_CSN);
struct address_t {
uint8_t rx[5];
uint8_t tx[5];
};
struct message_t {
uint8_t cnt;
uint8_t payload[32];
};
struct address_t address[] = {
{.rx = {0xF0, 0xF0, 0xF0, 0xF0, 0xE1}, .tx = {0xF0, 0xF0, 0xF0, 0xF0, 0xD2}},
{.rx = {0xF0, 0xF0, 0xF0, 0xF0, 0xD2}, .tx = {0xF0, 0xF0, 0xF0, 0xF0, 0xE1}}
};
struct message_t tx_msg = {0};
struct message_t rx_msg = {0};
void tx_action() {
memset(&tx_msg, 0, sizeof(tx_msg));
tx_msg.cnt = cnt;
snprintf((char*)tx_msg.payload, sizeof(tx_msg.payload), "msg from %s", sid);
if (radio_tx.write(&tx_msg, sizeof(tx_msg))) /* send OK */
{
printf("Tx (me:%s): payload=%s cnt=%d\n", sid, tx_msg.payload, tx_msg.cnt);
cnt++;
}
else {} /* send KO */
}
void tx_thread()
{
printf("TX Thread started\n");
while (true)
{
tx_action();
}
}
void rx_action() {
uint8_t pipe;
if (radio_rx.available(&pipe))
{
memset(&rx_msg, 0, sizeof(rx_msg));
radio_rx.read(&rx_msg, radio_rx.getDynamicPayloadSize());
printf("Rx (me:%s): pipe=%d, payload=%s cnt=%d\n", sid, pipe, rx_msg.payload, rx_msg.cnt);
}
}
void rx_thread()
{
printf("RX Thread started\n");
while (true)
{
rx_action();
}
}
void rx_tx_thread()
{
printf("RX TX Thread started\n");
while (true)
{
rx_action();
tx_action();
}
}
void setup()
{
uint8_t device_id = gpio_get(GPIO_MODE);
spi_1.begin(spi1, SPI1_SCK, SPI1_MISO, SPI1_MOSI);
while (!radio_rx.begin(&spi_1))
{
printf("radio_rx.begin failed\n");
}
spi_0.begin(spi0, SPI0_SCK, SPI0_MISO, SPI0_MOSI);
while (!radio_tx.begin(&spi_0, SPI0_CE, SPI0_CSN))
{
printf("radio_tx.begin failed\n");
}
/* RF24_PA_MIN RF24_PA_LOW RF24_PA_HIGH RF24_PA_MAX */
radio_rx.setPALevel(RF24_PA_LOW);
radio_tx.setPALevel(RF24_PA_LOW);
radio_rx.setDataRate(RF24_1MBPS);
radio_tx.setDataRate(RF24_1MBPS);
radio_rx.enableDynamicPayloads();
radio_tx.enableDynamicPayloads();
radio_rx.setAutoAck(true);
radio_tx.setAutoAck(true);
radio_rx.enableAckPayload();
radio_tx.enableAckPayload();
radio_rx.openReadingPipe(1 /* pipe */, address[device_id].rx);
radio_tx.openWritingPipe(address[device_id].tx);
radio_rx.startListening();
radio_tx.stopListening();
printf("device_id=%d\n", device_id);
printf("tx_address=%llX, rx_address=%llX\n", address[device_id].tx, address[device_id].rx);
}
void wait_usb_read() {
while (!tud_cdc_connected()) {
sleep_ms(500);
}
}
int main()
{
stdio_init_all();
pico_get_unique_board_id(&id);
pico_get_unique_board_id_string(sid, sizeof(sid));
wait_usb_read();
printf("--------\n");
printf("Board ID: %s\n", sid);
setup();
// multicore_launch_core1(rx_thread);
// tx_thread();
rx_tx_thread();
// shouldn't reach here
while (1)
{
printf("Main loop\n");
sleep_ms(1000);
}
} Could be related to power as I'm powering my rpi pico with USB and powering 2 NRF using pico. Will provide external power supply to both modules to ensure it's not the issue here. |
Power supply was going to be my next recourse. The RPi Pico board uses a switching regulator (last time I checked) which inherently produces a lot of noise (AKA instability) in favor of efficiency. Thanks for eliminating the multi-processing "unknown" (& posting the latest revision). You could also check RF24::failureDetected for tx failures, but it doesn't include RX behavior (referring to ACK payload transmission). |
I tried to catch Tx/Rx failures and reinit de radio as explained in the documentation, but nothing pops (I mean no failure). I'll try to use external power supply, but this will require some soldering, will do it later and post updates. Here is the updated code:
|
I think the endianess of your address buffers is backward. The unique byte (MSB) of the address should come first in the buffer: struct address_t address[] = {
{.rx = {0xE1, 0xF0, 0xF0, 0xF0, 0xF0}, .tx = {0xD2, 0xF0, 0xF0, 0xF0, 0xF0}},
{.rx = {0xD2, 0xF0, 0xF0, 0xF0, 0xF0}, .tx = {0xE1, 0xF0, 0xF0, 0xF0, 0xF0}}
}; |
why the unique byte of the address should come first? |
It is an implementation detail about how the address is set to the radio's registers (which must be done in big endian order). Keep in mind that the endianess of the data stored in memory is important when making SPI transfers. |
yes, but here it's an “address”, intuitively, as long as it 'match', endianness shouldn't matter. Will take a look at the code, thanks for pointing that out. I'll fix it in my code then and try external power supply. |
I added an example snippet to |
crystal clear, thanks. missed that comments and links. |
If you're using a single pico board with 2 radios, does it help to set the PA level to min for each? |
Thanks for the help! I think we can close this. Except if you want me to push my example to the repo. |
yeah! 🎉 that does confirm it is a power supply problem. Unfortunately, I foresee soldering in your future 😜.
Thanks, but no thanks... I'd rather not maintain another example; 6 examples per platform is tedious as it is. This isn't the first time we've seen problems with the RPi Pico board's 3v regulator though. It is probably worth a mention in the doc somewhere. |
can close this then :-) Thanks again for the help. |
Hopefully this can avoid issues like #912
I did a test inspired by your documentation, but that doesn't seem to work properly on my side.
What I do/observe:
My idea is to have 2 modules on a single pico to have fully bidirectional communication.
Here is my code, not doing anything smart (sending a unique id + counter to distinguish nodes and dropped packets).
example.zip
is it possible using these modules?
do I miss something with the lib?
Originally posted by @XDeschuyteneer in #892 (comment)
The text was updated successfully, but these errors were encountered: