This example shows a possibility of using dsPIC30F4013 or dsPIC6014A in order to realize control of the pointer of a GLCD on the basis of the signal from an acceleration sensor. In this example the use is made of an accelerometer card containing the sensor ADXL330 by Analog Devices. Besides the sensor, the card contains an operational amplifier used as a unit amplifier increasing the output current capacity of the sensor. The sensor measures the acceleration along two axes, X and Y. The offset voltage of the sensor has to be measured during the calibration procedure. From the accelerometer card, two analogue signals, for the X and Y axes, are fed to the inputs of AN8 and AN9 AD converters (pins PORTB.8 and PORTB.9). After the sampling and conversion, the measured value is presented as the shift of the pointer from the central position on the GLCD.This example is widely applicable for the realization of e.g. joysticks, simple gyroscopes, robot controls or movement detectors.
' An example of the use of the microcontroller dsPIC30F6014A and Accel Extra Board. ' The example shows how the signal from the sensor is sampled and how the information on the ' accelerations along the X and Y axes are used for controlling the cursor on a GLCD. ' The example also covers the calibration of the sensor (determination of zeroG ' and 1G values for X and Y axes). Pin RC1 is used as user input. Pull-down PORTC and ' put button jumper in Vcc position. program AccelerationPointer ' --- GLCD Messages --- const msg1 = "Put board to pos " const msg2 = "and press RC1" dim ' Global variables zeroG_x, zeroG_y as integer ' zero gravity values oneG_x, oneG_y as integer ' 1G values meas_x, meas_y as integer ' measured values box_x, box_y as integer ' variables for drawing box on GLCD positionNo as byte ' variable used in text messages text as String ' variable used for text messages sub procedure Init() ADPCFG = $FCFF ' configure AN8(RB8) and AN9(RB9) as analog pins TRISB.8 = 1 ' configure RB8 and RB9 as input pins TRISB.9 = 1 Glcd_Init_DsPicPro3() ' init GLCD for dsPICPRO3 board ' Noteas GLCD/LCD Setup routines are in the setup library files located in the Uses folder ' These routines will be moved into AutoComplete in the future. Glcd_Fill(0) ' clear GLCD TRISC = $02 ' pin PORTC.1 is input for calibration positionNo = 1 ' variable used in text messages end sub sub procedure DoMeasureXY() meas_x = Adc_Read(8) ' measure X axis acceleration meas_y = Adc_Read(9) ' measure Y axis acceleration end sub sub procedure DrawPointerBox() dim x_real, y_real as real x_real = (meas_x-zeroG_x)/(oneG_x-zeroG_x) ' scale [-1G..1G] to [-1..1] x_real = x_real * 64 ' scale [-1..1] to [-64..64] x_real = x_real + 64 ' scale [-64..64] to [0..128] y_real = (meas_y-zeroG_y)/(oneG_y-zeroG_y) ' scale [-1G..1G] to [-1..1] y_real = y_real * 32 ' scale [-1..1] to [-32..32] y_real = y_real + 32 ' scale [-32..32] to [0..64] ' convert reals to integers box_x = x_real box_y = y_real ' force x and y to range [0..124] and [0..60] because of Glcd_Box parameters range if (box_x>124) then box_x=124 end if if (box_x<0) then box_x=0 end if if (box_y>60) then box_y=60 end if if (box_y<0) then box_y=0 end if Glcd_Box(box_x, box_y, box_x+3, box_y+3, 2) ' draw box pointer, color=2(invert ecah dot) end sub sub procedure ErasePointerBox() Glcd_Box(box_x, box_y, box_x+3, box_y+3, 2) ' draw inverted box at the same position ' (erase box) end sub ' --- Calibration procedure determines zeroG and 1G values for X and Y axes ---' sub procedure DoCalibrate() ' 1) Put the Accel board in the position 1 : PARALLEL TO EARTH'S SURFACE ' to measure Zero Gravity values for X and Y text = msg1 text = positionNo + 48 Glcd_Write_Text(text,5,1,1) Inc(positionNo) text = msg2 Glcd_Write_Text(text,5,20,1) while (PORTC.1 = 0) ' wait for user to press RC1 button nop wend DoMeasureXY() zeroG_x = meas_x ' save Zero Gravity values zeroG_y = meas_y Delay_ms(1000) ' 2) Put the Accel board in the position 2 : X AXIS IS VERTICAL, WITH X LABEL UP ' to measure the 1G X value text = msg1 text = positionNo + 48 Glcd_Write_Text(text,5,1,1) Inc(positionNo) text = msg2 Glcd_Write_Text(text,5,20,1) while (PORTC.1 = 0) ' wait for user to press RC1 button nop wend DoMeasureXY() oneG_x = meas_x ' save X axis 1G value Delay_ms(1000) ' 3) Put the Accel board in the position 3 : Y AXIS IS VERTICAL, WITH Y LABEL UP ' to measure the 1G Y value text = msg1 text = positionNo + 48 Glcd_Write_Text(text,5,1,1) Inc(positionNo) text = msg2 Glcd_Write_Text(text,5,20,1) while (PORTC.1 = 0) ' wait for user to press RC1 button nop wend DoMeasureXY() oneG_y = meas_y ' save Y axis 1G value Delay_ms(1000) end sub main: Init() ' initialization DoCalibrate() ' calibration Glcd_Fill(0) ' clear GLCD Glcd_H_Line(0, 127, 32, 1) ' draw X and Y axes Glcd_V_Line(0, 63, 64, 1) Glcd_Write_Char("X", 122, 3, 1) Glcd_Write_Char("Y", 66, 0, 1) while TRUE ' endless loop DoMeasureXY() ' measure X and Y values DrawPointerBox() ' draw box on GLCD Delay_ms(250) ' pause ErasePointerBox() ' erase box wend end.