nRF24L01 один из самых популярных беспроводных модулей для интернета вещей (IoT). Подключив модуль nRF24L01+ к Raspberry Pi, Orange Pi, Banana Pi и т.п можно организовать многоканальную защищенную связь между мини-компьютерами и/или, например, Arduino. Таким образом можно подключить на каждую плату Arduino по датчику и передать полученые данные на, к примеру, Raspberry Pi, а там обрабатывать эти данные и/или загрузить в БД.
Рассмотрим, как установить библиотеку RF24 и как наладить связь между Orange Pi PC (плату можно менять на любую другую типа Raspberry Pi, Orange Pi, Banana Pi и т.п. — будет также работать) и несколько плат Ардуино по радиоканалу.
Установка библиотеки RF24
Библиотека RF24 универсальная, её можно установить и использовать как на Arduino, так и на устройства под ОС Linux (Raspberry Pi, Orange Pi, Banana Pi и т.п) поддерживающие SPIDEV, MRAA, RPi BCM2835 или LittleWire. Опция SPIDEV должна работать с большинством систем Linux, поддерживающих SPI.
Описание методов класса RF24 можете найти на странице Подключение модуля nRF24L01+ к Arduino.
Установка библиотеки RF24 на Raspberry Pi
- Установите необходимые компоненты, если они есть (библиотеки MRAA, LittleWire, SPI и т. д.). На Raspberry Pi используется нативная библиотека BCM2835, по этому нужно её установить. Также не забудьте включить SPI на Raspberry Pi, это можно сделать с помощью утилиты
raspi-config
; - Загрузите файл
install.sh
с http://tmrh20.github.io/RF24Installer/RPi/install.sh;wget http://tmrh20.github.io/RF24Installer/RPi/install.sh
- Сделайте это файл исполняемым
chmod +x install.sh
- Запустите его и выберите параметры
./install.sh
- Запустите пример из одной из библиотек
cd rf24libs/RF24/examples_linux
- Для проверки можете отредактировать пример gettingstarted, чтобы настроить конфигурацию выводов, и запустить его
nano gettingstarted.cpp make sudo ./gettingstarted
Установка библиотеки RF24 на Orange Pi, Banana Pi и др.
Этот метод подойдёт и для установки на Raspberry Pi, и на любой ОС Linux, что поддерживает SPI.
- Установите необходимые компоненты, если они есть (библиотеки MRAA, LittleWire, SPI и т. д.). Не забудьте включить SPI, это можно сделать с помощью утилиты
armbian-config
, более подробно о том, как настроить SPI на Orange Pi, можете найти на странице Включение и настройка SPI (SPI0 и SPI1) на Orange Pi на ядрах 3.4 (Ubuntu 16.04) и 4.14 (Ubuntu 18.04). - Клонируете репозиторий RF24.
git clone https://github.com/tmrh20/RF24.git RF24
- Перейдите в новый каталог RF24.
cd RF24
- Настройте среду сборки, используя скрипт
./configure
Скрипт автоматически определяет устройство и среду сборки. Если хотите вручную настроить, смотрите на список возможностей скрипта:
./configure --help
- Соберите и установите библиотеку
sudo make install
- Для проверки можете отредактировать пример gettingstarted, чтобы настроить конфигурацию выводов, и запустить его
nano gettingstarted.cpp make sudo ./gettingstarted
Схема подключения nRF24L01+ к Raspberry Pi
Подключается nRF24L01+ к Raspberry Pi по шине SPI (можно использовать как аппаратную так и программную шину). Выводы модуля Vcc и GND подключаются к шине питания 3.3 В постоянного тока. Выводы модуля MISO, MOSI, SCK и подключаются к одноименным выводам шины SPI на плате Raspberry Pi.
Вывод CSN (Chip Select nRF24L01+) подключается к выводу CE (Raspberry Pi) шины SPI, CE (Chip Enable) назначается при объявлении объекта библиотеки RF24 и подключаются к любым назначенным выводам Raspberry Pi. Вывод IRQ на NRF24L01+ в данном случае не используется.
Конкретные имена портов интерфейса SPI могут различаться в зависимости от производителя аппаратных средств, при этом возможны следующие варианты:
- MOSI: SIMO, SDI (на устройстве), DO, DON, SI, MRSR;
- MISO: SOMI, SDO (на устройстве), DI, DIN, SO, MTST;
- SCLK: SCK, CLK;
- SS: nCS, CS, CSB, CSN, nSS, STE, SYNC.
Полное представление о выводах Raspberry Pi см. http://pinout.xyz/. Если установлена библиотека WiringPi, можете воспользоваться командой
gpio readall
для определения назначения всех выводов на плате.
Подключение nRF24L01+ к Raspberry Pi напрямую
nRF24L01+ | Raspberry Pi |
---|---|
GND | 6 / GND |
VCC | 1 / 3.3V |
CE | 22 / GPIO25 |
CSN | 24 / GPIO8 / SPI_CE0_N |
SCK | 23 / GPIO11 / SPI0_CLK |
MOSI | 19 / GPIO10 / SPI0_MOSI |
MISO | 21 / GPIO9 / SPI0_MISO |
IRQ | — |
Подключение nRF24L01+ к Raspberry Pi через адаптер
nRF24L01+ | Raspberry Pi |
---|---|
GND | 6 / GND |
VCC | 2 / 5.0V |
CE | 22 / GPIO25 |
CSN | 24 / GPIO8 / SPI_CE0_N |
SCK | 23 / GPIO11 / SPI0_CLK |
MO / MOSI | 19 / GPIO10 / SPI0_MOSI |
MI / MISO | 21 / GPIO9 / SPI0_MISO |
IRQ | — |
Схема подключения nRF24L01+ к Orange Pi, Banana Pi и др.
Как и в случае с Raspberry Pi, подключается nRF24L01+ к Orange Pi по шине SPI. Выводы модуля Vcc и GND подключаются к 3.3 В и GND соответственно. Тоже самое и с выводами MISO, MOSI, SCK и CSN. Единственное отличие в подключении вывода CE (Chip Enable) — номер вывода отличается от Raspberry Pi, так как контроллер другой. Если установлена библиотека WiringOP или BPI-WiringPI (для Banana Pi), можете воспользоваться командой
gpio readall
для определения назначения всех выводов на плате Orange Pi или Banana Pi.
При объявлении объекта библиотеки RF24 нужно указывать номер пина из колонки BCM.
Подключение nRF24L01+ к Orange Pi напрямую
nRF24L01+ | Orange Pi |
---|---|
GND | 6 / GND |
VCC | 1 / 3.3V |
CE | 29 / GPIO7 |
CSN | 24 / GPIO67 / SPI_CE0_N |
SCK | 23 / GPIO66 / SPI0_CLK |
MOSI | 19 / GPIO64 / SPI0_MOSI |
MISO | 21 / GPIO65 / SPI0_MISO |
IRQ | — |
Подключение nRF24L01+ к Orange Pi через адаптер
nRF24L01+ | Orange Pi |
---|---|
GND | 6 / GND |
VCC | 2 / 5.0V |
CE | 29 / GPIO7 |
CSN | 24 / GPIO67 / SPI_CE0_N |
SCK | 23 / GPIO66 / SPI0_CLK |
MO / MOSI | 19 / GPIO64 / SPI0_MOSI |
MI / MISO | 21 / GPIO65 / SPI0_MISO |
IRQ | — |
Примеры
Пример 1: Сканер диапазона 2.4 ГГц на NRF24L01+
При создании проектов с передачей данных по радиочастотному каналу, нужно быть уверенным, что данный канал не занят другим устройством. Несколько устройств, находящихся в непосредственной близости, работающих на одной частоте, будут мешать друг другу, снижая скорость передачи данных, или вообще откажутся работать.
Ниже приведённый пример представляет собой сканер, с помощью которого можно определить свободные каналы в ISM (Industrial, Scientific, Medical) диапазоне частот от 2400 МГц до 2527 МГц. Данный сканер сможет определять такие устройства как: WiFi, Bluetooth, некоторые радио телефоны, другие модули nRF24L01.
#include <cstdlib> #include <iostream> /* * Подключаем файл настроек из библиотеки RF24 */ #include <RF24/nRF24L01.h> /* * Подключаем библиотеку для работы с nRF24L01+ */ #include <RF24/RF24.h> using namespace std; /* * Конфигурация оборудования */ #define BCM_PIN 7 #define SPI_DEV 0 #define NUM_CHANNELS 126 /* * Информация о канале */ uint8_t values[NUM_CHANNELS]; const int numReps = 100; int main() { /* * Создаём объект radio для работы с библиотекой RF24, * указывая номера вывода CE и SPI порта */ RF24 radio(BCM_PIN, SPI_DEV); /* * Инициируем работу nRF24L01+ */ radio.begin(); radio.setAutoAck(false); /* * Вход в режиме ожидания */ radio.startListening(); radio.stopListening(); /* * Дамп конфигурации RF для отладки */ radio.printDetails(); /* * Распечатка заголовка, верхний и нижний разряд */ for (int i = 0; i < NUM_CHANNELS; ++i) { printf("%x", i >> 4); } cout << endl; for (int i = 0; i < NUM_CHANNELS; ++i) { printf("%x", i & 0xf); } cout << endl; while (1) { /* * Очистка значений измерений */ memset(values, 0, sizeof(values)); /* * Сканирование всех каналов numReps раз */ for (int k = 0; k < numReps; ++k) { for (int i = 0; i < NUM_CHANNELS; ++i) { /* * Выбор канала */ radio.setChannel(i); /* * Послушать немного */ radio.startListening(); delayMicroseconds(128); radio.stopListening(); /* * Проверка наличия несущей частоты на выбранном канале (частоте). */ if (radio.testCarrier()) { ++values[i]; } } } /* * Распечатка измерения канала в одну шестнадцатеричную цифру */ for (int i = 0; i < NUM_CHANNELS; ++i) { printf("%x", min(0xf, (values[i] & 0xf))); } cout << endl; } return 0; }
Компиляция и сборка
g++ -Ofast -Wall RF24_scanner.cpp -lrf24 -o RF24_scanner
Результат
По полученным результатам мы можем сказать, что довольно много каналов заняты.
Пример 2: Получение данных от одного или нескольких передатчиков
В основном на Raspberry Pi, Orange Pi, Banana Pi и т.п. можно запустить любой рабочий пример для Arduino со страницы Подключение модуля nRF24L01+ к Arduino. Единственое, нужно будет поменять функции для вывода на консоль: Serial.print();
на аналогичные в C/C++: printf();
или cout;
.
Приёмнику можно задать до 6 труб функцией openReadingPipe(номер, адрес)
:
for (int i = 0; i < 6; i++) { radio.openReadingPipe(i, pipesAddress[i]); }
с номерами труб от 0 до 5 и адресами труб совпадающими с адресами труб передатчиков.
/* * номера труб */ uint8_t pipesAddress[6][5] = { { '0', 'P', 'I', 'P', 'E' }, { '1', 'P', 'I', 'P', 'E' }, { '2', 'P', 'I', 'P', 'E' }, { '3', 'P', 'I', 'P', 'E' }, { '4', 'P', 'I', 'P', 'E' }, { '5', 'P', 'I', 'P', 'E' }, };
Методом available()
осуществляется проверка получения данных. Метод возвращает true
если в буфере есть принятые данные доступные для чтения. В качестве необязательного аргумента можно указать адрес переменной в которую будет помещён номер трубы по которой были приняты данные (в примере используется адрес переменной &pipeNumber
), зная номер трубы мы знаем от какого передатчика пришли данные.
if (radio.available(&pipeNumber)) { /*...*/ }
Чтобы была возможность получить/передать данные разной длины, нужно разрешить динамически изменяемый размер блока данных для всех труб на приёмнике и на передатчике.
radio.enableDynamicPayloads();
Получить размер блока данных в последнем принятом пакете можно с помощью метода getDynamicPayloadSize()
.
payloadSize = radio.getDynamicPayloadSize();
Читаем данные в массив receivedData
и указываем сколько байт читать payloadSize
.
radio.read(&receivedData, payloadSize);
Полный код приёмника:
/* * Приемник */ #include <cstdlib> #include <iostream> #include <stdint.h> /* * Подключаем файл настроек из библиотеки RF24 */ #include <RF24/nRF24L01.h> /* * Подключаем библиотеку для работы с nRF24L01+ */ #include <RF24/RF24.h> using namespace std; #define BCM_PIN 7 #define SPI_DEV 0 #define MAX_LEN 32 /* * Создаём массив для приёма данных */ uint8_t receivedData[MAX_LEN]; uint8_t pipeNumber; uint8_t payloadSize; /* * номера труб */ uint8_t pipesAddress[6][5] = { { '0', 'P', 'I', 'P', 'E' }, { '1', 'P', 'I', 'P', 'E' }, { '2', 'P', 'I', 'P', 'E' }, { '3', 'P', 'I', 'P', 'E' }, { '4', 'P', 'I', 'P', 'E' }, { '5', 'P', 'I', 'P', 'E' }, }; int main() { /* * Создаём объект radio для работы с библиотекой RF24, * указывая номера вывода CE и SPI порта */ RF24 radio(BCM_PIN, SPI_DEV); /* * Инициируем работу nRF24L01+ */ radio.begin(); /* * режим подтверждения приёма, 1 вкл 0 выкл */ radio.setAutoAck(1); /* * время между попыткой достучаться, число попыток */ radio.setRetries(0, 15); /* * Разрешить динамически изменяемый размер блока данных для всех труб. */ radio.enableDynamicPayloads(); /* * Открываем трубу с идентификатором 0x1111111111LL для приема данных * (на одном канале может быть открыто до 6 разных труб, которые должны * отличаться только последним байтом идентификатора) */ for (int i = 0; i < 6; i++) { radio.openReadingPipe(i, pipesAddress[i]); } /* * Указываем канал передачи данных (от 0 до 127), * (на одном канале может быть только 1 приёмник и до 6 передатчиков) * Выбираем канал в котором нет шумов! */ radio.setChannel(0x70); /* * Указываем мощность передатчика * RF24_PA_MIN=-18dBm * RF24_PA_LOW=-12dBm * RF24_PA_HIGH=-6dBm * RF24_PA_MAX=0dBm */ radio.setPALevel(RF24_PA_MAX); /* * Указываем скорость передачи данных * RF24_250KBPS = 250Кбит/сек * RF24_1MBPS = 1Мбит/сек * RF24_2MBPS = 2Мбит/сек */ radio.setDataRate(RF24_1MBPS); /* * Включаем приемник, начинаем прослушивать открытую трубу */ radio.startListening(); radio.printDetails(); cout << "startListening" << endl; while (true) { /* * Если в буфере имеются принятые данные */ if (radio.available(&pipeNumber)) { payloadSize = radio.getDynamicPayloadSize(); /* * Читаем данные в массив data и указываем сколько байт читать */ radio.read(&receivedData, payloadSize); cout << "Pipe: " << (int) pipeNumber << "; "; cout << "Size: "; printf("%02d", (int) payloadSize); cout << "; "; cout << "Data: ["; for (uint8_t i = 0; i < payloadSize; ++i) { if (i == 0) { printf("%02X", receivedData[i]); } else { printf(", %02X", receivedData[i]); } } cout << "]" << endl; } __msleep(10); } return 0; }
Компиляция и сборка
g++ -Ofast -Wall RF24_receiver.cpp -lrf24 -o RF24_receiver
Результат
Пример 3: Передача данных — Arduino скетч
Ниже приведённый код нужно залить на Arduino, можно залить на 6 плат, но не забудьте менять адрес трубы radio.openWritingPipe(pipesAddress[0]);
— от 0 до 5.
/* Передатчик */ /* Подключаем файл настроек из библиотеки RF24 */ #include <nRF24L01.h> /* Подключаем библиотеку для работы с nRF24L01+ */ #include <RF24.h> #include <printf.h> /* Создаём объект radio для работы с библиотекой RF24, указывая номера вывода CE и SPI порта */ RF24 radio(9, 10); byte counter = 0; uint8_t data[32]; uint8_t payloadSize; uint8_t pipesAddress[6][5] = { { '0', 'P', 'I', 'P', 'E' }, { '1', 'P', 'I', 'P', 'E' }, { '2', 'P', 'I', 'P', 'E' }, { '3', 'P', 'I', 'P', 'E' }, { '4', 'P', 'I', 'P', 'E' }, { '5', 'P', 'I', 'P', 'E' }, }; //возможные номера труб void setup(void) { Serial.begin(115200); printf_begin(); /* Инициируем работу nRF24L01+ */ radio.begin(); /* Режим подтверждения приёма, 1 вкл 0 выкл */ radio.setAutoAck(1); /* Размер пакета, в байтах */ radio.enableDynamicPayloads(); /* Указываем канал передачи данных (от 0 до 127) (на одном канале может быть только 1 приёмник и до 6 передатчиков). Выбираем канал в котором нет шумов! */ radio.setChannel(0x70); /* Указываем скорость передачи данных 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); /* Открываем трубу для передачи данных (на одном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора) */ radio.openWritingPipe(pipesAddress[0]); /* Не слушаем радиоэфир, мы передатчик */ radio.stopListening(); /* Дамп конфигурации RF для отладки */ radio.printDetails(); } void loop(void) { /* Передаём счетчик */ payloadSize = random(1, 32); for (uint8_t i = 0; i < payloadSize; i++) { data[i] = i; } Serial.print("Передача:"); for (uint8_t i = 0; i < payloadSize; i++) { Serial.print(" "); Serial.print((int) data[i]); } Serial.print("; "); if (radio.write(data, payloadSize)) { Serial.println("Данные приняты приёмником."); } else { Serial.println("Данные не приняты приёмником."); } /* Ждем 1000мс */ delay(1000); }
Материалы
Serial Peripheral Interface
Optimized High Speed NRF24L01+ Driver Class Documenation
А можно подобным образом создать подобие Walkie-Talkie для подключения к ip-камерам, построенным на базе MotionEYEOs?
Возможно, вопрос сформулирован коряво (заранее извиняюсь).
Нестыкуется
Указано в таблице CE пин 22 оранжа, а на картинке с выводом пинов указан пин 29.
Что куда?
подскажите, пожалуйста, как полученные данные передавать в php скрипт на raspberry?
^_^
Trang web của chúng tôi cung cấp những cập nhật mới nhất về tỷ lệ kèo malaysia mới nhất, giúp bạn đưa ra quyết định cá cược chính xác hơn.
sildenafil precautions
viagra pills shoppers
перепродажа аккаунтов гарантия при продаже аккаунтов
маркетплейс аккаунтов маркетплейс аккаунтов соцсетей
маркетплейс аккаунтов соцсетей аккаунты с балансом
Sell Pre-made Account Account trading platform
Accounts market Secure Account Sales
Account Trading Platform Profitable Account Sales
Account exchange Account Trading Service
Account Buying Service Account Acquisition
account exchange online account store
account market marketplace for ready-made accounts
account acquisition database of accounts for sale
account market account buying platform
social media account marketplace account market
guaranteed accounts profitable account sales
buy pre-made account find accounts for sale
secure account purchasing platform accounts market
buy and sell accounts buy and sell accounts
account buying platform account exchange
website for selling accounts sell pre-made account
account acquisition buy accounts
account trading service accounts marketplace
account trading platform account trading platform
accounts for sale social media account marketplace
buy account buy accounts
sell accounts https://accounts-marketplace.xyz
account marketplace https://buy-best-accounts.org
account marketplace https://social-accounts-marketplaces.live
account buying service https://social-accounts-marketplace.xyz
database of accounts for sale https://buy-accounts-shop.pro/
guaranteed accounts https://social-accounts-marketplace.live
account market https://accounts-marketplace.online
buy accounts https://accounts-marketplace-best.pro
покупка аккаунтов https://kupit-akkaunt.xyz/
покупка аккаунтов https://kupit-akkaunty-market.xyz
купить аккаунт akkaunty-optom.live
покупка аккаунтов https://kupit-akkaunt.online/
buy facebook ads manager buy facebook old accounts
buy facebook accounts for advertising buy fb ad account
buy fb ad account facebook ads account buy
facebook ad account for sale https://buy-ad-account.click
buy fb ad account https://ad-accounts-for-sale.work
buy google ads https://buy-ads-account.top
facebook ad account for sale fb accounts for sale
google ads agency accounts buy google ads
old google ads account for sale https://ads-account-buy.work
google ads agency accounts https://buy-ads-invoice-account.top
buy google ads threshold accounts google ads reseller
buy google ads verified account https://sell-ads-account.click/
buy verified business manager buy-business-manager.org
buy google agency account https://buy-verified-ads-account.work/
facebook bm for sale buy business manager account
buy facebook bm https://buy-business-manager-verified.org
buy verified facebook business manager account verified-business-manager-for-sale.org
buy facebook business managers https://buy-business-manager-accounts.org
buy tiktok ads https://buy-tiktok-ads-account.org
buy tiktok business account https://tiktok-ads-account-buy.org
tiktok ads account buy buy tiktok ad account
buy tiktok ads account https://tiktok-agency-account-for-sale.org
tiktok agency account for sale https://buy-tiktok-ad-account.org
buy tiktok ads accounts https://buy-tiktok-ads-accounts.org
buy tiktok ads https://buy-tiktok-business-account.org
buy tiktok ads account https://buy-tiktok-ads.org
tiktok ad accounts https://tiktok-ads-agency-account.org
натяжные потолки недорого натяжные потолки недорого .
натяжной потолок липецк http://www.potolkilipetsk.ru/ .
шкаф в паркинг москва шкаф в паркинг москва .
септик для частного цена установки септик для частного цена установки .
кредит на карту с плохой ки кредит на карту с плохой ки .
где можно взять займ без отказа http://www.zajm-bez-otkaza-1.ru .
accutane mexican pharmacy
клиника нижний новгород психолог стационар psihiatry-nn-1.ru .
prescription drugs
best online international pharmacies
buy facebook account for ads accounts market ready-made accounts for sale
online pharmacy
prescription-free muscle relaxants: affordable Zanaflex online pharmacy — muscle relaxants online no Rx
AsthmaFree Pharmacy: ozempic vs rybelsus vs wegovy — semaglutide burping
https://ivercarepharmacy.shop/# ivermectin mechanism of action in scabies
AsthmaFree Pharmacy: AsthmaFree Pharmacy — can rybelsus cause yeast infections
IverCare Pharmacy: where can i buy stromectol — ivermectin dosage for sheep
horse ivermectin for dogs: IverCare Pharmacy — ivermectin oral for dogs
FluidCare Pharmacy: lasix dosage — lasix 40mg
https://gkwinviet.company/# Nha cai uy tin Vi?t Nam
Bandar togel resmi Indonesia: Situs togel online terpercaya — Bandar togel resmi Indonesia
https://1winphili.company/# jollibet app
Slot game d?i thu?ng: GK88 — Ca cu?c tr?c tuy?n GK88
Mandiribet login: Live casino Mandiribet — Slot jackpot terbesar Indonesia
Pinco kazino: Etibarl? onlayn kazino Az?rbaycanda — Etibarl? onlayn kazino Az?rbaycanda
Jiliko app: Jiliko slots — Jiliko app
https://mandiwinindo.site/# Slot gacor hari ini
maglaro ng Jiliko online sa Pilipinas: Jiliko slots — Jiliko casino walang deposit bonus para sa Pinoy
Link alternatif Beta138: Promo slot gacor hari ini — Live casino Indonesia
Onlayn rulet v? blackjack: Kazino bonuslar? 2025 Az?rbaycan — Yeni az?rbaycan kazino sayt?
Online betting Philippines: Online betting Philippines — Online betting Philippines
Withdraw cepat Beta138: Beta138 — Withdraw cepat Beta138
Jiliko bonus: maglaro ng Jiliko online sa Pilipinas — Jiliko casino walang deposit bonus para sa Pinoy
Slot gacor hari ini: Mandiribet login — Link alternatif Mandiribet
Live casino Mandiribet: Situs judi online terpercaya Indonesia — Slot jackpot terbesar Indonesia
Etibarl? onlayn kazino Az?rbaycanda: Etibarl? onlayn kazino Az?rbaycanda — Onlayn rulet v? blackjack
http://indianmedsone.com/# Indian Meds One
Indian Meds One: indianpharmacy com — Indian Meds One
http://indianmedsone.com/# Indian Meds One
india pharmacy mail order: top online pharmacy india — indian pharmacies safe
https://medidirectusa.com/# doxycycline the generics pharmacy
Mexican Pharmacy Hub: buying prescription drugs in mexico online — Mexican Pharmacy Hub
united states online pharmacy: lorazepam indian pharmacy — MediDirect USA
buy neurontin in mexico: buy cheap meds from a mexican pharmacy — buy antibiotics over the counter in mexico
canadian pharmacy no rx
isotretinoin from mexico: Mexican Pharmacy Hub — buy meds from mexican pharmacy
https://indianmedsone.com/# Indian Meds One
buy cheap meds from a mexican pharmacy: Mexican Pharmacy Hub — Mexican Pharmacy Hub
MediDirect USA: MediDirect USA — pharmacy online shopping usa
¡Un cordial saludo a todos los amantes del riesgo !
Los casino europa ofrecen una experiencia de juego segura y variada. Muchos jugadores prefieren casinosonlineeuropeos por sus bonos atractivos y soporte en varios idiomas. п»їcasinos online europeos Un los mejores casinos online garantiza retiros rГЎpidos y mГ©todos de pago confiables.
Los casinos europeos ofrecen una experiencia de juego segura y variada. Muchos jugadores prefieren los mejores casinos online por sus bonos atractivos y soporte en varios idiomas. Un casinosonlineeuropeos garantiza retiros rГЎpidos y mГ©todos de pago confiables.
Casino online europa con soporte 24h y promociones exclusivas — п»їhttps://casinosonlineeuropeos.xyz/
¡Que goces de increíbles partidas !
best mexican pharmacy online: sildenafil mexico online — Mexican Pharmacy Hub
https://indianmedsone.shop/# pharmacy website india
philidor rx pharmacy: Advair Diskus — propranolol indian pharmacy
MediDirect USA: MediDirect USA — ez rx pharmacy
Mexican Pharmacy Hub: Mexican Pharmacy Hub — best mexican pharmacy online
discount prescription
buy cheap viagra online: average cost for viagra — viagra super active price
online ed drugs no prescription
http://kamameds.com/# KamaMeds
Tadalify: maximpeptide tadalafil review — Tadalify
Tadalify: generic cialis tadalafil 20 mg from india — cialis 30 day free trial
Online sources for Kamagra in the United States: Affordable sildenafil citrate tablets for men — Safe access to generic ED medication
Fast-acting ED solution with discreet packaging: Men’s sexual health solutions online — Kamagra oral jelly USA availability
cialis meme: Tadalify — cialis dapoxetine overnight shipment
Non-prescription ED tablets discreetly shipped: Men’s sexual health solutions online — Compare Kamagra with branded alternatives
Tadalify: tadalafil without a doctor prescription — tadalafil cost cvs
Tadalify: cialis and grapefruit enhance — cialis not working anymore
brand viagra 50mg online: SildenaPeak — sildenafil 100mg paypal