nRF24L01+ ATMEGA + Raspberry Pi


25.12.2014

nRF24L01+ - радіо модуль, що працює на частоті 2.4ГГц. Дозволяє передавати інформацію у обох напрямках та об’єднувати декілька пристроїв.

Основні технічні характеристики nRF24L01+

  • Робоча частота - 2.4ГГц. Можливість вибору одного з 126 каналів (при швидкості 2Mbps використовуються два канали)
  • Можливість працювати на одному каналі з 6 пристроями
  • Швидкість передачі даних - 250kbps, 1Mbps, 2Mbps
  • Декілька режимів вихідної потужності (впливає на робочу дистанцію)
  • Дистанція - до 100 метрів на відкритому просторі, до 30 метрів у приміщені. На практиці впевнено "пробиває" 2 залізобетонних стіни на швидкості 1Mbps
  • Живлення - від 1.9 до 3.6B. Максимальний струм - 13.5мА, 26мкА у режимі standby, мінімальний - 900нА у режимі power down
  • Інтерфейс взаємодії з мікроконтролером - SPI
  • Входи витримують 5В, але живлення модуля не більше 3.6В
  • Максимальна довжина пакету даних - 32 байти
  • Ціна модуля - $1-$2
Документацію до nRF24L01+ можна скачати тут: nRF24L01Pluss.pdf

Принцип роботи та основні налаштування nRF24L01+

NRF24L01plus03 NRF24L01plus01

Частота 2.4ГГц дуже популярна і на ній працює досить велика кількість приладів, наприклад: WiFi, радіокеровані моделі, тощо. Як вони не заважають один одному? Справа у тому, що частота 2.4ГГц - це умовне позначення. Насправді, мається на увазі діапазон частот, близький до 2.4ГГц. nRF24L01+ працює на частотах 2.400-2.4835ГГц. Частота, на якій будуть працювати ваші модулі, обирається номером каналу. Канали мають крок в 1МГц. Тобто якщо ви обираєте канал 0 - це частота 2.400ГГц, якщо канал 76 - 2.476ГГц. Зрозуміло, треба обирати вільну хвилю (канал) - інакше зв’язок буде не стабільний або взагалі відсутній.

Ви можете обрати одну з трьох швидкостей передачі даних. Чим менша швидкість - тим більша чутливість. Тобто, при швидкості 250kbps модулі будуть працювати на більшій дистанції, ніж при вищих швидкостях.

На дальність роботи модулів також впливає налаштування вихідної потужності модуля. Ви можете обирати потужність в залежності від пріоритетів. Тобто, якщо для вас є важливішою максимальна дальність, то треба обрати максимальну потужність. Якщо пріоритетною є економічність, а дальність - кілька метрів, розумно обрати меншу потужність сигналу. Цікаве спостереження у режимі прийому данних (RX) модуль споживає більший струм ніж у режимі передачі (TX).

Модуль nRF24L01+ може знаходитись одночасно в одному з режимів:

Power Down - Виключений Standby - Сплячий режим RX Mode - режим ресивера (приймача) TX Mode - режим трансмітера (передавача)

Діаграма переходів з режиму у режим зображені на малюнку:

NRF24L01plus_modes

Інформаційний пакет, який передає модуль nRF24L01+ має наступний формат:

NRF24L01plus_paket

Preamble - Преамбула являє собою послідовність бітів і використовується для синхронізації демодуляторів приймачів.

Address - Адреса приймача. Адреса гарантує, що пакет отримає потрібний приймач. Ви можете налаштувати довжину адреси 3, 4 або 5 байтів. Треба намагатися щоб адреси були унікальні. Але інколи Адреси можуть бути однакові у декількох nRF24L01+ якщо це потребують Ваші задачі.

Packet Control Field - контрольне поле. Містить: 6 біт, що визначають довжину пакета (мається на увазі довжина пакета корисних даних (від 0 до 32 байт)); 2 біти PID, що використовуються для визначення чи є пакет новим чи пересланим повторно; 1 біт - прапор NO_ACK.

Payload - корисний "вантаж". Тобто дані, які передає мікроконтролер. Може бути від 0 до 32 байт. Довжину Payload можна налаштувати.

CRC - CRC є обов`язковим механізмом виявлення помилок в пакеті. Довжина CRC - 1 або 2 байти і залежить від загальної довжини пакета.

Для того, щоб переданий пакет був прийнятий потрібним приймачем, налаштування приймача повинні бути такими самими, як і у передавача. Якщо параметри пакета будуть відрізнятися, приймач не зможе його обробити. Також треба коректно вказувати адреси (про це трохи нижче).

Якщо одночасно будуть передавати декілька передавачів, або виникнуть інші перешкоди, станеться колізія. Приймач не зможе отримати пакет. Тому nRF24L01+ має налаштування щодо автоматичної повторної відправки пакета (Aoto Retransmission (ART)). Ці налаштування вказують з яким інтервалом і скільки разів намагатися відправити пакет.

Як зазначалося у самому початку nRF24L01+ може працювати на одному каналі з 6-тю nRF24L01+. Для цього кожен nRF24L01+ повинен мати унікальну адресу. Стосовно адресації у документації наведена наглядна діаграма:

NRF24L01plus_addr

Зверніть увагу що адреси для Data Pipe 1 - Pipe 5 відрізняються один від одного лише останнім байтом. Цього вимагає документація на nRF24L01+. На цій діаграмі модуль який позначено PRX прослуховує ефір для вказаних адресів RX_ADDR_P0..RX_ADDR_P5. Кожен з PTX1..PTX6 відправляє пакети на адреси TX_ADDR. Модуль який працює як PRX теж може відправляти модулям пакети за їх адресами.

Якщо всі налаштування (зрозуміло, окрім адрес) будуть однаковими - модулі повинні працювати нормально. Основні проблемі виникають коли налаштування передавача та приймача мають відмінності. Також проблеми можуть виникнути, якщо ви обрали канал, який зайнятий.

Призначення пінів модуля nRF24L01+

NRF24L01plus_pins

Схема підключення nRF24L01+ до мікроконтролера Atmega8

NRF24L01plus_Atmega

Схема підключення nRF24L01+ до Raspberry Pi

NRF24L01plus_RPi

Можливі проблеми з живленням nRF24L01+

В окремих випадках зазначались проблеми при слабкому живленні. Деякі плати Arduino мають заслабкий стабілізатор на 3.3В. Ця проблема вирішується допайкою на ноги живлення додаткового керамічного конденсатора 1-2мкФ.

NRF24L01plus02

Приклад трансмітера і ресивера для мікроконтролерів

Скачати приклади для Atmega8 та Raspberry Pi

У прикладах для Atmega8 використана бібліотека, написана Davide Gironi. Оригінальні файли і приклади також знаходяться у архіві.

Спочатку розглянемо приклад для мікроконтролерів, коли один модуль відправляє данні, а інший - приймає. У цьому прикладі приймач отримує дані по 6 адресам (Pipe). Передавач послідовно відправляє пакети по всіх адресах (Pipe). Для моніторингу роботи я підключав UART-USB перехідник до приймача або передавача. Та термінальною програмою через комп’ютера спостерігав за тим, що відбувається.

Передавач (sender.c):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "uart/uart.h"
#define UART_BAUDRATE (F_CPU/16/9600)-1
 
#include "nrf24l01/nrf24l01.h"
 
int main(void) {
    uint8_t i = 0;
    uint8_t bufferout[NRF24L01_PAYLOAD];
 
    uart_init(UART_BAUDRATE);
 
    //init nrf24l01
    nrf24l01_init();
 
    //init interrupt
    sei();
 
    uart_puts("Starting as TX...\r\n");
 
    //setup buffer
    for(i=0; i<sizeof(bufferout); i++)
        bufferout[i] = i+'A';
 
    //sending buffer addresses
    uint8_t sendpipe = 0;
    uint8_t addrtx0[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP0;
    uint8_t addrtx1[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP1;
    uint8_t addrtx2[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP2;
    uint8_t addrtx3[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP3;
    uint8_t addrtx4[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP4;
    uint8_t addrtx5[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP5;
 
    nrf24l01_printinfo(uart_puts, uart_putc);
 
    //main loop
    while(1) {
        //TX
        char pipebuffer[5];
        uart_puts("Pipe: ");
        itoa(sendpipe, pipebuffer, 10);
        uart_puts(pipebuffer);
        uart_puts("...");
 
        if(sendpipe == 0) {
            //set tx address for pipe 0
            nrf24l01_settxaddr(addrtx0);
        } else if(sendpipe == 1) {
            //set tx address for pipe 1
            nrf24l01_settxaddr(addrtx1);
        } else if(sendpipe == 2) {
            //set tx address for pipe 2
            nrf24l01_settxaddr(addrtx2);
        } else if(sendpipe == 3) {
            //set tx address for pipe 3
            nrf24l01_settxaddr(addrtx3);
        } else if(sendpipe == 4) {
            //set tx address for pipe 4
            nrf24l01_settxaddr(addrtx4);
        } else if(sendpipe == 5) {
            //set tx address for pipe 5
            nrf24l01_settxaddr(addrtx5);
        }
 
        //write buffer
        uint8_t writeret = nrf24l01_write(bufferout);
            if(writeret == 1)
            uart_puts("OK\r\n");
        else
            uart_puts("Failed\r\n");
 
        sendpipe++;
        sendpipe%=6;
 
        _delay_ms(100);
    }
}

Приймач (reciver.c):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "uart/uart.h"
#define UART_BAUDRATE (F_CPU/16/9600)-1
 
#include "nrf24l01/nrf24l01.h"
 
int main(void) {
    uint8_t i = 0;
    uint8_t bufferin[NRF24L01_PAYLOAD+1];
 
    uart_init(UART_BAUDRATE);
 
    nrf24l01_init();
 
    //init interrupt
    sei();
 
    uart_puts("Starting as RX...\r\n");
 
    //reset buffer
    for(i=0; i<sizeof(bufferin); i++)
        bufferin[i] = 0;
 
    nrf24l01_printinfo(uart_puts, uart_putc);
 
    //main loop
    while(1) {
        uint8_t pipe = 0;
        if(nrf24l01_readready(&pipe)) { //if data is ready
 
            char pipebuffer[5];
            uart_puts("Pipe: ");
            itoa(pipe, pipebuffer, 10);
            uart_puts(pipebuffer);
            uart_puts("\r\n");
 
            //read buffer
            nrf24l01_read(bufferin);
            bufferin[NRF24L01_PAYLOAD] = '\0';
            uart_puts("Data: ");
            uart_puts(bufferin);
            uart_puts("\r\n");
 
            for(i=0; i<sizeof(bufferin); i++)
                bufferin[i] = 0;
 
        }
        _delay_ms(10);
    }
}

Приклад ресивера для Raspberry Pi

Тепер підключимо модуль до Raspberry Pi та напишемо приклад для отримання даних. Спочатку встановимо бібліотеку RF24:


git clone https://github.com/tmrh20/RF24.git
cd RF24
sudo make install

Для Raspberry Pi код приймача виглядае так (nRF24L01_example1.cpp):


#include <cstdlib>
#include <iostream>
#include <RF24/RF24.h>
 
using namespace std;
 
// gpio pins, spi speed
RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
 
int main(int argc, char** argv)
{
  char receivePayload[16];
  uint8_t pipe_num=0;
 
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_1MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setRetries(15, 15);
  radio.setAutoAck(1);
  radio.setChannel(76);
  radio.setPayloadSize(16);
  radio.openReadingPipe(0,0xE8E8F0F0E2LL);
  radio.openReadingPipe(1,0xC1C2C2C2C2LL);
  radio.openReadingPipe(2,0xC1C2C2C2C3LL);
  radio.openReadingPipe(3,0xC1C2C2C2C4LL);
  radio.openReadingPipe(4,0xC1C2C2C2C5LL);
  radio.openReadingPipe(5,0xC1C2C2C2C6LL);
 
  radio.startListening();
  printf("Start\n");
 
  while(1) {
    while (radio.available(&pipe_num))
    {
      // Clear measurement values
      memset(receivePayload,0,sizeof(receivePayload));
 
      radio.read(&receivePayload, sizeof(receivePayload));
      printf("pipe %d: %s\n", pipe_num, receivePayload);
    }
  }
  return 0;
}

Режим "запитав - відповів"

Уявіть собі який гомін стоїть у ефірі, якщо декілька nRF24L01+ постійно відправляють дані навіть тоді, коли їх ніхто не слухає. Вони можуть заважати один одному. Переробимо наш приклад для мікроконтролерів таким чином, щоб nRF24L01+ відповідали тільки після того, як саме його запитають. Для цього nRF24L01+ будуть працювати у режимі прийому і коли отримають будь-який пакет на свою адресу - будуть відправляти дані. У прикладі пакет запиту не розбирається. Тобто, будь-який пакет сприймається як запит. Та при потребі можливо зробити аналіз та видавати ті чи інші дані.

Сторона, яка буде запитувати дані, спочатку надсилає пакет на запит (у прикладі - пакет з будь якими даними), потім переходить у режим прийому і очікує надходження даних протягом певного часу. Якщо дані за зазначений період не надходять, вважається, що потрібний модуль недосяжний.

Сторона що відповідає (reply.c):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "uart/uart.h"
#define UART_BAUDRATE (F_CPU/16/9600)-1
 
#include "nrf24l01/nrf24l01.h"
 
int main(void) {
    uint8_t pipe = 0;
    uint8_t i;
 
    uint8_t bufferout[NRF24L01_PAYLOAD];
    uint8_t bufferin[NRF24L01_PAYLOAD];
 
    uart_init(UART_BAUDRATE);
 
    nrf24l01_init();
 
    //init interrupt
    sei();
 
    //setup buffer
    for(i=0; i<sizeof(bufferout); i++)
        bufferout[i] = i+'a';
    for(i=0; i<sizeof(bufferin); i++)
        bufferin[i] = 0;
 
    nrf24l01_printinfo(uart_puts, uart_putc);
 
    while(1) {
        if(nrf24l01_readready(&pipe)) { //if data is ready
 
            char pipebuffer[5];
            uart_puts("Pipe: ");
            itoa(pipe, pipebuffer, 10);
            uart_puts(pipebuffer);
            uart_puts("\r\n");
 
            //read buffer
            nrf24l01_read(bufferin);
            uart_puts("Data: ");
            uart_puts(bufferin);
            uart_puts("\r\n");
 
            for(i=0; i<sizeof(bufferin); i++)
                bufferin[i] = 0;
 
            _delay_us(10);
            //write buffer
            uint8_t writeret = nrf24l01_write(bufferout);
 
            if(writeret == 1)
                uart_puts("OK\r\n");
            else
                uart_puts("Failed\r\n");
 
        }
    }
}

У цьому прикладі сторона, що отримує дані, послідовно опитує шість адрес (request.c):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "uart/uart.h"
#define UART_BAUDRATE (F_CPU/16/9600)-1
 
#include "nrf24l01/nrf24l01.h"
 
int main(void) {
    uint8_t i = 0;
    uint8_t state = 0;
    uint8_t counter = 0;
    uint8_t pipe = 0;
 
    uint8_t bufferout[NRF24L01_PAYLOAD];
    uint8_t bufferin[NRF24L01_PAYLOAD+1];
 
    uart_init(UART_BAUDRATE);
 
    nrf24l01_init();
 
    sei();
 
    //setup buffer
    for(i=0; i<sizeof(bufferout); i++)
        bufferout[i] = i+'a';
    for(i=0; i<sizeof(bufferin); i++)
        bufferin[i] = 0;
 
    //sending buffer addresses
    uint8_t sendpipe = 0;
    uint8_t addrtx0[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP0;
    uint8_t addrtx1[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP1;
    uint8_t addrtx2[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP2;
    uint8_t addrtx3[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP3;
    uint8_t addrtx4[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP4;
    uint8_t addrtx5[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP5;
 
    nrf24l01_printinfo(uart_puts, uart_putc);
 
    while(1) {
            if (state == 0) {
                //TX
                char pipebuffer[5];
                uart_puts("Pipe: ");
                itoa(sendpipe, pipebuffer, 10);
                uart_puts(pipebuffer);
                uart_puts("... ");
 
                if(sendpipe == 0) {
                    //set tx address for pipe 0
                    nrf24l01_settxaddr(addrtx0);
                } else if(sendpipe == 1) {
                    //set tx address for pipe 1
                    nrf24l01_settxaddr(addrtx1);
                } else if(sendpipe == 2) {
                    //set tx address for pipe 2
                    nrf24l01_settxaddr(addrtx2);
                } else if(sendpipe == 3) {
                    //set tx address for pipe 3
                    nrf24l01_settxaddr(addrtx3);
                } else if(sendpipe == 4) {
                    //set tx address for pipe 4
                    nrf24l01_settxaddr(addrtx4);
                } else if(sendpipe == 5) {
                    //set tx address for pipe 5
                    nrf24l01_settxaddr(addrtx5);
                }
 
                //write buffer
                uint8_t writeret = nrf24l01_write(bufferout);
 
                if(writeret == 1)
                    uart_puts("OK\r\n");
                else
                    uart_puts("Failed\r\n");
 
                sendpipe++;
                sendpipe%=6;
                state = 1;
                counter = 0;
                nrf24l01_setRX();
            }
            else {
                if(nrf24l01_readready(&pipe)) { //if data is ready
                    //read buffer
                    nrf24l01_read(bufferin);
                    bufferin[NRF24L01_PAYLOAD]='\0';
                    uart_puts("Data: ");
                    uart_puts(bufferin);
                    uart_puts("\r\n");
 
                    for(i=0; i<sizeof(bufferin); i++)
                        bufferin[i] = 0;
 
                    state = 0;
 
                }
                _delay_ms(1);
                counter ++;
                if (counter > 200) {
                    state = 0;
                }
        }
    }
}

Для Raspberry Pi программа, що запитує, відправляє запит на одну адресу - 0xE8E8F0F0E2 (nRF24L01_example2.cpp):


#include <cstdlib>
#include <iostream>
#include <RF24/RF24.h>
 
using namespace std;
 
// gpio pins, spi speed
RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
 
int main(int argc, char** argv)
{
  char receivePayload[16];
  uint8_t pipe_num = 0;
  uint8_t state = 0;
  uint8_t counter = 0;
 
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_1MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setRetries(15, 15);
  radio.setAutoAck(1);
  radio.setChannel(76);
  radio.setPayloadSize(16);
 
  radio.openWritingPipe(0xE8E8F0F0E2LL);
 
  printf("Start\n");
 
  while(1) {
    if (state == 0) {
      // Send request
      printf("Send request...\n");
      radio.openWritingPipe(0xE8E8F0F0E2LL);
      radio.write(receivePayload,sizeof(receivePayload));
      state = 1;
      counter = 0;
      // Start to Listening
      radio.startListening();
    }
    else {
      if (radio.available(&pipe_num)) {
        memset(receivePayload,0,sizeof(receivePayload));
        radio.read(&receivePayload, sizeof(receivePayload));
        printf("pipe %d: %s\n", pipe_num, receivePayload);
        state = 0;
        radio.stopListening();
      }
      delay(0.01);
      counter ++;
      if (counter > 200) {
        radio.stopListening();
        state = 0;
        printf("Nefiga :(\n");
      }
    }
    delay(1);
  }
  return 0;
}

Масив - це не цікаво, передамо структуру

З точки зору програміста отримувати, а потім розбирати масив, - не завжди зручно. Частіше за все є потреба у пересиланні числових даних, інколи декількох. Або, взагалі, різнотипні дані. Як спростити собі життя? Зазвичай створюють структуру та використовують її наступним чином:

Сторона, що відповідає (Atmega8) (reply_struct.c):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "uart/uart.h"
#define UART_BAUDRATE (F_CPU/16/9600)-1
 
#include "nrf24l01/nrf24l01.h"
 
typedef struct
    {
        int8_t      value1;
        int8_t      value2;
        int8_t      text[14];
    } PAYLOAD;
 
int main(void) {
    uint8_t pipe = 0;
    uint8_t i;
 
    //uint8_t bufferout[NRF24L01_PAYLOAD];
    PAYLOAD bufferout;
    uint8_t bufferin[NRF24L01_PAYLOAD];
 
    uart_init(UART_BAUDRATE);
 
    nrf24l01_init();
 
    //init interrupt
    sei();
 
    //setup buffer
    bufferout.value1 = 10;
    bufferout.value2 = 13;
    for(i=0; i<sizeof(bufferout.text); i++)
        bufferout.text[i] = i+'a';
    for(i=0; i<sizeof(bufferin); i++)
        bufferin[i] = 0;
 
    nrf24l01_printinfo(uart_puts, uart_putc);
 
    while(1) {
        if(nrf24l01_readready(&pipe)) { //if data is ready
 
            char pipebuffer[5];
            uart_puts("Pipe: ");
            itoa(pipe, pipebuffer, 10);
            uart_puts(pipebuffer);
            uart_puts("\r\n");
 
            //read buffer
            nrf24l01_read(bufferin);
            uart_puts("Data: ");
            uart_puts(bufferin);
            uart_puts("\r\n");
 
            for(i=0; i<sizeof(bufferin); i++)
                bufferin[i] = 0;
 
            _delay_us(10);
            //write buffer
            uint8_t writeret = nrf24l01_write(&bufferout);
 
            if(writeret == 1)
                uart_puts("OK\r\n");
            else
                uart_puts("Failed\r\n");
 
        }
    }
}

Сторона, що запитує, має приймати дані у таку ж саму структуру. Так виглядає приклад для Raspberry Pi (nRF24L01_example3.cpp):


#include <cstdlib>
#include <iostream>
#include <RF24/RF24.h>
 
using namespace std;
 
// gpio pins, spi speed
RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
 
typedef  struct
  {
    int8_t    value1;
    int8_t    value2;
    int8_t    text[14];
  } PAYLOAD;
 
PAYLOAD  receivePayload;
 
int main(int argc, char** argv)
{
  char bufferout[16];
  uint8_t pipe_num = 0;
  uint8_t state = 0;
  uint8_t counter = 0;
 
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_1MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setRetries(15, 15);
  radio.setAutoAck(1);
  radio.setChannel(76);
  radio.setPayloadSize(16);
 
  radio.openWritingPipe(0xE8E8F0F0E2LL);
 
  printf("Start\n");
 
  while(1) {
    if (state == 0) {
      // Send request
      printf("send request...\n");
      radio.openWritingPipe(0xE8E8F0F0E2LL);
      radio.write(bufferout,sizeof(bufferout));
      state = 1;
      counter = 0;
      // Start to Listening
      radio.startListening();
    }
    else {
      if (radio.available(&pipe_num)) {
        memset(receivePayload,0,sizeof(receivePayload));
        radio.read(&receivePayload, sizeof(receivePayload));
        printf("pipe %d: value1=%d value2=%d text=%s\n", pipe_num, receivePayload.value1, receivePayload.value2, receivePayload.text);
        state = 0;
        radio.stopListening();
      }
      delay(0.01);
      counter ++;
      if (counter > 200) {
        radio.stopListening();
        state = 0;
        printf("Nefiga :(\n");
      }
    }
    delay(1);
  }
  return 0;
}

Треба бути уважним і слідкувати за тим, щоб розмір структури не перевищив 32 байти (максимально можливий розмір Payload для nRF24L01+) та співпадав з довжиною Payload, яка вказується при налаштуванні модуля nRF24L01+.

Відео

Що я можу сказати на завершення про nRF24L01+. Це досить доступний шлях до створення простих бездротових систем. Але існують більш цікаві модулі, за допомогою яких можна забезпечити бездротовий зв’язок більш сучасними методами. Про них поговоримо в наступних статтях.

Скачати приклади для Atmega8 та Raspberry Pi

Успіхів.

Дивись також:

Raspberry Pi Корисно знати Початківцям Схеми і прошивки
Коментарі:
Олександр говорить:
09.06.2020 21:09
У вас тут помилка: nRF24L01+ працює на частотах 2.400-2.4835ГГц. 
насправді модулі працюють у діапазоні 2,400 - 2,525 ГГц.

andre говорить:
10.06.2020 05:55
Дякую за зауваження. Дуже слушне зауваження. Так, насправді модуль фізично може працювати на частотах 2.400 - 2.525 ГГц. Але загальнодоступний для громадського використання діапазон ISM band 2.400 - 2.4835GHz. В багатьох документах можна зустріти діапазон 2.400-2.500GHz, але у більшості країн він юридично обмежений до 2.400 — 2.4835GHz.

Додати коментар
Code
* - обов'язкові поля

Архіви