logo elektroda
logo elektroda
X
logo elektroda

How to connect nRF905 to ESP32-WROOM-32 v1.1? Transmit/receive not working

amidar 2769 12
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 17735156
    amidar
    Level 10  
    Posts: 43
    Rate: 12
    Hi,

    I would like to use the nrf905 module (433 and 868 radio on SPI) with the ESP32 WROOM 32 controller....
    I found a library to support this module for arduino, from the website
    http://blog.zakkemble.co.uk/nrf905-avrarduino-librarydriver/
    For testing I used the sources ping_client, and ping_server on 2 sets of ESP32 +nRF905. One was to work as a client, the other as a server.

    The library itself required a little pin remapping, additionally I switched the SPI from VSPI to HSPI on pins 12-15.
    The other pins used were:
    CD - 6,
    AM - 27,
    DR - 7,
    PWR - 11,
    TxE - 0
    CE - 34
    Module supply voltage 3.3V
    Probably everything....

    The examples compile without any major problems, load into ESP.... and they seemingly work, but.... don't transmit, or at least one can't see the other.

    Question is, has anyone tried plugging the nRF905 into the ESP32, did it work, maybe there is some other library, dedicated to the ESP?
    Oh and one more thing, I use Sloeber for compilation.

    Attached the client and server sources + library after correction.
    And one more detail in the SPI library, I changed a line at the end to switch the pinology to HSPI
    //SPIClass SPI(VSPI);
    SPIClass SPI(HSPI);


    Thanks in advance for any suggestions....
    Attachments:
    • source.zip (28.73 KB) You must be logged in to download this attachment.
  • ADVERTISEMENT
  • Helpful post
    #2 17735297
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #3 17736294
    amidar
    Level 10  
    Posts: 43
    Rate: 12
    khoam wrote:
    The library you refer to does not support the ESP32 architecture, as is clear from its source code - I don't know how you managed to compile it for ESP32.
    I suggest that you first use the information on RadioHead .
    .

    Thanks for the leads, I'll have something to do tonight :) .

    As for that library I knew it was written for the arduino, although I assumed that after changing the pinology (it's directly in the sources) it would still fire.... Well... It didn't fire. And from this, it follows that my knowledge of ESP is still too small.
  • ADVERTISEMENT
  • #4 17736545
    kaczakat
    Level 34  
    Posts: 1748
    Help: 317
    Rate: 229
    It could have worked, but just with V, the easiest way is to print yourself Serial.print(MOSI) and so each SPI pin, you will find out under which GPIO pins are mapped by default. You can reconfigure this as long as you don't use GPIO 6-11, these are used for the flash built into the ESP32 (and you use them too). Of course the GPIO no. doesn't have to coincide with that number on the board, you can still confirm by flashing the led on that pin just to be sure. Unfortunately it's messed up, but surely if you define the pin as 6 it's GPIO6, meaning to flash, and on the board marked as 6 it could be the GPIO34 pin.
    Helpful post? Buy me a coffee.
  • #5 17736648
    Anonymous
    Level 1  
  • #6 17736727
    kaczakat
    Level 34  
    Posts: 1748
    Help: 317
    Rate: 229
    If the library communicates at a defined interface level, e.g. any to GSM using the UART then it is indifferent to how the UART is handled by UNO, ESP or DUE. If it sets something in registers itself to activate/control low level from UART/SPI then it will fail. But the Arduino uses ready-made functions like SPI.begin() and this will work the same on all of the above. The library is just meant to be a building block of what to send over SPI, together with the building block provided by installing all the data into the ESP32 it should work the same.
    In ESP32, the default pins for SPI can be found at the ESP32 installation site in the "variants" directory, on most boards:
    Quote:
    static const uint8_t TX = 1;
    static const uint8_t RX = 3;

    static const uint8_t SDA = 21;
    static const uint8_t SCL = 22;

    static const uint8_t SS = 5;
    static const uint8_t MOSI = 23;
    static const uint8_t MISO = 19;
    static const uint8_t SCK = 18;
    .
    Of course, I've done some flimsy tests with SD and some I2C sensors, but I haven't installed any special libraries for this. If you want to use something more than the default defined, though, you'll probably have to do more messing around. E.g. you have to remap UART1 from the flash pins to use it, but it's possible to fire all 3 on the ESP32.
    Helpful post? Buy me a coffee.
  • #7 17737441
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #8 17737654
    kaczakat
    Level 34  
    Posts: 1748
    Help: 317
    Rate: 229
    I didn't test that much, and I even thought that yield() was just not needed anymore in ESP32, because it's the WIFI that runs itself on a separate core, you can use it without a problem, but anyway the default is only core1, core0 runs itself with WIFI support. And from the esp guru I found this quote:
    Quote:
    igrr says:
    October 31, 2016 at 9:20 am
    In ESP32 Arduino core we run the “sketch” (setup and loop and everything they call) on CPU1, while the WiFi stack is running on CPU0. This allows messing with interrupts at will, and running more or less timing critical code. No more yield, yay! Interrupts attached through Arduino APIs also run on CPU1.

    If you want to run something on CPU0 from Arduino, you have to use FreeRTOS function to start a new task, with task affinity set to CPU0. That’s it! Then use some FreeRTOS synchronization primitives to communicate with the new task.
    .
    So your entry is pretty much just for ESP8266, I'll test it sometime next time I play with ESP32, maybe the entry is out of date and something came up along the way.
    Also no library should hang around waiting for a response, you can do this by dividing the function into stages and despite calling it cyclically only execute the stage remaining to be executed, and keep in a variable only the stage number to be executed, e.g. waiting for a response. Alternatively, you could count the time of each stage and set a limit for each, and simply report an error/start again when the timeout expires. In any case, whatever should work, at most it would spill resets. It certainly won't work if it uses proprietary pins.
    Helpful post? Buy me a coffee.
  • #9 17738388
    Anonymous
    Level 1  
  • #10 17738836
    kaczakat
    Level 34  
    Posts: 1748
    Help: 317
    Rate: 229
    Logically, if there is a separate core then 100% of core1's power is for the Arduino code, even if there are interrupts on core0 it won't affect core1, it's harder to synchronise them to work together because it's actually done "manually" than to negatively affect one on the other - each one flies independently. Sort of like how an active PWM in an AVR stops for the duration of an interrupt.
    Helpful post? Buy me a coffee.
  • #11 17738849
    Anonymous
    Level 1  
  • #12 17815839
    mao73a
    Level 2  
    Posts: 2
    Amidar,
    did you manage to get this working?
    I am just trying to connect the NRF905 with the ESP8266 and have not been able to find a ready-made wiring diagram on the web.
    Is it necessary to switch to HSPI?
    I found a page Link where it describes how to connect the NRF905 and the raspberry and there the DR pin is connected via a resistor (220Ohm).
    Shouldn't it be similar here?

    Greetings,
    Mao73a
  • #13 17818964
    amidar
    Level 10  
    Posts: 43
    Rate: 12
    Just as a quick aside, I also tested RadioHead. I don't know which solution is worse. For a while I thought about writing my own library, but I don't have time for that. The solution on the lowest line of resistance. An additional Arduino nano to connect to the Radio. It works...

Topic summary

✨ The discussion addresses difficulties in interfacing the nRF905 radio module (operating at 433 and 868 MHz via SPI) with the ESP32-WROOM-32 v1.1 microcontroller. The original approach used an Arduino-targeted nRF905 library, requiring pin remapping and switching SPI from VSPI to HSPI on ESP32 pins 12-15, with additional control pins assigned to various GPIOs. Although the code compiled and loaded successfully, transmission and reception between two ESP32+nRF905 setups failed. Responses highlight that the referenced library lacks ESP32 support and may not handle ESP32-specific architecture, such as dual-core operation and interrupt management. SPI pin assignments must avoid GPIO6-11 due to flash memory usage, and proper GPIO mapping is critical. Suggestions include consulting the RadioHead library for radio communication, though it also may not fully support ESP32. The ESP32 Arduino framework requires careful handling of critical sections using portENTER_CRITICAL/portEXIT_CRITICAL instead of noInterrupts()/interrupts(). Timing and task scheduling must consider ESP32’s dual-core and WiFi stack to prevent blocking or resets. Additional hardware considerations include proper wiring of the DR pin, possibly with a resistor, and verifying power supply levels. Some users resorted to using an Arduino Nano as an intermediary to handle the nRF905 communication due to lack of a dedicated ESP32 library. Overall, successful integration demands ESP32-specific library support, correct SPI and GPIO configuration, and attention to ESP32 multitasking and interrupt handling nuances.
Generated by the language model.

FAQ

TL;DR: ESP32 has 2 cores; Arduino sketch runs on CPU1, Wi‑Fi on CPU0. "No more yield, yay!" Many nRF905 TX/RX issues come from ESP32 specifics, so validate pins and tasking first. [Elektroda, kaczakat, post #17737654]

Why it matters: This FAQ helps ESP32/ESP8266 builders fix nRF905 links that compile but don’t pass packets.

Quick Facts

Does Zak Kemble’s nRF905 library work on ESP32?

Not as‑is. That driver targets AVR. A responder noted it “does not support the ESP32 architecture.” It may compile after pin edits but fail at runtime. Start with RadioHead for ESP32 instead, then adapt SPI pins and examples. [Elektroda, khoam, post #17735297]

What SPI pins should I use on ESP32 with nRF905?

Use the default VSPI mapping unless you must remap: SS 5, MOSI 23, MISO 19, SCK 18. These come from the ESP32 Arduino variant. Remapping is possible, but expect extra setup. Keep bus and pins consistent across your code. [Elektroda, kaczakat, post #17736727]

Do I need HSPI instead of VSPI for nRF905 on ESP32?

No. Both buses work. VSPI is the Arduino default. Switch to HSPI only when other peripherals occupy VSPI pins. Map SCK, MISO, MOSI, and SS to valid GPIOs for the chosen bus. [Elektroda, kaczakat, post #17736727]

How do I verify my SPI pin mapping fast?

Print the SPI pin constants and blink LEDs before wiring the radio. How‑To:
  1. Serial.print(MOSI/MISO/SCK/SS) to see GPIOs.
  2. Blink an LED on each chosen GPIO.
  3. Connect nRF905 after verifying, then retest. “You can reconfigure this as long as you don’t use GPIO 6–11.” [Elektroda, kaczakat, post #17736545]

Why does my ESP32+nRF905 “do nothing” after flashing?

Wrong pins are the top cause. GPIO 6–11 drive the on‑board SPI flash and must not be used. Routing SPI or control lines there will stop the radio. Reassign lines to safe GPIOs and test again. [Elektroda, kaczakat, post #17736545]

Should I use noInterrupts() on ESP32, or critical sections?

Use portENTER_CRITICAL/portEXIT_CRITICAL for short protected regions. noInterrupts() only blocks CPU1 on ESP32, so it isn’t a cross‑core guard. “noInterrupts() for ESP32 only blocks interrupts on CPU1.” Keep critical sections brief. [Elektroda, khoam, post #17738388]

Does delay() break Wi‑Fi on ESP32?

No. In this core, delay() calls yield() and cooperates with the scheduler. “Using Arduino delay() is quite correct, and sometimes advisable in ESP32.” Avoid long busy loops or blocking waits on IRQs. [Elektroda, khoam, post #17737441]

Can I use GPIO34 (or 34–39) for CE/TxE/PWR pins?

Do not. GPIO 34–39 are input‑only on ESP32. CE, TXEN, and PWR need outputs. Using input‑only pins creates a silent failure that looks like a dead radio. Pick output‑capable GPIOs (e.g., 2, 4, 5, 12–33). [Espressif, 2020]

Do I need a series resistor on the nRF905 DR pin?

Not required. DR is a digital output from the nRF905 to the MCU. Connect to a 3.3 V‑tolerant input. A small 220 Ω series resistor is optional for protection. AM and CD are also outputs to the MCU. [Nordic, 2006]

What’s a practical workaround if libraries keep failing?

Use a small AVR board, like an Arduino Nano, as a radio coprocessor. Communicate from ESP32 over UART or SPI. One user did this and restored reliable nRF905 links without porting effort. [Elektroda, amidar, post #17818964]

Is RadioHead a better starting point for ESP32+nRF905 than others?

Yes, as a portable baseline. A responder suggested RadioHead for ESP32. It avoids AVR‑only register code and ships with examples. Use its nRF905 driver and adjust SPI pins. [Elektroda, khoam, post #17735297]

What voltage and basics should I observe for nRF905?

Power the module at 3.3 V. Wire CE, TXEN, PWR, DR, AM, and CD to suitable GPIOs. Then test with simple client/server pings to check the link after wiring. This mirrors the original test setup. [Elektroda, amidar, post #17735156]

What data rate can I expect from nRF905?

Typical on‑air bitrate is 50 kbps. Effective throughput is lower due to headers and retries. Antennas and band choice (433/868/915 MHz) shift range, not the nominal bitrate. [Nordic, 2006]

How does ESP32’s dual‑core design affect radio libraries?

Arduino sketches run on CPU1; the Wi‑Fi stack runs on CPU0. That separation helps timing. “No more yield, yay!” To run code on CPU0, start a FreeRTOS task with CPU0 affinity. [Elektroda, kaczakat, post #17737654]
Generated by the language model.
ADVERTISEMENT