Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
|
1. In troduction to Glove-In-Command
ST-sensorTile is one of comprehensive development kit designed to IoT designs. I have completed one prototype for Gesture capture handle based on ST MCU and one simple APP to for Angle Sensor Data communication.
This Glove-In-Command shall include more information of motion like accel, gyro and angle sensors. The sensoTile shall be embedded in the glove.
Response to at least double tap, sweep, the Glove-In-Command can send be motion sensor Mux and directing command directly to mobile APP to show the result.
2. Software and hardware
2.1 With ST-cubeMX for coding, the BlueMS APP on android for test.FP-SNS-MOTENV1 shall be used as reference for coding
2.2 SensorTile and one glove is needed for this design. Since it includes everything needed, even the battery. For Racing car part, I will use one Nucleo board STM32-Nucleo-L476 and one extension board as hardware for debug.
2.3 Code shall can be flashed into the sensortile.
3. The design shall monitor the angle and variation of sensorTile, the data shall be collected and sent. The Data shall be received via BLE for data fetching.
In cordova CLI, run 'cordova run', with the following screenshot,
One cavas can show the diagram. The data shall be quantified as less than 1.28 for better Visual effect.
app.onConnectButton = function() {
if(app.device) return;
evothings.easyble.stopScan();
app.status("Scanning...");
evothings.easyble.startScan(
function(device) {
if(app.connecting) return;
if(app.isMG(device)) {
evothings.easyble.stopScan();
app.connect(device);
}
},
function(errorCode) {
// Report error.
callbackFun(null, errorCode);
},
{allowDuplicates:false}
);
}
app.isMG = function(device) {
return device.name == "MAGICGV";
}
4. The process is complete and it can be fitted into other mobile APP or sensor Hub center for better data.
/**
******************************************************************************
* @file main.c
* @date 2017-04-27
******************************************************************************
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include "TargetFeatures.h"
#include "main.h"
#include "sensor_service.h"
#include "bluenrg_utils.h"
#include "HWAdvanceFeatures.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Imported Variables -------------------------------------------------------------*/
extern uint8_t set_connectable;
extern int connected;
#ifdef MOTENV_ENABLE_PRINTF
extern TIM_HandleTypeDef TimHandle;
extern void CDC_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif /* MOTENV_ENABLE_PRINTF */
/* Exported Variables -------------------------------------------------------------*/
/* Acc sensitivity multiply by FROM_MG_TO_G constant */
float sensitivity_Mul;
uint32_t ConnectionBleStatus =0;
uint8_t BufferToWrite[256];
int32_t BytesToWrite;
TIM_HandleTypeDef TimCCHandle;
uint8_t bdaddr[6];
uint32_t uhCCR4_Val = DEFAULT_uhCCR4_Val;
uint32_t uhCCR1_Val = DEFAULT_uhCCR1_Val;
/* Private variables ---------------------------------------------------------*/
static volatile int ButtonPressed =0;
static volatile int MEMSInterrupt =0;
static volatile uint32_t HCI_ProcessEvent=0;
static volatile uint32_t SendAccGyroMag =0;
static volatile uint32_t SendMG =0; // Send
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Init_BlueNRG_Custom_Services(void);
static void Init_BlueNRG_Stack(void);
static void InitTimers(void);
static void ButtonCallback(void);
static void SendMotionData(void);
static void SendMGData(void); // Send
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
HAL_Init();
/* Configure the System clock */
SystemClock_Config();
InitTargetPlatform(TARGET_SENSORTILE);
/* Initialize the BlueNRG */
Init_BlueNRG_Stack();
/* Initialize the BlueNRG Custom services */
Init_BlueNRG_Custom_Services();
if(TargetBoardFeatures.HWAdvanceFeatures) {
InitHWFeatures();
}
/* Set Full Scale to +/-2g */
(TargetBoardFeatures.SnsAltFunc ? BSP_ACCELERO_Set_FS_Value_IKS01A2 : BSP_ACCELERO_Set_FS_Value)(TargetBoardFeatures.HandleAccSensor,2.0f);
/* Read the Acc Sensitivity */
(TargetBoardFeatures.SnsAltFunc ? BSP_ACCELERO_Get_Sensitivity_IKS01A2 : BSP_ACCELERO_Get_Sensitivity)(TargetBoardFeatures.HandleAccSensor,&sensitivity_Mul);
sensitivity_Mul *= ((float) FROM_MG_TO_G);
/* initialize timers */
InitTimers();
/* Infinite loop */
while (1){
/* Led Blinking when there is not a client connected */
if(!connected) {
if(!TargetBoardFeatures.LedStatus) {
if(!(HAL_GetTick()&0x3FF)) {
LedOnTargetPlatform();
}
} else {
if(!(HAL_GetTick()&0x3F)) {
LedOffTargetPlatform();
}
}
}
/* Handle user button */
if(ButtonPressed) {
ButtonCallback();
ButtonPressed=0;
}
/* handle BLE event */
if(HCI_ProcessEvent) {
HCI_ProcessEvent=0;
HCI_Process();
}
if(set_connectable){
/* Now update the BLE advertize data and make the Board connectable */
setConnectable();
set_connectable = FALSE;
}
/* Motion Data */
if(SendAccGyroMag) {
SendAccGyroMag=0;
SendMGData();
}
/* Wait for Event */
__WFI();
}
}
/**
* @brief Output Compare callback in non blocking mode
* @param htim : TIM OC handle
* @retval None
*/
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
uint32_t uhCapture=0;
/* TIM1_CH1 toggling with frequency = 2Hz */
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
/* Set the Capture Compare Register value */
__HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_1, (uhCapture + uhCCR1_Val));
SendMG=1;
}
/* TIM1_CH4 toggling with frequency = 20 Hz */
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);
/* Set the Capture Compare Register value */
__HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_4, (uhCapture + uhCCR4_Val));
SendAccGyroMag=1;
}
}
#ifdef STM32_SENSORTILE
#ifdef MOTENV_ENABLE_PRINTF
/**
* @brief Period elapsed callback in non blocking mode for Environmental timer
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == (&TimHandle)) {
CDC_TIM_PeriodElapsedCallback(htim);
}
}
#endif /* MOTENV_ENABLE_PRINTF */
#endif /* STM32_SENSORTILE */
/**
* @brief Callback for user button
* @param None
* @retval None
*/
static void ButtonCallback(void)
{
MOTENV_PRINTF("UserButton Pressed\r\n");
}
/**
* @brief SendMGData() // SendData()
* @param None
* @retval None
*/
static void SendMGData(void)
{
SensorAxes_t ACC_Value;
SensorAxes_t GYR_Value;
SensorAxes_t MAG_Value;
/* Read the Acc values */
(TargetBoardFeatures.SnsAltFunc ? BSP_ACCELERO_Get_Axes_IKS01A2 : BSP_ACCELERO_Get_Axes)(TargetBoardFeatures.HandleAccSensor,&ACC_Value);
/* Read the Magneto values */
(TargetBoardFeatures.SnsAltFunc ? BSP_MAGNETO_Get_Axes_IKS01A2 : BSP_MAGNETO_Get_Axes)(TargetBoardFeatures.HandleMagSensor,&MAG_Value);
/* Read the Gyro values */
(TargetBoardFeatures.SnsAltFunc ? BSP_GYRO_Get_Axes_IKS01A2 : BSP_GYRO_Get_Axes)(TargetBoardFeatures.HandleGyroSensor,&GYR_Value);
SendMG_Notify(&ACC_Value,&GYR_Value,&MAG_Value); // SendData()
}
/**
* @brief Send Motion Data Acc/Mag/Gyro to BLE
* @param None
* @retval None
*/
static void SendMotionData(void)
{
SensorAxes_t ACC_Value;
SensorAxes_t GYR_Value;
SensorAxes_t MAG_Value;
/* Read the Acc values */
(TargetBoardFeatures.SnsAltFunc ? BSP_ACCELERO_Get_Axes_IKS01A2 : BSP_ACCELERO_Get_Axes)(TargetBoardFeatures.HandleAccSensor,&ACC_Value);
/* Read the Magneto values */
(TargetBoardFeatures.SnsAltFunc ? BSP_MAGNETO_Get_Axes_IKS01A2 : BSP_MAGNETO_Get_Axes)(TargetBoardFeatures.HandleMagSensor,&MAG_Value);
/* Read the Gyro values */
(TargetBoardFeatures.SnsAltFunc ? BSP_GYRO_Get_Axes_IKS01A2 : BSP_GYRO_Get_Axes)(TargetBoardFeatures.HandleGyroSensor,&GYR_Value);
AccGyroMag_Update(&ACC_Value,&GYR_Value,&MAG_Value);
}
/**
* @brief Function for initializing timers for sending the information to BLE:
* - 1 for sending MotionFX/AR/CP and Acc/Gyro/Mag
* - 1 for sending the Environmental info
* @param None
* @retval None
*/
static void InitTimers(void)
{
uint32_t uwPrescalerValue;
/* Timer Output Compare Configuration Structure declaration */
TIM_OC_InitTypeDef sConfig;
/* Compute the prescaler value to have TIM3 counter clock equal to 10 KHz */
uwPrescalerValue = (uint32_t) ((SystemCoreClock / 10000) - 1);
/* Set TIM1 instance (Motion)*/
/* Set TIM1 instance */
#if ((defined (USE_STM32F4XX_NUCLEO)) || (defined (USE_STM32L4XX_NUCLEO)))
TimCCHandle.Instance = TIM1;
#elif (defined (USE_STM32L0XX_NUCLEO))
TimCCHandle.Instance = TIM2;
#endif
TimCCHandle.Init.Period = 65535;
TimCCHandle.Init.Prescaler = uwPrescalerValue;
TimCCHandle.Init.ClockDivision = 0;
TimCCHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_OC_Init(&TimCCHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Configure the Output Compare channels */
/* Common configuration for all channels */
sConfig.OCMode = TIM_OCMODE_TOGGLE;
sConfig.OCPolarity = TIM_OCPOLARITY_LOW;
/* Output Compare Toggle Mode configuration: Channel1 */
sConfig.Pulse = DEFAULT_uhCCR1_Val;
if(HAL_TIM_OC_ConfigChannel(&TimCCHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
/* Output Compare Toggle Mode configuration: Channel4 */
sConfig.Pulse = DEFAULT_uhCCR4_Val;
if(HAL_TIM_OC_ConfigChannel(&TimCCHandle, &sConfig, TIM_CHANNEL_4) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
}
/** @brief Initialize the BlueNRG Stack
* @param None
* @retval None
*/
static void Init_BlueNRG_Stack(void)
{
const char BoardName[8] = {NAME_MOTENV,0};
uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
int ret;
uint8_t hwVersion;
uint16_t fwVersion;
#ifdef MAC_MOTENV
{
uint8_t tmp_bdaddr[6]= {MAC_MOTENV};
int32_t i;
for(i=0;i<6;i++)
bdaddr[i] = tmp_bdaddr[i];
}
#endif /* MAC_MOTENV */
#ifndef STM32_NUCLEO
/* Initialize the BlueNRG SPI driver */
BNRG_SPI_Init();
#endif /* STM32_NUCLEO */
/* Initialize the BlueNRG HCI */
HCI_Init();
/* Reset BlueNRG hardware */
BlueNRG_RST();
/* get the BlueNRG HW and FW versions */
getBlueNRGVersion(&hwVersion, &fwVersion);
if (hwVersion > 0x30) {
/* X-NUCLEO-IDB05A1 expansion board is used */
TargetBoardFeatures.bnrg_expansion_board = IDB05A1;
} else {
/* X-NUCLEO-IDB0041 expansion board is used */
TargetBoardFeatures.bnrg_expansion_board = IDB04A1;
}
/*
* Reset BlueNRG again otherwise it will fail.
*/
BlueNRG_RST();
#ifndef MAC_MOTENV
#ifdef MAC_STM32UID_MOTENV
/* Create a Unique BLE MAC Related to STM32 UID */
{
bdaddr[0] = (STM32_UUID[1]>>24)&0xFF;
bdaddr[1] = (STM32_UUID[0] )&0xFF;
bdaddr[2] = (STM32_UUID[2] >>8)&0xFF;
bdaddr[3] = (STM32_UUID[0]>>16)&0xFF;
#ifdef STM32_NUCLEO
/* if IDB05A1 = Number between 100->199
* if IDB04A1 = Number between 0->99
* where Y == (MOTENV_VERSION_MAJOR + OSX_BMS_VERSION_MINOR)&0xF */
bdaddr[4] = (hwVersion > 0x30) ?
((((MOTENV_VERSION_MAJOR-48)*10) + (MOTENV_VERSION_MINOR-48)+100)&0xFF) :
((((MOTENV_VERSION_MAJOR-48)*10) + (MOTENV_VERSION_MINOR-48) )&0xFF) ;
#else /* STM32_NUCLEO */
bdaddr[4] = (((MOTENV_VERSION_MAJOR-48)*10) + (MOTENV_VERSION_MINOR-48)+100)&0xFF;
#endif /* STM32_NUCLEO */
bdaddr[5] = 0xC0; /* for a Legal BLE Random MAC */
}
#else /* MAC_STM32UID_MOTENV */
{
/* we will let the BLE chip to use its Random MAC address */
uint8_t data_len_out;
ret = aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, 6, &data_len_out, bdaddr);
if(ret){
MOTENV_PRINTF("\r\nReading Random BD_ADDR failed\r\n");
goto fail;
}
}
#endif /* MAC_STM32UID_MOTENV */
#else /* MAC_MOTENV */
ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
CONFIG_DATA_PUBADDR_LEN,
bdaddr);
if(ret){
MOTENV_PRINTF("\r\nSetting Pubblic BD_ADDR failed\r\n");
goto fail;
}
#endif /* MAC_MOTENV */
ret = aci_gatt_init();
if(ret){
MOTENV_PRINTF("\r\nGATT_Init failed\r\n");
goto fail;
}
if (TargetBoardFeatures.bnrg_expansion_board == IDB05A1) {
ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
}else {
ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
}
if(ret != BLE_STATUS_SUCCESS){
MOTENV_PRINTF("\r\nGAP_Init failed\r\n");
goto fail;
}
#ifndef MAC_MOTENV
#ifdef MAC_STM32UID_MOTENV
ret = hci_le_set_random_address(bdaddr);
if(ret){
MOTENV_PRINTF("\r\nSetting the Static Random BD_ADDR failed\r\n");
goto fail;
}
#endif /* MAC_STM32UID_MOTENV */
#endif /* MAC_MOTENV */
ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
7/*strlen(BoardName)*/, (uint8_t *)BoardName);
if(ret){
MOTENV_PRINTF("\r\naci_gatt_update_char_value failed\r\n");
while(1);
}
ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
OOB_AUTH_DATA_ABSENT,
NULL, 7, 16,
USE_FIXED_PIN_FOR_PAIRING, 123456,
BONDING);
if (ret != BLE_STATUS_SUCCESS) {
MOTENV_PRINTF("\r\nGAP setting Authentication failed\r\n");
goto fail;
}
MOTENV_PRINTF("SERVER: BLE Stack Initialized \r\n"
"\t\tBoard type=%s HWver=%d, FWver=%d.%d.%c\r\n"
"\t\tBoardName= %s\r\n"
"\t\tBoardMAC = %x:%x:%x:%x:%x:%x\r\n\n",
(TargetBoardFeatures.bnrg_expansion_board==IDB05A1) ? "IDB05A1" : "IDB04A1",
hwVersion,
fwVersion>>8,
(fwVersion>>4)&0xF,
(hwVersion > 0x30) ? ('a'+(fwVersion&0xF)-1) : 'a',
BoardName,
bdaddr[5],bdaddr[4],bdaddr[3],bdaddr[2],bdaddr[1],bdaddr[0]);
/* Set output power level */
aci_hal_set_tx_power_level(1,4);
return;
fail:
return;
}
/** @brief Initialize all the Custom BlueNRG services
* @param None
* @retval None
*/
static void Init_BlueNRG_Custom_Services(void)
{
int ret;
ret = Add_HWServW2ST_Service();
if(ret == BLE_STATUS_SUCCESS) {
MOTENV_PRINTF("HW Service W2ST added successfully\r\n");
} else {
MOTENV_PRINTF("\r\nError while adding HW Service W2ST\r\n");
}
ret = Add_ConsoleW2ST_Service();
if(ret == BLE_STATUS_SUCCESS) {
MOTENV_PRINTF("Console Service W2ST added successfully\r\n");
} else {
MOTENV_PRINTF("\r\nError while adding Console Service W2ST\r\n");
}
ret = Add_ConfigW2ST_Service();
if(ret == BLE_STATUS_SUCCESS) {
MOTENV_PRINTF("Config Service W2ST added successfully\r\n");
} else {
MOTENV_PRINTF("\r\nError while adding Config Service W2ST\r\n");
}
}
#ifdef USE_STM32F4XX_NUCLEO
#ifdef STM32_NUCLEO
/**
* @brief System Clock Configuration
* The system Clock is configured as follow:
* System Clock source = PLL (HSI)
* SYSCLK(Hz) = 84000000
* HCLK(Hz) = 84000000
* AHB Prescaler = 1
* APB1 Prescaler = 2
* APB2 Prescaler = 1
* HSI Frequency(Hz) = 16000000
* PLL_M = 16
* PLL_N = 336
* PLL_P = 4
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale2 mode
* Flash Latency(WS) = 2
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/* Enable HSI Oscillator and activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 0x10;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
Error_Handler();
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){
Error_Handler();
}
}
#endif /* STM32_NUCLEO */
#endif /* USE_STM32F4XX_NUCLEO */
#ifdef USE_STM32L4XX_NUCLEO
#ifdef STM32_NUCLEO
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (MSI)
* SYSCLK(Hz) = 80000000
* HCLK(Hz) = 80000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* MSI Frequency(Hz) = 4000000
* PLL_M = 1
* PLL_N = 40
* PLL_R = 2
* PLL_P = 7
* PLL_Q = 4
* Flash Latency(WS) = 4
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* MSI is enabled after System reset, activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
/* Initialization Error */
while(1);
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
/* Initialization Error */
while(1);
}
}
#elif STM32_SENSORTILE
/**
* @brief System Clock Configuration
* @param None
* @retval None
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnableBkUpAccess();
/* Enable the LSE Oscilator */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
while(1);
}
/* Enable the CSS interrupt in case LSE signal is corrupted or not present */
HAL_RCCEx_DisableLSECSS();
/* Enable MSI Oscillator and activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 6;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
RCC_OscInitStruct.PLL.PLLR = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
while(1);
}
/* Enable MSI Auto-calibration through LSE */
HAL_RCCEx_EnableMSIPLLMode();
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){
while(1);
}
}
#endif /* STM32_NUCLEO */
#endif /* USE_STM32L4XX_NUCLEO */
#ifdef STM32_NUCLEO
#ifdef USE_STM32L0XX_NUCLEO
/**
* @brief System Clock Configuration
* The system Clock configuration
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 0x10;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
__SYSCFG_CLK_ENABLE();
}
#endif /* USE_STM32L0XX_NUCLEO */
#endif /* STM32_NUCLEO */
/**
* @brief This function provides accurate delay (in milliseconds) based
* on variable incremented.
* @note This is a user implementation using WFI state
* @param Delay: specifies the delay time length, in milliseconds.
* @retval None
*/
void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay){
__WFI();
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void Error_Handler(void)
{
/* User may add here some code to deal with this error */
while(1){
}
}
/**
* @brief EXTI line detection callback.
* @param uint16_t GPIO_Pin Specifies the pins connected EXTI line
* @retval None
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin){
#ifdef STM32_NUCLEO
case SPI1_CMN_DEFAULT_IRQ_PIN:
#else
case BNRG_SPI_EXTI_PIN:
#endif /* STM32_NUCLEO */
HCI_Isr();
HCI_ProcessEvent=1;
break;
case LSM6DSM_INT2_PIN:
MEMSInterrupt=1;
break;
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: MOTENV_PRINTF("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1){
}
}
#endif
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no,
shrink-to-fit=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
<title>Magic Gloove</title>
<style>
@import 'ui/css/evothings-app.css';
</style>
<style>
#connectButton {
width: 50%;
float: left;
}
#disconnectButton {
width: 50%;
float: right;
}
</style>
<script src="cordova.js"></script>
<script src="libs/jquery/jquery.js"></script>
<script src="libs/evothings/evothings.js"></script>
<script src="libs/evothings/ui/ui.js"></script>
<script src="libs/evothings/easyble/easyble.js"></script>
<script src="app.js"></script>
</head>
<body ontouchstart=""><!-- ontouchstart="" enables low-delay CSS transitions. -->
<header>
<button class="back" onclick="history.back()">
<img src="ui/images/arrow-left.svg" />
</button>
<img class="logotype" src="ui/images/logo.jpg" alt="Evothings" />
</header>
<h1>Magic Gloove</h1>
<p id="status">Not initialized</p>
<button id="connectButton" class="green" onclick="app.onConnectButton();">
Connect
</button>
<button id="disconnectButton" class="red" onclick="app.disconnect();">
Disconnect
</button>
<canvas id="canvas" width="300" height="150"></canvas>
</body>
</html>
app = {
};
app.connecting = false;
app.device = false;
app.timer = false;
app.accelerationSamples = [];
app.MOTION_SERVICE = "00000000-0001-11e1-9ab4-0002a5d5c51b";
app.MOTION_ACCELEROMETER = "10000000-0001-11e1-ac36-0002a5d5c51b";
app.initialize = function() {
document.addEventListener(
'deviceready',
function() { evothings.scriptsLoaded(app.onDeviceReady) },
false);
}
app.status = function(text) {
if(app.oldStatus == text) return;
app.oldStatus = text;
console.log(text);
document.getElementById("status").innerHTML = text;
}
app.onDeviceReady = function()
{
app.status("Ready");
app.onConnectButton();
}
app.onConnectButton = function() {
if(app.device) return;
evothings.easyble.stopScan();
app.status("Scanning...");
evothings.easyble.startScan(
function(device) {
if(app.connecting) return;
if(app.isMG(device)) {
evothings.easyble.stopScan();
app.connect(device);
}
},
function(errorCode) {
// Report error.
callbackFun(null, errorCode);
},
{allowDuplicates:false}
);
}
app.isMG = function(device) {
return device.name == "MAGICGV";
}
app.disconnect = function() {
if(app.timer) {
clearInterval(app.timer);
app.timer = false;
}
if(app.device) {
app.device.close();
app.device = false;
app.status("Disconnected");
}
}
app.connect = function(device) {
app.disconnect();
app.connecting = true;
app.device = device;
app.status("Connecting...");
device.connect(
function(device) {
app.connecting = false;
app.status("Reading services...");
device.readServices(
function(device) {
app.startNotifications();
},
function(errorCode) {
app.status("readServices error: "+errorCode);
},
{ serviceUUIDs: [app.MOTION_SERVICE] });
},
function(errorCode) {
app.status("Connect error: "+errorCode);
});
}
app.startNotifications = function() {
app.timer = window.setInterval(app.poll, 200);
}
app.poll = function() {
app.device.readCharacteristic(app.MOTION_SERVICE, app.MOTION_ACCELEROMETER,
function(data) {
app.status("Active");
var v = new Int16Array(data);
var v0 = v[0] ;
var ax = Math.floor(v[0]/256)/100; //x-commond;
var ay = v[1]%256/100; //y-commond
var az = 5;
//var showA=Math.floor(v[0]/256); //x-commond
//var showA=v[1]%256; //y-commond
//app.status("Mousr Flying");
app.status(ax);
app.drawDiagram({ x: ax, y: ay, z: az });
},
function(errorCode) {
app.status("readCharacteristic error: "+errorCode);
});
}
app.clearDiagram = function() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// Clear diagram canvas.
context.clearRect(0, 0, canvas.width, canvas.height);
// Remove samples from array.
app.accelerationSamples.length = 0;
};
// Draw diagram to canvas.
app.drawDiagram = function(values) {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var x_mouse, y_mouse;
// Value is an accelerometer reading between -1 and 1.
function calcDiagramY(value){
// Return Y coordinate for this value.
var diagramY = ((value * canvas.height) / 8) + (canvas.height / 2);
return diagramY;
}
function calcDiagramX(value){
// Return X coordinate for this value.
var diagramY = ((value * canvas.width) / 8) + (canvas.width / 2);
return diagramX;
}
x_mouse=calcDiagramX("x");
y_mouse=calcDiagramY("y");
x_mouse=calcDiagramX(value);
y_mouse=calcDiagramY(value);
// Clear background.
context.clearRect(0, 0, canvas.width, canvas.height);
// Draw lines.
context.strokeStyle = '#f00';
context.moveTo(x_mouse, y_mouse20);
context.lineTo(x_mouse+0.2, y_mouse20+0.4);
context.lineTo(x_mouse+0.4, y_mouse20);
context.lineTo(x_mouse, y_mouse20);
context.stroke();
};
app.initialize();
/**
******************************************************************************
* @file motenv1_config.h
* @author Central LAB
* @version V2.2.0
* @date 24-November-2016
* @brief MotEnv1 configuration
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MOTENV1_CONFIG_H
#define __MOTENV1_CONFIG_H
/* Exported define ------------------------------------------------------------*/
/* Define the MOTENV1 MAC address, otherwise it will create a MAC related to STM32 UID */
//#define MAC_MOTENV 0xFF, 0xEE, 0xDD, 0xAA, 0xAA, 0xAA
#ifndef MAC_MOTENV
/* For creating one MAC related to STM32 UID, Otherwise the BLE will use it's random MAC */
#define MAC_STM32UID_MOTENV
#endif /* MAC_MOTENV */
/*************** Debug Defines ******************/
/* For enabling the printf on UART */
#ifdef STM32_SENSORTILE
/* Enabling this define for SensorTile..
* it will introduce a delay of 10Seconds before starting the application
* for having time to open the Terminal
* for looking the BlueMicrosystem Initialization phase */
//#define MOTENV_ENABLE_PRINTF
#else /* STM32_SENSORTILE */
#ifndef USE_STM32L0XX_NUCLEO
/* For Nucleo F401RE/L476RG it's enable by default */
#define MOTENV_ENABLE_PRINTF
#endif /* USE_STM32L0XX_NUCLEO */
#endif /* STM32_SENSORTILE */
/* For enabling connection and notification subscriptions debug */
#define MOTENV_DEBUG_CONNECTION
/* For enabling trasmission for notified services (except for quaternions) */
#define MOTENV_DEBUG_NOTIFY_TRAMISSION
/*************** Don't Change the following defines *************/
/* Package Version only numbers 0->9 */
#define MOTENV_VERSION_MAJOR 'C'
#define MOTENV_VERSION_MINOR 'G'
#define MOTENV_VERSION_PATCH 'V'
/* Define the MOTENV1 Name MUST be 7 char long */
#define NAME_MOTENV 'M','A','G','I',MOTENV_VERSION_MAJOR,MOTENV_VERSION_MINOR,MOTENV_VERSION_PATCH
/* Package Name */
#define MOTENV_PACKAGENAME "MOTENV1"
#ifdef MOTENV_ENABLE_PRINTF
#ifdef STM32_NUCLEO
#define MOTENV_PRINTF(...) printf(__VA_ARGS__)
#elif STM32_SENSORTILE
#include "usbd_cdc_interface.h"
#define MOTENV_PRINTF(...) {\
char TmpBufferToWrite[256];\
int32_t TmpBytesToWrite;\
TmpBytesToWrite = sprintf( TmpBufferToWrite, __VA_ARGS__);\
CDC_Fill_Buffer(( uint8_t * )TmpBufferToWrite, TmpBytesToWrite);\
}
#endif /* STM32_NUCLEO */
#else /* MOTENV_ENABLE_PRINTF */
#define MOTENV_PRINTF(...)
#endif /* MOTENV_ENABLE_PRINTF */
/* STM32 Unique ID */
#ifdef USE_STM32F4XX_NUCLEO
#define STM32_UUID ((uint32_t *)0x1FFF7A10)
#endif /* USE_STM32F4XX_NUCLEO */
#ifdef USE_STM32L4XX_NUCLEO
#define STM32_UUID ((uint32_t *)0x1FFF7590)
#endif /* USE_STM32L4XX_NUCLEO */
#ifdef USE_STM32L0XX_NUCLEO
#define STM32_UUID ((uint32_t *)0x1FF80050)
#endif /* USE_STM32L0XX_NUCLEO */
/* STM32 MCU_ID */
#define STM32_MCU_ID ((uint32_t *)0xE0042000)
#endif /* __MOTENV1_CONFIG_H */
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
Comments