Project tutorial
Gesture Drive: Accelerate with  Freedom

Gesture Drive: Accelerate with Freedom © GPL3+

The Idea is to control both Direction+Acceleration of a Bluetooth Robotic Car with the movement of Forearm using Kinetis K82 Freedom board.

  • 3,403 views
  • 0 comments
  • 12 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
Hy gluegun
Hot glue gun (generic)
Seeed Drill Motor

Apps and online services

About this project

Hand/Wrist/Finger Free, Arm Only Control

The idea is to develop a Robotic Car which will be controlled by NXP Freedom (FRDM-K82F) board that has Kinetis K82F MCU (ARM Cortex M4) and FXOS8700CQ - accelerometer+magnetometer.

User can control the Speed & Direction by the movement of K82 Board mounted on his/her forearm. Gesture movement is interpreted by the Accelerometer and converted into command.

The Robot will be powered from a 4500 mAh 6 volts maintenance free Lead Acid Battery and the K82 Freedom Board will be powered form a homemade Power Shield with LED Display.

Live Action

Sorry I couldn't provide a better video, it was raining outdoor during day so I had to do this indoor at night ! The response slightly lags probably because of Arduino Serial.AvailableUntil () function which responds a bit late.

Gesture Drive

There is a 5 Volt Power Bank in my hand, nothing fishy here !!! The LiPo Battery on the shield was low during the video recording, so I had to power it form external power pack !!!!!!

Real Life Application: Electronic Wheel Chair Driving with Arm only Disables

Think about a disable person with no hand or leg. Without hand that person cannot drive a wheel chair. But with the hardware I made, it would be possible for him/her to drive an electronic wheel chair by attaching the Bluetooth Gesture Controller on Forearm.

Although, real life application requires more concern with safety, security, and quality. For safety of embedded system requires watchdog interrupt to avoid frenzy state, Real Time Response (by replacing Arduino with 32 bit ARM ) and Improved code.

For Security, K82 Board’s Encryption Features can be used with Gesture Password.


Getting Started with NXP K82 Freedom Board

To start with this Freedom K82 Board manual to know which pins are connected to RGB LED, Switches, Accelerometer, Jumpers and Power Options !

Freedom board user guide

To know about Electrical Characteristics (voltage, current, power, frequency etc) of the MCU check this datasheet.

The K82 Sub-Family Reference Manual (MCU on Freedom K82 Board -K82P121M150SF5) has 2213 pages , which is quite overwhelming for hobbyist.

Webinar 1

Webinar 2

Webinar 3

FAQs

Very well explained instruction, 10 times better than the Webinars :

Getting Started Videos Freedom K82 Videos

A better way to learn is to watch Kinetis K Series MCU Online Training

There are APIs(functions) to do things, so you don't need to dig into Register Level of ARM. Check this API guide to understand how to write codes :

API Reference Manual

About Kinetis Design Studio

The Kinetis Design Studio (KDS) is a free IDE for Kinetis MCUs that enables creating, compiling and debugging Embedded Designs for Kinetis MCUs.

Download KDS

Here are some snapshots of most frequently used files/folders in KDS. On the left most column are the projects files directory.

Source folder ( which is a sub directory of project folder) contains the main.c code. By clicking, it will show up in the middle editor window.

Most frequently used Build, Flash, Debug options are here :

Segger J-Link Debugger tab contains the flash files of all the build projects :-

KDS allows programming in C/C++ with high level APIs/Functions and Peripheral Drivers.

Here is a Block Diagram of KDS from NXP's -

Board Overview & Onboard Hardware

Here is a quick overview of the Kinetis K82 Freedom Board from Freedom Board for Kinetis K82F Hardware (FRDM-K82F) User's Guide :

The FRDMK82F board features the MK82FN256VLL15 MCU, which boasts a maximum operation frequency of 150 MHz, 256 KB of flash, a 256 KB RAM, a full-speed USB controller with available crystal-less operation, and analog and digital peripherals. The FRDM-K82F hardware is form-factor compatible with the ArduinoTM R3 pin layout, providing a broad range of expansion board options. The onboard interface includes a six-axis digital accelerometer and magnetometer, an RGB LED, FlexIO header, and sufficient footprint to add an optional Bluetooth module (for use over UART) and RF module (for useover SPI).
The FRDM-K82F platform features OpenSDAv2.1, the Freescale open-source hardware embedded serial and debug adapter running an open-source bootloader. This circuit offers several options for serial communication, flash programming, and run-control debugging. OpenSDAv2.1 is an mbed™ HDKcompatible debug interface preloaded with the open-source CMSIS-DAP Interface firmware (mbed interface) for rapid prototyping and product development, with a focus on connected Internet of Things devices.

Important!

Some pins are used to connect on-board resources (Switch, LED, sensor), be careful about these pins, while setting I/O.

Stuffs Needed to Make This

Some images of the devices, modules, tools used in this project :-

Building the Hardware

I have got this nice looking vintage Intercom Box as family heirloom from the 90', which I am going to use as the chassis for the thing.

Step 1: Cool LED Dot Circle Displays+Power Shield

Red, Green, Yellow LEDs two of each color are soldered in circular pattern on a protoboard with all the cathodes through 1K resistance to Ground. 1k Network Resistor is used.

The Plastic Circular Ring is salvaged from a 6 Color Pen .

8 Blue LEDs are soldered in a Circular Fashion on Protoboard and all the Cathode terminals (-) are soldered to Gnd Pin.

Next, Male Pin Headers are soldered, RED for Vin, 3.3 V, 5V (any + Rail), Black for Ground (-) and Yellow for I/O.

Heat Shrink Tube, Hot Glue, Hookup Wires are used to Route the connections, LiPo Battery is placed beneath the board.

Step 2: The Cart: Gear Motors, Nuts & Bolts

Using the Drill-Motor some holes are made on the Intercom Box, Then Motors are mounter with Nuts & Bolts, Gear Motor Mountings and a pair of Eraser to absorb shock.

Next, solid core wires are solders and routed to the other side.

A 360 Degree rotating front wheel is attached to the box to complete the mechanical parts installation.

After putting all the pieces the car will look something like this :

Finally the motor wires are connected to the L298 Motor Driver module.

Step 3: HC-05 Bluetooth as Master/Slave

2 HC-05 Bluetooth module are used to connect a wireless serial link. HC-05 module directly plugs into Freedom K82's Bluetooth Header.

By default, HC-05 modules are configured in slave mode and Baud rate of 9600 bps.

One of the HC-05 module is connected to PC using a USB-to-Serial module by press and holding the switch on HC-05 before powering it up to Enter AT Command Mode. Then release the switch once powered up. The Red LED on HC-05 will blink slowly (once every two second).

The on the serial terminal ( I used Arduino IDE Serial Monitor ) Baud of 38400 and Both NL & CR for configuring purpose of the device.

Then Following AT command are issued one by one : -

AT+RMAAD
AT+ROLE=1
AT+RESET

Enter again in AT Command Mode by pressing & holding the switch.

AT+CMODE=1 
CMODE=1
AT+UART=115200,0,0
AT+INQM=0,5,5

Now one of the HC-05 is Master with 115200 serial link baud rate.

For the other HC-05 following AT Commands are issued :-

AT+RMAAD 
AT+ROLE=0
AT+UART=11500,0,0

Here is a nice tutorial about how to do this.

The Master HC-05 is connected to K82 Freedom Board and the Slave HC-05 is connected to the (Arduino Bootloaded) AVR ATmega8A/168/328P 8 bit 16 MHz MCU.

Step 4: Do as Kinetis Command's

This is a homemade Arduino Uno Clone made with AVR ATmega8A/328P.

Supports full Arduino functionality.

It receives Wireless Commands over Bluetooth-Serial Link and performs accordingly.

PWM and GPIO controls the L298 Driver which drives the motor as per command. Serial polls to get commands received from K82 Board.

Working Principle: Accelerometer Basics

An accelerometer is an electromechanical sensor that will measure acceleration forces like (Natural) Gravitational Force or Movement/Vibration Force.

There are many different ways an accelerometer can work. Some accelerometers has piezoelectric microscopic crystal structures that get stressed by acceleration, which causes a voltage to be generated. Another way to do it is by sensing changes in capacitance of micro-structures MEMS next to each other, they have a certain capacitance between them. If acceleration force changes on the structures, then the capacitance will change, which can be converted from capacitance to voltage.

Here is an illustration of accelerometer from WikID

We know , Gravitational Acceleration is 9.81 m/s^2 on a flat surface ! If the surface is tilted then this acceleration will split into perpendicular and horizontal component.

By doing some trigonometric calculation the tilt angle can be measured. This Tilt Angel ( which is a Gesture of forearm ) can be programmed as User Input to operate something. This is the working principle of this project.

Building the Software

The software is based on the bubble example of NXP K82 Freedom Board, which is the demo program comes with each newly shipped board.

I have made my project by changing and adding codes to that program's source codes.

  • The main.c file has the #included header files , defined constants, global variable, function prototypes
  • In the main loop first I/O pins are initialized, module clocking are enabled, configuration for peripherals are loaded.
  • In the infinite while loop some of the control functions are sequentially called to get new acceleration data, calculate angle, RGB PWM, Gear/Acceleration Dial, send command over LPUART to Bluetooth etc.

Step 1: Flow Chart

Step 2: Adapting Existing Example: bubble.c & pin_mux.c

The bubble.c which is an example acceleration sensor app shows Pitch and Roll of the Board with Green/Blue LEDs. This example is changed and new codes are added to adapt for the project .

Here are the changes in pin_mux.c explained pictorially -

Most important part of K82 Sub-Family Reference Manual is from page 213-222 where Pin Muxing Information is available.

MCU's Utilized Peripherals

Following Peripherals of K82 MCU are utilized :

FlexIO FTM Module >> to create PWM to Drive onboard RGB LED

GPIO Module >> to Drive Dial Display to represent Gear & Acceleration

LPUART Module >> to Establish Bluetooth Serial Link

I2C Module >> to Fetch Accelerometer Data from Sensor

UART Module >> to do Serial Debugging

Conclusion

This project demonstrates some interesting application of Accelerometer for Controlling Vehicle. There is more scope of improvement and more work required for transforming form project to product.

Code

main cC/C++
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of Freescale Semiconductor, Inc. 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.
 */

#include "fsl_debug_console.h"
#include "board.h"
#include "math.h"
#include "fsl_fxos.h"
#include "fsl_i2c.h"
#include "fsl_ftm.h"
#include "fsl_lpuart.h"
#include "fsl_common.h"
#include "pin_mux.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define BOARD_TIMER_BASEADDR TPM3

//============= Change Made here for 3rd channel ==================//
#define BOARD_FIRST_TIMER_CHANNEL 6U
#define BOARD_SECOND_TIMER_CHANNEL 5U
#define BOARD_THIRD_TIMER_CHANNEL 4U


/* Get source clock for TPM driver */
#define BOARD_TIMER_SOURCE_CLOCK CLOCK_GetFreq(BUS_CLK)
/* I2C source clock */
#define ACCEL_I2C_CLK_SRC I2C3_CLK_SRC
#define I2C_BAUDRATE 100000U
/* Upper bound and lower bound angle values */

// UART for BT
#define BT_LPUART LPUART1
#define LPUART_CLKSRC kCLOCK_Osc0ErClk


//======================= Change Made here for Gearing Range ===========//
int ANGLE_UPPER_BOUND = 90U;
int ANGLE_LOWER_BOUND = 10U;

int16_t xData = 0;
 int16_t yData = 0;
 int16_t xAngle = 0;
 int16_t xAngle_Gear=0;
 int16_t yAngle_Left = 0;
 int16_t yAngle_Right = 0;
// Make Function to Update Power level from gear counter and accele counter and angle
 uint8_t power_level=160;

 uint8_t car_cmd[5];

 fxos_handle_t fxosHandle = {0};
    fxos_data_t sensorData = {0};

    uint8_t  Ardu_Left_Wheel_Pwr_Min=1;
    uint8_t  Ardu_Right_Wheel_Pwr_Min=1;


    uint8_t  Ardu_Left_Wheel_Pwr_Max=240;
    uint8_t  Ardu_Right_Wheel_Pwr_Max=240;
    uint8_t Accel_Level=1; // max 8

/*******************************************************************************
 * Prototypes
 ******************************************************************************/


/*******************************************************************************
 * Variables
 ******************************************************************************/
i2c_master_handle_t g_MasterHandle;
/* FXOS device address */
const uint8_t g_accel_address[] = {0x1CU, 0x1DU, 0x1EU, 0x1FU};
uint8_t gear_counter=1U;

/*******************************************************************************
 * Code
 ******************************************************************************/
/* Initialize timer module */
static void Timer_Init(void)
{
    ftm_config_t ftmInfo;

    //============================== Change made here for 3 PWM ==========================//
    //ftm_chnl_pwm_signal_param_t ftmParam[2];
    ftm_chnl_pwm_signal_param_t ftmParam[3];
    /* Configure ftm params with frequency 24kHZ */
    ftmParam[0].chnlNumber = (ftm_chnl_t)BOARD_FIRST_TIMER_CHANNEL;
    ftmParam[0].level = kFTM_LowTrue;
    ftmParam[0].dutyCyclePercent = 0U;
    ftmParam[0].firstEdgeDelayPercent = 0U;

    ftmParam[1].chnlNumber = (ftm_chnl_t)BOARD_SECOND_TIMER_CHANNEL;
    ftmParam[1].level = kFTM_LowTrue;
    ftmParam[1].dutyCyclePercent = 0U;
    ftmParam[1].firstEdgeDelayPercent = 0U;

// ================== 3rf PWM ========================================
    ftmParam[2].chnlNumber = (ftm_chnl_t)BOARD_THIRD_TIMER_CHANNEL;
    ftmParam[2].level = kFTM_LowTrue;
    ftmParam[2].dutyCyclePercent = 0U;
    ftmParam[2].firstEdgeDelayPercent = 0U;

    /*
     * ftmInfo.prescale = kFTM_Prescale_Divide_1;
     * ftmInfo.bdmMode = kFTM_BdmMode_0;
     * ftmInfo.pwmSyncMode = kFTM_SoftwareTrigger;
     * ftmInfo.reloadPoints = 0;
     * ftmInfo.faultMode = kFTM_Fault_Disable;
     * ftmInfo.faultFilterValue = 0;
     * ftmInfo.deadTimePrescale = kFTM_Deadtime_Prescale_1;
     * ftmInfo.deadTimeValue = 0;
     * ftmInfo.extTriggers = 0;
     * ftmInfo.chnlInitState = 0;
     * ftmInfo.chnlPolarity = 0;
     * ftmInfo.useGlobalTimeBase = false;
     */
    FTM_GetDefaultConfig(&ftmInfo);
    /* Initialize FTM module */
    FTM_Init(BOARD_FTM_BASEADDR, &ftmInfo);

    // CHanged Here from 2U to 3U for 3 channel support //
    FTM_SetupPwm(BOARD_FTM_BASEADDR, ftmParam, 3U, kFTM_EdgeAlignedPwm, 2000U, BOARD_TIMER_SOURCE_CLOCK);
    FTM_StartTimer(BOARD_FTM_BASEADDR, kFTM_SystemClock);
}

/* Update the duty cycle of an active pwm signal */
// =================Changed HERE for 3 PWM ======================//
static void Board_UpdatePwm(uint16_t x, uint16_t y,uint16_t a)
{
    /* Start PWM mode with updated duty cycle */
    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_FIRST_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, x);
    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_SECOND_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, y);

    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_THIRD_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, a);

    /* Software trigger to update registers */
    FTM_SetSoftwareTrigger(BOARD_FTM_BASEADDR, true);
}

/*===============================
 *
 * CHANGE MAFE HERE
 *
=============================================================//
 */

void DIAL_OFF(void)
{
				GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 0);
                GPIO_WritePinOutput (GPIOD, 1U, 0);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 0);
                GPIO_WritePinOutput (GPIOB, 20U, 0);

}


void Change_Accel_level(void)
{
int level=0;
if (xAngle>yAngle_Left)
{
if(xAngle>yAngle_Right)
	{
	level=xAngle/10;
	}
	else
		{level=yAngle_Right/10;}
}
else
{
	level=yAngle_Left/10;

}

if (level==1)
{
	//          GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 0);
                GPIO_WritePinOutput (GPIOD, 1U, 0);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 0);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}
if (level==2)
{
	  //        GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 0);
                GPIO_WritePinOutput (GPIOD, 1U, 0);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}

if (level==3)
{
	  //          GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 0);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}
if (level==4)
{
	  //        GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 1);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}
if (level==5)
{
	     //     GPIO_WritePinOutput (GPIOC, 3U,1);
                GPIO_WritePinOutput (GPIOC, 5U, 1);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}

if (level==6)
{
	       //   GPIO_WritePinOutput (GPIOC, 3U,1);
                GPIO_WritePinOutput (GPIOC, 5U, 1);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 1);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}
if (level==7)
{
	        //    GPIO_WritePinOutput (GPIOC, 3U,1);
                GPIO_WritePinOutput (GPIOC, 5U, 1);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 1);
                GPIO_WritePinOutput (GPIOD, 4U, 1);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}
if (level>=8)
{
	         //   GPIO_WritePinOutput (GPIOC, 3U,1);
                GPIO_WritePinOutput (GPIOC, 5U, 1);
                GPIO_WritePinOutput (GPIOD, 1U, 1);
                GPIO_WritePinOutput (GPIOD, 2U, 1);
                GPIO_WritePinOutput (GPIOD, 3U, 1);
                GPIO_WritePinOutput (GPIOD, 4U, 1);
                GPIO_WritePinOutput (GPIOB, 21U, 1);
                GPIO_WritePinOutput (GPIOB, 20U, 1);
}


//Func ends here//
}

void DIAL_SPIN_CW(void)
{

}
void DIAL_SPIN_CCW(void)
{

}

void RGY_OFF(void)
{

	GPIO_WritePinOutput (GPIOA, 5U, 0);
	GPIO_WritePinOutput (GPIOA, 12U, 0);
	GPIO_WritePinOutput (GPIOA, 13U, 0);
	GPIO_WritePinOutput (GPIOA, 14U, 0);
	GPIO_WritePinOutput (GPIOA, 17U, 0);
	GPIO_WritePinOutput (GPIOC, 7U, 0);
}

void GEAR_Change(void)

{



if (gear_counter>=6)
{gear_counter=6;}
if (gear_counter<=1)
{gear_counter=1;}

if (gear_counter==1)
{
	GPIO_WritePinOutput (GPIOA, 5U, 0);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 0);
		GPIO_WritePinOutput (GPIOA, 14U, 0);
		GPIO_WritePinOutput (GPIOA, 17U, 0);
		GPIO_WritePinOutput (GPIOC, 7U, 0);

}
if (gear_counter==2)
{
	GPIO_WritePinOutput (GPIOA, 5U, 0);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 1);
		GPIO_WritePinOutput (GPIOA, 14U, 0);
		GPIO_WritePinOutput (GPIOA, 17U, 0);
		GPIO_WritePinOutput (GPIOC, 7U, 0);

}
if (gear_counter==3)
{
	GPIO_WritePinOutput (GPIOA, 5U, 0);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 1);
		GPIO_WritePinOutput (GPIOA, 14U, 0);
		GPIO_WritePinOutput (GPIOA, 17U, 1);
		GPIO_WritePinOutput (GPIOC, 7U, 0);

}
if (gear_counter==4)
{
	GPIO_WritePinOutput (GPIOA, 5U, 0);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 1);
		GPIO_WritePinOutput (GPIOA, 14U, 1);
		GPIO_WritePinOutput (GPIOA, 17U, 1);
		GPIO_WritePinOutput (GPIOC, 7U, 0);

}
if (gear_counter==5)
{
	GPIO_WritePinOutput (GPIOA, 5U, 0);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 1);
		GPIO_WritePinOutput (GPIOA, 14U, 1);
		GPIO_WritePinOutput (GPIOA, 17U, 1);
		GPIO_WritePinOutput (GPIOC, 7U, 1);

}
if (gear_counter==6)
{
	GPIO_WritePinOutput (GPIOA, 5U, 1);
		GPIO_WritePinOutput (GPIOA, 12U,1);
		GPIO_WritePinOutput (GPIOA, 13U, 1);
		GPIO_WritePinOutput (GPIOA, 14U, 1);
		GPIO_WritePinOutput (GPIOA, 17U, 1);
		GPIO_WritePinOutput (GPIOC, 7U, 1);

}


// Gear Func stops here
}



void Delay(uint32_t n)
{
	  SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;                      /* use core clock */
	    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;                       /* disable interrupt */
	    SysTick->LOAD = n * ((CLOCK_GetFreq(kCLOCK_CoreSysClk)) / 1000U); /* n ms */
	    SysTick->VAL = 0U;                                                /* clear COUNTFLAG */

	    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

	    /* wait for timeout */
	    while (0U == (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
	    {
	    }

	    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

void Update_Angles(void)
{
    /* Get new accelerometer data. */
        FXOS_ReadSensorData(&fxosHandle, &sensorData);

        /* Get the X and Y data from the sensor data structure.fxos_data */
        xData = (int16_t)((uint16_t)((uint16_t)sensorData.accelXMSB << 8) | (uint16_t)sensorData.accelXLSB);
        yData = (int16_t)((uint16_t)((uint16_t)sensorData.accelYMSB << 8) | (uint16_t)sensorData.accelYLSB);

        // Convert raw data to angle ( -90:0:90 degrees).

        //=======xData and yData Swapped ===========///
        xAngle = (int16_t)floor((double)yData * 0.011);
      //===================Changed Here ==================
        if (xAngle >= 0)
                {
        	xAngle_Gear=xAngle;
        	xAngle=0;

                }
        if (xAngle < 0)
        {

            xAngle *= -1;
            xAngle_Gear=0;


        }
        yAngle_Left = (int16_t)floor((double)xData * 0.011);
        if (yAngle_Left < 0)
        {
        //    yAngle *= -1;
        	yAngle_Right=yAngle_Left*(-1);
        	yAngle_Left=0;
        }
}

void Send_Car_Cmd(void)

{
if(xAngle>5)
	{
	if ((xAngle+10>yAngle_Left)&(xAngle+10>yAngle_Right))
			{
		power_level=xAngle*gear_counter/2;
		car_cmd[0]='B';
		car_cmd[1]=0x30+(power_level/100);
		car_cmd[2]=0x30+((power_level%100) /10);
		car_cmd[3]=0x30+((power_level%10) /1);
		car_cmd[4]='\n';

	    LPUART_WriteBlocking(BT_LPUART, car_cmd, sizeof(car_cmd) - 1);
			}
	 if((yAngle_Left)<(yAngle_Right))
	{
		power_level=yAngle_Right*gear_counter/2;
		car_cmd[0]='R';
			car_cmd[1]=0x30+(power_level/100);
			car_cmd[2]=0x30+((power_level%100) /10);
			car_cmd[3]=0x30+((power_level%10) /1);
			car_cmd[4]='\n';

		    LPUART_WriteBlocking(BT_LPUART, car_cmd, sizeof(car_cmd) - 1);

	}

	if((yAngle_Left)>(yAngle_Right))
		{
		power_level=yAngle_Left*gear_counter/2;
		car_cmd[0]='G';
		car_cmd[1]=0x30+(power_level/100);
		car_cmd[2]=0x30+((power_level%100) /10);
		car_cmd[3]=0x30+((power_level%10) /1);
		car_cmd[4]='\n';

	    LPUART_WriteBlocking(BT_LPUART, car_cmd, sizeof(car_cmd) - 1);
}

	}



}


//==========================================================//

int main(void)
{

    i2c_master_config_t i2cConfig = {0};
    uint32_t i2cSourceClock = 0;

    // =================Changed HERE for 3 PWM ======================//




    uint8_t i = 0;
    uint8_t regResult = 0;
    uint8_t array_addr_size = 0;
    bool foundDevice = false;

    i2cSourceClock = CLOCK_GetFreq(ACCEL_I2C_CLK_SRC);
    fxosHandle.base = BOARD_ACCEL_I2C_BASEADDR;
    fxosHandle.i2cHandle = &g_MasterHandle;


    /*=======================================================
     * Changes made here
     *
     * ======================================================
     */
    gpio_pin_config_t pin_config =

        {
        kGPIO_DigitalOutput,1,
        };

    // LPUART (BT Config)
    lpuart_config_t config_lpuart;


    //=========================================================//
    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    CLOCK_SetLpuartClock(2U);
    LPUART_GetDefaultConfig(&config_lpuart);


    /*=======================================================
     * Changes made here
     *

     * ======================================================
     */

    config_lpuart.baudRate_Bps = 115200;
    config_lpuart.enableTx = true;
    config_lpuart.enableRx = true;

    LPUART_Init(BT_LPUART, &config_lpuart, CLOCK_GetFreq(LPUART_CLKSRC));



  //  	GPIO_PinInit(GPIOC, 3U, &pin_config);
        GPIO_PinInit(GPIOC, 5U, &pin_config);
        GPIO_PinInit(GPIOB, 21U, &pin_config);
        GPIO_PinInit(GPIOB, 20U, &pin_config);
        GPIO_PinInit(GPIOD, 1U, &pin_config);
        GPIO_PinInit(GPIOD, 2U, &pin_config);
        GPIO_PinInit(GPIOD, 3U, &pin_config);
        GPIO_PinInit(GPIOD, 4U, &pin_config);

        //=========================================================//
        GPIO_PinInit(GPIOA, 5U, &pin_config);
           GPIO_PinInit(GPIOA, 12U, &pin_config);
           GPIO_PinInit(GPIOA, 13U, &pin_config);
           GPIO_PinInit(GPIOA, 14U, &pin_config);
           GPIO_PinInit(GPIOA, 17U, &pin_config);
           GPIO_PinInit(GPIOC, 7U, &pin_config);
       RGY_OFF();

    /*
     * i2cConfig.baudRate_Bps = 100000U;
     * i2cConfig.enableHighDrive = false;
     * i2cConfig.enableStopHold = false;
     * i2cConfig.glitchFilterWidth = 0U;
     * i2cConfig.enableMaster = true;
     */
    I2C_MasterGetDefaultConfig(&i2cConfig);
    I2C_MasterInit(BOARD_ACCEL_I2C_BASEADDR, &i2cConfig, i2cSourceClock);
    I2C_MasterTransferCreateHandle(BOARD_ACCEL_I2C_BASEADDR, &g_MasterHandle, NULL, NULL);

    /* Find sensor devices */
    array_addr_size = sizeof(g_accel_address) / sizeof(g_accel_address[0]);
    for (i = 0; i < array_addr_size; i++)
    {
        fxosHandle.xfer.slaveAddress = g_accel_address[i];
        if (FXOS_ReadReg(&fxosHandle, WHO_AM_I_REG, &regResult, 1) == kStatus_Success)
        {
            foundDevice = true;
            break;
        }
        if ((i == (array_addr_size - 1)) && (!foundDevice))
        {
        //    PRINTF("\r\nDo not found sensor device\r\n");
        	// GLOW AN LED HERE
            while (1)
            {
            };
        }
    }

    /* Init accelerometer sensor */
    FXOS_Init(&fxosHandle);
    /* Init timer */
    Timer_Init();

   //* Print a note to terminal */
 //   PRINTF("\r\nWelcome to BUBBLE example\r\n");
//    PRINTF("\r\nYou will see the change of LED brightness when change angles of board\r\n");

    // reset Gear dial


    /* Main loop. Get sensor data and update duty cycle */


    while (1)
    {
    	Update_Angles();
    	Board_UpdatePwm(xAngle, yAngle_Left,yAngle_Right);
    	Change_Accel_level();
    	Send_Car_Cmd();
    	 for(int x=0;x<16;x++){Delay(1000000);}







// Gear Control Here

        while(xAngle_Gear>0)
        {
        	DIAL_OFF();
        		power_level=0;
        		car_cmd[0]='S';
        			car_cmd[1]=0x30;
        			car_cmd[2]=0x30;
        			car_cmd[3]=0x30;
        			car_cmd[4]='\n';
        			   LPUART_WriteBlocking(BT_LPUART, car_cmd, sizeof(car_cmd) - 1);
        		    	 for(int x=0;x<16;x++){Delay(1000000);}

        			   if(xAngle_Gear>50)
        			   {
        						power_level=yAngle_Left*gear_counter/2;
        						car_cmd[0]='O';
        						car_cmd[1]=0x30+(power_level/100);
        						car_cmd[2]=0x30+((power_level%100) /10);
        						car_cmd[3]=0x30+((power_level%10) /1);
        						car_cmd[4]='\n';
        					    LPUART_WriteBlocking(BT_LPUART, car_cmd, sizeof(car_cmd) - 1);

        				}


        		    	 for(int x=0;x<16;x++){Delay(1000000);}

        	// Car is stop for gear change

        	Update_Angles();
        	 Board_UpdatePwm(xAngle, yAngle_Left,yAngle_Right);
                  while(yAngle_Left>30)
                  {
                	  gear_counter++;
                	  GEAR_Change();
                	  Update_Angles();
                	  Board_UpdatePwm(xAngle, yAngle_Left,yAngle_Right);
                	  for(int x=0;x<6;x++){Delay(1000000);}
                  }

                  while(yAngle_Right>30)
                                    {
                	  gear_counter--;
                	  GEAR_Change();
                	  Update_Angles();
                	  Board_UpdatePwm(xAngle, yAngle_Left,yAngle_Right);
                	  for(int x=0;x<6;x++){Delay(1000000);}

                                    }

                  }
        }




        /* Print out the raw accelerometer data. */
      //  PRINTF("x= %d y = %d\r\n", xData, yData);

   // infinity loop ends here
    }
pin_mux.cC/C++
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of Freescale Semiconductor, Inc. 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.
 */

#include "fsl_port.h"
#include "pin_mux.h"
#include "fsl_gpio.h"

//==================== header added for TSI ====================//
#include "fsl_common.h"

/*******************************************************************************
 * Code
 ******************************************************************************/
void BOARD_InitPins(void)
{
    port_pin_config_t pinConfig = {0};
    port_pin_config_t ftmPinConfig = {0};

    pinConfig.pullSelect = kPORT_PullUp;
    pinConfig.mux = kPORT_MuxAlt4;
    pinConfig.openDrainEnable = kPORT_OpenDrainEnable;

    /* Initialize LPUART4 pins below */
    /* Ungate the port A B C D clocks */

    CLOCK_EnableClock(kCLOCK_PortA);
    CLOCK_EnableClock(kCLOCK_PortB);
    CLOCK_EnableClock(kCLOCK_PortC);
    CLOCK_EnableClock(kCLOCK_PortD);

    /* Affects PORTC_PCR14 register */
    PORT_SetPinMux(PORTC, 14U, kPORT_MuxAlt3);
    /* Affects PORTC_PCR15 register */
    PORT_SetPinMux(PORTC, 15U, kPORT_MuxAlt3);

    //LPUART for Bluetooth Link

    // Port C pin 3,4 are low Power UART that connects to Bluetooth HC05

    PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3);
        /* Affects PORTC_PCR15 register */
        PORT_SetPinMux(PORTC, 4U, kPORT_MuxAlt3);


    /* Release I2C bus */
    BOARD_I2C_ReleaseBus();

    /* PIN_MUX and I2C3_pull_up resistor setting */
    PORT_SetPinConfig(PORTA, 1U, &pinConfig);
    PORT_SetPinConfig(PORTA, 2U, &pinConfig);

    /* FTM3 */
    /* Affects PORTC_PCR10 register */
    ftmPinConfig.driveStrength = kPORT_LowDriveStrength;
    ftmPinConfig.slewRate = kPORT_SlowSlewRate;
    ftmPinConfig.pullSelect = kPORT_PullDisable;
    ftmPinConfig.mux = kPORT_MuxAlt3;

    /*=====================================================//
    CHANGES MAGE HERE FOR RGB
    */
    PORT_SetPinConfig(PORTC, 10U, &ftmPinConfig);
    PORT_SetPinConfig(PORTC, 9U, &ftmPinConfig);
    PORT_SetPinConfig(PORTC, 8U, &ftmPinConfig);

    /*=====================================================//
        CHANGES MAGE HERE FOR BLUE DIAL
        void DIALOFF (void)
{
	GPIO_WritePinOutput (GPIOC, 3U, 0);
    GPIO_WritePinOutput (GPIOC, 5U, 0);
    GPIO_WritePinOutput (GPIOD, 1U, 0);
    GPIO_WritePinOutput (GPIOD, 2U, 0);
    GPIO_WritePinOutput (GPIOD, 3U, 0);
    GPIO_WritePinOutput (GPIOD, 4U, 0);
    GPIO_WritePinOutput (GPIOB, 21U, 0);
    GPIO_WritePinOutput (GPIOB, 20U, 0);

     */
// Enabling these pins  as GPIO to drive Blue LED Dial

  //  PORT_SetPinMux(PORTC, 3U,kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTC, 5U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTB, 20U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTB, 21U,kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTD, 1U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTD, 2U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTD, 3U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTD, 4U, kPORT_MuxAsGpio);

    // Enabling these pins  as GPIO to drive RGY LED Dial

    PORT_SetPinMux(PORTA, 5U, kPORT_MuxAsGpio);
     PORT_SetPinMux(PORTA, 12U,kPORT_MuxAsGpio);
     PORT_SetPinMux(PORTA, 13U, kPORT_MuxAsGpio);
     PORT_SetPinMux(PORTA, 14U, kPORT_MuxAsGpio);
     PORT_SetPinMux(PORTA, 17U, kPORT_MuxAsGpio);
     PORT_SetPinMux(PORTC, 7U, kPORT_MuxAsGpio);



}

void BOARD_I2C_ReleaseBus(void)
{
    port_pin_config_t i2c_pin_config = {0};
    gpio_pin_config_t pin_config;
    uint8_t i = 0;
    uint8_t j = 0;

    /* Config pin mux as gpio */
    i2c_pin_config.pullSelect = kPORT_PullUp;
    i2c_pin_config.mux = kPORT_MuxAsGpio;

    pin_config.pinDirection = kGPIO_DigitalOutput;
    pin_config.outputLogic = 1U;

    PORT_SetPinConfig(PORTA, 1U, &i2c_pin_config);
    PORT_SetPinConfig(PORTA, 2U, &i2c_pin_config);

    GPIO_PinInit(GPIOA, 1U, &pin_config);
    GPIO_PinInit(GPIOA, 2U, &pin_config);

    /* Send 9 pulses on SCL and keep SDA high */
    for (i = 0; i < 9; i++)
    {
        GPIO_WritePinOutput(GPIOA, 2U, 0U);
        for (j = 0; j < 255; j++)
        {
            __asm("nop");
        }
        GPIO_WritePinOutput(GPIOA, 2U, 1U);
        for (j = 0; j < 255; j++)
        {
            __asm("nop");
        }
    }
    /* Send STOP */
    GPIO_WritePinOutput(GPIOA, 2U, 1U);
    GPIO_WritePinOutput(GPIOA, 1U, 1U);
}
main c C/C++
update 2
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of Freescale Semiconductor, Inc. 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.
 */

#include "fsl_debug_console.h"
#include "board.h"
#include "math.h"
#include "fsl_fxos.h"
#include "fsl_i2c.h"
#include "fsl_ftm.h"

#include "fsl_common.h"
#include "pin_mux.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define BOARD_TIMER_BASEADDR TPM3

//============= Change Made here for 3rd channel ==================//
#define BOARD_FIRST_TIMER_CHANNEL 6U
#define BOARD_SECOND_TIMER_CHANNEL 5U
#define BOARD_THIRD_TIMER_CHANNEL 4U


/* Get source clock for TPM driver */
#define BOARD_TIMER_SOURCE_CLOCK CLOCK_GetFreq(BUS_CLK)
/* I2C source clock */
#define ACCEL_I2C_CLK_SRC I2C3_CLK_SRC
#define I2C_BAUDRATE 100000U
/* Upper bound and lower bound angle values */

//======================= Change Made here for Gearing Range ===========//
int ANGLE_UPPER_BOUND = 85U;
int ANGLE_LOWER_BOUND =5U;

/*******************************************************************************
 * Prototypes
 ******************************************************************************/


/*******************************************************************************
 * Variables
 ******************************************************************************/
i2c_master_handle_t g_MasterHandle;
/* FXOS device address */
const uint8_t g_accel_address[] = {0x1CU, 0x1DU, 0x1EU, 0x1FU};

/*******************************************************************************
 * Code
 ******************************************************************************/
/* Initialize timer module */
static void Timer_Init(void)
{
    ftm_config_t ftmInfo;

    //============================== Change made here for 3 PWM ==========================//
    //ftm_chnl_pwm_signal_param_t ftmParam[2];
    ftm_chnl_pwm_signal_param_t ftmParam[3];
    /* Configure ftm params with frequency 24kHZ */
    ftmParam[0].chnlNumber = (ftm_chnl_t)BOARD_FIRST_TIMER_CHANNEL;
    ftmParam[0].level = kFTM_LowTrue;
    ftmParam[0].dutyCyclePercent = 0U;
    ftmParam[0].firstEdgeDelayPercent = 0U;

    ftmParam[1].chnlNumber = (ftm_chnl_t)BOARD_SECOND_TIMER_CHANNEL;
    ftmParam[1].level = kFTM_LowTrue;
    ftmParam[1].dutyCyclePercent = 0U;
    ftmParam[1].firstEdgeDelayPercent = 0U;

// ================== 3rf PWM ========================================
    ftmParam[2].chnlNumber = (ftm_chnl_t)BOARD_THIRD_TIMER_CHANNEL;
    ftmParam[2].level = kFTM_LowTrue;
    ftmParam[2].dutyCyclePercent = 0U;
    ftmParam[2].firstEdgeDelayPercent = 0U;

    /*
     * ftmInfo.prescale = kFTM_Prescale_Divide_1;
     * ftmInfo.bdmMode = kFTM_BdmMode_0;
     * ftmInfo.pwmSyncMode = kFTM_SoftwareTrigger;
     * ftmInfo.reloadPoints = 0;
     * ftmInfo.faultMode = kFTM_Fault_Disable;
     * ftmInfo.faultFilterValue = 0;
     * ftmInfo.deadTimePrescale = kFTM_Deadtime_Prescale_1;
     * ftmInfo.deadTimeValue = 0;
     * ftmInfo.extTriggers = 0;
     * ftmInfo.chnlInitState = 0;
     * ftmInfo.chnlPolarity = 0;
     * ftmInfo.useGlobalTimeBase = false;
     */
    FTM_GetDefaultConfig(&ftmInfo);
    /* Initialize FTM module */
    FTM_Init(BOARD_FTM_BASEADDR, &ftmInfo);

    // CHanged Here from 2U to 3U for 3 channel support //
    FTM_SetupPwm(BOARD_FTM_BASEADDR, ftmParam, 3U, kFTM_EdgeAlignedPwm, 24000U, BOARD_TIMER_SOURCE_CLOCK);
    FTM_StartTimer(BOARD_FTM_BASEADDR, kFTM_SystemClock);
}

/* Update the duty cycle of an active pwm signal */
// =================Changed HERE for 3 PWM ======================//
static void Board_UpdatePwm(uint16_t x, uint16_t y,uint16_t a)
{
    /* Start PWM mode with updated duty cycle */
    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_FIRST_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, x);
    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_SECOND_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, y);

    FTM_UpdatePwmDutycycle(BOARD_FTM_BASEADDR, (ftm_chnl_t)BOARD_THIRD_TIMER_CHANNEL, kFTM_EdgeAlignedPwm, a);

    /* Software trigger to update registers */
    FTM_SetSoftwareTrigger(BOARD_FTM_BASEADDR, true);
}

/*===============================
 *
 * CHANGE MAFE HERE
 *
=============================================================//
 */

void DIAL_OFF(void)
{
				GPIO_WritePinOutput (GPIOC, 3U, 0);
                GPIO_WritePinOutput (GPIOC, 5U, 0);
                GPIO_WritePinOutput (GPIOD, 1U, 0);
                GPIO_WritePinOutput (GPIOD, 2U, 0);
                GPIO_WritePinOutput (GPIOD, 3U, 0);
                GPIO_WritePinOutput (GPIOD, 4U, 0);
                GPIO_WritePinOutput (GPIOB, 21U, 0);
                GPIO_WritePinOutput (GPIOB, 20U, 0);

}


void DIAL_SPIN_CW(void)
{

}
void DIAL_SPIN_CCW(void)
{

}

//==========================================================//

int main(void)
{
    fxos_handle_t fxosHandle = {0};
    fxos_data_t sensorData = {0};
    i2c_master_config_t i2cConfig = {0};
    uint32_t i2cSourceClock = 0;
    int16_t xData = 0;
    int16_t yData = 0;
    int16_t xAngle = 0;
    // =================Changed HERE for 3 PWM ======================//

    int16_t yAngle_Left = 0;
    int16_t yAngle_Right = 0;


    uint8_t i = 0;
    uint8_t regResult = 0;
    uint8_t array_addr_size = 0;
    bool foundDevice = false;

    i2cSourceClock = CLOCK_GetFreq(ACCEL_I2C_CLK_SRC);
    fxosHandle.base = BOARD_ACCEL_I2C_BASEADDR;
    fxosHandle.i2cHandle = &g_MasterHandle;


    /*=======================================================
     * Changes made here
     *
     * ======================================================
     */
    gpio_pin_config_t pin_config =

        {
        kGPIO_DigitalOutput,1,
        };
    //=========================================================//
    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();


    /*=======================================================
     * Changes made here
     *
     * ======================================================
     */

    	GPIO_PinInit(GPIOC, 3U, &pin_config);
        GPIO_PinInit(GPIOC, 5U, &pin_config);
        GPIO_PinInit(GPIOB, 21U, &pin_config);
        GPIO_PinInit(GPIOB, 20U, &pin_config);
        GPIO_PinInit(GPIOD, 1U, &pin_config);
        GPIO_PinInit(GPIOD, 2U, &pin_config);
        GPIO_PinInit(GPIOD, 3U, &pin_config);
        GPIO_PinInit(GPIOD, 4U, &pin_config);

        //=========================================================//

    /*
     * i2cConfig.baudRate_Bps = 100000U;
     * i2cConfig.enableHighDrive = false;
     * i2cConfig.enableStopHold = false;
     * i2cConfig.glitchFilterWidth = 0U;
     * i2cConfig.enableMaster = true;
     */
    I2C_MasterGetDefaultConfig(&i2cConfig);
    I2C_MasterInit(BOARD_ACCEL_I2C_BASEADDR, &i2cConfig, i2cSourceClock);
    I2C_MasterTransferCreateHandle(BOARD_ACCEL_I2C_BASEADDR, &g_MasterHandle, NULL, NULL);

    /* Find sensor devices */
    array_addr_size = sizeof(g_accel_address) / sizeof(g_accel_address[0]);
    for (i = 0; i < array_addr_size; i++)
    {
        fxosHandle.xfer.slaveAddress = g_accel_address[i];
        if (FXOS_ReadReg(&fxosHandle, WHO_AM_I_REG, &regResult, 1) == kStatus_Success)
        {
            foundDevice = true;
            break;
        }
        if ((i == (array_addr_size - 1)) && (!foundDevice))
        {
        //    PRINTF("\r\nDo not found sensor device\r\n");
        	// GLOW AN LED HERE
            while (1)
            {
            };
        }
    }

    /* Init accelerometer sensor */
    FXOS_Init(&fxosHandle);
    /* Init timer */
    Timer_Init();

   //* Print a note to terminal */
 //   PRINTF("\r\nWelcome to BUBBLE example\r\n");
//    PRINTF("\r\nYou will see the change of LED brightness when change angles of board\r\n");

    /* Main loop. Get sensor data and update duty cycle */

    while (1)
    {
        /* Get new accelerometer data. */
        FXOS_ReadSensorData(&fxosHandle, &sensorData);

        /* Get the X and Y data from the sensor data structure.fxos_data */
        xData = (int16_t)((uint16_t)((uint16_t)sensorData.accelXMSB << 8) | (uint16_t)sensorData.accelXLSB);
        yData = (int16_t)((uint16_t)((uint16_t)sensorData.accelYMSB << 8) | (uint16_t)sensorData.accelYLSB);

        /* Convert raw data to angle (normalize to 0-90 degrees). No negative angles. */

        //=======xData and yData Swapped ===========///
        xAngle = (int16_t)floor((double)yData * 0.011);
      //===================Changed Here ==================
        if (xAngle >= 0)
                {
        	xAngle=0;
                }
        if (xAngle < 0)
        {
            xAngle *= -1;

        }
        yAngle_Left = (int16_t)floor((double)xData * 0.011);
        if (yAngle_Left < 0)
        {
        //    yAngle *= -1;
        	yAngle_Right=yAngle_Left*(-1);
        	yAngle_Left=0;
        }
        /* Update angles to turn on LEDs when angles ~ 90 */
        if (xAngle > ANGLE_UPPER_BOUND)
        {
            xAngle = 100;
        }
        // ==========CHange Made Here =========//
        if (yAngle_Left > ANGLE_UPPER_BOUND)
        {
            yAngle_Left = 100;
        }

        if (yAngle_Right > ANGLE_UPPER_BOUND)
                {
                    yAngle_Right = 100;
                }

        /* Update angles to turn off LEDs when angles ~ 0 */
        if (xAngle < ANGLE_LOWER_BOUND)
        {
            xAngle = 0;
        }
        if (yAngle_Left < ANGLE_LOWER_BOUND)
        {
            yAngle_Left = 0;
        }

        if (yAngle_Right < ANGLE_LOWER_BOUND)
        {
            yAngle_Right = 0;
        }

        Board_UpdatePwm(xAngle, yAngle_Left,yAngle_Right);
        if ((xAngle>40)&(yAngle_Left>40))
        {
        	GPIO_WritePinOutput (GPIOC, 3U, 1);
            GPIO_WritePinOutput (GPIOC, 5U, 1);
            GPIO_WritePinOutput (GPIOD, 1U, 1);
            GPIO_WritePinOutput (GPIOD, 2U, 1);
            GPIO_WritePinOutput (GPIOD, 3U, 1);
            GPIO_WritePinOutput (GPIOD, 4U, 1);
            GPIO_WritePinOutput (GPIOB, 21U, 1);
            GPIO_WritePinOutput (GPIOB, 20U, 1);
        }
        else

        {DIAL_OFF();}





        /* Print out the raw accelerometer data. */
      //  PRINTF("x= %d y = %d\r\n", xData, yData);
    }
}
Arduino Receiving end codeArduino
// Gesture Driving Receiving End Code
/* NXP Kinetis K82 Board will send 
Speed & Wheel Select Info

For Example If only Left wheel needs rotate
send G60
Code By Shahariar
*/

String K82_CMD = "";         // a string to hold incoming data
int speed_val=0;

void setup()
{
  
Serial.begin(115200);
 K82_CMD.reserve(200);
Serial.flush();
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);

pinMode(10,OUTPUT);
pinMode(11,OUTPUT);

pinMode(8,OUTPUT);
pinMode(9,OUTPUT);

}


void loop()
{

    
    // Left Wheel Rotation
  if(Serial.available()>0)
  
  {
    K82_CMD=Serial.readStringUntil('\n');
    
    if(K82_CMD[0]=='G')
    {
      digitalWrite(12,HIGH);
      digitalWrite(13,LOW);
      
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
 
    
      speed_val=(K82_CMD[1]-0x30)*100+(K82_CMD[2]-0x30)*10+(K82_CMD[3]-0x30);
      analogWrite(11,speed_val);
  }
    
    // Right Wheel Rotation
        if(K82_CMD[0]=='R')
    {
      digitalWrite(12,LOW);
      digitalWrite(13,LOW);
      
      digitalWrite(8,HIGH);
      digitalWrite(9,LOW);
      speed_val=(K82_CMD[1]-0x30)*100+(K82_CMD[2]-0x30)*10+(K82_CMD[3]-0x30);
      analogWrite(10,speed_val);
    }
     // Both Wheel Rotation
      if(K82_CMD[0]=='B')
    {
      digitalWrite(12,HIGH);
      digitalWrite(13,LOW);
      
      digitalWrite(8,HIGH);
      digitalWrite(9,LOW);
      
      speed_val=(K82_CMD[1]-0x30)*100+(K82_CMD[2]-0x30)*10+(K82_CMD[3]-0x30);
      analogWrite(10,speed_val);
      analogWrite(11,speed_val);
      
    }
    
    // Opposite Both Wheel Rotation
    
    if(K82_CMD[0]=='O')
    {
      digitalWrite(12,LOW);
      digitalWrite(13,LOW);
      
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      speed_val=(K82_CMD[1]-0x30)*100+(K82_CMD[2]-0x30)*10+(K82_CMD[3]-0x30);
      analogWrite(11,speed_val);
      analogWrite(10,speed_val);
            
      
  }
  
  // stop Wheels
      if(K82_CMD[0]=='S')
    {
      digitalWrite(12,LOW);
      digitalWrite(13,LOW);
      
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      
      //speed_val=000;
      analogWrite(10,0);
      analogWrite(11,0);
      
    }
    K82_CMD="";
    delay(10);
  }
}
KDS FilesC/C++
No preview (download only).

Schematics

Shield Layers
Power Pack & Dial Shields
Shield%20mapping
Bluetooth HC-05 Connection
HC-05 plugged to K82
K82
Car Circuit
Ardu+ L298 Motor Driver + Gear Motor
Gearmot
K82 Freedom + LEDs
LED Connection
Untitled

Comments

Similar projects you might like

How to Make a Gesture Control Robot at Home

Project tutorial by Shubham Shinganapure

  • 4,206 views
  • 8 comments
  • 32 respects

Third Eye for The Blind

Project tutorial by Muhammed Azhar

  • 74,892 views
  • 45 comments
  • 150 respects

Hand Gesture Controlled Robot

Project tutorial by Mayoogh Girish

  • 75,264 views
  • 81 comments
  • 87 respects

Android Guided Vehicle

Project in progress by bharath.s

  • 3,546 views
  • 0 comments
  • 7 respects

Gesture Recognition Using Accelerometer and ESP

Project tutorial by mellis

  • 44,044 views
  • 26 comments
  • 79 respects

Gesture-Controlled Robot

Project tutorial by Youssef El-Gendy and Romina Abachi

  • 4,880 views
  • 0 comments
  • 13 respects
Add projectSign up / Login