========= Přenos dat pomocí Bluetooth ====== Vypracoval: Jáchym Macura ---- ====== Zadání ====== Navrhněte zařízení sloužící k přenosu dat pomocí standardu Bluetooth Low Energy. Zařízení bude schopno komunikovat s telefonem Raspberry Pi a ovládat (set, clear, toggle, read) tři LED diody, komunikovat z PC po UARTu do Raspberry Pi, vysílat v pravidelných intervalech teplotu (popř. jiný údaj). Zaměřte se na spotřebu navrženého zařízení. Využijte vývojovou desku Nordic Semiconductor nRF52 DK (PCA10040) a SDK v15.2 ---- ====== Úvod ====== Projekt se zabývá realizací zařízení, které je schopné komunikovat pomocí standardu Bluetooth. Technologie Bluetooth nabízí bezdrátové připojení pro kompaktní aplikace s bateriemi. Jedná se o bezdrátový protokol pracující v pásmu ISM 2,4 GHz s výkonem až 1,4 Mb/s a dosahem do 1000 m. Bluetooth je vysoce efektivní a minimalizuje potřebnou energii k přenosu dat. ---- ====== Hardwarová část ====== Celý projekt je prakticky složen z vývojového kitu PCA10040, mini počítače Raspberry Pi 3 a modulu MPU-6050. Kit PCA10040 je osazen čipem NRF52832, který má integrované Bluetooth rádio na čipu. Tento čip NRF63932 je srdce projektu, a poslouží pro vyčítání hodnot z modulu MPU-6050 po I2C, sériovou komunikaci s PC, měření napětí na baterii po mocí ADC a odesílaní dat pomocí Bluetooth do Raspberry. Raspberry PI slouží jako sběrný bod dat a poskytuje grafické rozhraní. {{ :2018:bluetooth:diagram.png?nolink&400 |}} \\ ===== Vývojová kit nRF52-PCA10040 ===== {{ :2018:bluetooth:nrf52pca10040.png?nolink&300|}} **Kit PCA10040** *Osazeno nRF52832 podporující ANT/ANT+, Bluetooth® Low Energy SoC *4 tlačítko a 4 LED pro uživatele *I/O interface pro Arduino moduly *SEGGER J-Link OB debugger *Virtualní COM port *Podporuje NFC-A naslouchací mód *Možnost Mbed **nRF52832 - klíčové parametry** *Architektura: ARM® Cortex™-M4 *Integrovaný Bluetooth5 stack, ANT *FPU *Paměť: RAM 64KB, Flash 512KB *Citlivost přijímače: -96dBm *Vysílací výkon: -40:4:4dBm Velice zajímavou je možnost vlastního výběru GPIO pro všechny digitální periferie. ===== MPU6050 ===== {{ :2018:bluetooth:mpu.png?nolink&120|}} **Parametry** *Napájecí napětí: 3,3V - 5V (interní stabilizátor) *Teploměr, Gyroskop, Akcelerometr *Komunikace: I2C ===== Raspberry Pi 3 ===== {{ :2018:bluetooth:rpi.png?nolink&300|}} *Quad Core 1.2GHz Broadcom BCM2837 64bit CPU *1GB (900 MHz) LPDDR2 RAM *100 Base Ethernet *40 GPIO *4x USB2 porty *HDMI ---- ====== Firmware ====== ===== Firmware nRF52832 ===== Pro práci bylo použito volně dostupné SDK v15.2. Zde jsem vycházel z mnoha dobře zpracovaných examplů. Projekt pak byl vytvořen na základě šablony ble_peripheral/ble_app_template. Vývojové prostředí bylo použito studio SEGGER Embedded Studio, ze kterého lze přímo flashovat a debuggovat zařízení. Hlavním zdrojem informací je pak stránka https://devzone.nordicsemi.com/, kde už je z 99% vyřešen problém, který právě řešíte. Pro první debuggování a testování je pak volně dostupná aplikace na telefon: nRF Connect. Firmware ve finální podobě pracuje takto: *Zařízení 1 za sekundu vyčítá po I2C data z modulu MPU-6050 a odesílá je po Bluetooth *Zařízení 1 za sekundu vyčítá data z ADC a vypočítá aktuální napětí na baterii (mV) a odesílá je po Bluetooth *Příchozí data po UARTu jsou odeslána pomocí Bluetooth a naopak *Možnost ovládání LED diod na vývojovém kitu pomocí Bluetooth *Nekonečná smyčka v Main funkci obsahuje pouze funkci pro uspání zařízení Tyto funkce jsou pak rozděleny do dvou BLE servisů. A každý servis obsahuje BLE charakteristiky viz. rozdělení níže. Informace v hranatých závorkách udává maximální počet bytů, které je možno přes tuto charakteristiku přenést. Znaky v uvozovkách pak odkazují použité UUID. UUID je použito 128 bitů dlouhé, ale pro ušetření paměti všechny využívají stejný základ {0x23, 0xD1, 0x13, 0xEF, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}. Poslední 2 byty jsou poté vymaskovány s vlastními vymyšlenými UUID dlouhé 16 bitů. Poslední informací pak je, zda bylo u dané charakteristiky použito notifikace nebo indikace. *Service - Data, "0xDA7A" *Characteristic - LED, "0x2EED" - řídí stav LEDek [1] - Vyšší 4 bity podle hodnoty mění mód: 0 - off, 1 - on, 2 - toggle, 3 read, Notifikace *Characteristic - UART, "0x4A87" - slouží pro komunikaci a přenos dat [20] - odeslaný string musí být ukončen '/n', Indikace *Service - Sensor, "0xAAAA" *Characteristic - Temp-ADC, "0xCCCC" - [4] - [Temperature_int, Temperature_frac, ADC15-8b, ADC7-0b], Notifikace {{ :2018:bluetooth:nrfconnect_popisky.png?nolink&400 |}} V hlavní smyčce jsou jako první inicializovány všechny potřebné periferie jako UART, I2C(TWI), TIMER, tlačítka, LEDky, ADC a nastaven power management. int main(void) { uart_init(); twi_init(); MPU6050_set_mode(NORMAL); log_init(); timers_init(); buttons_leds_init(&erase_bonds); saadc_init(); power_management_init(); ... V dalším kroku jsou potom inicializovány záležitosti ohledně Bluetooth. Jsou zde přidány komentáře, aby bylo jasné, k čemu každá funkce slouží. Ty nejdůležitější(která já jsem výrazněji modifikoval), bylo nastavení GAP. GAP slouží pro nastavení parametrů jako je jméno zařízení, lze zde zvolit typ zařízení pod kterým se má hlásit. Dále se zde nastavují časové parametry pro připojení, spárování. Dalším je Advertising nastavení, ve kterém se konfigurují věci jako správa vysílaná při advertisingu, síla výkonu, síla vysílače ale i například výrobce chipu. Tím nejdůležitějším parametrem je doba vysílaní advertingu. Po uplynutí této doby, přechází zařízení do deep sleep módu a může být probuzeno pouze hard resetem. ... ble_stack_init(); //Initializes the SoftDevice and the BLE event interrupt. gap_params_init(); //Initializes Generic Access Profile gatt_init(); //Initializes Generic Attribute Profile advertising_init(); //Self-explanatory services_init(); //Self-explanatory conn_params_init(); //Connection Parameters peer_manager_init(); //Security setup Uvádět zde inicializaci a nastavení pro vytvoření vlastního servisu a charakteristiky by v mém podání určitě nebyla ta nejlepší možnost. Přikládám raději odkaz na výborné tutoriály, podle kterých jsem postupoval já. https://devzone.nordicsemi.com/tutorials/b/bluetooth-low-energy Funkce pro odesílání dat po Bluetooth(tato slouží pro odeslání informací o nastavených LED diodách): void led_characteristic_update(ble_service_data_t *p_our_service) { // Update characteristic value //Check if Connected and if notification is ON if ((p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID) && (p_our_service->fs_t.f_notifi_LED_ON == true)) { uint32_t err_code; uint16_t len = 1; uint32_t port_state = nrf_gpio_port_out_read(NRF_GPIO); uint8_t data = (~(port_state >> 18)) & 7; ble_gatts_hvx_params_t hvx_params; memset(&hvx_params, 0, sizeof(hvx_params)); hvx_params.handle = p_our_service->char_led_handle.value_handle; hvx_params.type = BLE_GATT_HVX_NOTIFICATION; //hvx_params.type = BLE_GATT_HVX_INDICATION; hvx_params.offset = 0; hvx_params.p_len = &len; hvx_params.p_data = &data; err_code = sd_ble_gatts_hvx(p_our_service->conn_handle, &hvx_params); SEGGER_RTT_printf(0, "HVX led status: %d\n", err_code); APP_ERROR_CHECK(err_code); } } ===== Firmware Raspberry Pi ===== Pro vizualizaci dat a snadnější ovládání, bylo vytvořeno velice jednoduché GUI pomocí Pythonu a konkrétně knihovny PyQt. Pro komunikaci po Bluetooth na Raspberry Pi byla použita knihovna Bluepy. Z Gui je možnost ovládat LED diody, využít Bluetooth UART a prohlížet si grafy s naměřenou teplotou a napětí na baterii. {{ :2018:bluetooth:gui.png?nolink&600 |}} ---- ====== Demonstrační video ====== {{ youtube>lJ0eoUvo_P8?medium }} \\ ---- ====== Zdrojový kód ====== Zdrojový kód pro Nordic: https://github.com/xmacur06/MPOA2018_NORDIC \\ Zdrojový kód pro GUI: {{ :2018:bluetooth:mpoa_gui_final.zip |}} ---- ====== Závěr ====== Jelikož nešlo o projekt, ve kterém by měl vzniknout nějaký finální produkt, ale spíše se seznámit s mikroprocesory Nordic s integrovaným Bluetooth stackem, tak se dá zhodnotit, že zadání bylo splněno. Byla vytvořena vzorová aplikace, ve která byla pro mód Bluetooth periferie využita téměř každá fičura. Myslím, že do budoucna může tento projekt sloužit jako kostra (template) pro další projekty. ---- ====== Zdroje ====== *http://infocenter.nordicsemi.com/index.jsp *https://github.com/pyqt *https://github.com/IanHarvey/bluepy *https://devzone.nordicsemi.com/tutorials/b/bluetooth-low-energy