this is a new program based on BLE_Uart_Peripheral. Change program name due to relation Client&Peripheral to Client&Server
Dependencies: RingBuffer nRF51_Vdd nRF51_WakeUp
This is a BLE Server (Device) program for nRF51.
You can communicate with mbed BLE using "BLE_Uart_Client" program as follows.
/users/kenjiArai/code/BLE_Uart_Client/
Please refer following my notebook.
/users/kenjiArai/notebook/ble-client-and-peripheral-using-switch-sience-ty51/#
main.cpp
- Committer:
- kenjiArai
- Date:
- 2016-04-16
- Revision:
- 2:2322afea6ecf
- Parent:
- 1:9b27a9710d94
- Child:
- 3:fd5273a70b21
File content as of revision 2:2322afea6ecf:
/* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * ------- BLE Peripheral UART function -------------------------------- * --- Tested on Switch Science mbed TY51822r3 --- * * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * * Started: March 7th, 2016 * Revised: April 17th, 2016 * * Original program: * BLE_LoopbackUART * https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LoopbackUART/ * Tested Controller Device: * BLE_Uart_Client * https://developer.mbed.org/users/kenjiArai/code/BLE_Uart_Client/ * */ // Include --------------------------------------------------------------------------------------- #include "mbed.h" #include "BLE.h" #include "UARTService.h" #include "nRF51_Vdd.h" #include "nRF51_WakeUp.h" // Definition ------------------------------------------------------------------------------------ #define GOTO_SLEEP_MODE 0 #define NEED_CONSOLE_OUTPUT 0 #if NEED_CONSOLE_OUTPUT #define DEBUG(...) { printf(__VA_ARGS__); } #else #define DEBUG(...) #endif // Object ---------------------------------------------------------------------------------------- BLEDevice ble; DigitalOut connectedLED(LED2); InterruptIn wake_up_sw(P0_1); nRF51_WakeUp wakeup(LED1, P0_0); nRF51_Vdd vdd(3.0f, 2.2f); Serial pc(USBTX, USBRX); UARTService *uartServicePtr; Ticker ticker; // ROM / Constant data --------------------------------------------------------------------------- #warning "You need to confirm your device name." const char *deviceName = "UART_P"; // RAM ------------------------------------------------------------------------------------------- Gap::Address_t my_mac; uint8_t tx_buf[24]; uint8_t tx_len = 0; uint8_t rx_buf[24]; uint8_t rx_len = 0; volatile bool trigger_transmit = false; volatile bool trigger_receive = false; volatile uint8_t command_continue = 0; uint16_t time_out_cntr = 3600; volatile bool time_out = false; bool line_input = false; uint8_t linebuf_irq[24]; int linebf_irq_len = 0; uint8_t linebuf[24]; int linebf_len = 0; // Function prototypes --------------------------------------------------------------------------- // BLE void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params); void onDataWritten(const GattWriteCallbackParams *params); void periodicCallback(void); // Application related void adjust_line(uint8_t *bf); void action_tx_help(void); void action_tx_vdd(void); void action_tx_temperature(void); void action_tx_pwrup(void); void action_tx_pwrdwn(void); void fill_space_n(uint8_t *bf, uint8_t n); void Update_Values(void); // Interrupt related void action_tx_quit(void); void interrupt_by_sw(void); void serialRxCallback(void); //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- int main(void){ connectedLED = 0; pc.attach(&serialRxCallback, Serial::RxIrq); ticker.attach(periodicCallback, 1); for (int k = 0; k < 20; k++) { pc.printf("\r\n");} // clear terminal output pc.printf("UART Communication / Peripheral side\r\n"); // opening message pc.printf(" Client(Central) and Peripheral(device)\r\n"); // opening message // Interrupt by switch wake_up_sw.fall(&interrupt_by_sw); ble.init(); Gap::AddressType_t my_mac_type; ble.gap().getAddress(&my_mac_type, my_mac); pc.printf( " my_MAC %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0], (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random" ); pc.printf( " mac_board_? = {0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x};\r\n", my_mac[0], my_mac[1], my_mac[2], my_mac[3], my_mac[4], my_mac[5] ); pc.printf(" Please write above mac_board_?(?=1,2,...) data into Client main.cpp\r\n"); ble.setDeviceName((const uint8_t *)deviceName); ble.onDisconnection(disconnectionCallback); ble.onDataWritten(onDataWritten); /* setup advertising */ ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)deviceName, strlen(deviceName) ); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed) ); // Advertize Interval ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */ // Start ble.startAdvertising(); UARTService uartService(ble); uartServicePtr = &uartService; while(true){ if (time_out){ #if GOTO_SLEEP_MODE wakeup.set_and_wait(120); while(true){ // never come here but just in case deepsleep(); } #endif } if (line_input){ line_input = false; adjust_line(linebuf); ble.updateCharacteristicValue( uartServicePtr->getRXCharacteristicHandle(), linebuf, 20 ); } if (trigger_transmit){ trigger_transmit = false; pc.printf("%s\r\n", rx_buf); if (rx_buf[0] == '*'){ switch (rx_buf[1]){ case 'v': action_tx_vdd(); break; case 't': action_tx_temperature(); break; case 'q': action_tx_quit(); break; case 'h': case '?': action_tx_help(); break; default: break; } } } ble.waitForEvent(); } } void serialRxCallback(){ char c = pc.getc(); if (c == '\r') { linebuf_irq[linebf_irq_len++] = c; pc.printf("\r\n"); linebf_len = linebf_irq_len; strcpy((char *)linebuf, (char *)linebuf_irq); linebf_irq_len = 0; line_input = true; } else if ((c == '\b') && linebf_irq_len) { linebf_irq_len--; pc.putc(c); pc.putc(' '); pc.putc(c); } else if (((uint8_t)c >= ' ') && (linebf_irq_len < 20)) { linebuf_irq[linebf_irq_len++] = c; pc.putc(c); } else if ( c == 0x1f ){ // Control+? SCB->AIRCR = 0x05fa0004; // System RESET!! } linebuf_irq[linebf_irq_len] = 0; } void adjust_line(uint8_t *bf){ uint8_t i, c; for (i = 0; i <20; bf++, i++){ c = *bf; if ( (c == '\r') || (c == '\n') || (c == 0)){ break; } } for (; i < 20; bf++, i++){ *bf = ' '; } *(bf + 1) = 0; } void onDataWritten(const GattWriteCallbackParams *params){ if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) { strcpy((char *)rx_buf, (const char *)params->data); rx_len = params->len; trigger_transmit = true; DEBUG("RX_data\r\n"); DEBUG("Length: %d\r\n", rx_len); DEBUG("Data: "); DEBUG("%s", rx_buf); DEBUG("\r\n"); } } void action_tx_help(){ // 12345678901234567890 sprintf((char *)tx_buf,"?:help by JH1PJL"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.2); // 12345678901234567890 sprintf((char *)tx_buf,"v:vdd"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.2); // 12345678901234567890 sprintf((char *)tx_buf,"t:temperature"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.2); // 12345678901234567890 sprintf((char *)tx_buf,"q:quit/sleep"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.2); } void action_tx_vdd(){ sprintf((char *)tx_buf,"Vdd:%3.2fV", vdd.read_real_value()); tx_len = strlen((const char *)tx_buf); Update_Values(); } void action_tx_temperature(){ int32_t p_temp; float temperature; // Update a temperature (inside nRF51822 chip) sd_temp_get(&p_temp); // -16.0f is offset vale for chip die temp to ambient temp (depend on your board) temperature = float(p_temp) / 4; // Original = float(p_temp)/4.0f - 16.0f; sprintf((char *)tx_buf,"T:%+4.1fdC", temperature); tx_len = strlen((const char *)tx_buf); Update_Values(); } void action_tx_quit(){ #if GOTO_SLEEP_MODE ticker.detach(); // 12345678901234567890 sprintf((char *)tx_buf,"Terminated the BLE"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(1.0); wakeup.set_and_wait(120); while(true){ // never come here but just in case deepsleep(); } #else SCB->AIRCR = 0x05fa0004; // System RESET!! #endif } void interrupt_by_sw(){ // Go to sleep NVIC_SystemReset(); // Not come here (Just in case) deepsleep(); } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){ DEBUG("Disconnected!\r\n"); DEBUG("Restarting the advertising process\r\n"); ble.startAdvertising(); } void periodicCallback(void){ #if GOTO_SLEEP_MODE if (--time_out_cntr == 0){ time_out = true; } #endif } void Update_Values(void){ ble.updateCharacteristicValue( uartServicePtr->getRXCharacteristicHandle(), tx_buf, tx_len ); DEBUG("TX_data: %s\r\n", tx_buf); DEBUG("Length: %d\r\n", tx_len); tx_len = 0; }