Подключение модуля nRF24L01+ к Arduino — соединяем две arduino по радиоканалу

nRF24L01 один из самых популярных беспроводных модулей для интернета вещей (IoT). Подключение модуля nRF24L01+ к Arduino позволит организовать многоканальную защищенную связь между Arduino и устройствами на расстоянии. Рассмотрим, как наладить связь между двумя или несколько плат Ардуино по радиоканалу.

Содержание

Установка библиотеки RF24

Работать с nRF24L01+ можно с помощью библиотеки RF24 — довольно популярная и удобная библиотека. Скачиваем, распаковываем и закидываем библиотеку RF24 в папку Arduino/libraries. В случае, если на момент добавления библиотеки, Arduino IDE была открытой, перезагружаем среду.

Библиотеку можно установить из самой среды следующим образом:

  1. В Arduino IDE открываем менеджер библиотек: Скетч->Подключить библиотеку->Управлять библиотеками…Подключение модуля nRF24L01+ к Arduino - Управлять библиотеками...
  2. В строке поиска вводим «RF24», находим библиотеку автора TMRh20, выбираем последнюю версию и кликаем Установить.Подключение модуля nRF24L01+ к Arduino - RF24 Установка
  3. Библиотека установлена (INSTALLED).Подключение модуля nRF24L01+ к Arduino - RF24 INSTALLED

Описание методов библиотеки RF24

begin()

Инициализация работы модуля.

bool RF24::begin(void);

Возвращает
bool — результат инициализации (true / false).

startListening()

Начать прослушивание труб, открытых для приёма данных.

void RF24::startListening(void);

stopListening()

Прекратить прослушивание труб и переключиться в режим передатчика.

void RF24::stopListening(void);

available()

Проверить наличие принятых данных доступных для чтения.

bool RF24::available(void);
bool RF24::available(uint8_t * pipe_num);

Параметры
pipe_num — адрес переменной типа uint8_t в которую требуется поместить номер трубы по которой были приняты данные.
Возвращает
bool — флаг наличия принятых данных (true / false).

isAckPayloadAvailable()

Проверить передатчиком наличие данных в ответе приёмника.

bool RF24::isAckPayloadAvailable(void);

Возвращает
bool — флаг наличия принятых данных от приёмника (true / false).

read()

Прочитать принятые данные.

void RF24::read(void * buf, uint8_t len);

Параметры
buf — адрес массива, строки или переменной в которую требуется поместить принятые данные.
len — количество байт занимаемое массивом, строкой или переменной в которую требуется поместить принятые данные.

write()

Отправить данные по радиоканалу.

bool RF24::write(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
Возвращает
bool — результат доставки данных приёмнику (true / false).

writeAckPayload()

Подготовить данные для ответа передатчику.

void RF24::writeAckPayload(uint8_t pipe, const void * buf, uint8_t len);

Параметры
pipe — Номер трубы передатчика которому требуется ответить данными.
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить вместе с ответом передатчику.
len — Размер отправляемых данных в байтах.

openWritingPipe()

Открыть трубу для передачи данных.

void RF24::openWritingPipe(uint64_t address);

Параметры
address — Адрес трубы, состоит из 5 байт (по умолчанию) и может быть представлен числом типа uint64_t или массивом из 5 однобайтных элементов. Адрес трубы передатчика должен совпадать с одним из адресов труб приёмника.

openReadingPipe()

Открыть трубу для приёма данных.

void RF24::openReadingPipe(uint8_t number, const uint8_t * address);
void RF24::openReadingPipe(uint8_t number, uint64_t address);

Параметры
number — Номер трубы (число от 0 до 5).
address — Адрес трубы, состоит из 5 байт (по умолчанию) и может быть представлен числом типа uint64_t или массивом из 5 однобайтных элементов. Адрес трубы приёмника должен совпадать с адресом трубы передатчика.

closeReadingPipe()

Закрыть трубу открытую ранее для прослушивания (приёма данных).

void RF24::closeReadingPipe(uint8_t pipe):

Параметры
number — Номер трубы (число от 0 до 5), которую более не требуется прослушивать.

setChannel()

Установить радиочастотный канал связи. Номер канала определяет частоту на которой работает модуль. Каждый канал имеет шаг в 1 МГц, а каналу 0 соответствует частота 2,4 ГГц = 2400 МГц, следовательно, каналу 1 соответствует частота 2401 МГц, каналу 2 — частота 2402 МГц и т.д. до канала 125 с частотой 2525 МГц.

void RF24::setChannel(uint8_t channel);

Параметры
channel — Номер канала, указывается числом от 0 до 125.

getChannel()

Получить номер текущего радиочастотного канала связи.

uint8_t RF24::getChannel(void);

Возвращает
Номер канала, число от 0 до 125.

setDataRate()

Установить скорость передачи данных по радиоканалу.

bool RF24::setDataRate(rf24_datarate_e speed);

Параметры
speed — Скорость, задаётся одной из констант: RF24_1MBPS — 1 Мбит/сек, RF24_2MBPS — 2 Мбит/сек и RF24_250KBPS — 250 Кбит/сек (только для модуля NRF24L01+PA+LNA).
Возвращает
Флаг успешной установки новой скорости (true / false).

getDataRate()

Получить текущую скорость передачи данных по радиоканалу.

rf24_datarate_e RF24::getDataRate(void);

Возвращает
значение одной из констант сопоставленной скорости:RF24_1MBPS — 1 Мбит/сек, RF24_2MBPS — 2 Мбит/сек и RF24_250KBPS — 250 Кбит/сек (только для модуля NRF24L01+PA+LNA).

setPALevel()

Установить уровень усиления мощности передатчика.

void RF24::setPALevel(uint8_t level);

Параметры
level — Уровень, задаётся одной из констант:

  • RF24_PA_MIN — минимальный уровень усиления = -18 дБм.
  • RF24_PA_LOW — низкий уровень усиления = -12 дБм.
  • RF24_PA_HIGH — высокий уровень усиления = -6 дБм.
  • RF24_PA_MAX — максимальный уровень усиления = 0 дБм.

getPALevel()

Получить текущий уровень усиления мощности передатчика.

uint8_t RF24::getPALevel(void);

Возвращает
значение одной из констант сопоставленной мощности:RF24_PA_MIN — минимальный уровень усиления = -18 дБм.

  • RF24_PA_LOW — низкий уровень усиления = -12 дБм.
  • RF24_PA_HIGH — высокий уровень усиления = -6 дБм.
  • RF24_PA_MAX — максимальный уровень усиления = 0 дБм.
  • RF24_PA_ERROR — уровень усиления не определён.

setCRCLength()

Установить размер CRC (циклически избыточный код).

void RF24::setCRCLength(rf24_crclength_e length);

Параметры
length — Размер, задаётся одной из констант: RF24_CRC_8 — под CRC отводится 8 бит (CRC-8) или RF24_CRC_16 — под CRC отводится 16 бит (CRC-16).

getCRCLength()

Получить текущий размер CRC (циклически избыточный код).

rf24_crclength_e RF24::getCRCLength(void);

Возвращает
значение одной из констант сопоставленной размеру CRC: RF24_CRC_8 — под CRC отводится 8 бит (CRC-8), RF24_CRC_16 — под CRC отводится 16 бит (CRC-16) или RF24_CRC_DISABLED — передача и проверка CRC отключены.

disableCRC()

Отключить передачу CRC передатчиком и проверку данных приёмником.

void RF24::disableCRC(void);

setPayloadSize()

Установить статичный размер блока данных пользователя в байтах.

void RF24::setPayloadSize(uint8_t size);

Параметры
size — Размер блока данных пользователя в байтах.

getPayloadSize()

Получить текущий статичный размер блока данных пользователя в байтах.

uint8_t RF24::getPayloadSize(void);

Возвращает
текущий статичный размер блока данных от 0 до 32 байт.

getDynamicPayloadSize()

Получить размер блока данных в последнем принятом пакете.

uint8_t RF24::getDynamicPayloadSize(void);

Возвращает
размер данных последнего принятого пакета в байтах.

enableDynamicPayloads()

Разрешить динамически изменяемый размер блока данных для всех труб.

void RF24::enableDynamicPayloads(void);

enableDynamicAck()

Разрешить отказываться от запроса пакетов подтверждения приёма.

void RF24::enableDynamicAck(void);

enableAckPayload()

Разрешить размещать данные пользователя в пакете подтверждения приёма.

void RF24::enableAckPayload(void);

setAutoAck()

Управление автоматической отправкой пакетов подтверждения приёма данных.

void RF24::setAutoAck(bool enable);
void RF24::setAutoAck(uint8_t pipe, bool enable);

Параметры
pipe — номер трубы, для которой разрешается / запрещается автоматическая отправка пакетов подтверждения приема. Указывается только на стороне приёмника. Если номер трубы на стороне приёмника не указан, то действие функции распространяется на все трубы.
enable — Флаг разрешающий автоматическую отправку пакетов подтверждения приёма данных. true — разрешить / false — запретить.

setAddressWidth()

Указать длину адресов труб в байтах.

void RF24::setAddressWidth(uint8_t a_width);

Параметры
a_width — Размер адреса трубы в байтах, представлен числом 3, 4 или 5.

setRetries()

Указать максимальное количество попыток отправки данных и время ожидания.

void RF24::setRetries(uint8_t delay, uint8_t count);

Параметры
delay — целое число от 0 до 15 определяющее время ожидания подтверждения приема.
count — целое число от 1 до 15 определяющее максимальное количество попыток доставить данные передатчику.

powerDown()

Перейти в режим пониженного энергопотребления.

void RF24::powerDown(void);

powerUp()

Выйти из режима пониженного энергопотребления.

void RF24::powerUp(void);

isPVariant()

Проверить аппаратную совместимость модуля с функциями nRF24L01.

bool RF24::isPVariant(void);

Возвращает
(true / false) флаг указывающий на совместимость аппаратного обеспечения модуля с функциями чипа nRF24L01+.

writeFast()

Быстро отправить данные по радиоканалу.

bool RF24::writeFast(const void * buf, uint8_t len);
bool RF24::writeFast(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
Возвращает
результат записи данных в буфер для передачи (true / false).

writeBlocking()

Быстро отправить данные по радиоканалу с указанием таймаута.

bool RF24::writeBlocking(const void * buf, uint8_t len, uint32_t timeout);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
timeout — Максимальное время ожидания освобождения буфера FIFO в миллисекундах.
Возвращает
результат записи данных в буфер для передачи (true / false).

startFastWrite()

Начать быструю отправку данных.

void RF24::startFastWrite(const void * buf, uint8_t len, const bool multicast, bool startTx = 1);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
startTx — флаг перехода в режим TX или STANDBY-II. Если не указан, значит установлен.

startWrite()

Начать отправку данных.

void RF24::startWrite(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.

txStandBy()

Подождать пока передаются данные и вернуть результат.

bool RF24::txStandBy(void);
bool RF24::txStandBy(uint32_t timeout, bool startTx = 0);

Параметры
timeout — максимальное время ожидания указывается в миллисекундах.
Возвращает
результат передачи данных из буферов FIFO в радиоканал (true / false).

rxFifoFull()

Проверить не заполнены ли все три буфера FIFO.

bool RF24::rxFifoFull(void);

Возвращает
флаг указывающий на то что все буферы FIFO заполнены.

flush_tx()

Очистка буферов FIFO.

uint8_t RF24::flush_tx(void);

reUseTX()

Повторная отправка данных из буфера FIFO, если они там есть.

void RF24::reUseTX(void);

testCarrier()

Проверка наличия несущей частоты на выбранном канале (частоте).

bool RF24::testCarrier(void);

Возвращает
наличие несущей на выбранном канале за все время его прослушивания.

testRPD()

Проверка наличия любого сигнала выше -64 дБм на выбранном канале (частоте).

bool RF24::testRPD(void);

Возвращает
наличие сигнала мощностью выше -64 дБм на выбранном канале за все время его прослушивания.

isValid()

Проверить используется ли модуль или выполняется отладка кода.

bool RF24::isValid(void);

Возвращает
назначение редактируется (true / false).

Схема подключения nRF24L01+ к Arduino

Подключается nRF24L01+ к Arduino по шине SPI (можно использовать как аппаратную так и программную шину). Выводы модуля Vcc и GND подключаются к шине питания 3.3 В постоянного тока. Выводы модуля MISO, MOSI и SCK подключаются к одноименным выводам шины SPI на плате Arduino. Выводы SS (Slave Select) и CE (Chip Enable) назначаются при объявлении объекта библиотеки RF24 и подключаются к любым назначенным выводам Arduino.

Подключить nRF24L01+ к Arduino можно как напрямую, так и через специальный адаптер.

Подключение nRF24L01+ к Arduino напрямую

Подключение nRF24L01+ к Arduino UNO напрямую

Внимание!

  • Необходимо помнить, что модуль работает от 3.3 В и в нем нет защиты от переполюсовки, если не соблюдать два этих правила, можно сжечь модуль!
  • Для стабильной работы модуля NRF24L01+ необходимо припаять конденсатор на 10 мкФ между VCC и GND.

nRF24L01+ - электролитический конденсатор емкостью 100 мкФ

nRF24L01+ Arduino UNO/Pro Mini Arduino MEGA2560
GND GND GND
VCC 3.3V 3.3V
CE 9 9
CSN 10 53
SCK 13 52
MOSI 11 51
MISO 12 50
IRQ

Подключение nRF24L01+ к Arduino через адаптер

Адаптер nRF24L01+ Arduino UNO/Pro Mini Arduino MEGA2560
GND GND GND
VCC 5.0V 5.0V
CE 9 9
CSN 10 53
SCK 13 52
MO/MOSI 11 51
MI/MISO 12 50
IRQ

Примеры

Обмен данными между двумя платами Arduino UNO и Pro Mini через nRF24L01+

Пример 1: Проверочный скетч

/*
  Подключаем файл настроек из библиотеки RF24.
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку для работы с nRF24L01+.
*/
#include <RF24.h>
#include <printf.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  printf_begin();
  /*
    Инициируем работу модуля nRF24L01+.
  */
  radio.begin();
  if (radio.isPVariant()) {
    /*
      Если модуль поддерживается библиотекой RF24,
      то выводим текст «Модуль nRF24L01 подключен».
    */
    Serial.println("Модуль nRF24L01 подключен");
    /*
      Дамп конфигурации RF для отладки
    */
    radio.printDetails();
  } else {
    /*
      Иначе, если модуль не поддерживается,
      то выводи текст «Неизвестный модуль».
    */
    Serial.println("Неизвестный модуль");
  }
}

void loop() {
}

Результат

Подключение модуля nRF24L01+ к Arduino - Проверочный скетч, Результат

Если после загрузки проверочного скетча увидели, в окне монитора последовательного порта, надпись «Модуль nRF24L01 подключен», значит Ваш модуль поддерживается библиотекой RF24. Если Вы увидели надпись «Неизвестный модуль», проверьте подключение модуля к Arduino. В скетче указано что вывод «CE» (Chip Enable) модуля подключается к выводу 7 Arduino, а вывод SS (Slave Select) модуля подключается к выводу 10 Arduino. При необходимости измените выводы на другие. Если модуль подключён правильно, значит он собран на чипе отличном от nRF24L01.

Пример 2: Передача данных

В функции setup() данного примера модулю задаются основные настройки:

  • по умолчанию модуль работает в качестве передатчика;
  • 0x30 канал;
  • скорость 1 Мбит/сек (RF24_1MBPS);
  • максимальная мощности (RF24_PA_MAX);
  • адрес трубы 0x0123456789LL.

На стороне приёмника нужно указать тот же номер канала, скорость передачи, мощность и адрес трубы.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
   Объявляем массив для хранения и передачи данных
   (до 32 байт включительно).
*/
int dataToBeTransmitted[5] = {'0', '1', '2', '3', '4'};

void setup() {
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);

  /*
     Открываем трубу с адресом 0x0123456789LL для передачи данных
     (передатчик может одновременно вещать только по одной трубе).
  */
  radio.openWritingPipe(0x0123456789LL);
}

void loop() {
  /*
     Отправляем данные из массива dataToBeTransmitted
     указывая весь размер массива в байтах.
  */
  radio.write(&dataToBeTransmitted, sizeof(dataToBeTransmitted));
  /*
     Устанавливаем задержку на 1000 мс.
  */
  delay(1000);
}

Пример 3: Получение данных от одного передатчика

В коде setup() приёмника задаются такие же настройки как и передатчику (канал, скорость, мощность передатчика).

  • 0x30 канал;
  • скорость 1 Мбит/сек (RF24_1MBPS);
  • максимальная мощности (RF24_PA_MAX);
  • адрес трубы 0x0123456789LL, для приёма данных.

Чтобы включить прослушивание труб, нужно вызвать startListening(), метод переводит модуль в режим работы приёмника. Если далее вызвать stopListening(), то модуль перейдёт в режим работы передатчика.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
  Объявляем массив для хранения и передачи данных
  (до 32 байт включительно).
*/
int receivedData[5];

/*
  Объявляем переменную в которую будет сохраняться
  номер трубы по которой приняты данные.
*/
uint8_t pipe;

uint8_t i;

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);
  /*
    Открываем 1 трубу с адресом 1 передатчика 0x0123456789LL, для приема данных.
  */
  radio.openReadingPipe(1, 0x0123456789LL);
  /*
    Включаем приемник, начинаем прослушивать открытые трубы.
  */
  radio.startListening();
}

void loop() {
  /*
    Если в буфере имеются принятые данные, то получаем номер трубы
    по которой эти данные пришли в переменную pipe.
  */
  if (radio.available(&pipe)) {
    /*
      Читаем данные из буфера в массив receivedData указывая
      сколько всего байт может поместиться в массив.
    */
    radio.read(&receivedData, sizeof(receivedData));
    /*
      Если данные пришли от 1 передатчика (по 1 трубе),
      то можно выполнить соответствующее действие ...
    */
    Serial.print("Данные [ ");
    for (i = 0; i < 5; i++) {
      Serial.print((char) receivedData[i]);
      Serial.print(' ');
    }
    Serial.print("] пришли по трубе ");
    Serial.println(pipe);
  }
}

Результат

Подключение модуля nRF24L01+ к Arduino - Приём данных, Результат

Пример 4: Передача данных с проверкой их доставки

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
   Объявляем массив для хранения и передачи данных
   (до 32 байт включительно).
*/
uint8_t dataToBeTransmitted[5] = {'0', '1', '2', '3', '4'};

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);

  /*
     Открываем трубу с адресом 0x0123456789LL для передачи данных
     (передатчик может одновременно вещать только по одной трубе).
  */
  radio.openWritingPipe(0x0123456789LL);
}

void loop() {
  /*
     Отправляем данные из массива dataToBeTransmitted
     указывая весь размер массива в байтах.
  */
  if (radio.write(&dataToBeTransmitted, sizeof(dataToBeTransmitted))) {
    /*
       Данные передатчика были корректно приняты приёмником
    */
    Serial.println("Данные были корректно приняты приёмником");
  } else {
    /*
       Данные передатчика не приняты или дошли с ошибкой CRC
    */
    Serial.println("Данные не приняты или дошли с ошибкой CRC");
  }
  /*
     Устанавливаем задержку на 1000 мс.
  */
  delay(1000);
}

Результат

Подключение модуля nRF24L01+ к Arduino - Передача данных с проверкой, РезультатСкетч данного примера отличается от предыдущего только кодом loop() где функция write() вызывается в условии оператора if(). Дело в том, что функция write() не только отправляет данные, но и возвращает true (если данные были доставлены) или false (если данные не доставлены). По умолчанию передача данных реализована так, что передатчик не только отправляет данные, но и запрашивает у приёмника подтверждение их получения, а приёмник получив данные и проверив CRC, возвращает передатчику пакет подтверждения приема данных. Таким образом на стороне передатчика можно контролировать факт доставки данных приёмнику.

Если не нужно определить факт доставки данных приёмнику, можете заменить write() на writeFast().

/*
   Отправляем данные из массива dataToBeTransmitted 
   указывая сколько байт массива мы хотим отправить.
 */
radio.writeFast(&dataToBeTransmitted, sizeof(dataToBeTransmitted));

writeFast() принимает те же параметры что и write(), но возвращает не флаг доставки данных приёмнику, а флаг записи данных в буфер FIFO. Значит в большинстве случаев функция вернёт true даже до того как приёмник получит данные. Если же все три буфера FIFO заполнены, то функция writeFast() ждёт пока один из них не освободится или пока не истечёт время таймаута но и это ожидание на порядок меньше чем у функции write().

Запретить отправку пакетов подтверждения приёма можно и на стороне приёмников, вызвав у них функцию setAutoAck(false) или setAutoAck(номер_трубы, false). Но в таком случае и на стороне передатчика нужно вызвать функцию setAutoAck(false) иначе приёмник не будет понимать что ему прислал передатчик.

Пример 5: Получение данных от одного или нескольких передатчиков

Приёмнику можно задать до 6 труб функцией openReadingPipe(номер, адрес) с номерами труб от 0 до 5 и адресами труб совпадающими с адресами труб передатчиков.

/*...*/
radio.openReadingPipe(0, 0x0123456789LL);
radio.openReadingPipe(1, 0x0123456799LL);
radio.openReadingPipe(2, 0x012345679ALL);
radio.openReadingPipe(3, 0x01234567AALL);
radio.openReadingPipe(4, 0x01234567ABLL);
radio.openReadingPipe(5, 0x01234567BBLL);
/*...*/

Сколько труб Вы укажете, столько передатчиков будет слушать приёмник.

Методом available() осуществляется проверка получения данных. Метод возвращает true если в буфере есть принятые данные доступные для чтения. В качестве необязательного аргумента можно указать адрес переменной в которую будет помещён номер трубы по которой были приняты данные (в примере используется адрес переменной &pipe), зная номер трубы мы знаем от какого передатчика пришли данные.

if(radio.available(&pipe)) {
  /*...*/
}

Если приемник будет принимать данные только от одного передатчика, то переменную pipe можно не использовать, а метод available() можно вызвать без параметра, так как в этом случае не требуется узнавать от какого передатчика приняты данные.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
  Объявляем массив для хранения и передачи данных
  (до 32 байт включительно).
*/
uint8_t receivedData[5];

/*
  Объявляем переменную в которую будет сохраняться
  номер трубы по которой приняты данные.
*/
uint8_t pipe;

uint8_t i;

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);
  /*
    Открываем 1 трубу с адресом 1 передатчика 0x0123456789LL, для приема данных.
  */
  radio.openReadingPipe(1, 0x0123456789LL);
  /*
    Открываем 2 трубу с адресом 2 передатчика 0x0123456799LL, для приема данных.
  */
  radio.openReadingPipe(2, 0x0123456799LL);
  /*
    Включаем приемник, начинаем прослушивать открытые трубы.
  */
  radio.startListening();
}

void loop() {
  /*
    Если в буфере имеются принятые данные, то получаем номер трубы
    по которой эти данные пришли в переменную pipe.
  */
  if (radio.available(&pipe)) {
    /*
      Читаем данные из буфера в массив receivedData указывая
      сколько всего байт может поместиться в массив.
    */
    radio.read(&receivedData, sizeof(receivedData));
    /*
      Если данные пришли от 1 передатчика (по 1 трубе),
      то можно выполнить соответствующее действие ...
    */
    Serial.print("Данные [ ");
    for (i = 0; i < 5; i++) {
      Serial.print((char) receivedData[i]);
      Serial.print(' ');
    }
    Serial.print("] пришли по трубе ");
    Serial.println(pipe);
  }
}

Результат

Подключение модуля nRF24L01+ к Arduino - Получение данных от одного или нескольких передатчиков, Результат

Материалы

Радио модуль NRF24L01+ / PA+LNA 2.4G (Trema-модуль V2.0)
Урок 26.4 Соединяем две arduino по радиоканалу через nRF24L01+
Optimized High Speed NRF24L01+ Driver Class Documenation

Похожие записи

Комментарии 109

  • Спасибо за описание методов. Только здесь нашел.

  • В примере 4 тип данных для отправки uint8_t, а в примере 3 тип данных для приема int. Несколько неожиданно, когда принимается не совсем то что отправляется. ))

    • Да, нужно отправить/получать используя один тип данных, лучше всего использовать uint8_t, но можно использовать любой тип данных, к примеру вам нужно отправить int или double и не хотите вручную преобразовать из 4-х uint8_t в int.

  • вместо RF24 radio(7, 10); должно быть RF24 radio(9, 10);

  • Вовсе не обязательно. Это зависит от того, к каким выводам Ардуино подведены сигналы ce и csn радиомодуля.

  • Спасибо большое! Реально только здесь нашел информацию. Хотелось бы еще увидеть пример с переключением с приема на передачу и обратно.

  • Всегда интересно было, какая каша в голове у тех, кто схему проводками рисует, цветными. Даже на принципиальной схеме разбирать всё это невозможно. При этом распиновку самого модуля не показали..

  • Hi there, I enjoy reading all of your post. I like to write a little comment to support you.

  • Thank you for sharing your article with us. If you’re an investor in mutual funds and wish to gauge the rate of return over time, consider using a CAGR calculator . This tool provides a stable perspective on mutual fund performance, assisting in comprehending and monitoring investment growth. To delve into CAGR further, visit the article link.

  • Hey there, You’ve done an excellent job. I will certainly digg it
    and personally suggest to my friends. I am sure they’ll be benefited from this website.

  • Truly many of good information.

  • Reduslim: Ihr Partner für Gesundheit und Wohlbefinden!

    Sind Sie auf der Suche nach einer natürlichen und effektiven Lösung,
    um Ihre Gesundheit zu fördern und Ihr Wohlbefinden zu steigern?
    Dann ist Reduslim genau das Richtige für Sie! Unser Produkt steht für Qualität und
    Natürlichkeit und hilft Ihnen, Ihren Körper auf gesunde Weise
    in Form zu bringen.

    Reduslim ist nicht nur ein Produkt, sondern ein Versprechen für ein besseres Leben. Dank seiner einzigartigen Zusammensetzung aus natürlichen Inhaltsstoffen unterstützt Reduslim Ihren Körper
    dabei, effizienter zu arbeiten und fördert gleichzeitig eine gesunde Gewichtsabnahme.
    Egal, ob Sie sich fit halten, Gewicht verlieren oder einfach nur gesünder leben möchten, Reduslim ist Ihr idealer Begleiter.

    Unsere Formel ist das Ergebnis intensiver Forschung und Entwicklung.
    Sie kombiniert die besten natürlichen Inhaltsstoffe, die
    nicht nur wirksam, sondern auch sicher sind.
    Mit Reduslim erhalten Sie ein Produkt, das keine künstlichen Zusatzstoffe oder schädlichen Chemikalien enthält.
    So können Sie sicher sein, dass Sie Ihrem Körper nur
    das Beste geben.

    Reduslim ist mehr als nur ein Gewichtsverlustprodukt.
    Es ist eine Investition in Ihre Gesundheit und Ihr Wohlbefinden. Dank seiner natürlichen Zusammensetzung trägt Reduslim
    dazu bei, Ihren Stoffwechsel zu optimieren, Ihr Energieniveau zu erhöhen und
    Ihr allgemeines Wohlbefinden zu verbessern.

    Warten Sie nicht länger, um die Vorteile von Reduslim Expressversand zu
    erleben. Bestellen Sie noch heute und beginnen Sie Ihren Weg
    zu einem gesünderen, glücklicheren Ich!

  • Fascinating blog! Is your theme custom made or did you download it from somewhere?
    A design like yours with a few simple adjustements would
    really make my blog shine. Please let me know where you got your theme.
    Many thanks

  • I am not sure where you are getting your info, but great topic.
    I needs to spend some time learning more or understanding
    more. Thanks for excellent info I was looking
    for this information for my mission.

  • I like the helpful info you supply for your articles.
    I will bookmark your blog and test once more right
    here regularly. I’m relatively certain I’ll be informed a lot of
    new stuff proper right here! Good luck for the next!

  • Selam admin, geçici bir WiFi ağına bağlanıp bu yorumu yapıyorum. E postama 2 tane güncel Kazandirio kodu gönderir misin acaba? 동해출장샵League of Legends Wild Rift oynayarak dereceli basamaklarını tırmanmaktan geri kalmak istemiyorum şimdiden teşekkür ederim.

  • Если вам нужно построение отдела продаж важно учесть несколько
    ключевых шагов и аспектов.
    Вот некоторые рекомендации: Определение целей и стратегии: Начните с определения целей,
    которые вы хотите достичь с помощью отдела продаж.
    Разработайте стратегию, которая будет направлена на достижение этих целей.

    Учтите, какие рынки и сегменты вы хотите охватить.

    Создание организационной структуры:
    Решите, какую структуру будет
    иметь ваш отдел продаж. Она может быть функциональной, географической или
    комбинированной. Уделите внимание
    ролям и обязанностям сотрудников.

    Найм и обучение персонала: Подберите квалифицированных сотрудников с опытом в продажах или предоставьте им
    обучение. Эффективные продавцы играют
    ключевую роль в успехе отдела.
    Выбор и внедрение CRM-системы: Внедрение Customer Relationship Management
    (CRM) системы поможет отслеживать
    взаимодействие с клиентами, управлять лидами и анализировать данные.

    Разработка процессов продаж: Определите процессы продаж от начала до конца, включая генерацию лидов, ведение переговоров и заключение сделок.

    Мониторинг и анализ: Установите систему мониторинга и
    анализа результатов, чтобы постоянно улучшать эффективность
    вашего отдела продаж.
    Важно помнить, что построение отдела продаж – это непрерывный процесс, и его развитие требует постоянного внимания и адаптации
    к изменяющимся условиям на рынке.

    4J8kazM9

  • Whoa! This blog looks exactly like my old one!
    It’s on a completely different subject but it has pretty much the
    same layout and design. Wonderful choice of colors!

  • Thanks for every other excellent article. Where else may just anyone get that type of info in such a perfect approach of writing?
    I’ve a presentation next week, and I am on the search for such information.

  • I am not sure where you are getting your information,
    but great topic. I needs to spend some time learning much more or understanding more.
    Thanks for wonderful info I was looking for this information for my mission.

  • When I originally commented I clicked the «Notify me when new comments are added» checkbox and now each time a comment is added I get three e-mails
    with the same comment. Is there any way you can remove people
    from that service? Many thanks!

  • It’s fantastic that you are getting ideas from this post as well
    as from our dialogue made here.

  • At this time it appears like Drupal is the top blogging platform available right
    now. (from what I’ve read) Is that what you’re using
    on your blog?

  • Thanks for sharing your thoughts on pocket option. Regards

  • With havin so much content and articles do you ever run into any issues of plagorism or copyright violation? My site has a lot of exclusive content I’ve either
    authored myself or outsourced but it seems a lot of it is
    popping it up all over the web without my agreement.
    Do you know any techniques to help prevent content from being ripped off?
    I’d certainly appreciate it.

  • My brother recommended I might like this website.
    He was entirely right. This publish truly made my
    day. You cann’t believe just how so much time I had spent
    for this info! Thank you!

  • Its like you read my mind! You appear to know a lot about this, like you wrote
    the book in it or something. I think that you could do with some pics to drive the message home a little bit, but
    other than that, this is magnificent blog. An excellent read.
    I will certainly be back.

  • I’ve been exploring for a little for any high quality
    articles or blog posts in this kind of area . Exploring in Yahoo I at last stumbled upon this website.

    Studying this info So i’m satisfied to convey that I have a very good uncanny feeling I found out
    exactly what I needed. I such a lot without a doubt will make certain to don?t forget this site and provides it a glance
    on a relentless basis.

  • Attractive portion of content. I simply stumbled upon your
    weblog and in accession capital to claim that I get actually loved account your blog posts.

    Anyway I will be subscribing in your augment and even I success you get entry
    to consistently fast.

  • I don’t know whether it’s just me or if perhaps everyone else encountering problems with
    your blog. It appears as though some of the text in your posts are running off the screen. Can somebody else please provide feedback and let me know if
    this is happening to them too? This may be a issue with my internet browser because I’ve had this happen before.
    Kudos

  • This is really interesting, You’re a very skilled
    blogger. I’ve joined your feed and look forward to seeking more of your great post.
    Also, I’ve shared your site in my social networks!

  • Keep this going please, great job!

  • I’ve learn a few excellent stuff here. Definitely worth bookmarking for revisiting.
    I surprise how so much attempt you put to create
    this type of wonderful informative website.

  • This is a very good tip especially to those fresh to the blogosphere.
    Short but very accurate info… Thanks for sharing this one.

    A must read article!

  • Hi there! I just wanted to ask if you ever have any trouble with hackers?
    My last blog (wordpress) was hacked and I ended up losing many months of
    hard work due to no data backup. Do you have any solutions to prevent hackers?

  • This is a very good tip especially to those fresh to the blogosphere.
    Brief but very accurate information… Thank you for sharing this one.
    A must read article!

  • I like the helpful info you provide in your articles.
    I will bookmark your weblog and check again here regularly.
    I am quite sure I will learn many new stuff right here!
    Best of luck for the next!

  • My brother recommended I might like this web site. He was entirely
    right. This post truly made my day. You can not imagine just how much time I had
    spent for this information! Thanks!

  • Appreciate this post. Will try it out.

  • Your style is so unique compared to other folks I
    have read stuff from. Thanks for posting when you’ve got the opportunity,
    Guess I will just bookmark this web site.

  • Definitely imagine that that you said. Your favourite justification appeared
    to be at the internet the simplest factor to understand of.
    I say to you, I definitely get irked even as other people think about worries that they just do not realize about.
    You controlled to hit the nail upon the top and also defined out the whole thing without
    having side-effects , folks can take a signal.
    Will probably be again to get more. Thanks

    Feel free to visit my blog post … Flat Roof Toronto

  • This is really interesting, You are a very skilled blogger.
    I’ve joined your feed and look forward to seeking more of
    your great post. Also, I’ve shared your site in my social networks!

  • First of all I want to say fantastic blog! I had a quick question which I’d like to ask if you do not mind.
    I was interested to know how you center yourself and clear your mind prior
    to writing. I have had a hard time clearing my mind in getting my
    thoughts out there. I truly do take pleasure in writing however it just seems like the
    first 10 to 15 minutes are wasted simply just trying to figure out how
    to begin. Any suggestions or tips? Thanks!

  • I have been exploring for a little for any high quality articles or weblog posts in this sort of area .
    Exploring in Yahoo I ultimately stumbled upon this web site.
    Studying this info So i’m satisfied to express that I’ve an incredibly good uncanny feeling I came upon exactly what I needed.
    I such a lot without a doubt will make certain to do not put out of your mind this web site and
    provides it a glance regularly.

  • Creating a 1,000-word article with specific instructions
    to use LSI (Latent Semantic Indexing) keywords in a spintax format for «Leak Repair in Phoenix, Arizona» presents an innovative approach to content
    creation. This method not only ensures the inclusion of
    a variety of related terms but also allows for the generation of unique versions of the content.
    Here’s a condensed example that illustrates how to integrate these
    elements into a comprehensive article. For the full 1,
    000 words, this snippet will serve as a foundation.

    In the heart of the Sonoran Desert, Phoenix, Arizona, battles with its fair share of heat and, surprisingly, water leak
    issues. Whether it’s the scorching summer temperatures affecting plumbing or
    the rare but impactful rainstorms, plumbing repair becomes a critical service for homeowners
    and businesses alike. This article delves into the essentials of pipe repair services in Phoenix, highlighting
    the importance of timely intervention, the process
    of drainage repair, and tips for leak prevention.

    The Critical Nature of Leak Detection in Phoenix
    Phoenix’s unique climate poses distinct challenges for waterproofing efforts.

    The extreme heat can cause pipes to expand and contract, leading to leaks
    that are not only a nuisance but can also cause significant water
    loss and damage. Early water leak detection is crucial.

    Professionals equipped with the latest technology can pinpoint leaks without invasive
    digging or wall-breaking, saving time and money.

    Comprehensive Leak Repair Services
    When it comes to fixing leaks, Phoenix residents have access to a wide range of services.
    From pipe repair to structural repair, it’s essential to
    choose a service provider who can offer a comprehensive solution. Techniques such as leak sealing are employed to ensure a
    long-lasting repair, preventing future issues and water damage restoration.

    The Importance of Professional Leak Diagnosis
    A thorough moisture control is the first
    step in effectively addressing a leak. Professionals
    in Phoenix use advanced methods to identify the source and extent of the leak.
    This accurate diagnosis is crucial for applying the correct plumbing repair techniques, ensuring that the repair addresses the root cause of the problem.

    Preventing Leaks: Tips and Strategies
    Leak prevention is key to avoiding the inconvenience and cost
    of repairs. Regular plumbing maintenance can identify potential issues before they become major problems.
    Additionally, installing moisture control measures, especially in critical areas such
    as basements and roofs, can significantly reduce the risk of leaks.

    Choosing the Right Leak Repair Service in Phoenix
    With numerous options available, selecting the right leak repair service in Phoenix can be daunting.
    Look for companies with a strong reputation, extensive experience, and positive customer reviews.

    A provider offering a range of services, from drainage repair to water damage restoration,
    ensures that you have access to comprehensive care for any leak-related issue.

    Conclusion
    Leak repair in Phoenix, Arizona, requires a proactive and informed
    approach. Understanding the significance of early leak diagnosis
    and the benefits of professional roof leak repair services can save property owners time
    and money. By following tips for leak prevention and choosing a reputable service provider, residents can protect their homes and
    businesses from the potential damages caused by
    leaks. Remember, in the battle against leaks, knowledge, and
    preparation are your best allies.

  • That is very fascinating, You’re an excessively professional blogger.
    I have joined your feed and look forward to in the hunt
    for extra of your wonderful post. Additionally, I have shared your
    website in my social networks

  • Thank you for the good writeup. It in fact was a amusement account it.
    Look advanced to more added agreeable from you!
    However, how could we communicate?

  • Oh my goodness! Awesome article dude! Thank you, However I am having troubles
    with your RSS. I don’t understand the reason why I am unable to subscribe to it.
    Is there anybody getting identical RSS issues?
    Anybody who knows the answer will you kindly respond?
    Thanx!!

  • I am genuinely pleased to glance at this web site posts which contains tons of valuable data,
    thanks for providing these information.

  • Wow! This blog looks just like my old one!
    It’s on a totally different subject but it has pretty much the same layout and design. Superb
    choice of colors!

  • Hi, this weekend is nice for me, for the reason that this
    moment i am reading this fantastic informative piece of writing here at my house.

  • I feel that is one of the so much important information for me.

    And i am glad reading your article. However want to observation on few general issues, The site taste is great, the articles is in reality
    excellent : D. Excellent task, cheers

  • wonderful issues altogether, you just received a new reader.
    What might you suggest about your publish that you made a
    few days ago? Any sure?

  • What a material of un-ambiguity and preserveness of precious knowledge regarding unexpected emotions.

  • Right here is the right blog for anybody who wishes to understand this topic.
    You realize so much its almost hard to argue with you (not that I personally will need to…HaHa).

    You definitely put a new spin on a topic which has been written about for a long time.
    Wonderful stuff, just excellent!

  • Thank you for every other informative web site. Where else could I
    am getting that type of info written in such a perfect
    means? I’ve a challenge that I am simply now running on, and I’ve been at the look out for such info.

  • Oh my goodness! Impressive article dude!
    Thanks, However I am having difficulties with
    your RSS. I don’t understand the reason why I can’t subscribe to it.
    Is there anyone else having the same RSS issues?

    Anybody who knows the solution can you kindly respond?
    Thanks!!

  • I like looking through a post that will make men and women think.
    Also, thanks for allowing me to comment!

  • Hi there to all, the contents existing at this web site are
    actually remarkable for people knowledge, well, keep up
    the good work fellows.

  • I used to be able to find good info from your content. Click

  • What’s up to every one, the contents present at this website are actually amazing for people experience, well, keep up
    the good work fellows.

  • We absolutely love your blog and find most of your post’s
    to be just what I’m looking for. Does one offer guest writers to write content available for you?
    I wouldn’t mind writing a post or elaborating on many of the subjects you write
    concerning here. Again, awesome site!

  • you are actually a good webmaster. The site loading speed is amazing.
    It sort of feels that you’re doing any distinctive
    trick. In addition, The contents are masterpiece.
    you have done a excellent process in this topic!

  • This post will help the internet visitors for setting up new web
    site or even a blog from start to end.

  • Keep on working, great job!

  • What’s up, I would like to subscribe for this webpage to take most up-to-date updates, so where
    can i do it please assist.

  • It’s actually a great and helpful piece of information. I’m satisfied that
    you just shared this helpful information with us.
    Please stay us informed like this. Thanks for sharing.

  • Superb website you have here but I was curious if you knew
    of any message boards that cover the same topics talked
    about in this article? I’d really love to be a part of group where I can get feedback from other experienced individuals that share the same interest.
    If you have any suggestions, please let me know. Thank you!

  • excellent points altogether, you simply gained a new reader.
    What might you recommend in regards to your post
    that you simply made some days ago? Any certain?

  • Thank you for sharing your info. I truly appreciate your efforts and I will be waiting for your further post thank you once again.

  • I’m extremely impressed with your writing skills and also with the structure for your
    weblog. Is this a paid topic or did you customize it yourself?
    Anyway stay up the excellent high quality writing, it’s rare to look a great
    weblog like this one nowadays..

  • Hi, i feel that i noticed you visited my site thus i came to
    go back the choose?.I’m attempting to to find issues to improve my site!I assume its adequate to make use of
    a few of your ideas!!

  • It’s remarkable designed for me to have a website, which is
    good in favor of my experience. thanks admin

  • Definitely consider that which you said. Your favorite reason seemed to be on the web
    the simplest thing to take into accout of. I say to you, I
    certainly get annoyed whilst folks consider issues that they
    plainly don’t recognize about. You managed to hit the nail upon the highest and outlined out the whole thing without having side-effects , folks can take a signal.
    Will probably be back to get more. Thanks

  • Nice post. I learn something new and challenging on websites I stumbleupon everyday.
    It will always be exciting to read content from other authors and use a
    little something from their websites.

  • Услуга по сносу старых домов и утилизации мусора в Москве и Московской области. Мы предлагаем услуги по сносу старых построек и удалению отходов на территории Москвы и Московской области. Услуга демонтаж дачи предоставляется опытными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на веб-сайте компании.

  • Услуга по сносу старых зданий и утилизации отходов в Москве и Московской области. Мы предоставляем услуги по сносу старых сооружений и удалению мусора на территории Москвы и Московской области. Услуга демонтаж и вывоз мусора цена выполняется квалифицированными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на сайте компании.

  • Услуга по сносу старых зданий и утилизации отходов в Москве и Московской области. Мы предоставляем услуги по сносу старых сооружений и удалению мусора на территории Москвы и Московской области. Услуга разбор дома выполняется квалифицированными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на сайте компании.

  • Услуга по сносу старых зданий и утилизации отходов в Москве и Московской области. Мы предоставляем услуги по сносу старых сооружений и удалению мусора на территории Москвы и Московской области. Услуга убрать фундамент выполняется квалифицированными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на сайте компании.

  • Do you have a spam issue on this site; I also am a blogger, and I was curious about your situation; many of us have developed
    some nice procedures and we are looking to trade strategies with other
    folks, be sure to shoot me an email if interested.

  • I aam really enjoying the theme/design of your blog.

    Do you ever run into any internet browser compatibility issues?
    A number of my blog audience havbe complained about my site not working correctly in Explorer
    but looks great in Opera. Do you have any solutions to help
    fix this issue?

    Also visit my webb site … 토토가이드

  • If some one wants to be updated with latest technologies then he must be pay a visit this web site and be up
    to date daily.

  • What’s up to every one, it’s truly a pleasant for me to visit this web site, it consists of precious Information.

  • Thanks for the auspicious writeup. It in reality was a amusement account it.
    Glance advanced to far added agreeable from you! By the way, how can we be in contact?

  • Услуга по сносу старых зданий и утилизации отходов в Москве и Московской области. Мы предоставляем услуги по сносу старых сооружений и удалению мусора на территории Москвы и Московской области. Услуга демонтаж домов в московской области выполняется квалифицированными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на сайте компании.

  • Услуга по сносу старых зданий и утилизации отходов в Москве и Московской области. Мы предоставляем услуги по сносу старых сооружений и удалению мусора на территории Москвы и Московской области. Услуга сломать фундамент выполняется квалифицированными специалистами в течение 24 часов после оформления заказа. Перед началом работ наш эксперт бесплатно посещает объект для определения объёма работ и предоставления консультаций. Чтобы получить дополнительную информацию и рассчитать стоимость услуг, свяжитесь с нами по телефону или оставьте заявку на сайте компании.

  • Excellent article! We are linking to this great content on our
    website. Keep up the good writing.

  • What’s up, yup this article is really good and I have
    learned lot of things from it regarding blogging.
    thanks.

  • An intriguing discussion is definitely worth comment. I believe that you need
    to publish more about this issue, it might not be a taboo
    subject but typically people don’t talk about
    these subjects. To the next! Kind regards!!

  • My partner and I stumbled over here coming from a different web page and thought I might as well check things out.
    I like what I see so now i am following you. Look forward to exploring your web page for
    a second time.

  • I visited several sites except the audio feature for audio
    songs present at this site is truly fabulous.

  • It’s actually a nice and useful piece of info.
    I am satisfied that you simply shared this useful information with us.
    Please stay us informed like this. Thanks for sharing.

  • I am extremely inspired along with your writing talents and also with the structure on your blog.
    Is that this a paid subject or did you modify it your self?
    Anyway stay up the excellent high quality writing, it is uncommon to peer a
    nice weblog like this one these days..

  • Someone necessarily assist to make critically articles I would
    state. That is the first time I frequented your web page and up
    to now? I amazed with the research you made to make this particular publish extraordinary.
    Magnificent job!

  • Its such as you learn my mind! You appear to grasp a lot about
    this, such as you wrote the guide in it or something.
    I feel that you just can do with some percent to force the message house
    a little bit, but instead of that, that is excellent blog.
    An excellent read. I will certainly be back.

  • Hi there, just became aware of your blog through Google, and found that it’s truly informative.
    I am going to watch out for brussels. I will be grateful if you continue this in future.

    Many people will be benefited from your writing. Cheers!

  • This is a very good tip especially to those new to the blogosphere.
    Short but very accurate info… Thank you for sharing this one.

    A must read post!

  • I love your blog.. very nice colors & theme. Did you design this website yourself
    or did you hire someone to do it for you? Plz reply as I’m looking to
    construct my own blog and would like to find out where u got this from.
    thanks

  • They are very enthusiastic about this; you may be too—time to release the stress,
    time for some real enjoyable.

  • mostbet azerbaycan (https://tropicalbrasiljeri.com.br/)
    yukle basketbol mərcləri üçün lap əla platforma ilə tanış
    ola bilərsiniz!

Добавить комментарий для law firm turkish citizenship by investment Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *