You can control from iPhone and put some command. h=show commands help, v=show TY51822r3 VDD data, t=show chip temperature, q=you can make deep sleep condition.
Dependencies: BLE_API mbed nRF51822 nRF51_Vdd nRF51_WakeUp nRF51_LowPwr
Fork of BLE_LoopbackUART by
Please refer follows.
/users/kenjiArai/notebook/ty51822r3-current-consumption-using-nrf51_wakeup-l/#
main.cpp
- Committer:
- kenjiArai
- Date:
- 2016-06-11
- Revision:
- 16:c8f4e56fa239
- Parent:
- 15:d7764da3f37c
File content as of revision 16:c8f4e56fa239:
/* 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. */ /* * /////// Tested on Switch Science mbed TY51822r3 /////// * Modified by Kenji Arai * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * * Started: March 7th, 2016 * Revised: June 11th, 2016 * * Original program: * BLE_LoopbackUART * https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LoopbackUART/ * Tested Controller Device: * iPhone6 nRF UART by Nordic * https://itunes.apple.com/us/app/nrf-uart/id614594903?mt=8 * */ // Include --------------------------------------------------------------------------------------- #include <string.h> #include "mbed.h" #include "BLE.h" #include "UARTService.h" #include "nRF51_Vdd.h" #include "nRF51_WakeUp.h" #include "nRF51_lowpwr.h" // Definition ------------------------------------------------------------------------------------ // Before using this function, please specify your program are used following functions or not. #define USE_DEVICE_STDIO_MESSAGES 0 // printf #define USE_DEVICE_SERIAL 0 // Serial or DEBUG & etc. #define USE_DEVICE_I2C 0 // Sensors with I2C, LCD, EEPROM, Driver chips & etc. #define USE_DEVICE_SPI 0 // Sensors with SOI, LCD, EEPROM, Driver chips & etc. #define USE_DEVICE_SPISLAVE 0 // Communication with master vis SPI #define USE_DEVICE_PWMOUT 0 // PWM duty output, Serve & etc. #define USE_DEVICE_ANALOGIN 0 // Analog adc #if USE_DEVICE_STDIO_MESSAGES // See disable_cpu_functions.h #define DEBUG(...) { printf(__VA_ARGS__); } #else #define DEBUG(...) #endif #define HIGH_PWR 1 #define TXRX_BUF_LEN 22 // send & receive number = 20 #define PWR_RANG_NO 8 enum TX_Content { TX_VDD = 1, TX_TEMP, TX_PWR_UP, TX_PWR_DWN, TX_QUIT, TX_HELP }; // Object ---------------------------------------------------------------------------------------- BLEDevice ble; DigitalOut myled(LED2); InterruptIn wake_up_sw(P0_1); // If you change P0_1, you also need to change PORT_OUTPUT. nRF51_WakeUp wakeup(LED1, P0_0); nRF51_Vdd vdd(3.0f, 2.2f, ONLY4VDD); UARTService *uartServicePtr; Ticker ticker; #if USE_DEVICE_STDIO_MESSAGES Serial pc(P0_4,P0_0); #endif // ROM / Constant data --------------------------------------------------------------------------- const char *deviceName = "JH1PJL"; const uint8_t pwr_range[PWR_RANG_NO] = { RADIO_TXPOWER_TXPOWER_Neg30dBm,/*!< -30dBm. */ RADIO_TXPOWER_TXPOWER_Neg20dBm,/*!< -20dBm. */ RADIO_TXPOWER_TXPOWER_Neg16dBm,/*!< -16dBm. */ RADIO_TXPOWER_TXPOWER_Neg12dBm,/*!< -12dBm. */ RADIO_TXPOWER_TXPOWER_Neg8dBm, /*!< -8dBm. */ RADIO_TXPOWER_TXPOWER_Neg4dBm, /*!< -4dBm. */ RADIO_TXPOWER_TXPOWER_0dBm, /*!< 0dBm. */ RADIO_TXPOWER_TXPOWER_Pos4dBm, /*!< +4dBm. */ }; const nRF51_LOWPWR_TypeDef lowpwr_table = { #if USE_DEVICE_STDIO_MESSAGES true, #else false, #endif #if USE_DEVICE_SERIAL true, #else false, #endif #if USE_DEVICE_I2C true, #else false, #endif #if USE_DEVICE_SPI true, #else false, #endif #if USE_DEVICE_SPISLAVE true, #else false, #endif #if USE_DEVICE_PWMOUT true, #else false, #endif #if USE_DEVICE_ANALOGIN true #else false #endif }; // RAM ------------------------------------------------------------------------------------------- uint8_t tx_buf[TXRX_BUF_LEN]; uint8_t tx_len=0; uint8_t time_data[TXRX_BUF_LEN]; uint8_t pwr_selection; volatile bool trigger_transmit = false; volatile bool trigger_receive = false; volatile uint8_t command_continue = 0; TX_Content transmit_contents; uint8_t time_out_cntr = 30; volatile bool time_out = false; // Function prototypes --------------------------------------------------------------------------- // BLE void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params); void onDataWritten(const GattWriteCallbackParams *params); void periodicCallback(void); // Application related 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); //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- int main(void){ LowPwr set_lowpwr(&lowpwr_table); myled = 1; ticker.attach(periodicCallback, 1); // Interrupt by switch wake_up_sw.fall(&interrupt_by_sw); DEBUG("Initialising the nRF51822\r\n"); ble.init(); //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) ); // Power #if HIGH_PWR pwr_selection = 7; #else pwr_selection = 0; #endif ble.gap().setTxPower(pwr_range[pwr_selection]); // Advertize Interval ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */ // Start ble.startAdvertising(); UARTService uartService(ble); uartServicePtr = &uartService; while(true){ if (time_out){ myled = 0; wakeup.set_and_wait(30); while(true){ // never come here but just in case deepsleep(); } } if (trigger_transmit){ trigger_transmit = false; switch(transmit_contents){ case TX_VDD: action_tx_vdd(); break; case TX_TEMP: action_tx_temperature(); break; case TX_QUIT: action_tx_quit(); break; case TX_PWR_UP: action_tx_pwrup(); break; case TX_PWR_DWN: action_tx_pwrdwn(); break; case TX_HELP: action_tx_help(); break; default: break; } } else { myled = !myled; ble.waitForEvent(); } } } void led_control(float t){ myled = !myled; wait(t); } void onDataWritten(const GattWriteCallbackParams *params){ uint8_t buf[TXRX_BUF_LEN]; uint16_t bytesRead; if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) { strcpy((char *)buf, (const char *)params->data); bytesRead = params->len; switch (buf[0]){ case 'v': trigger_transmit = true; transmit_contents = TX_VDD; break; case 't': trigger_transmit = true; transmit_contents = TX_TEMP; break; case 'u': trigger_transmit = true; transmit_contents = TX_PWR_UP; break; case 'd': trigger_transmit = true; transmit_contents = TX_PWR_DWN; break; case 'q': trigger_transmit = true; transmit_contents = TX_QUIT; break; case 'h': case '?': trigger_transmit = true; transmit_contents = TX_HELP; break; default: break; } fill_space_n(buf, bytesRead); DEBUG("RX_data\r\n"); DEBUG("Length: %d\r\n", bytesRead); DEBUG("Data: "); DEBUG("%s", 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.1); // 12345678901234567890 sprintf((char *)tx_buf,"v:vdd"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.1); // 12345678901234567890 sprintf((char *)tx_buf,"t:temperature"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.1); // 12345678901234567890 sprintf((char *)tx_buf,"u:power up"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.1); // 12345678901234567890 sprintf((char *)tx_buf,"d:power down"); tx_len = strlen((const char *)tx_buf); Update_Values(); wait(0.1); // 12345678901234567890 sprintf((char *)tx_buf,"q(0x71):quit/sleep"); tx_len = strlen((const char *)tx_buf); Update_Values(); } void action_tx_pwrup(){ if (pwr_selection != 0){ --pwr_selection; } ble.gap().setTxPower(pwr_range[pwr_selection]); sprintf((char *)tx_buf,"Pwr:%+ddBm", (4 - (pwr_selection * 4))); tx_len = strlen((const char *)tx_buf); Update_Values(); } void action_tx_pwrdwn(){ if (pwr_selection != (PWR_RANG_NO - 1)){ ++pwr_selection; } ble.gap().setTxPower(pwr_range[pwr_selection]); sprintf((char *)tx_buf,"Pwr:%+ddBm", (4 - (pwr_selection * 4))); tx_len = strlen((const char *)tx_buf); Update_Values(); } 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(){ ticker.detach(); // 12345678901234567890 sprintf((char *)tx_buf,"Terminated the BLE"); tx_len = strlen((const char *)tx_buf); Update_Values(); myled = 0; wait(1.0); wakeup.set_and_wait(30); while(true){ // never come here but just in case deepsleep(); } } 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 (--time_out_cntr == 0){ time_out = true; } } void fill_space_n(uint8_t *bf, uint8_t n){ bf += n; for (uint8_t i = n; i <= 20; bf++, i++){ *bf = ' '; } *bf = '.'; *(bf + 1) = 0; } 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; }