nrf24l01+ противоречит самому себе?
Недавно я купил несколько таких микросхем на платах вместе с некоторыми "адаптерными платами", которые предположительно регулируют напряжение от 5 В до 3,3 В с помощью необходимых конденсаторов. Так что источник питания не должен быть проблемой, хотя я и не пробовал использовать отдельный источник питания. Итак, мне нравится создавать свои вещи с нуля, чтобы действительно знать все, что происходит, поэтому я не использую библиотеку для этого чипа, но я полностью прочитал техническое описание и разобрался во всех функциях. Сначала, пройдя через каждый вариант одного из модулей был успешно посылая пакеты, как указано в TX_DS прерывать, но ничего не показывает вверх на один в режиме приемника, и после проверки я выбрал, чтобы отключить все функции и удалось, наконец, добиться каких-то действий в качестве приемника прерывается каждый раз, когда передатчик послал пакет с КПР и не ACK.
Но теперь возникла проблема, в таблице данных четко указано:
IRQ RX_DR утверждается событием прибытия нового пакета. Процедура обработки этого прерывания должна быть следующей:
1) считывание полезной нагрузки через SPI,
2) очистить IRQ RX_DR,
3) прочитайте FIFO_STATUS,чтобы проверить, доступны ли дополнительные полезные нагрузки в RX FIFO,
4) если в RX FIFO больше данных, повторите шаг 1).
Однако после получения прерывания и считывания 33 байтов с помощью команды регистр состояния считывает 4E (0100 1110), в котором говорится, что прерывание действительно было RX_DR, но все биты номера канала включены, что означает пустой RX FIFO. Следующие 32 байта означают 0.
Как это может быть? Кто-нибудь испытывал нечто подобное?
ОБНОВЛЕНИЕ: Протестировано с отдельным блоком питания на стороне RX, проблема все еще остается в силе.
Фотографии: https://1drv.ms/f/s!ag6xbmoahj8xkokwmg89riaa1m71квт
Код Arduino: (не стесняйтесь поправлять меня, я не эксперт в этом языке :p)
Главная
void setup() {
attachInterrupt(digitalPinToInterrupt(radio.irq), interrupt, FALLING);
Serial.begin(9600) ;
Serial.write("\n ----Boot----\n\nInitializing radio...\n");
//Starts radio as PRX
//Sets channel
//Sets bitrate to 1Mbps
if (radio.init()) {
Serial.println("Radio ready.\n\n ----Boot complete----\n\n");
} else {
Serial.write("Couldn't initialize radio!\n\n ----Boot failed----\n");
return;
}
delay(10);
digitalWrite(9, HIGH);
}
void loop() {
}
void interrupt() {
Serial.write("\nINTERRUPT\n");
digitalWrite(9, LOW);
radio.readRegister(0x17, 2, true, BIN);
radio.readRXpayload(true);
radio.clearIRQ();
digitalWrite(9, HIGH);
}
Класс радиосвязи
#include "BitUtils.h"
BitUtils utils;
uint8_t* tmp = (uint8_t*)malloc(sizeof(uint8_t) * 33);
uint8_t initialPipe0[5] = {0x28, 0x18, 0xdb, 0xc2, 0x86};
uint8_t beaconAddress[5] = {0x29, 0x26, 0x13, 0x12, 0x00};
class Radio {
public:
uint8_t nullmsg[1] = {0x00};
uint8_t rx_config[1] = {0b00100011}; //0x00
uint8_t tx_config[1] = {0b00100010}; //0x00
uint8_t aa_config[1] = {0b00000000}; //0x01
uint8_t ch_config[1] = {0b00110100}; //0x05
uint8_t rf_config[1] = {0b00000110}; //0x06
uint8_t features_config[1] = {0b00000000}; //0x1D
uint8_t clear_irq[1] = {0b01110000}; //0x07
uint8_t clk = 13;
uint8_t miso = 12;
uint8_t mosi = 11;
uint8_t slaveselect = 10;
uint8_t chipenable = 9;
uint8_t irq = 2;
SPISettings spiConfig = SPISettings(2000000, MSBFIRST, SPI_MODE0);
boolean init() {
noInterrupts();
pinMode(clk, OUTPUT);
pinMode(miso, INPUT);
pinMode(mosi, OUTPUT);
pinMode(slaveselect, OUTPUT);
pinMode(chipenable, OUTPUT);
pinMode(irq, INPUT);
digitalWrite(clk, LOW);
digitalWrite(slaveselect, HIGH);
digitalWrite(chipenable, LOW);
delay(11);
transfer(nullmsg, 1, tmp);
if (tmp[0] != 0b00001110) {
return false;
}
writeRegister(0x00, rx_config, 2); Serial.print("0x00: ");
readRegister(0x00, 2, true, BIN);
writeRegister(0x01, aa_config, 2); Serial.print("0x01: ");
readRegister(0x01, 2, true, BIN);
writeRegister(0x05, ch_config, 2); Serial.print("0x05: ");
readRegister(0x05, 2, true, BIN);
writeRegister(0x06, rf_config, 2); Serial.print("0x06: ");
readRegister(0x06, 2, true, BIN);
writeRegister(0x1D, features_config, 2); Serial.print("0x1D: ");
readRegister(0x1D, 2, true, BIN);
pipeAddress(initialPipe0, 0);
pipeAddress(beaconAddress, 1);
Serial.print("Pipe 0 address: ");
readRegister(0x0A, 6, true, HEX);
Serial.print("Pipe 1 address: ");
readRegister(0x0B, 6, true, HEX);
delay(2);
interrupts();
return true;
}
// -- Operations --
void clearIRQ() {
writeRegister(0x07, clear_irq, 2);
Serial.println("Cleared IRQ");
}
void sendTXpayload(uint8_t data[], boolean ack) {
uint8_t message[33] = {0b10100000};
if (!ack) {
message[0] = 0b10110000;
}
for (int i = 31; i > -1; i--) {
message[32 - i] = data[i];
}
transfer(message, 33, tmp);
pulseCE(12);
delay(2);
}
void readRXpayload(boolean report) {
uint8_t message[33] = {0b01100001};
transfer(message, 33, tmp);
if (report) {
utils.prtArr(tmp, 33, HEX);
}
}
void mode(char m) {
digitalWrite(chipenable, LOW);
if (m == 't') {
writeRegister(0x00, tx_config, 2);
Serial.println("Set tx mode.");
}
if (m == 'r') {
writeRegister(0x00, rx_config, 2);
Serial.println("Set rx mode.");
}
}
void pipeAddress(uint8_t* address, uint8_t number) {
uint8_t pipeNumber = 0x0A + number;
for (int i = 4; i > -1; i--) {tmp[4 - i] = address[i];}
if (number < 2) {
writeRegister(pipeNumber, tmp, 6);
}else{
writeRegister(pipeNumber, address, 2);
}
}
void sendTo(uint8_t* address) {
for (int i = 4; i > -1; i--) {
tmp[4 - i] = address[i];
}
writeRegister(0x10, tmp, 6);
Serial.print("TX Address: ");
readRegister(0x10, 6, true, HEX);
}
void setChannel(uint8_t ch) {
writeRegister(0b00000101, new uint8_t[1] {ch}, 2);
Serial.write("Frequency set to: ");
Serial.print(2400 + tmp[1], DEC);
Serial.println("MHz");
}
// -- Low operations --
void readStatus(boolean prt) {
transfer(nullmsg, 1, tmp);
if (prt) {
utils.prtArr(tmp, 2, BIN);
}
}
void readRegister(uint8_t address, uint8_t amount, boolean prt, uint8_t format) {
uint8_t message[amount] = {address};
transfer(message, amount, tmp);
if (prt) {
utils.prtArr(tmp, amount, format);
}
}
void writeRegister(uint8_t address, uint8_t* data, uint8_t amount) {
uint8_t message[amount] = {(uint8_t)(0b00100000 | address)};
for (uint8_t i = 1; i < amount; i++) {
message[i] = data[i - 1];
}
transfer(message, amount, tmp);
}
void pulseCE(int duration) {
digitalWrite(chipenable, HIGH);
delayMicroseconds(duration);
digitalWrite(chipenable, LOW);
}
// -- Bidirectional SPI bus --
void transfer(uint8_t* data, uint8_t amount, uint8_t* output) {
SPI.beginTransaction(spiConfig);
digitalWrite(slaveselect, LOW);
delayMicroseconds(1);
for (uint8_t i = 0; i < amount; i++) {
output[i] = SPI.transfer(data[i]);
}
delayMicroseconds(1);
digitalWrite(slaveselect, HIGH);
SPI.endTransaction();
}
};
@Manuel Covas, 👍2
Обсуждение2 ответа
Мой совет состоял бы в том, чтобы удалить весь ненужный код, чтобы создать минимальный полный пример (MCVE). nRF24L01 не так сложен, когда вы знакомитесь с регистрами данных, и, к сожалению, именно здесь многие люди застревают, пытаясь использовать библиотеки, не читая данные. Однако опубликованный код предполагает, что вы выполнили свою домашнюю работу. Вот как я настроил nRF24L01 для использования IRQ (хронологический порядок сверху вниз):
// Begin SPI
// Register 0x0A: set receiver addresses
// Register 0x11: set payload number of bytes
// flush RX (spi transfer B11100010) and TX (spi transfer B11100001)
// attach ISR on IRQ digital input pin.
// start the main program loop
Это называется ISR:
void isr(){
// Read payload data
digitalWrite(CSN_pin, LOW);
data_in[0] = SPI.transfer(B01100001); //read payload register
data_in[1] = SPI.transfer(B00000000);
data_in[2] = SPI.transfer(B00000000);
data_in[3] = SPI.transfer(B00000000);
// etc
digitalWrite(CSN_pin, HIGH);
// flush RX
digitalWrite(CSN_pin, LOW);
SPI.transfer(B11100010);//flush RX
digitalWrite(CSN_pin, HIGH);
// Read status register 0x07
digitalWrite(CSN_pin, LOW);
SPI.transfer(0x07);
reg7 = SPI.transfer(0x00);
digitalWrite(CSN_pin, HIGH);
reg7 |= B01000000; // RX_DR set bit 6
// write back to status register
digitalWrite(CSN_pin, LOW);
SPI.transfer(0x20+0x07);
SPI.transfer(reg7);
digitalWrite(CSN_pin, HIGH);
}
Изменить: бит 6 регистра состояния-это
флаг RX_DR. Если это 1 (что имеет место в примере операции), то данные не были получены. Установите бит 6, чтобы очистить прерывание.
Я думал, что "RX_DR` означает "Данные готовы", и на странице 30 они указывают: "После проверки пакета Enhanced ShockBurst™ разбирает пакет и загружает полезную нагрузку в FIFO RX и утверждает IRQ RX_DR"., @Manuel Covas
Вы правы, но в паспорте данных (p59) также говорится, что "RX_DR=0" утверждается, когда новые данные поступают в RX FIFO, напишите "1", чтобы очистить бит. Это то, что делает код в моем ответе. Помните также "MASK_RX_DR=0", но это значение по умолчанию при запуске., @MichaelT
Это было бы странно, нет? Значения сброса для IRQ равны "0", и я действительно получаю прерывание, когда пакет отправляется другим радиоприемником. RX_DR
переходит в " 1 "в регистре состояния, кроме того, при записи" 1 "для очистки бита он возвращается к "0". Не знаю, почему они сделали это таким образом, но, по крайней мере, это то, что происходит со мной. Основная проблема заключалась в том, что IRQ и остальная часть устройства указывали пустые FIFO., @Manuel Covas
Я просто следую тому, что написано в паспорте. (Псевдо) код, написанный выше, действительно работает, я использую его в своих собственных проектах nRF24., @MichaelT
Мне интересно, связана ли ваша проблема с проблемой, с которой я сталкиваюсь с моим nRF24L01? См. nRF24L01 непрерывное считывание закрытой трубы
- Проблемы передачи NRF24L01 между Arduino UNO и Arduino Nano
- NRF24L01 PA+LNA с Arduino
- nRF24L01+ Невозможно установить адрес
- Не вызовут ли помехи одновременно работающие радиомодули nrf24L01 ?
- Состояние цифрового вывода Arduino не передается через NRF24L01, тогда как состояние аналогового вывода передается, почему?
- Использую передатчик + Arduino *Uno*..и приемник + arduino *nano* будет ли это работать?
- Код правильный? Nrf24l01
- Arduino NRF24LO1
Вы можете опубликовать код Arduino?, @MichaelT
@MichaelT отредактировано в коде, @Manuel Covas
Мне интересно, связана ли ваша проблема с проблемой, с которой я сталкиваюсь с моими nRF24L01? Видишь https://arduinoprosto.ru/q/85874/nrf24l01-continuously-reading-closed-pipe, @PyNZ