nRF24L01+ ATMEGA + Raspberry Pi
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+
Частота 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 - режим трансмітера (передавача)
Діаграма переходів з режиму у режим зображені на малюнку:
Інформаційний пакет, який передає модуль nRF24L01+ має наступний формат:
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+ повинен мати унікальну адресу. Стосовно адресації у документації наведена наглядна діаграма:
Зверніть увагу що адреси для Data Pipe 1 - Pipe 5 відрізняються один від одного лише останнім байтом. Цього вимагає документація на nRF24L01+. На цій діаграмі модуль який позначено PRX прослуховує ефір для вказаних адресів RX_ADDR_P0..RX_ADDR_P5. Кожен з PTX1..PTX6 відправляє пакети на адреси TX_ADDR. Модуль який працює як PRX теж може відправляти модулям пакети за їх адресами.
Якщо всі налаштування (зрозуміло, окрім адрес) будуть однаковими - модулі повинні працювати нормально. Основні проблемі виникають коли налаштування передавача та приймача мають відмінності. Також проблеми можуть виникнути, якщо ви обрали канал, який зайнятий.
Призначення пінів модуля nRF24L01+
Схема підключення nRF24L01+ до мікроконтролера Atmega8
Схема підключення nRF24L01+ до Raspberry Pi
Можливі проблеми з живленням nRF24L01+
В окремих випадках зазначались проблеми при слабкому живленні. Деякі плати Arduino мають заслабкий стабілізатор на 3.3В. Ця проблема вирішується допайкою на ноги живлення додаткового керамічного конденсатора 1-2мкФ.Приклад трансмітера і ресивера для мікроконтролерів
Скачати приклади для 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 — що це таке?
- Raspberry Pi — GPIO
- Raspberry Pi — UART
- Raspberry Pi — FT232
- Raspberry Pi — PWM і Сервопривод
- Raspberry Pi — DHT11
- Raspberry Pi - FM Transmitter
- Прошивка AVR мікроконтролерів за допомогою Raspberry Pi
- Raspberry Pi — LCD display 1602
- Raspberry Pi — WiFi
- Raspberry-Pi — I2C (TWI)
- Raspberry Pi - DS18B20
- Raspberry Pi Camera
- nRF24L01+ ATMEGA + Raspberry Pi
- BMP180 + Raspberry Pi + WH1602
- Wi-Fi Метео станція
- Raspbian. Apache + PHP + Python + MySQL
- Встановлюємо Raspbian на Raspberry Pi без клавіатури та монітору
- IR-дистанційне керування. Використання LIRC у Python
- Raspberry Pi. Raspbian. Відправлення пошти через аккаунт Gmail
- Neoway M590 – GSM/GPRS modem
- MPU-6050 – гіроскоп – акселерометр
- HMC5883L Магнітометр
- PWM контролер з інтерфейсом I2С на базі мікросхеми PCA9685
- Метеостанція на Raspberry Pi своїми руками
- Raspberry Pi. Live-stream video
У вас тут помилка: nRF24L01+ працює на частотах 2.400-2.4835ГГц. насправді модулі працюють у діапазоні 2,400 - 2,525 ГГц.
Дякую за зауваження. Дуже слушне зауваження. Так, насправді модуль фізично може працювати на частотах 2.400 - 2.525 ГГц. Але загальнодоступний для громадського використання діапазон ISM band 2.400 - 2.4835GHz. В багатьох документах можна зустріти діапазон 2.400-2.500GHz, але у більшості країн він юридично обмежений до 2.400 — 2.4835GHz.
Недавні записи
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
- DC-DC для IGBT драйверів ізольований 2 W +15 -8 вольт
Tags
battery soldering java-script ngnix adc rs-232 flask esp8266 watchdog web exti solar mongodb rtc sms pwm usart books ethernet smd git websocket meteo css python dc-dc displays led ssd1306 eeprom gpio barometer max1674 mpx4115a brushless motor mpu-6050 timer sensors remap servo bldc atmega pmsm 3d-printer flash encoder examples dma raspberry-pi tim ssd1331 piezo mpu-9250 rfid eb-500 foc bme280 gps nvic dht11 bluetooth hih-4000 stm32 st-link docker uart avr html wifi bmp280 bkp nodemcu options usb lcd programmator i2c capture
Архіви