Back to Getting Started

Back to Examples

This example demonstrates setting up and making use of the Accelerometer Board

This examples helps you in learning APIs and application firmware that can be used to

1. To figure out the SPIP headers on the peripheral board

2. Accessing the acceleration sensor using the I2C pins on the SPIP headers and reading the XYZ values of acceleration.

3. Using the accel data and LED to build a level indicator.


Before you proceed with this tutorial, you must have Koliada visual studio plugin and Koliada toolchain setup. For more information on the setup check out Koliada Getting started. This tutorial is currently based on the TI CC2541 which uses the 8051.

Before working on this example, make sure you have set the latest KoliadaESDK(TM). More information on setSDK setup and setting the path is shown here.

Note: After making sure the SDK path is set, you must know that the board config must be flashed only if you are using any I/O pins. In this particular example there are I/O configurations for the LED and Switch and hence you should open the accel config project in visual studio. You can find the project under KoliadaESDK(TM)→examples→AccelConfig.

Select the SDK using the SDK Dropdown button at the top.

Now compile the config project and hit download to target.

You should see the following output on your serial terminal

Fig. 3: Output of serial terminal

Now since the I/O ports for the LED and the Switch are configured by downloading the config project we can move on to download the application firmware. You find the application firmware for LED and Switch examples under KoliadaESDK(TM)→examples→accel.

Now compile the project and hit download to target.

You should see the following output on your serial terminal. The accel values XYZ of accelerometer are continuously printed out on the serial monitor

In this example we should be testing the operation of the accelerometer

When you hold the hardware kit upright with the LED and switch board facing up without any tilt, the middle two LEDs D2 and D3 should light up and you can also see the corresponding XYZ values on the terminal monitor. As you tilt the hardware kit right horizontally you should see the LEDs changing their state.

(for e.g. initial state when the hardware kit is upright with the LED/switch board facing upright, D2,D3 will be ON When tilted right horizontally the D3 will be ON and D2 will be OFF, more tilt towards right and D4 will be ON and D3 will be OFF When tilted left horizontally the D2 will be ON and D3 will be OFF, more tilt towards left and D1 will be ON and D2 will be OFF.

You should also see the corresponding XYZ values on the serial monitor as you tilt.

Accel Config

As mentioned above the AccelConfig.c file configures the I/O pins. Hence we configure the necessary LEDs that we intend to use. Here in this example LED1,LED2,LED3 and LED4 are used. Hence the respective port numbers are configured. Port and Bit specifies the port and mask used. The port and mask details for the LED and SWITCH board can be found in the map file here. The given five binary bits specify the direction of the port input/ output, the edge trigger rising/falling, reenable, inversion and initial high/low state. The name describes the I/O pin name that can be used in the application firmware.

PinDescriptor pinTable[] =
// mark unused entries with GPIOX
// there is an implicit assumption that LEDs 1-4 and SW1-4 are first 8 entries
// single entry can describe multiple pins with same port/config (OR the bits together)
// for outputpins, REN is the init state (lo = 0, 1 = hi)
//                       +-------------- dir: 0 = input,   1 = output
//                       |  +----------- ies: 0 = rising,  1 = falling
//                       |  |  +-------- ren: 0 - pull,    1 - 3-state
//                       |  |  |  +----- inv: 0 - normal,  1 - invert
//                       |  |  |  |  +-- set: 0 = off,     1 = on
//                       |  |  |  |  |
//  pin    port   mask   |  |  |  |  |        Name
/*   0 */ {PORT0, BIT3, {1, 0, 0, 1, 0}},	/*< LED1, SYSLED, OTA_READY, OTA_LOAD, OTA_DECODE, OTA_ERROR >*/
/*   1 */ {PORT0, BIT2, {1, 0, 0, 1, 0}},	/*< LED2, TP0 >*/
/*   2 */ {PORT0, BIT5, {1, 0, 0, 1, 0}},	/*< LED3, TP1 >*/
/*   3 */ {PORT0, BIT4, {1, 0, 0, 1, 0}},	/*< LED4 >*/

We can now walkthrough the accel.c step by step

Application firmware(accel) app explanation

The main.c calls accel function in accel.c

#define TimerType kIntervalTimer
 void TestAccel()
	printf(">>%s\n", __func__);
	// create a timer
	// the memory for timer is in user space
	// objectCreate initializes testTimer as a member of class TIMER
	// interval timers never stop firing until told to
	objectCreate(accelTimer, TimerType, TICKS(1000));
	// connect handler to timer
	// the handler is the function that will be called whenever the timer 'fires'
	// this is the same call as for event (inherited function)
	 OnEvent(accelTimer, (HANDLER) accelTimerHandler);
    debug("who am i - 0x%8b",lis2dh_getId());
   LED1 = GPIO.FIND("LED1");
   LED2 = GPIO.FIND("LED2");
   LED3 = GPIO.FIND("LED3");
   LED4 = GPIO.FIND("LED4");
   // start the timer, passing the led to be used to the handler
   cmStartTimer(accelTimer, LED1);
   // we're done
   printf("<<%s\n", __func__);

The accel() function intializes the accelerometer and sets the configuration registers using the configaccel() The GPIO.FIND("LED1") finds the port named under LED1 and its respective settings. Similarly the port and port settings of the other LED are found.

The objectCreate(accelTimer, TimerType, TICKS(1000)); creates a timer under the name accelTimer(which is supposed to happen when ever every 1000ms). On this timer event (OnEvent(accelTimer, (HANDLER) accelTimerHandler)) the accelTimerHandler will be called. Also once the timer event is defined and eventhandlers are set for acceltimer we need to enable/start the timer using cmStartTimer(accelTimer, LED1).

Now since all the events are set the system goes to event listening mode. This is done by using WaitEvent(0, 0); which waits for any event(button trigger event in this case).

void configAccel()
	//selectI2C(LIS2DH_I_AM_MASK, i2cClock_267KHZ);
	//selectI2C(0x30, i2cClock_267KHZ);
	// set up accel
	i2cTx(LIS2DH_CTRL_REG1, (DATA_RATE << 4) + 0x0F);	 // normal mode all-axis enabled
	i2cTx(LIS2DH_CTRL_REG2, 0x00);
	i2cTx(LIS2DH_CTRL_REG3, 0x40);
	i2cTx(LIS2DH_CTRL_REG4, 0x00);                     // 2G
	i2cTx(LIS2DH_CTRL_REG5, 0x00);
	//i2cTx(LIS2DH_CTRL_REG6, 0x00);                   // interrupt active high
	i2cTx(LIS2DH_CTRL_REG6, 0x02);                     //interrupt active low
	i2cTx(LIS2DH_INT1_THS, 0x0F);		// 32LSB*15.625mg/LSB=0.5g
	i2cTx(LIS2DH_INT1_DURATION, 0x00);	// Duration= 10LSB*(1/10Hz) = 1sec
	//spiTx(LIS2DH_INT1_CFG, 0xCC);		// Direction detection on y-axis
	//spiTx(LIS2DH_INT1_CFG, 0xC3);		// Direction detection on x-axis
	i2cTx(LIS2DH_INT1_CFG, 0xCF);		// Direction detection on z-axis
	//selectI2C(TCA6416A_ADDR, i2cClock_267KHZ); // select IO expander as I2C slave

The configaccel() mainly configures the control registers and interrupt registers using I2C communication(I2C api definitions can be found in hal_i2c.h and hal_i2.c). For example CTRL_REG1 sets the sensor power mode bits as well as the X,Y,Z axis enable/disable bits. For more information on for what functionality these different registers are used. You can refer to this information in accelerometer(lis2dh) datasheet .

void accelTimerHandler(TIMER t, word led)
	// called when the timer expires
	// when the timer expires, KoliadaES passes the args defined for the timer
	// in cmStartTimer(accelTimer, LED1) below, to the event handler.
   //i2cReadReg(0x0F,  &whoami, 1);
   //debug("who am i - 0x%8b", whoami);
    debug("who am i - 0x%2x\n",lis2dh_getId());
    int x = lis2dh_getX();
    int y = lis2dh_getY();
    int z = lis2dh_getZ();
    debug("X value - %d\n", x);
    debug("Y value - %d\n", y);
    debug("Z value - %d\n", z);
     else if((y>-11000) && (y<-2500))
     else if((y>2500) && (y<11000))
     else if(y>11000)

The accel timer handler is called whenever the timer event is triggered which is every 1000 ms. The lis2dh_getId(), lis2dh_getX(),lis2dh_getY(),lis2dh_getZ() are used to get the XYZ values of the sensor every second and based on the Y value of the accelerometer the different set of LEDs are switched ON or OFF using GPIO.SET()

The functions The lis2dh_getId(), lis2dh_getX(),lis2dh_getY(),lis2dh_getZ() are defined in lis2dh.c.

byte lis2dh_getId(void) // get ACCEL internal ID.
	selectI2C(LIS2DH12_ADDR, i2cClock_267KHZ); // select IO expander as I2C slave
	return i2cRx(LIS2DH_WHO_AM_I);
int lis2dh_getZ(void)
	int data;
	data   = i2cRx(LIS2DH_OUT_Z_H);
	data <<= 8;
	data  += i2cRx(LIS2DH_OUT_Z_L);
	return data;
int lis2dh_getY(void)
	int data;
	data   = i2cRx(LIS2DH_OUT_Y_H);
	data <<= 8;
	data  += i2cRx(LIS2DH_OUT_Y_L);
	return data;
int lis2dh_getX(void)
	int data;
	data   = i2cRx(LIS2DH_OUT_X_H);
	data <<= 8;
	data  += i2cRx(LIS2DH_OUT_X_L);
	return data;

We have now accomplished setting up and accessing the accelerometer sensor through i2c pins on the SPIP headers and reading the XYZ values of acceleration. and thereby using the accel data(Y axis value) and LED to build a level indicator. Now you can try creating a different application using the different configuration settings of the accelerometer sensor.

More Examples

More Boards

      Copyright © 2018-2019 Koliada, LLC
  • piep/examples/accel.txt
  • Last modified: 2019/04/16 00:57
  • by venkat