nopnop2002 / esp-idf-mirf

nRF24L01 Driver for esp-idf
MIT License
59 stars 10 forks source link

Using less pins #8

Closed Farzinkh closed 1 year ago

Farzinkh commented 1 year ago

Hi, I was looking for a way to use at least one less pin, for example disconnect the CS or CE pin from the ESP32. I don't have any other alternatives, because I ran out of pins on the ESP32CAM board. Is it possible anyway?

nopnop2002 commented 1 year ago

There is no problem with CSN fixed at 3.3V.

nRF24L01 ESP32 ESP32-S2/S3 ESP32-C2/C3
MISO -- GPIO19 GPIO37 GPIO4 (*1)
MOSI -- GPIO23 GPIO35 GPIO3 (*1)
SCK -- GPIO18 GPIO36 GPIO2 (*1)
CE -- GPIO16 GPIO34 GPIO1 (*1)
CSN -- 3.3V 3.3V 3.3V
GND -- GND GND GND
VCC -- 3.3V 3.3V 3.3V

(*1)You can change it to any pin using menuconfig.

Note that CSN is set to OUTPUT mode, HIGH level inside the library.

mirf.c:46:      gpio_reset_pin(CONFIG_CSN_GPIO);
mirf.c:47:      gpio_set_direction(CONFIG_CSN_GPIO, GPIO_MODE_OUTPUT);
mirf.c:48:      gpio_set_level(CONFIG_CSN_GPIO, 1);

If you want to use CSN's GPIO freely, you need to comment them out.

nopnop2002 commented 1 year ago

my mistake. Both CE and CSN needed GPIO.

The nRF24L01 requires 5 GPIOs.

Farzinkh commented 1 year ago

Thank you for your fast reply. what about using nRF24L01 only as transmitter or receiver?

nopnop2002 commented 1 year ago

Even if you use the nRF24L01 only as a transmitter or receiver, you still need 5 GPIOs.

ESP32-CAM has GPIO0,1,2,3,4,12,13,14,15,16. GPIO1 is TXD. GPIO3 is RXD. Therefore, you can use eight GPIOs are available: GPIO0, 2, 4, 12, 13, 14, 15, 16. 5 of the 8 GPIOs are used by the nRF24L01. Three GPIOs remain. If you run out of GPIO, you can use the I2C IO expander to expand.


You can use these I2C IO expanders.

| Component                | Description                                                                      |
|--------------------------|----------------------------------------------------------------------------------|
| **mcp23008**             | Driver for 8-bit I2C GPIO expander MCP23008                                      |
| **mcp23x17**             | Driver for I2C/SPI 16 bit GPIO expanders MCP23017/MCP23S17                       |
| **pca9557**              | Driver for PCA9537/PCA9557/TCA9534 remote 4/8-bit I/O expanders for I2C-bus      |
| **pcf8574**              | Driver for PCF8574 remote 8-bit I/O expander for I2C-bus                         |
| **pcf8575**              | Driver for PCF8575 remote 16-bit I/O expander for I2C-bus                        |
| **tca95x5**              | Driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus               |
nopnop2002 commented 1 year ago

ESP32-CAM has 10 GPIOs. GPIO0,1,2,3,4,12,13,14,15,16

GPIO1 is TXD. GPIO3 is RXD.

These can also be used as general purpose GPIO.

5 of the 10 GPIOs are used by the nRF24L01. Five GPIOs remain. You have 5 GPIOs at your disposal, are they not enough?

Farzinkh commented 1 year ago

I am going to use IRQ pin too and sim800 occupy GPIO1 and 3 pins, also GPIO0 is used to entering esp32 into uploading mode, and unfortunately I have 3 ADC inputs.

nopnop2002 commented 1 year ago

unfortunately I have 3 ADC inputs.

You can use this. https://github.com/nopnop2002/esp-idf-mcp3002

Although exclusive control is required, nRF24L01 and MCP32XX can share MISO, MOSI, and SCK. If you share one SPI-BUS between two devices, you need to change the SPI-BUS initialization.

nRF24L01 ESP32-CAM
MISO -- GPIO12
MOSI -- GPIO13
SCK -- GPIO14
CE -- GPIO15
CSN -- GPIO16
MCP3204/08 ESP32-CAM
MISO -- GPIO12
MOSI -- GPIO13
SCK -- GPIO14
CS -- GPIO04

A driver for the MCP3428 is available. You can use 4 channel analog input with i2c. You may need to change the sim800 IRQ to polling.

nRF24L01 ESP32-CAM
MISO -- GPIO12
MOSI -- GPIO13
SCK -- GPIO14
CE -- GPIO15
CSN -- GPIO16
MCP3428 ESP32-CAM
SDA -- GPIO4
SCL -- GPIO2
nopnop2002 commented 1 year ago

I will close this issue. You can re-open at any time.

Farzinkh commented 1 year ago

Hi I tackled my problem by using less adc pins and now I have new problem. As I mentioned earlier I want to use IRQ pin on NRF24L01 but I dont see any straight way to use it. I have configured ISR for this pin on my main.c but clearly it is not enough and I have to change something in this component, can you help me with that?

nopnop2002 commented 1 year ago

This project does not use IRQs.

If you want to use interrupts, you can solve it by doing task splitting.

It is for the same reason that most device drivers provided by ESP-IDF do not support interrupts.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

#include "mirf.h"

typedef union {
    uint8_t value[4];
    unsigned long now_time;
} MYDATA_t;

MYDATA_t mydata;
bool nrf24l01 = false;

void receiver(void *pvParameters)
{
    ESP_LOGI(pcTaskGetName(0), "Start");
    NRF24_t dev;
    Nrf24_init(&dev);
    uint8_t payload = sizeof(mydata.value);
    uint8_t channel = 90;
    Nrf24_config(&dev, channel, payload);

    //Set own address using 5 characters
    esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
    if (ret != ESP_OK) {
        ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
        while(1) { vTaskDelay(1); }
    }

    //Print settings
    Nrf24_printDetails(&dev);
    ESP_LOGI(pcTaskGetName(0), "Listening...");

    while(1) {
        //When the program is received, the received data is output from the serial port
        if (Nrf24_dataReady(&dev)) {
            Nrf24_getData(&dev, mydata.value);
            ESP_LOGI(pcTaskGetName(0), "Got data:%lu", mydata.now_time);
            nrf24l01 = true;
        }
        vTaskDelay(1);
    }
}

void app_main(void)
{
    xTaskCreate(receiver, "RECEIVER", 1024*3, NULL, 2, NULL);
    whie(1) {
        if (nrf24l01) {
            // DO something
            nrf24l01 = false;
        }
    }
}
Farzinkh commented 1 year ago

Since my goal is to send a file through NRF24L01, every single packet is important to me. So far I can't figure out why the IRQ pin state doesn't change at all it's always 3.3V.

nopnop2002 commented 1 year ago

So far I can't figure out why the IRQ pin state doesn't change at all it's always 3.3V.

How about looking at the value of the CONFIG register (Address=0x00) at an appropriate time?

MASK_RX_DR MASK_TX_DS MASK_MAX_RT I think they are all set to 0.

config

nopnop2002 commented 1 year ago

Now I found out why the IRQ is not asserted when the transmission is complete.

After transmission, the nRF24L01 switches to receive mode, and when it receives the ACK payload, it enters the transmission complete state.

In other words, a transmission completion is actually a reception completion of an ACK payload.

Therefore, the TX_DS interrupt should be disabled.

We are currently testing.

Farzinkh commented 1 year ago

How about looking at the value of the CONFIG register (Address=0x00) at an appropriate time?

what do you mean by appropriate time? and my bad I changed pins configuration for ESP32CAM now I can detect IRQ changes and it is now shared SPI buss for SDcard, but I need to do further tests.

nRF24L01   ESP32-CAM
MISO -- GPIO2
MOSI -- GPIO15
SCK -- GPIO14
CE -- GPIO12
CSN -- GPIO0
IRQ -- GPIO16

Also I changed this line: #define mirf_CONFIG ((0<<MASK_RX_DR) | (0<<MASK_TX_DS) | (0<<MASK_MAX_RT) | (1<<EN_CRC) | (0<<CRCO) )

nopnop2002 commented 1 year ago

I can detect IRQ changes

Is it possible to detect both reception completion and transmission completion?

Also I changed this line:

In C language, these two lines have the same result Nothing changed from before the change.

#define mirf_CONFIG ((0<<MASK_RX_DR)  | (0<<MASK_TX_DS)  | (0<<MASK_MAX_RT)  | (1<<EN_CRC) | (0<<CRCO) )

#define mirf_CONFIG ((1<<EN_CRC) | (0<<CRCO) )