原帖/2022
我目前正在尝试使用nopnop2002的驱动程序库通过ESP32开发板通过nRF24传输音频。我使用i2s-adc库函数从模拟麦克风获取数据,并在将其缩放到8位后将其保存到缓冲区中,以便其他esp32可以直接使用其DAC转换器播放。
起初,我有一个大的i2s_read_len
,后来我怀疑这可能是一个问题,所以我决定将其减少到12位(esp32的ADC位宽度)用于测试目的。我的音频数据包的理想大小是多少?
我也不确定如何处理i2s_read
的采样率和我试图通过SPI将数据发送到nRF24的速率。据我所知,内部ADC-I2S已经实现了队列,我应该再做一个并使用vTaskDelay(??? / portTICK_PERIOD_MS);
避免发送数据太快?
下面是我目前忽略的include:
#define V_REF 1100
#define I2S_COMM_MODE 0 // ADC/DAC Mode
#define I2S_SAMPLE_RATE 44100
#define I2S_SAMPLE_BITS 16
#define I2S_BUF_DEBUG 0 // enable display buffer for debug
#define I2S_READ_LEN 16 * 1024 // I2S read buffer length
#define I2S_FORMAT (I2S_CHANNEL_FMT_ONLY_RIGHT)
#define I2S_CHANNEL_NUM 0 // I2S channel number
#define I2S_ADC_UNIT ADC_UNIT_1 // I2S built-in ADC unit
#define I2S_ADC_CHANNEL ADC1_CHANNEL_0 // I2S built-in ADC channel GPIO36
#define BIT_SAMPLE 16
#define SPI_DMA_CHAN SPI_DMA_CH_AUTO
#define NUM_CHANNELS 1 // For mono recording only!
#define SAMPLE_SIZE (BIT_SAMPLE * 1024)
#define BYTE_RATE (I2S_SAMPLE_RATE * (BIT_SAMPLE / 8)) * NUM_CHANNELS
/**
* @brief I2S ADC mode init.
*/
void init_microphone(void)
{
int i2s_num = I2S_COMM_MODE;
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = I2S_SAMPLE_BITS,
.communication_format = I2S_COMM_FORMAT_STAND_MSB,
.channel_format = I2S_FORMAT,
.intr_alloc_flags = 0,
.dma_buf_count = 6,
.dma_buf_len = 256,
.use_apll = 1,
};
// Call driver installation function and adc pad.
ESP_ERROR_CHECK(i2s_driver_install(i2s_num, &i2s_config, 0, NULL));
ESP_ERROR_CHECK(i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL));
}
/**
* @brief Scale data to 8bit for data from ADC.
* Data from ADC are 12bit width by default.
* @param d_buff: destination buffer
* @param s_buff: source buffer
* @param len: length of source buffer
*/
void i2s_adc_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len)
{
uint32_t j = 0;
uint32_t dac_value = 0;
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
for (int i = 0; i < len; i += 2)
{
dac_value = ((((uint16_t)(s_buff[i + 1] & 0xf) << 8) | ((s_buff[i + 0]))));
d_buff[j++] = 0;
d_buff[j++] = dac_value * 256 / 4096;
}
#else
for (int i = 0; i < len; i += 4)
{
dac_value = ((((uint16_t)(s_buff[i + 3] & 0xf) << 8) | ((s_buff[i + 2]))));
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = dac_value * 256 / 4096;
}
#endif
}
#if CONFIG_TRANSMITTER
void transmitter(void *pvParameters)
{
size_t bytes_read;
ESP_LOGI(pcTaskGetName(0), "Start");
int i2s_read_len = (12);
char *i2s_read_buff = (char *)calloc(i2s_read_len, sizeof(char));
uint8_t *i2s_write_buff = (uint8_t *)calloc(i2s_read_len, sizeof(char));
i2s_adc_enable(I2S_CHANNEL_NUM);
NRF24_t dev;
Nrf24_init(&dev);
uint8_t payload = sizeof(i2s_read_buff);
uint8_t channel = 90;
Nrf24_config(&dev, channel, payload);
// Set the receiver address using 5 characters
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
if (ret != ESP_OK)
{
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
while (1)
{
vTaskDelay(1);
}
}
#if CONFIG_ADVANCED
AdvancedSettings(&dev);
#endif // CONFIG_ADVANCED
// Print settings
Nrf24_printDetails(&dev);
// Start ADC
while (1)
{
// Read data from I2S bus, in this case, from ADC. //
i2s_read(I2S_CHANNEL_NUM, (void *)i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
// process data and scale to 8bit for I2S DAC.
i2s_adc_data_scale(i2s_write_buff, (uint8_t *)i2s_read_buff, i2s_read_len);
// i2s_write_buff needs to be the buffer that is sent via nr24l01.
Nrf24_send(&dev, i2s_write_buff);
if (Nrf24_isSend(&dev, 1000))
{
ESP_LOGI(pcTaskGetName(0), "sending audio data ...");
}
else
{
ESP_LOGW(pcTaskGetName(0), "sending failed ...");
}
}
}
#endif // CONFIG_TRANSMITTER
void app_main(void)
{
// I2S ADC mode microphone init.
init_microphone();
#if CONFIG_TRANSMITTER
xTaskCreate(transmitter, "TRANSMITTER", 1024 * 3, NULL, 2, NULL);
#endif
// Stop I2S driver and destroy
// ESP_ERROR_CHECK(i2s_driver_uninstall(I2S_COMM_MODE));
}
下面是定义Nrf24_send
的代码:
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <driver/spi_master.h>
#include <driver/gpio.h>
#include "esp_log.h"
#include "mirf.h"
#define TAG "NRF24"
// SPI Stuff
#if CONFIG_SPI2_HOST
#define HOST_ID SPI2_HOST
#elif CONFIG_SPI3_HOST
#define HOST_ID SPI3_HOST
#endif
static const int SPI_Frequency = 4000000; // Stable even with a long jumper cable
//static const int SPI_Frequency = 6000000;
//static const int SPI_Frequency = 8000000; // Requires a short jumper cable
//static const int SPI_Frequency = 10000000; // Unstable even with a short jumper cable
const char rf24_datarates[][8] = {"1Mbps", "2Mbps", "250Kbps"};
const char rf24_crclength[][10] = {"Disabled", "8 bits", "16 bits"};
const char rf24_pa_dbm[][8] = {"PA_MIN", "PA_LOW", "PA_HIGH", "PA_MAX"};
void Nrf24_init(NRF24_t * dev)
{
esp_err_t ret;
ESP_LOGI(TAG, "CONFIG_MISO_GPIO=%d", CONFIG_MISO_GPIO);
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d", CONFIG_MOSI_GPIO);
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d", CONFIG_SCLK_GPIO);
ESP_LOGI(TAG, "CONFIG_CE_GPIO=%d", CONFIG_CE_GPIO);
ESP_LOGI(TAG, "CONFIG_CSN_GPIO=%d", CONFIG_CSN_GPIO);
//gpio_pad_select_gpio(CONFIG_CE_GPIO);
gpio_reset_pin(CONFIG_CE_GPIO);
gpio_set_direction(CONFIG_CE_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(CONFIG_CE_GPIO, 0);
//gpio_pad_select_gpio(CONFIG_CSN_GPIO);
gpio_reset_pin(CONFIG_CSN_GPIO);
gpio_set_direction(CONFIG_CSN_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(CONFIG_CSN_GPIO, 1);
spi_bus_config_t spi_bus_config = {
.sclk_io_num = CONFIG_SCLK_GPIO,
.mosi_io_num = CONFIG_MOSI_GPIO,
.miso_io_num = CONFIG_MISO_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1
};
ret = spi_bus_initialize( HOST_ID, &spi_bus_config, SPI_DMA_CH_AUTO );
ESP_LOGI(TAG, "spi_bus_initialize=%d",ret);
assert(ret==ESP_OK);
spi_device_interface_config_t devcfg;
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
devcfg.clock_speed_hz = SPI_Frequency;
// It does not work with hardware CS control.
//devcfg.spics_io_num = csn_pin;
// It does work with software CS control.
devcfg.spics_io_num = -1;
devcfg.queue_size = 7;
devcfg.mode = 0;
devcfg.flags = SPI_DEVICE_NO_DUMMY;
spi_device_handle_t handle;
ret = spi_bus_add_device( HOST_ID, &devcfg, &handle);
ESP_LOGI(TAG, "spi_bus_add_device=%d",ret);
assert(ret==ESP_OK);
dev->cePin = CONFIG_CE_GPIO;
dev->csnPin = CONFIG_CSN_GPIO;
dev->channel = 1;
dev->payload = 16;
dev->_SPIHandle = handle;
}
bool spi_write_byte(NRF24_t * dev, uint8_t* Dataout, size_t DataLength )
{
spi_transaction_t SPITransaction;
if ( DataLength > 0 ) {
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
SPITransaction.length = DataLength * 8;
SPITransaction.tx_buffer = Dataout;
SPITransaction.rx_buffer = NULL;
spi_device_transmit( dev->_SPIHandle, &SPITransaction );
}
return true;
}
bool spi_read_byte(NRF24_t * dev, uint8_t* Datain, uint8_t* Dataout, size_t DataLength )
{
spi_transaction_t SPITransaction;
if ( DataLength > 0 ) {
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
SPITransaction.length = DataLength * 8;
SPITransaction.tx_buffer = Dataout;
SPITransaction.rx_buffer = Datain;
spi_device_transmit( dev->_SPIHandle, &SPITransaction );
}
return true;
}
uint8_t spi_transfer(NRF24_t * dev, uint8_t address) {
uint8_t datain[1];
uint8_t dataout[1];
dataout[0] = address;
//spi_write_byte(dev, dataout, 1 );
spi_read_byte(dev, datain, dataout, 1 );
return datain[0];
}
void spi_csnHi(NRF24_t * dev) {
gpio_set_level( dev->csnPin, 1 );
}
void spi_csnLow(NRF24_t * dev) {
gpio_set_level( dev->csnPin, 0 );
}
// Sets the important registers in the MiRF module and powers the module
// in receiving mode
// NB: channel and payload must be set now.
void Nrf24_config(NRF24_t * dev, uint8_t channel, uint8_t payload)
{
dev->channel = channel;
dev->payload = payload;
Nrf24_configRegister(dev, RF_CH, dev->channel); // Set RF channel
Nrf24_configRegister(dev, RX_PW_P0, dev->payload); // Set length of incoming payload
Nrf24_configRegister(dev, RX_PW_P1, dev->payload);
Nrf24_powerUpRx(dev); // Start receiver
Nrf24_flushRx(dev);
}
// Sets the receiving device address
//void Nrf24_setRADDR(NRF24_t * dev, uint8_t * adr)
esp_err_t Nrf24_setRADDR(NRF24_t * dev, uint8_t * adr)
{
esp_err_t ret = ESP_OK;
Nrf24_writeRegister(dev, RX_ADDR_P1, adr, mirf_ADDR_LEN);
uint8_t buffer[5];
Nrf24_readRegister(dev, RX_ADDR_P1, buffer, sizeof(buffer));
for (int i=0;i<5;i++) {
ESP_LOGD(TAG, "adr[%d]=0x%x buffer[%d]=0x%x", i, adr[i], i, buffer[i]);
if (adr[i] != buffer[i]) ret = ESP_FAIL;
}
return ret;
}
// Sets the transmitting device address
//void Nrf24_setTADDR(NRF24_t * dev, uint8_t * adr)
esp_err_t Nrf24_setTADDR(NRF24_t * dev, uint8_t * adr)
{
esp_err_t ret = ESP_OK;
Nrf24_writeRegister(dev, RX_ADDR_P0, adr, mirf_ADDR_LEN); //RX_ADDR_P0 must be set to the sending addr for auto ack to work.
Nrf24_writeRegister(dev, TX_ADDR, adr, mirf_ADDR_LEN);
uint8_t buffer[5];
Nrf24_readRegister(dev, RX_ADDR_P0, buffer, sizeof(buffer));
for (int i=0;i<5;i++) {
ESP_LOGD(TAG, "adr[%d]=0x%x buffer[%d]=0x%x", i, adr[i], i, buffer[i]);
if (adr[i] != buffer[i]) ret = ESP_FAIL;
}
return ret;
}
// Add the receiving device address
void Nrf24_addRADDR(NRF24_t * dev, uint8_t pipe, uint8_t adr)
{
uint8_t value;
Nrf24_readRegister(dev, EN_RXADDR, &value, 1);
if (pipe == 2) {
Nrf24_configRegister(dev, RX_PW_P2, dev->payload);
Nrf24_configRegister(dev, RX_ADDR_P2, adr);
value = value | 0x04;
Nrf24_configRegister(dev, EN_RXADDR, value);
} else if (pipe == 3) {
Nrf24_configRegister(dev, RX_PW_P3, dev->payload);
Nrf24_configRegister(dev, RX_ADDR_P3, adr);
value = value | 0x08;
Nrf24_configRegister(dev, EN_RXADDR, value);
} else if (pipe == 4) {
Nrf24_configRegister(dev, RX_PW_P4, dev->payload);
Nrf24_configRegister(dev, RX_ADDR_P4, adr);
value = value | 0x10;
Nrf24_configRegister(dev, EN_RXADDR, value);
} else if (pipe == 5) {
Nrf24_configRegister(dev, RX_PW_P5, dev->payload);
Nrf24_configRegister(dev, RX_ADDR_P5, adr);
value = value | 0x20;
Nrf24_configRegister(dev, EN_RXADDR, value);
}
}
// Checks if data is available for reading
extern bool Nrf24_dataReady(NRF24_t * dev)
{
// See note in getData() function - just checking RX_DR isn't good enough
uint8_t status = Nrf24_getStatus(dev);
if ( status & (1 << RX_DR) ) return 1;
// We can short circuit on RX_DR, but if it's not set, we still need
// to check the FIFO for any pending packets
//return !Nrf24_rxFifoEmpty(dev);
return 0;
}
// Get pipe number for reading
uint8_t Nrf24_getDataPipe(NRF24_t * dev) {
uint8_t status = Nrf24_getStatus(dev);
return ((status & 0x0E) >> 1);
}
extern bool Nrf24_rxFifoEmpty(NRF24_t * dev)
{
uint8_t fifoStatus;
Nrf24_readRegister(dev, FIFO_STATUS, &fifoStatus, sizeof(fifoStatus));
return (fifoStatus & (1 << RX_EMPTY));
}
// Reads payload bytes into data array
extern void Nrf24_getData(NRF24_t * dev, uint8_t * data)
{
spi_csnLow(dev); // Pull down chip select
spi_transfer(dev, R_RX_PAYLOAD ); // Send cmd to read rx payload
spi_read_byte(dev, data, data, dev->payload); // Read payload
spi_csnHi(dev); // Pull up chip select
// NVI: per product spec, p 67, note c:
// "The RX_DR IRQ is asserted by a new packet arrival event. The procedure
// for handling this interrupt should be: 1) read payload through SPI,
// 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more
// payloads available in RX FIFO, 4) if there are more data in RX FIFO,
// repeat from step 1)."
// So if we're going to clear RX_DR here, we need to check the RX FIFO
// in the dataReady() function
Nrf24_configRegister(dev, STATUS, (1 << RX_DR)); // Reset status register
}
// Clocks only one byte into the given MiRF register
void Nrf24_configRegister(NRF24_t * dev, uint8_t reg, uint8_t value)
{
spi_csnLow(dev);
spi_transfer(dev, W_REGISTER | (REGISTER_MASK & reg));
spi_transfer(dev, value);
spi_csnHi(dev);
}
// Reads an array of bytes from the given start position in the MiRF registers
void Nrf24_readRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len)
{
spi_csnLow(dev);
spi_transfer(dev, R_REGISTER | (REGISTER_MASK & reg));
spi_read_byte(dev, value, value, len);
spi_csnHi(dev);
}
// Writes an array of bytes into inte the MiRF registers
void Nrf24_writeRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len)
{
spi_csnLow(dev);
spi_transfer(dev, W_REGISTER | (REGISTER_MASK & reg));
spi_write_byte(dev, value, len);
spi_csnHi(dev);
}
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
void Nrf24_send(NRF24_t * dev, uint8_t * value)
{
uint8_t status;
status = Nrf24_getStatus(dev);
while (dev->PTX) // Wait until last paket is send
{
status = Nrf24_getStatus(dev);
if ((status & ((1 << TX_DS) | (1 << MAX_RT))))
{
dev->PTX = 0;
break;
}
}
Nrf24_ceLow(dev);
Nrf24_powerUpTx(dev); // Set to transmitter mode , Power up
spi_csnLow(dev); // Pull down chip select
spi_transfer(dev, FLUSH_TX ); // Write cmd to flush tx fifo
spi_csnHi(dev); // Pull up chip select
spi_csnLow(dev); // Pull down chip select
spi_transfer(dev, W_TX_PAYLOAD ); // Write cmd to write payload
spi_write_byte(dev, value, dev->payload); // Write payload
spi_csnHi(dev); // Pull up chip select
Nrf24_ceHi(dev); // Start transmission
}
// Test if chip is still sending.
// When sending has finished return chip to listening.
bool Nrf24_isSending(NRF24_t * dev) {
uint8_t status;
if (dev->PTX)
{
status = Nrf24_getStatus(dev);
if ((status & ((1 << TX_DS) | (1 << MAX_RT)))) {// if sending successful (TX_DS) or max retries exceded (MAX_RT).
Nrf24_powerUpRx(dev);
return false;
}
return true;
}
return false;
}
// Test if Sending has finished or retry is over.
// When sending has finished return trur.
// When reach maximum number of TX retries return false.
bool Nrf24_isSend(NRF24_t * dev, int timeout) {
uint8_t status;
TickType_t startTick = xTaskGetTickCount();
if (dev->PTX) {
while(1) {
status = Nrf24_getStatus(dev);
/*
if sending successful (TX_DS) or max retries exceded (MAX_RT).
*/
if (status & (1 << TX_DS)) { // Data Sent TX FIFO interrup
Nrf24_powerUpRx(dev);
return true;
}
if (status & (1 << MAX_RT)) { // Maximum number of TX retries interrupt
ESP_LOGW(TAG, "Maximum number of TX retries interrupt");
Nrf24_powerUpRx(dev);
return false;
}
// I believe either TX_DS or MAX_RT will always be notified.
// Therefore, it is unusual for neither to be notified for a period of time.
// I don't know exactly how to respond.
TickType_t diffTick = xTaskGetTickCount() - startTick;
if ( (diffTick * portTICK_PERIOD_MS) > timeout) {
ESP_LOGE(TAG, "Status register timeout. status=0x%x", status);
return false;
}
vTaskDelay(1);
}
}
return false;
}
uint8_t Nrf24_getStatus(NRF24_t * dev) {
uint8_t rv;
Nrf24_readRegister(dev, STATUS, &rv, 1);
return rv;
}
void Nrf24_powerUpRx(NRF24_t * dev) {
dev->PTX = 0;
Nrf24_ceLow(dev);
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG | ( (1 << PWR_UP) | (1 << PRIM_RX) ) ); //set device as TX mode
Nrf24_ceHi(dev);
Nrf24_configRegister(dev, STATUS, (1 << TX_DS) | (1 << MAX_RT)); //Clear seeded interrupt and max tx number interrupt
}
void Nrf24_flushRx(NRF24_t * dev)
{
spi_csnLow(dev);
spi_transfer(dev, FLUSH_RX );
spi_csnHi(dev);
}
void Nrf24_powerUpTx(NRF24_t * dev) {
dev->PTX = 1;
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG | ( (1 << PWR_UP) | (0 << PRIM_RX) ) );
}
void Nrf24_ceHi(NRF24_t * dev) {
gpio_set_level( dev->cePin, 1 );
}
void Nrf24_ceLow(NRF24_t * dev) {
gpio_set_level( dev->cePin, 0 );
}
void Nrf24_powerDown(NRF24_t * dev)
{
Nrf24_ceLow(dev);
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG );
}
//Set tx power : 0=-18dBm,1=-12dBm,2=-6dBm,3=0dBm
void Nrf24_SetOutputRF_PWR(NRF24_t * dev, uint8_t val)
{
if (val > 3) return;
uint8_t value;
Nrf24_readRegister(dev, RF_SETUP, &value, 1);
value = value & 0xF9;
value = value | (val<< RF_PWR);
//Nrf24_configRegister(dev, RF_SETUP, (val<< RF_PWR) );
Nrf24_configRegister(dev, RF_SETUP, value);
}
//Select between the high speed data rates:0=1Mbps, 1=2Mbps, 2=250Kbps
void Nrf24_SetSpeedDataRates(NRF24_t * dev, uint8_t val)
{
if (val > 2) return;
uint8_t value;
Nrf24_readRegister(dev, RF_SETUP, &value, 1);
if(val == 2)
{
value = value | 0x20;
value = value & 0xF7;
//Nrf24_configRegister(dev, RF_SETUP, (1 << RF_DR_LOW) );
Nrf24_configRegister(dev, RF_SETUP, value);
}
else
{
value = value & 0xD7;
value = value | (val << RF_DR_HIGH);
//Nrf24_configRegister(dev, RF_SETUP, (val << RF_DR_HIGH) );
Nrf24_configRegister(dev, RF_SETUP, value);
}
}
//Set Auto Retransmit Delay 0=250us, 1=500us, ... 15=4000us
void Nrf24_setRetransmitDelay(NRF24_t * dev, uint8_t val)
{
uint8_t value;
Nrf24_readRegister(dev, SETUP_RETR, &value, 1);
value = value & 0x0F;
value = value | (val << ARD);
Nrf24_configRegister(dev, SETUP_RETR, value);
}
void Nrf24_printDetails(NRF24_t * dev)
{
printf("================ SPI Configuration ================n" );
printf("CSN Pin t = GPIO%dn",dev->csnPin);
printf("CE Pin t = GPIO%dn", dev->cePin);
printf("Clock Speedt = %dn", SPI_Frequency);
printf("================ NRF Configuration ================n");
Nrf24_print_status(Nrf24_getStatus(dev));
Nrf24_print_address_register(dev, "RX_ADDR_P0-1", RX_ADDR_P0, 2);
Nrf24_print_byte_register(dev, "RX_ADDR_P2-5", RX_ADDR_P2, 4);
Nrf24_print_address_register(dev, "TX_ADDRt", TX_ADDR, 1);
Nrf24_print_byte_register(dev, "RX_PW_P0-6", RX_PW_P0, 6);
Nrf24_print_byte_register(dev, "EN_AAt", EN_AA, 1);
Nrf24_print_byte_register(dev, "EN_RXADDR", EN_RXADDR, 1);
Nrf24_print_byte_register(dev, "RF_CHt", RF_CH, 1);
Nrf24_print_byte_register(dev, "RF_SETUP", RF_SETUP, 1);
Nrf24_print_byte_register(dev, "CONFIGt", CONFIG, 1);
Nrf24_print_byte_register(dev, "DYNPD/FEATURE", DYNPD, 2);
//printf("getDataRate()=%dn",Nrf24_getDataRate(dev));
printf("Data Ratet = %sn",rf24_datarates[Nrf24_getDataRate(dev)]);
#if 0
printf_P(PSTR("Modeltt = "
PRIPSTR
"rn"),pgm_read_ptr(&rf24_model_e_str_P[isPVariant()]));
#endif
//printf("getCRCLength()=%dn",Nrf24_getCRCLength(dev));
printf("CRC Lengtht = %sn", rf24_crclength[Nrf24_getCRCLength(dev)]);
//printf("getPALevel()=%dn",Nrf24_getPALevel(dev));
printf("PA Powert = %sn", rf24_pa_dbm[Nrf24_getPALevel(dev)]);
uint8_t retransmit = Nrf24_getRetransmitDelay(dev);
int16_t delay = (retransmit+1)*250;
printf("Retransmitt = %d usn", delay);
}
#define _BV(x) (1<<(x))
void Nrf24_print_status(uint8_t status)
{
printf("STATUStt = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%xrn", status, (status & _BV(RX_DR)) ? 1 : 0,
(status & _BV(TX_DS)) ? 1 : 0, (status & _BV(MAX_RT)) ? 1 : 0, ((status >> RX_P_NO) & 0x07), (status & _BV(TX_FULL)) ? 1 : 0);
}
void Nrf24_print_address_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty)
{
printf("%st =",name);
while (qty--) {
//uint8_t buffer[addr_width];
uint8_t buffer[5];
Nrf24_readRegister(dev, reg++, buffer, sizeof(buffer));
printf(" 0x");
#if 0
uint8_t* bufptr = buffer + sizeof buffer;
while (--bufptr >= buffer) {
printf("%02x", *bufptr);
}
#endif
for(int i=0;i<5;i++) {
printf("%02x", buffer[i]);
}
}
printf("rn");
}
void Nrf24_print_byte_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty)
{
printf("%st =", name);
while (qty--) {
uint8_t buffer[1];
Nrf24_readRegister(dev, reg++, buffer, 1);
printf(" 0x%02x", buffer[0]);
}
printf("rn");
}
uint8_t Nrf24_getDataRate(NRF24_t * dev)
{
rf24_datarate_e result;
uint8_t dr;
Nrf24_readRegister(dev, RF_SETUP, &dr, sizeof(dr));
//printf("RF_SETUP=%xn",dr);
dr = dr & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
// switch uses RAM (evil!)
// Order matters in our case below
if (dr == _BV(RF_DR_LOW)) {
// '10' = 250KBPS
result = RF24_250KBPS;
} else if (dr == _BV(RF_DR_HIGH)) {
// '01' = 2MBPS
result = RF24_2MBPS;
} else {
// '00' = 1MBPS
result = RF24_1MBPS;
}
return result;
}
uint8_t Nrf24_getCRCLength(NRF24_t * dev)
{
rf24_crclength_e result = RF24_CRC_DISABLED;
uint8_t config;
Nrf24_readRegister(dev, CONFIG, &config, sizeof(config));
//printf("CONFIG=%xn",config);
config = config & (_BV(CRCO) | _BV(EN_CRC));
uint8_t AA;
Nrf24_readRegister(dev, EN_AA, &AA, sizeof(AA));
if (config & _BV(EN_CRC) || AA) {
if (config & _BV(CRCO)) {
result = RF24_CRC_16;
} else {
result = RF24_CRC_8;
}
}
return result;
}
uint8_t Nrf24_getPALevel(NRF24_t * dev)
{
uint8_t level;
Nrf24_readRegister(dev, RF_SETUP, &level, sizeof(level));
//printf("RF_SETUP=%xn",level);
level = (level & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) >> 1;
return (level);
}
uint8_t Nrf24_getRetransmitDelay(NRF24_t * dev)
{
uint8_t value;
Nrf24_readRegister(dev, SETUP_RETR, &value, 1);
return (value >> 4);
}
我得到以下输出:
...
W (19498) NRF24: Maximum number of TX retries interrupt
W (19498) TRANSMITTER: sending failed ...
...
更新:传输成功,但音频无法理解- 02/2023
我发现我正在使用Si24R1 (nRF24L01的中文克隆),我仍然使用I2S -adc sp-idf lib函数从模拟麦克风获取数据,我需要通过ESP32和nRF24L01分断板克隆之间的SPI接口获得这个I2S流。这可能吗?
我看到一些人在互联网上提到北欧半导体公司有支持I2S的nRF芯片,但我宁愿坚持使用我现有的硬件。
这是我查阅的链接。
我还发现这个库支持使用nRF24L01/Si24R1芯片使用nrf24.h
库进行音频传输,但它是用c++编写的,我不清楚如何将其集成到我的项目中。
让我知道你认为问题是什么,或者/如果你对学习这门学科的材料有好的建议。
提前感谢您的帮助!
您的硬件是否可以从adruino ide中找到的示例代码中使用简单的发送者/接收者?如果您没有检查,请尝试一下,以验证硬件是否正常。
如果简单的发送/接收不工作,检查你的电源线路。有时电压调节器的电流不够。在rf24模块电源引脚上加一些帽来过滤一些噪声,也可以根据电源的质量有所帮助。
。/X