Run on TY51822r3 board with ACC sensor (LIS3DH or BMC050)
Dependencies: BLE_API LIS3DH mbed nRF51822 BMC050 nRF51_LowPwr nRF51_Vdd
Fork of BLE_EddystoneBeacon_Service by
main.cpp
- Committer:
- kenjiArai
- Date:
- 2016-06-01
- Revision:
- 36:5508506dda71
- Parent:
- 35:c64495aac4d1
- Child:
- 37:ea459e6c6a35
File content as of revision 36:5508506dda71:
/* 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. */ /* * /////// Works well on Switch Science mbed TY51822r3 /////// * Modified by Kenji Arai * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * * Started: Feburary 1st, 2016 * Revised: June 1st, 2016 * * Original: * nRF51822_SimpleControls * https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_EddystoneBeacon_Service/ * Tested Controller Device: * iPhone6 Physical Web (PhyWeb) By Viet Hoa Dinh * https://itunes.apple.com/us/app/physical-web/id927653608?mt=8 */ /* * STEP1 * If you just got the board, plese set following difinition and not connect all of pins. #define USE_ACC 0 #define CHK_ACC 0 #define USE_DEVICE_SERIAL 0 // in nRF51_disable_peripheral.h #define ACC_DEVIC x // No effect * STEP2 * If you equiped the Acc sensor, please check ACC data using folloing definition. #define USE_ACC 1 #define CHK_ACC 1 #define USE_DEVICE_SERIAL 1 // in nRF51_disable_peripheral.h #define ACC_DEVIC 0 or 1 // depends on your sensor device * STEP3 * This is a final setup without no debug information. #define USE_ACC 1 #define CHK_ACC 0 #define USE_DEVICE_SERIAL 0 // in nRF51_disable_peripheral.h #define ACC_DEVIC 0 or 1 // depends on your sensor device * */ #define ACC_DEVIC 1 // 0=LIS3DH, 1=BMC050 // Include --------------------------------------------------------------------------------------- #include "mbed.h" #include "BLE.h" #include "EddystoneService.h" #if ACC_DEVIC #include "BMC050.h" #else #include "LIS3DH.h" #endif // ACC_DEVIC #include "nRF51_Vdd.h" #include "nRF51_lowpwr.h" // Definition ------------------------------------------------------------------------------------ #define USE_ACC 1 // if you equipped ACC sensor, please set 1 #define CHK_ACC 0 #define POWER_LEVEL 0 // 0,1,2 // 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 1 // 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 #define DEBUG(...) { printf(__VA_ARGS__); } #else #define DEBUG(...) #endif #if USE_DEVICE_SERIAL #define BAUD(x) pc.baud(x) #define GETC(x) pc.getc(x) #define PUTC(x) pc.putc(x) #define PRINTF(...) { pc.printf(__VA_ARGS__); } #define READABLE(x) pc.readable(x) #define ATTACH(x,y) pc.attach(x, y); #else #define BAUD(x) #define GETC(x) 'c' #define PUTC(x) #define PRINTF(...) #define READABLE(x) #define ATTACH(x,y) #endif // RAM ------------------------------------------------------------------------------------------- EddystoneService *eddyServicePtr; Gap::Address_t my_mac; // ROM / Constant data --------------------------------------------------------------------------- #if (USE_ACC == 1) && (ACC_DEVIC == 1) const BMC050ACC_TypeDef acc_parameter = { BMC050_A_G_CHIP_ADDR, // I2C Address BMC050_FS_2G, // G-range slection BMC050_BW_250, // Bandwidth }; const BMC050MAG_TypeDef mag_parameter = { BMC050_MAG_NOT_USED_ADDR,// Not use mag sensor BMC050_DUMMY // dummy }; #endif 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 }; // Function prototypes --------------------------------------------------------------------------- int8_t check_dice(void); uint16_t update_vdd(uint16_t x); uint16_t update_temp(uint16_t x); void onBleInitError(BLE::InitializationCompleteCallbackContext* initContext); void bleInitComplete(BLE::InitializationCompleteCallbackContext* initContext); // Object ---------------------------------------------------------------------------------------- DigitalOut CHG_LED(LED1); #if USE_DEVICE_SERIAL Serial pc(USBTX, USBRX); #endif // USE_DEVICE_SERIAL nRF51_Vdd vdd(3.6f, 1.8f, ONLY4VDD); #if USE_ACC == 1 I2C i2c(P0_3, P0_4); // SDA, SCL #if ACC_DEVIC BMC050 acc(i2c, &acc_parameter, &mag_parameter); #else LIS3DH acc(i2c,LIS3DH_G_CHIP_ADDR,LIS3DH_DR_NR_LP_50HZ, LIS3DH_FS_2G); #endif // ACC_DEVIC #endif // USE_ACC == 1 //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- void bleInitComplete(BLE::InitializationCompleteCallbackContext* initContext){ BLE &ble = initContext->ble; ble_error_t error = initContext->error; if (error != BLE_ERROR_NONE) { onBleInitError(initContext); return; } // Set UID and TLM frame data const UIDNamespaceID_t uidNamespaceID = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}; const UIDInstanceID_t uidInstanceID = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; uint8_t tlmVersion = 0x00; Gap::AddressType_t my_mac_type; ble.gap().getAddress(&my_mac_type, my_mac); 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" ); 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] ); // Initialize a EddystoneBeaconConfig service // Values for ADV packets related to firmware levels, calibrated based on measured values at 1m #if POWER_LEVEL == 0 static const PowerLevels_t defaultAdvPowerLevels = {-47, -33, -21, -13}; #elif POWER_LEVEL == 1 static const PowerLevels_t defaultAdvPowerLevels = {-87, -73, -61, -53}; #else static const PowerLevels_t defaultAdvPowerLevels = {-107, -93, -81, -73}; #endif // POWER_LEVEL // Values for radio power levels, provided by manufacturer. #if POWER_LEVEL == 0 static const PowerLevels_t radioPowerLevels = {-30, -16, -4, 4}; #elif POWER_LEVEL == 1 static const PowerLevels_t radioPowerLevels = {-60, -46, -34, -26}; #else static const PowerLevels_t radioPowerLevels = {-90, -76, -64, -56}; #endif // POWER_LEVEL eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels); // created short cut web addres by http://bitly.oshiire.org/ switch (check_dice()){ case 1: eddyServicePtr->setURLData("http://bit.ly/1oJh91B"); // Switch sience(mbed) break; case 2: eddyServicePtr->setURLData("http://bit.ly/1oJhP7g"); // switch sience(HP) break; case 3: eddyServicePtr->setURLData("http://bit.ly/1VvuCVr"); // Taiyo Yuden BLE break; case 4: eddyServicePtr->setURLData("http://bit.ly/1Vvtp0l"); // Taiyo Yuden break; case 5: eddyServicePtr->setURLData("http://bit.ly/1Vvt51J"); // JH1PJL(mbed) break; case 6: eddyServicePtr->setURLData("http://bit.ly/1VvteT0"); // JH1PJL(HP) break; case 0: default: eddyServicePtr->setURLData("http://mbed.org"); break; } eddyServicePtr->setUIDData(&uidNamespaceID, &uidInstanceID); eddyServicePtr->setTLMData(tlmVersion); eddyServicePtr->onTLMBatteryVoltageUpdate(&update_vdd); eddyServicePtr->onTLMBeaconTemperatureUpdate(&update_temp); eddyServicePtr->startBeaconService(5, 5, 5); // Start Eddystone in config mode } #if (CHK_ACC == 0) int main(void){ uint8_t old_dice; CHG_LED = 1; LowPwr set_lowpwr(&lowpwr_table); BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); ble.init(bleInitComplete); while (ble.hasInitialized() == false){;} old_dice = check_dice(); // set initial value wait(0.5); CHG_LED = 0; while (true) { ble.waitForEvent(); if (old_dice != check_dice()){ SCB->AIRCR = 0x05fa0004; // System RESET!![ // Not come here (Just in case) deepsleep(); while(true){ wait(100);} } } } #else #if (USE_ACC == 0) #error "Please set USE_ACC = 1) #else int main(void){ float fa[3]; while (true){ if (acc.read_id_acc() == I_AM_BMC050_ACC){ PRINTF("I'm BMC050\r\n"); acc.read_data_acc(fa); break; } else { PRINTF("I'm NOT BMC050\r\n"); } wait(1.0); } LowPwr set_lowpwr(&lowpwr_table); while (true) { #if ACC_DEVIC acc.read_data_acc(fa); #else acc.read_data(fa); #endif PRINTF("acc:x=%+4.2f,y=%+4.2f,z=%+4.2f\r\n",fa[0],fa[1],fa[2]); wait(0.5); } } #endif // (USE_ACC == 0) #endif // (CHK_ACC == 0) #if (USE_ACC == 1) int8_t check_dice(void){ float fa[3]; // Acc 0:X, 1:Y, 2:Z #if ACC_DEVIC acc.read_data_acc(fa); #else acc.read_data(fa); #endif //PRINTF("acc:%4.3f\r\n", fa[0]); PRINTF("acc:x=%+4.2f,y=%+4.2f,z=%+4.2f\r\n",fa[0],fa[1],fa[2]); if (fa[0] > 6.0f){ return 2;} if (fa[0] < -6.0f){ return 5;} if (fa[1] > 6.0f){ return 4;} if (fa[1] < -6.0f){ return 3;} if (fa[2] > 6.0f){ return 1;} if (fa[2] < -6.0f){ return 6;} return 0; } #else int8_t check_dice(void){ return 1; } #endif // (USE_ACC == 1) void onBleInitError(BLE::InitializationCompleteCallbackContext* initContext){ // Initialization error handling goes here... (void) initContext; } // Update Vdd data uint16_t update_vdd(uint16_t x){ #if USE_DEVICE_SERIAL float v; v = vdd.read_real_value(); PRINTF("Vdd:%f[V]\r\n", v); return (uint16_t)(v * 1000); #else return (uint16_t)(vdd.read_real_value() * 1000); #endif // USE_DEVICE_SERIAL } // Update Temperature data uint16_t update_temp(uint16_t x){ float t; uint16_t temp; int32_t p_temp; NRF_TEMP->TASKS_START = 1; while (NRF_TEMP->EVENTS_DATARDY == 0){;} NRF_TEMP->EVENTS_DATARDY = 0; if ((NRF_TEMP->TEMP & 0x00000200) != 0){ p_temp = (NRF_TEMP->TEMP | 0xFFFFFC00); } else { p_temp = NRF_TEMP->TEMP; } NRF_TEMP->TASKS_STOP = 1; /** Stop the temperature measurement. */ t = float(p_temp) / 4; // Original = float(p_temp)/4.0f - 16.0f; #if USE_DEVICE_SERIAL PRINTF("Chip temp: %+4.1f[degC]\r\n", t); #endif if ( t >= 0){ temp = (uint16_t)(t * 256); } else { temp = (uint16_t)(t * -256); temp = 0x10000 - temp; } return temp; }