Saturday, 6 April 2013

[12 November 2012] A Light-Activated Shock Detector - Part II

12 November 2012
National University of Singapore
EE2024 PROGRAMMING FOR COMPUTER INTERFACES
A Light-Activated Shock Detector - Part II
Project Report

Abstract

The aim of this project is to implement a night-time shock detector which can either operate on its own in "detect mode", or as part of a larger system in "co-operative mode". This is achieved by integrating C Programming and Thumb-32 bit Assembly language to instruct an ARM-Cortex M3 Microprocessor chip to control various peripherals such as a light sensor and an accelerometer. This report focuses mainly on how C programming was used to activate the peripheral devices as well as implement "Detect Mode" and "Co-operative Mode". For more information on how thumb-32 assembly language was integrated into this project, please refer to part 1 of the project hereThis project was carried out in August 2012 - November 2012 as a group of 2 team-mates.


Contents

1 Introduction
  • 1.1  Project Overview
  • 1.2  Implementation of the SysTick Interrupt
2 Detect Mode
  • 2.1 Detect Mode Overview
  • 2.2 GPIO Peripherals and Devices
    •  2.2.1 SW4 Pushbutton
    •  2.2.2 RGB LED
    • 2.2.3 SW3 GPIO Interrupt
  • 2.3 I2C Peripherals and Devices
    • 2.3.1 Accelerometer
    • 2.3.2 Light Sensor
  • 2.4 SSP/SPI Initialization
3 Co-Operative Mode
  • 3.1 Co-Operative Mode Overview 
  • 3.2 UART Initialization and Interrupt Configuration
  • 3.3 Receiving Data through UART Protocol
  • 3.4 String Comparison and Data Processing
4 Conclusion
  • 4.1 Special Feature
  • 4.2 Reflections
Appendix
  • Appendix A: UML Design
  • Appendix B: PC – System Communication Specifications
  • Appendix C: Baseboard Diagram

1 Introduction

1.1  Project Overview

In this project, we have implemented a shock detection and localization system by using C programming in conjunction with assembly language to configure an ARM Cortex M3 Processor and certain baseboard Peripherals. The system we have implemented operates in two modes, ‘Detect’ and ‘Co-Operative’. A comprehensive illustration of our system through a UML State Chart and a Use Case Diagram can be found in Appendix A.

1.2 Implementation of the SysTick Interrupt

One of the project requirements is to read the accelerometer and light sensor every 40ms. Thus, we have chosen to use the “SysTick” interrupt to accurately time our readings. We have configured it to send an interrupt to the processor every 40ms using the library helper function “SysTick_Config”. The parameter to be parsed into this function is the number of ‘ticks’ between each interrupt.  Therefore, we parse in the number of ticks per second, SysCoreClock, divided by  to the function. Within the interrupt handler function, the program reads the accelerometer and light sensor values, and then proceeds to set a flag (Global Integer Variable “dataRead”) which the main function can poll to check if there is any new data to be processed.

2 Detect Mode

2.1 Overview of Detect Mode

In detect mode, the system constantly polls the “dataRead” flag to see if there is any new data for processing. If the flag is set, the system calculates the variance and maximum of the last 6 accelerometer z-axis readings using the “asm_variance” function from Project 1. A shock is detected if the luminance level is below 100, and if the time-windowed variance of the z-axis acceleration is greater than 200, which is the threshold set by us. A detected shock triggers the alarm, which can be stopped by pressing the SW3 pushbutton on the baseboard. Once SW3 is pushed, the system returns to polling the “dataRead” Flag.

2.2 GPIO Peripherals and Devices

2.2.1 SW4 Pushbutton
We have configured the SW4 pushbutton as a mode-switch as illustrated in Figure X. Every time SW4 is pushed, it will cause a change in mode, from “Detect” to “Co-op” and vice versa. SW4 is initialized as a GPIO by setting P1.311 to function number 0. The “GPIO_SetDir” helper function is then used to set P1.31 as an input signal. The “GPIO_ReadValue” helper function is used to set a variable for the system to poll every cycle to see if it should change mode

2.2.2 RGB LED
For the direct digital IO peripheral RGB LED, it is initialized as a GPIO output (RED). With reference to the datasheet in Appendix C, we can deduce that the RED LED is connected to P2.0. Thus, we set P2.0 to function number ‘0’ to initialize it as GPIO. The “GPIO_SetDir” helper function is then used to set P2.0 as an output signal.

2.2.3 GPIO Interrupt SW3
For SW3 pushbutton, it is implemented it as a GPIO interrupt. We have configured P2.10 to function number ‘2’ as an external interrupt (EINT) signal. Since all port 2 GPIO interrupts are sent as EINT3 signals, we enable the processor to receive the interrupt by using the helper function “NVIC_EnableIRQ(EINT3_IRQn)”. To enable the device to send the interrupt, we have chosen out of convenience to use “LPC_GPIOINT->IO2IntEnF |= 1<<10” to write directly to the register which enables the falling edge interrupts for all pins on port 2.

Inside the EINT3 interrupt handler function, which runs when SW3 is pushed, the “stopAlarm” flag is set. Since our alarm function polls the flag every period time to determine if the alarm should continue running, the alarm will stop if the flag is set. Upon exiting the alarm function, we reset the values stored in the variance buffer so that any residual readings will not trigger an alarm unnecessarily.

2.3 I2C Peripherals and Devices

In this project, the two I2C peripherals which we are required to utilize is the light sensor and the accelerometer. First, we initialize the pin functions for the data (SDA2) and clock (SCL2) signals required for I2C communication between the processor and the peripherals. Referring to the figure 1, in order to activate the above-mentioned signals, we have to set the function number for P0.10 and P0.11 to ‘2’.

Figure 1: Pinsel0 Function Select Table
Source: user.manual.lpc17xx.pdf, Reference Materials, EE2024 IVLE Workbin, AY2012/13 Semester 1

The clock rate is then defined by setting the divider and setting the I2C operation to default by using the helper function “I2C_Init(LPC_I2C, 100000)”. Next, the I2C interface is enabled by the helper function “I2C_Cmd(LPC_I2C, ENABLE)”. Lastly, we include the libraries “acc.h” and “light.h” in order to configure the light sensor and accelerometer settings.

2.3.1 Accelerometer
The accelerometer is a device which can detect motion. It is initialized by using the “acc_init” function and set to ‘measure mode. Data is read by parsing the address of variables x, y and z into the “acc_read” function.

2.3.2 Light Sensor
The light sensor is a device which measures the level of luminance of its surroundings. It is initialized by using the “light_enable” function. The range is set to 1000, and the hi/lo thresholds are set to 1000 and 0 respectively. Data is read by reading the return from the “light_read” function, which does not require any parameters to be parsed in.

2.4 SSP/SPI Initialization

As SSP/SPI is not within the syllabus, we will just briefly go through the initialization process for it. 4 signals need to be activated for SSP/SPI. Namely: clock (SCK1), Master Input Slave Output (MISO1), Master Output Slave Input (MOSI1) and Chip Select (SSEL). As can be seen from figure 2, we need to configure P0.7, P0.8 and P0.9 to function number ‘2’ in order to do so. However, rather than activating the SSEL signal, we configure P2.2 to function number ‘0’ as GPIO to use as a chip select signal. We need to enable SSP/SPI in order to use the OLED screen.

Figure 2: Pinsel0 function select table
Source: user.manual.lpc17xx.pdf, Reference Materials, EE2024 IVLE Workbin, AY2012/13 Semester 1

Next, the SSP/SPI peripheral is initialized and enabled by the following helper functions, “SSP_Init(LPC_SSP1, &SSP_ConfigStruct)” and “SSP_Cmd(LPC_SSP1, ENABLE);”.

3 Co-Operative Mode

3.1 Overview of Co-Operative Mode

When the system enters Co-Operative Mode, it is expected to be able to receive commands from a PC, and respond accordingly. All communication and handshaking between system and PC is supposed to be done through the Universal Asynchronous Receiver/Transmitter (UART) Protocol. UART protocol transmits/receives data in serial form and is capable of full duplex2 transmissions. However, it is important to note that the UART does not send/receive signals directly. Rather, it is connected in conjunction with physical layer communication standards such as RS232 which sends/receives the actual data.
                                                                                                        
In Co-Operative Mode, the PC will send commands to the system in the form of character arrays (strings) ending with the ASCII character ‘\r’. The system is then expected to send back appropriate responses to the PC also in the form of strings, but this time ending with “\r\n” instead of just ‘\r’. A complete annex of the communication procedure between PC and system can be found in Appendix B. “IDR AWESOME 66\r\n” is our system’s only unique response, which is sent when the PC sends the “IDQ\r” command. Unlike in Detect Mode where it was the system which set the luminance and z-axis variance thresholds for shock detection, it is now the PC which determines whether or not there has been a shock. The PC is also supposed to have the ability to stop the Alarm of the system while it is ringing.

3.2 UART Initialization and Interrupt Configuration

In order to initialize the UART protocol for our system, we first have to define the user-configured settings as specified in figure 3.

User-Configurable Setting
Configuration
Baud Rate
115200
Data Length
8 bits
Parity Bit
None
Stop
1 bit
Figure 3: UART Configuration Settings

Since we are provided with USB Cables, we have decided to use the UART3 signal to communicate with the PC. As such, we will have to configure the system as specified by the appropriate Tables in the user manual. As can be seen from figure 4, we have to set Port ‘0’, pins ‘0 and 1’ to Function number ‘2’ in order to activate the ‘TXD3’ and ‘RXD3’ to initialize UART3.

Figure 4: PINSEL0 Function Select Table
Source: user.manual.lpc17xx.pdf, Reference Materials, EE2024 IVLE Workbin, AY2012/13 Semester 1

We have also decided to enable the “Receive Data Available” (RDA) interrupt for UART3 with RX Trigger Level 0. This means that an interrupt will be triggered whenever there is at least 1 character inside the Rx FIFO Buffer. As with all interrupts, the RDA interrupt needs to be enabled both on the device side, and the processor side. Thus, we have manually set the U3FCR Register’s bits 7:6 to “00” which set the Rx Trigger level to 0, and the U3IER Register’s bit 0 to ‘1’ which enables UART 3 to send RDA interrupts to the processor. We then made use of the helper function “NVIC_EnableIRQ(UART3_IRQn);” to enable the processor to receive interrupts from UART3.

3.3 Receiving Data through the UART Protocol

In our program, the RDA interrupt is triggered by every character sent through the UART protocol. Thus, we have decided to read the data one character at a time using the UART3 Interrupt Handler function. We declared a global string variable “rcv_string” to store the characters received, and a counter variable “rcv_len” which decides which position within “rcv_string” the character will be placed. If the character received is ‘\r’, it means that it is the end of the PC command and our program proceeds to clear all remaining spaces in the “rcv_string” array by means of a ‘for’ loop, reset “rcv_len” to 0, and set a flag (Global Integer “uartRead”) to inform the main function that a command has been read from the PC.

3.4 String Comparison and Data Processing

When the main function detects that the “uartRead” flag has been set, it utilizes “if-else” block instructions and the library function “strcmp” to determine what command has been sent. The only exception to this is when “B max_var1 max_var2 max_var3 max_var4\r\n” is sent from the PC, the program checks whether the first character in “rcv_string” is ‘B’ in order to identify this type of command. Following which, nested loops and the library function “atoi” is used to convert “rcv_string” into 4 separate integer values. The maximum of those 4 values is then compared with the maximum variance sent to the PC. If they are equal, the system sends “MEE\r\n” to the PC and sounds the alarm. Otherwise, the system sends “NME\r\n” to the PC.

From Appendix B, the response expected from the system is form most commands is constant. For example, “ENA\r\n” is always expected when PC sends “END\r” command. Thus, “strcpy” is used to copy the appropriate response into a separate string “send_string” before sending it out to the PC. The only exception is when the PC sends the “REQ\r” command as the expected response contains the max variance and luminance values to be which are variables. Thus, the “print” function is used instead as it is able to copy numerical values of variables into strings.  

4 Conclusion

4.1 Special Feature

For this project, the additional feature we have implemented is Joystick control over the variance and luminance thresholds for shock detection in detect mode. Figure X shows the exact specifications of this feature. The ranges are as follows: (20 < Var < 990) and (20 < Lux < 950).

JoyStick Position
Action
JoyStick_Left
Lux Threshold decreased by 10
JoyStick_Right
Lux Threshold increased by 10
JoyStick_Down
Var Threshold decreased by 10
JoyStick_Up
Var Threshold increased by 10
JoyStick_Center
Lux & Var Thresholds reset to 100/200
Figure 5: Joystick Control Specifications

Do note that when the system is in Co-Operative Mode, the threshold for shock detection is decided solely by the PC and thus, this special feature is only implemented in Detect Mode.

4.2 Reflections

Through this project, we have learnt the basics of embedded systems design. We now have a better understanding of how to utilize library functions in conjunction with datasheets provided by the manufacturer to implement a system using an ARM processor to control peripheral devices on a baseboard. We also have a better grasp on the debugging process and can now see the importance of using breakpoints and memory tracking to perform debugging efficiently.

Appendix

Appendix A: UML Design

UML Use Case Diagram



UML State Chart




Appendix B: PC – System Communication Specifications

Communication Flowchart

Source: Project 2 Manual Annex

Detailed Description of Communication Procedure

Source: Project 2 Manual Annex


Appendix C:

Datasheet for RGB LED

Source: LPCXpresso_Base_Board_revB.pdf, Reference Materials, EE2024 IVLE Workbin, AY2012/13 Semester 1

  • From the datasheet, it can be seen that the RED LED is connected to PIO1_9 on the baseboard.
  • Now we need to match PIO1_9 to the appropriate Port/Pin of the Processor Chip.


Matching to Processor Port/Pin Number

Source: LPCXpresso_Base_Board_revB.pdf, Reference Materials, EE2024 IVLE Workbin, AY2012/13 Semester 1

  • From the above diagram, it can be seen that PIO1_9 is connected to Port 2 Pin 0 of the processor chip.
  • In general, this is how we deduce which port/pin of the processor any device or peripheral on the baseboard is connected to.


1 comment: