nRF24L01 один из самых популярных беспроводных модулей для интернета вещей (IoT). Подключение модуля nRF24L01+ к Arduino позволит организовать многоканальную защищенную связь между Arduino и устройствами на расстоянии. Рассмотрим, как наладить связь между двумя или несколько плат Ардуино по радиоканалу.
- 1 Установка библиотеки RF24
- 2 Описание методов библиотеки RF24
- 2.1 begin()
- 2.2 startListening()
- 2.3 stopListening()
- 2.4 available()
- 2.5 isAckPayloadAvailable()
- 2.6 read()
- 2.7 write()
- 2.8 writeAckPayload()
- 2.9 openWritingPipe()
- 2.10 openReadingPipe()
- 2.11 closeReadingPipe()
- 2.12 setChannel()
- 2.13 getChannel()
- 2.14 setDataRate()
- 2.15 getDataRate()
- 2.16 setPALevel()
- 2.17 getPALevel()
- 2.18 setCRCLength()
- 2.19 getCRCLength()
- 2.20 disableCRC()
- 2.21 setPayloadSize()
- 2.22 getPayloadSize()
- 2.23 getDynamicPayloadSize()
- 2.24 enableDynamicPayloads()
- 2.25 enableDynamicAck()
- 2.26 enableAckPayload()
- 2.27 setAutoAck()
- 2.28 setAddressWidth()
- 2.29 setRetries()
- 2.30 powerDown()
- 2.31 powerUp()
- 2.32 isPVariant()
- 2.33 writeFast()
- 2.34 writeBlocking()
- 2.35 startFastWrite()
- 2.36 startWrite()
- 2.37 txStandBy()
- 2.38 rxFifoFull()
- 2.39 flush_tx()
- 2.40 reUseTX()
- 2.41 testCarrier()
- 2.42 testRPD()
- 2.43 isValid()
- 3 Схема подключения nRF24L01+ к Arduino
- 4 Примеры
- 5 Материалы
- 6 Похожие записи
Установка библиотеки RF24
Работать с nRF24L01+ можно с помощью библиотеки RF24 — довольно популярная и удобная библиотека. Скачиваем, распаковываем и закидываем библиотеку RF24 в папку Arduino/libraries. В случае, если на момент добавления библиотеки, Arduino IDE была открытой, перезагружаем среду.
Библиотеку можно установить из самой среды следующим образом:
- В Arduino IDE открываем менеджер библиотек: Скетч->Подключить библиотеку->Управлять библиотеками…
- В строке поиска вводим «RF24», находим библиотеку автора TMRh20, выбираем последнюю версию и кликаем Установить.
- Библиотека установлена (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 напрямую
Внимание!
- Необходимо помнить, что модуль работает от 3.3 В и в нем нет защиты от переполюсовки, если не соблюдать два этих правила, можно сжечь модуль!
- Для стабильной работы модуля NRF24L01+ необходимо припаять конденсатор на 10 мкФ между VCC и GND.
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 | — | — |
Примеры
Пример 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 подключен», значит Ваш модуль поддерживается библиотекой 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); } }
Результат
Пример 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); }
Результат
Скетч данного примера отличается от предыдущего только кодом 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+ / PA+LNA 2.4G (Trema-модуль V2.0)
Урок 26.4 Соединяем две arduino по радиоканалу через nRF24L01+
Optimized High Speed NRF24L01+ Driver Class Documenation
Спасибо за описание методов. Только здесь нашел.
В примере 4 тип данных для отправки uint8_t, а в примере 3 тип данных для приема int. Несколько неожиданно, когда принимается не совсем то что отправляется. ))
Да, нужно отправить/получать используя один тип данных, лучше всего использовать
uint8_t
, но можно использовать любой тип данных, к примеру вам нужно отправитьint
илиdouble
и не хотите вручную преобразовать из 4-хuint8_t
вint
.вместо RF24 radio(7, 10); должно быть RF24 radio(9, 10);
абсолютно не обязательно, у меня работают 7, 8.
Вовсе не обязательно. Это зависит от того, к каким выводам Ардуино подведены сигналы ce и csn радиомодуля.
Спасибо большое! Реально только здесь нашел информацию. Хотелось бы еще увидеть пример с переключением с приема на передачу и обратно.
Всегда интересно было, какая каша в голове у тех, кто схему проводками рисует, цветными. Даже на принципиальной схеме разбирать всё это невозможно. При этом распиновку самого модуля не показали..
Nice blog! Is your theme custom made or did you download
it from somewhere? A design like yours with a few simple tweeks would really make my blog jump out.
Please let me know where you got your design. Bless you
My brother suggested I would possibly like this web site.
He used to be entirely right. This post truly made my day.
You cann’t believe simply how so much time I had spent
for this information! Thanks!
Very nice article, exactly what I wanted to find.
Howdy are using WordPress for your site platform? I’m new to the blog world but I’m trying to get started and create my own. Do you need any html coding knowledge to make your own blog?
Any help would be really appreciated!
YGR หรือ Yes Get Rich คือ เว็บสล็อตออนไลน์ ที่สุดแห่งการเล่นเกมการพนัน ในยุคนี้ โดยนำเสนอเกมที่มีความ สุดปัง และ มีความสนุกสนาน ไม่ว่าว่าจะเป็นสล็อต,
แบล็คแจ็ค และอื่น ๆ ที่มั่นใจได้ว่านักพนันทุกท่านจะ ลุ้นเพลิดเพลิน กับการเล่นเกม เกมนี้ แน่นอน.
เริ่มต้น เล่นเกมส์ กับ ตู้สล็อตออนไลน์
YGR มี ขั้นตอนง่ายๆ เพียงแค่ทำการสมัครสมาชิก จากนั้นก็ เติมเงินเข้าสู่บัญชีของคุณ แล้วคุณก็สามารถ เริ่มการเดิมพัน ทันที ทีมงาน พร้อมบริการ ตลอด24ชั่วโมง รู้ทันทุกรายละเอียด หากมี ความสับสน หรือ ข้อสงสัย ใดๆ ขณะที่ เล่นสล็อตออนไลน์.
YGR ตู้สล็อตออนไลน์สุดปัง มี กลยุทธ์ สำหรับการกระจายเงินรางวัล ไม่มีข้อจำกัดสำหรับการจ่ายโบนัส หรือ จ้างพนัน ที่มีอัตราการจ่ายเงินที่สูง ผู้เล่น สามารถ รู้สึกที่สุด และ รอยืนยันรางวัล ด้วยเล่นผ่านวันที่เอกรูป ใน YGR เราเชื่อว่าการเล่นเกมควร
สนุก และ เป็นกำลังใจ ให้กับผู้เล่น และแน่นอนว่า คุณสามารถทำตัวเองมั่งคั่งจากการเล่นเกมออนไลน์
ในตู้สล็อต YGR — Yes Get Rich.
Feel free to surf to my blog; เกมคาสิโนออนไลน์ที่มีโบนัสและรางวัลแจ็กพอตมากที่สุด
(list.ly)
Pretty nice post. I just stumbled upon your weblog and wished
to say that I’ve really enjoyed surfing around your blog posts.
In any case I will be subscribing to your rss feed and I
hope you write again soon!
RED TIGER เว็บสล็อตเกม ออนไลน์ครบถ้วนทุกทีมที่นี่ คุณก็จะสามารถพักผ่อนด้วยการเล่นสล็อตแต่ละเกมที่คุณต้องการได้โดยสะดวก ไม่จำเป็นต้องไปตามหาที่อื่น
Hello, i think that i saw you visited my blog so i came
to “return the favor”.I am trying to find things to enhance my site!I suppose its ok to
use a few of your ideas!!
Oh my goodness! Incredible article dude! Thanks, However I am encountering issues
with your RSS. I don’t know the reason why
I am unable to join it. Is there anyone else having similar RSS
issues? Anybody who knows the answer will you kindly respond?
Thanx!!
Pretty section of content. I just stumbled upon your site
and in accession capital to assert that I acquire actually enjoyed account your blog
posts. Anyway I’ll be subscribing to your augment and even I achievement you access consistently rapidly.
Hi there everybody, here every one is sharing these
know-how, thus it’s fastidious to read this web site, and I used
to go to see this website all the time.
Hey there would you mind stating which blog platform you’re working with?
I’m planning to start my own blog soon but I’m having a difficult time selecting between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design seems different then most blogs and I’m
looking for something completely unique.
P.S My apologies for being off-topic but I had to ask!
Truly lots of helpful tips.
Hi fantastic website! Does running a blog like this take a great deal of work?
I have no expertise in coding but I was hoping to start my own blog soon. Anyways,
if you have any suggestions or techniques for new blog owners please share.
I understand this is off topic but I simply wanted to ask.
Thanks a lot!
บริษัท NetEnt เป็นที่รู้จักในอุตสาหกรรมคาสิโนออนไลน์ ด้วยประสบการณ์ที่มีมาอย่างช้านาน
และได้สร้างชื่อเสียงจากการเป็นผู้นำด้านการพัฒนาในเกมคาสิโนไลฟ์และสล็อตแบบออนไลน์ ด้วยแกรฟิคที่ทันสมัยและการเล่นที่สนุกสนาน ซึ่งทำให้เกมของ NetEnt เป็นที่ชื่นชอบจากนักพนันหลายพันธุ์ ไม่เพียงแค่เกมที่มีเนื้อหาหลากหลายและมีเสน่ห์เท่านั้น แต่ยังคำนึงถึงความยุติธรรม และมีคุณภาพการเชื่อมต่อที่ลื่นไหล บริษัท ยังใส่ใจถึงความรับผิดชอบในการเล่นเกม และได้นำเสนอมาตรการเพื่อการป้องกันปัญหาพนันอย่างจริงจัง เพื่อทำให้มั่นใจว่าผู้เล่นสามารถสนุกสนานไปกับเกมพนันอย่างปลอดภัยและในรูปแบบที่ความสุข
Here is my page :: คลิ้กที่นี่
(netent.vip)
To slim down your choices, conduct preliminary analysis
to identify areas that curiosity you and have enough academic assets
accessible to support your writing.
GOLDENHOKI GoldenHoki Indonesia adalah salah sebuah situs judi online terbaik 2024 di Indonesia.
This design is spectacular! You definitely know how to keep
a reader entertained. Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Fantastic job.
I really loved what you had to say, and more than that, how
you presented it. Too cool!
Attractive component to content. I just stumbled upon your
blog and in accession capital to say that I get
actually enjoyed account your blog posts. Any way I’ll
be subscribing for your augment and even I fulfillment you get admission to consistently rapidly.
การ ลุ้น «หวยฮานอย» เป็นอีก ช่องทาง หนึ่งที่ได้รับ ความต้องการ จาก ประชาชนไทย
ในการเสี่ยงโชค เมื่อ ดูเสมือน การ
เสี่ยง หวยรัฐบาลหรือ»หวยลาว» ความ น่าท้าทาย ของ»หวยฮานอย»คือ
การ จัดการลุ้นรางวัล ทุกวัน ส่งผลให้ผู้ เสี่ยง สามารถ ได้รับ ได้บ่อยครั้ง และ
มีช่องทาง สร้างรายได้พิเศษ
จากการ ซื้อ หวย
อย่างไรก็ตาม การ ซื้อ «หวยฮานอย» ก็ไม่ปราศจาก เนื่องจากผู้ ซื้อ
บางรายอาจ ลงทุน มากเกินไปหรือ มุ่งหมาย การพนัน ซึ่งอาจ ทำให้เกิดปัญหาตามมา
ต่อ สุขภาพ นอกจากนี้
ยังมี ความเป็นไปได้ เรื่อง การทุจริต จากผู้ที่
หาผลประโยชน์ โดยมิชอบ
เพื่อให้การเล่น «หวยฮานอย»
เป็นเพียงการเสี่ยงโชค เพื่อ ความเพิ่มพูน และไม่ก่อให้เกิดปัญหา จึงควรมีการ ปกป้อง และกำกับดูแล อย่างใกล้ชิด เช่น การ ระบุ
ระยะเวลา ในการ พนัน
ที่ พอดี รวมถึงการ ดูแล
ผู้ ทำผิดกฎระเบียบ ทั้งนี้เพื่อให้การ พนัน
«หวยฮานอย» เป็นส่วนหนึ่งของการใช้เวลาว่าง
อย่าง ระมัดระวัง และ ไม่ก่อให้เกิดผลเสีย สภาพแวดล้อม ของผู้ ซื้อ
My homepage — ศูนย์รวมคาสิโนออนไลน์
Hi there, after reading this awesome post i
am as well delighted to share my know-how here with friends.
this is a very good websit https://campasti.com/
I savor, cause I found exactly what I used to be taking a look for.
You have ended my four day long hunt! God Bless you man.
Have a nice day. Bye
This is a fantastic blog post! Don’t you want to know what are the features of screen mirroring? Well, Screen mirroring is a technology that allows for real-time content sharing, making collaboration easier and more efficient. For that make it possible there is an app called Scrcpy that is used for screen mirroring. For more detailed info visit the post.
What’s up, just wanted to tell you, I enjoyed this article.
It was practical. Keep on posting!
накрутка подписчиков тг
накрутка лайков тик ток
купить просмотры ютуб
накрутка лайков вк
накрутка лайков ютуб
накрутка просмотров тг
https://smm.ytmonster.ru/youtube/views/nakrutka-prosmotrov-iutub
https://smm.ytmonster.ru/vk/subscribers/nakrutka-podpischikov-vk
https://smm.ytmonster.ru/telegram/likes/nakrutka-reaktsii-telegram
https://smm.ytmonster.ru/tiktok/views/nakrutka-prosmotrov-tik-tok
https://smm.ytmonster.ru/tiktok/likes/nakrutka-laikov-tiktok
Come on, play on our site, on our site there are lots of bonuses and various kinds of prizes on our site.
I invite all of you to join our site so that you can all experience the excitement and fun of playing on our site. Come on, hurry up and register, what are you waiting for, the best site in the world is only at
https://cammewah.com/
AGENCANTIK
AGENCANTIK says I used to be checking constantly this weblog thanks alot
Fantastic post! Are you intrigued by the newest trends while organizing your upcoming camping adventure? One of them is renewable energy sources and zero-waste programs which are examples of environmentally friendly activities that are gaining traction. However, using a zip code map gives you a more personalized way to easily find your next destination. Check out the informative blog on camping trends to find out more.
ยินดีต้อนรับเข้าไปสู่บริษัท Cicon Interiorซึ่งให้บริการตกแต่งภายในครบวงจรในสไตล์ที่ไม่ซ้ำใคร ด้วยความพิถีพิถันและมีคุณภาพที่สูง หากคุณกำลังมองหาบริการ furniture built inที่จะสร้างความประทับใจให้กับบ้าน คอนโดหรือออฟฟิศของคุณ บริษัท
Cicon Interiorคุณสามารถพูดคุยและให้คำปรึกษาเกี่ยวกับการสร้างตัวตนและเอกลักษณ์ของคุณของการออกแบบบิ้วอินที่คุณต้องการ ด้วยประสบการณ์และความเชี่ยวชาญของทีมงานที่มีคุณภาพ คุณจะได้รับการดูแลอย่างใกล้ชิดและครอบคลุมทุกขั้นตอนของงานบิ้วอิน จนถึงการ built inเสร็จสิ้น กับ Cicon Interior คุณจะได้รับผลลัพธ์ เฟอร์นิเจอร์ชิ้นในอาคารที่มีคุณภาพทั้งดีไซน์ความทนทาน และการบริการสูงที่จะเป็นประโยชน์ต่อคุณในระยะยาว.
Everyone loves what you guys are usually up too. Such clever work and exposure!
Keep up the fantastic works guys I’ve added you guys to my own blogroll.
My partner and I stumbled over here different page and thought I should check
things out. I like what I see so now i am following you. Look forward to looking over your web page
again.
AGENCANTIK
AGENCANTIK says the final part i like to read
Great info. Lucky me I recently found your site by accident (stumbleupon).
I have book-marked it for later!
https://rybalka-v-rossii.ru/ — сайт о рыбалке в России, способах ловли рыб, и выборе правильных снастей.
официальный сайт lee bet al-club.ru
al-club.ru lee bet
15 Things You’re Not Sure Of About What Is The Best Online Shopping In Uk vimeo.Com
20 Fun Facts About Online Shop Vimeo
https://formomebel.ru/divany/modulnye
Unexpected Business Strategies For Business That
Aided Shopping Online Uk To Ireland To Succeed vimeo.Com
купить микронаушники https://jasdam.cz/
A Guide To Best Online Shopping Uk Clothes In 2023 vimeo.com
10 Things Everybody Hates About Cheapest Online Grocery Shopping Uk Vimeo.Com
купить флешки оптом https://meflash.ru/
With the rise in mosquito-borne diseases and the nuisance they cause during outdoor activities, it has become crucial to find effective ways to protect yourself and your loved ones from these pesky insects.
Полный спектр бухгалтерское обслуживание для вашего бизнеса.
Are you looking for reliable and fast proxies? https://fineproxy.org/account/aff.php?aff=29 It offers a wide range of proxy servers with excellent speed and reliability. Perfect for surfing, scraping and more. Start right now with this link: FineProxy.org . Excellent customer service and a variety of tariff plans!
https://autoblog.kyiv.ua путеводитель в мире автомобилей. Обзоры и тест-драйвы, актуальные новости, автокаталог, советы по уходу и ремонту, а также общение с автолюбителями. Всё, что нужно для выбора и эксплуатации авто, вы найдете у нас.
Воспользуйтесь промокод 1win, чтобы получить максимальные бонусы.
สวัสดีค่ะ! AE Casino เป็นเว็บไซต์ที่มีเกมคาสิโนออนไลน์ที่น่าสนใจมากมายสำหรับผู้เล่นทุกคนในทุกวัยทุกเพศ ทั้งคาสิโนสด,
สล็อตออนไลน์, และเกมโป๊กเกอร์ออนไลน์ คุณสามารถเข้าเล่นเกมได้ตลอดเวลาผ่านทางอุปกรณ์สมาร์ทโฟนหรือคอมพิวเตอร์ นอกจากนี้ AE
Gaming ยังมีโปรโมชั่นและของขวัญพิเศษเพื่อเพิ่มโอกาสในการชนะเล่นเกมอีกด้วย สำหรับใครที่ชื่นชอบเสี่ยงโชคและคาสิโนออนไลน์
AE Gaming เป็นเว็บไซต์ที่คุณไม่ควรพลาดเลยค่ะ!
ลองลองสัมผัสประสบการณ์การเล่นกันเถอะ!
Here is my blog :: เล่นคาสิโนออนไลน์ได้เงินจริงหรือไม่ 100%
7 Simple Changes That Will Make A Big Difference In Your Best Online
Shopping Groceries Uk Pedigree Rice And Veggie
Проверьте 1wincodes.ru и получите доступ к эксклюзивным бонусам и предложениям для 1win.
10 Quick Tips To Shopping Online Uk Tabletop Brochure And Magazine Holder
букмекерская контора 1win предлагает широкий выбор ставок и привлекательные бонусы.
Why Nobody Cares About Online Shopping Uk Cheap
Windproof Lighter
ยินดีต้อนรับเข้าสู่สู่บริษัท Cicon Interiorซึ่งให้บริการตกแต่งภายในครบวงจรในสไตล์ซึ่งไม่ซ้ำใคร ด้วยความพิถีพิถันและมีคุณภาพสูง หากคุณกำลังมองหาบริการเฟอร์นิเจอร์บิ้วอินที่จะสร้างความประทับใจให้กับบ้าน คอนโดหรือออฟฟิศของคุณ บริษัท Cicon Interiorคุณสามารถพูดคุยและให้คำปรึกษาเกี่ยวกับการสร้างเอกลักษณ์และความเป็นตัวคุณของงานบิ้วอินที่คุณต้องการ ด้วยประสบการณ์และความเชี่ยวชาญของทีมงานที่มีคุณภาพ คุณจะได้รับการดูแลอย่างใกล้ชิดและครอบคลุมทุกขั้นตอนของงานบิ้วอิน จนถึงการ built inเสร็จสิ้น กับ Cicon Interior คุณจะได้รับผลลัพธ์ เฟอร์นิเจอร์บิ้วอินที่มีคุณภาพทั้งดีไซน์ความทนทาน และการบริการสูงที่จะเป็นประโยชน์ต่อคุณในระยะยาว.
My web page: บิ้วอิน คอนโด
How Do You Know If You’re Ready For Online Shopping
Sites List For Clothes mizuno men’s premier short pant
промокод 1вин поможет вам увеличить свои выигрыши.
Воспользуйтесь промокод 1win и начните игру с дополнительными бонусами.
Finished Reading a Blog Post: A Formal Contribution to the Comment Section and an Invitation to Join «KING855»
‘After meticulously reading the blog post, I would like to furnish the following contribution to the
discussion .
Your observations on the subject matter were
quite intriguing . I found myself in concurrence with many
of the points you mentioned .
It is pleasing to witness such an animated exchange
unfolding.
If you are keen in additional investigating this
theme, I would sincerely urge you to participate in the «KING855» network .
In that space, you will have the opportunity to interact with kindred spirit members and
dive deeper into these intriguing topics .
I believe your involvement would be a valuable addition to the discussion .
Thank you remarks, and I anticipate the possibility of continuing this stimulating conversation.
Here is my site :: online sports betting
Поиск реплик AirPods PRO может быть сложным без правильной информации.
ความชื่นชอบ ในการ ลุ้น «หวยลาว» เป็นหนึ่งในกิจกรรมยอดนิยมในประเทศไทย โดยผู้คนจำนวนมากมักจะหลงใหล
ในการ ทำ ด้วยความหวังที่จะได้รับ ความร่ำรวย และ ปรับเปลี่ยน ชีวิตของตนเอง
«หวยลาว» เป็นการ เสี่ยง ที่ถูกกฎหมายในประเทศลาว และได้รับ
ความต้องการ อย่างมากในหมู่ พลเมืองไทย โดยเฉพาะอย่างยิ่งในช่วงเทศกาลสำคัญ ๆ เช่น วันสงกรานต์ วันขึ้นปีใหม่ และช่วงก่อนการออกรางวัลใหญ่ของ»หวยลาว» ผู้คนจะ ต่างทำ เพื่อลุ้นรับ ความมั่งมี ที่จะ
ยกระดับ ชีวิตของพวกเขา
อย่างไรก็ตาม การ ซื้อ «หวยลาว» ก็ไม่ปราศจากปัญหา เนื่องจากบางคนอาจ
ต้องการ การพนันและใช้เงินมากเกินไป ส่งผลให้เกิดปัญหาทางการเงิน
นอกจากนี้ การ ลุ้น «หวยลาว» ยังอาจเป็นช่องทางให้คนบางกลุ่ม ทำการฉ้อโกง
โดยมิชอบ ด้วยการ ปิดบัง
รางวัลของผู้ชนะ
แม้ว่าการ เสี่ยง «หวยลาว» จะเป็นกิจกรรมที่ถูกกฎหมายและ เป็นที่สนใจ ในหมู่
ผู้คนในไทย แต่ควรมีการ ตรวจสอบ อย่างใกล้ชิดเพื่อ หลีกเลี่ยง ปัญหาที่อาจ ส่งผลกระทบ
ทั้งนี้ เพื่อให้การ เสี่ยง
«หวยลาว» เป็นเพียงการเสี่ยงโชค
เท่านั้น และไม่ส่งผลกระทบ ต่อ
ความสัมพันธ์ ของ ผู้เสี่ยง
Look into my homepage เว็บคาสิโนออนไลน์ที่ปลอดภัยและน่าเชื่อถือที่สุด
Truly all kinds of awesome advice!
my blog https://www.youtube7.com/
Введите промокод 1win и активируйте эксклюзивные предложения.
Воспользуйтесь промокод 1win, чтобы получить максимальные бонусы.
Стоит ли покупать реплика Airpods PRO? Однозначно да, если хотите сэкономить.
магазин секс шоп https://24sex-shop.ru/
секс шоп москва https://24sex-shop.ru/
интим магазин товары цена https://24sex-shop.ru/
How To Build Successful Online Shopping Sites List For Clothes Tutorials
On Home Screwdriver Set With Organizing Rack
интим товары для взрослых https://24sex-shop.ru/
интим товары москва https://24sex-shop.ru/