(back to: main 5785 page, 5785 lab page)
Your ColdFire board contains a solid-state 3-axis accelerometer
very similar to the one used in the Nintendo Wii controller.
This lab is about acquiring and exploiting data from this device.
Accelerometer Driver
For this part of the lab refer to
your existing pot driver,
the ADC chapter of the
MCF5223x reference manual, the documentation for the
M52233DEMO board, and the documentation for the MMA7260Q
accelerometer.
Write these two functions:
void init_accelerometer_and_pot (int mode);
void sample_accelerometer_and_pot (int which, struct accel_data * datap);
Where the structure for storing data is defined as:
struct accel_data {
int x, y, z, pot;
};
The initialization function must:
-
Ensure that the accelerometer's three analog outputs, for the X, Y, and Z
axes (see documentation), are ADC inputs to your ColdFire processor.
See the docs and schematics for the MCF52233DEMO board. Also configure
the potentiometer input as an ADC input.
-
Configure the ADC unit properly to receive these 4 inputs.
-
Pull the accelerometer's SLEEP pin high.
-
Set the sense of the accelerometer's configuration pins such that g-Select1
is set high iff bit 0 of the mode argument is 1 and g-Select2
is set high iff bit 1 of the mode argument is 1.
The sampling function must:
-
Fill in the struct referenced by the datap argument with X, Y, and Z
data, and potentiometer data, as dictated by the which argument.
The bottom 4 bits of
which
determine which values are read from the accelerometer. In other words, if
bit 1 of which is set, the Y channel is sampled and the resulting
value is written into the structure.
Do not perform an A/D conversion for any sample that is not requested. In
other
words, you are not permitted sample all four A/D channels and then return only
the requested values. This implies that if no bits of which are set,
no samples should be taken and your function should return immediately.
-
Do not use interrupts, just poll the ADC for completion.
-
Use a parallel sampling mode to get the A and B ADC units to work in parallel
to keep sampling latency as low as possible.
-
Values you return should be raw 12-bit ADC values.
You should test your driver, ensuring that it returns sensible readings for the
accelerometer and potentiometer.
Accelerometer Calibration
Calibrate your accelerometer. Your goal is to determine, for each of the
three axes, the sensor reading at -1g, 0g, and 1g. These values completely
calibrate the device since you may assume that the volatage response in linear in
the acceleration sensed by the device.
You should pick the accelerometer sensitivity setting that gives the widest
response curve (and hence best precision) for all three axes in the -1g to 1g
range. For whatever reason, the most sensitive (1.5g) setting did not work
for me (the readings for one axis were squashed against 0v). It may work for
you, but you need to determine this experimentally. The setting and
calibration
values that you use here should be used for all subsequent portions of the lab.
If you run into calibration problems for one or more of the three
axes, let an instructor know. An example of a calibration problem
would be where there is no sensitivity setting for the accelerometer
that permits the full -1g to 1g range to be sensed.
Accelerometer Tennis
This part of the lab will use only the X axis of the accelerometer, which is
in line with your board's 4 user LEDs. The board and a human holding
the board play a game.
-
The game begins when the processor is reset or
the SW1 switch is released.
-
A game consists of 6 volleys. For each volley, the
player attempts to return a serve.
-
A serve is indicated by flashing LED3,
then LED2, then LED1, then LED0.
-
By the time that LED0 goes out,
the player must return the serve by lightly flicking the board in the X-axis
direction. Hence you must implement a "flick" detector that is
fairly sensitive (we don't want anyone breaking their board) but
that does not register false positives. For example, you do not
want to register a flick if the board is bumped or jostled.
How you detect flicks
is up to you, but you should separately test your flick detector
before implementing the rest of the game. It is strongly likely
that some parts of the flick detector will need to be running
before LED0 goes out.
-
If the player successfully returns a serve, the board shows this
by successively lighting LED0, then LED1, etc. The speed of the
return should mirror the speed of the serve.
-
If the player fails to return a serve, the game proceeds to the
next volley.
-
There should be a random delay of a few seconds between volleys.
-
The potentiometer serves as a difficulty selector for this
game. At the minimum pot setting (volage wise) the game is
most easy (slowest
serves), whereas at the maximum pot setting, it is hardest.
You should feel free to make the game more difficult in other
ways as the pot setting is increased. For example, you might
increase the variance of the delay between serves and/or
the variance of the serve speed.
-
The speed of the serve should be random with a distribution
centered around a value that is determined by the current
difficulty setting.
-
If the difficulty is changed mid-game, you should take
this change into account
for the next volley.
-
Once the game ends, the board is quiescent until either SW1
or SW2 is released.
-
When SW2 is released, the board goes into "flick debug" mode.
In this mode, all LEDs are dark and the flick detection algorithm
is run continuously. When a flick is detected, all 4 LEDs should
light up for 0.1s. The board remains in this mode until it is
reset or SW1 is released.
-
Attempt to make a tennis game that is fun to play. It should be easy
at the easy settings and difficult at the difficult settings.
Position Estimation
The output of an accelerometer, integrated twice, gives position information.
Your assignment is to implement a ColdFire application which determines the
position of your demo board in the X and Y dimensions.
-
You should assume that your board will be moved around like a puck on a flat
surface. Its movement will have two degrees of freedom. The other four
degrees of freedom -- the Z axis and the
pitch, roll, and yaw of the board -- may be assumed to be fixed.
-
Implement position estimation. Feel free to borrow any information and code from
this FreeScale application note. Note that constants and other details from this
code will need to be tuned and adapted.
-
As the document states, a uniform sampling rate is key. Your application's
sampling should be driven by a timer interrupt
that fires at 2500 Hz. The timer interrupt handler should take the sample
and place it into a buffer in memory.
-
When
the sample buffer fills, the main (non-interrupt) context should perform the
filtering, movement end check, position estimation, and mode change functionality.
-
You should implement the "movement end" check described in the application
note. Your board will always be in one of three states: moving, stopped,
and error.
-
Your code should not use any floating point values. Do everything with
integers. Rather than messing around with fixed-point fractions, it is
easiest to choose a length unit small enough that integral quantites of them
do not interfere too much with accuracy. The choice of length unit is up to you.
The time unit should also be discretized.
-
When the board is stopped or in error, and the SW1 button is pressed, the board
should zero its estimation of position and velocity and enter the stopped state.
The SW1 button should never be pressed when the board is moving -- it is not
possible to cope with estimator reset of a moving board.
-
When the board is stopped and the SW2 button is pressed, it should report its position
using printf() in units of millimeters from the last zero point.
Positive millimeters are towards the top and right side of the board, when
it is positioned so you can normally read the M52233DEMO logo.
-
If either SW1 or SW2 is pressed in the moving state, or if significant Z-axis
acceleration is detected in any state, the board enters the error
state.
-
In the stopped state, position does not change, but the board must
automatically detect the transition to the moving state.
-
A board in the error state does not care about its position, velocity, or
acceleration.
-
In the moving or stopped state:
-
When the board's X position is positive, LED0 should be lit. Otherwise
this LED should be off.
-
When the board's Y position is positive, LED1 should be lit. Otherwise
this LED should be off.
-
In the moving state, LED2 should be lit. Otherwise this LED should be off.
-
When the board is in the error state, LEDs 0-2 should blink at about 5 Hz.
-
LED3 is available to you for debugging.
-
A board that is stopped should be able to safety call printf().
However, a moving board should never make this call as the sampling delays imposed
by USB communication will likely hurt estimation precision.
Lab report
-
Handin the files you wrote for the tennis and position sensor
applications, which should include your accelerometer driver.
Files should be commented. Handin files for the game
using
handin cs5785 lab4-tennis file
and handin the files for the position sensor using
handin cs5785 lab4-position file.
Do not handin makefiles or other things not written by you.
-
Show an instructor your working tennis game and position sensor in
lab.
This page is maintained by John Regehr, mail me if you find a
mistake or if any content is unclear.