calculating acceleration using adxl213 – dual axis accelerometer use equivalent idea in lab. 3...
TRANSCRIPT
Calculating acceleration using ADXL213 – dual axis accelerometer
Use equivalent idea in Lab. 3 with thermal sensor
2 / 28
Cargo Monitoring System Disaster likely to be in remote areas Cargo to be delivered by skid-air drop During transport
Quick indication of health of product NOW Acceleration in range – accuracy of +- 1/8 G Temperature steady – accuracy of +- 1 / 32 C
On delivery Display of ranges that cargo has experienced Range of temperatures and accelerations Other cargo information
3 / 28
ReminderHow is the project being split up? Devices use pulse-width modulation
Acceleration – Handle through examples in the lectures Temperature – You are handling this in Lab. 3.
This means that all the tests and functions developed in the lectures for handling acceleration using a pulse-width modulated device will need to be modified by you for handling temperature
LCD display – SPI interface Acceleration – Handle through examples in the lectures Temperature – You are handling this in Lab. 4 This means that all the tests and functions developed in the
lectures for displaying acceleration using am SPI display device will need to be modified by you for handling temperature
4 / 28
Overall designInitialize stuff (C++)
Calculate Temperature
Store temperature, calculate averages
and ranges
Calculate Acceleration
Store acceleration, calculate averages
and ranges
General Purpose Timercontrolling Display as
ISR
Temperature / Accelerationgraphic (non-text) display
Changes, actual temperatures
Core temperatureISR clockused for
Temperature / Accelerationdetermination
Communications with LCDMOSI / MISO format -- ISR
Temperature / AccelerationinformationText format
main( )
Lecture
Lab. 3
5 / 28
Design details addedInitialize stuff (C++)
Calculate Temperature
Store temperature, calculate averages
and ranges
Calculate Acceleration
Store acceleration, calculate averages
and ranges
General Purpose Timercontrolling Display as
ISR
Temperature / Accelerationgraphic (non-text) display
Changes, actual temperatures
#define TEMPERATURE_STEADY 1 etc#define ACCELERATION_STEADY 1#define ACCELERATION_DECREASING 2#define ACCELERATION_INCREASING 3
variable acceleration_changing
Communicationbetweenmain( )
and ISR
main( )
6 / 28
Three files are going to be neededLab3 directory – where product will end up being built lab3prototypes.h
#define TEMPERATURE_STEADY 1#define ACCELERATION_STEADY 1#define ACCELERATION_DECREASING 2 #define ACCELERATION_INCREASING 3
void Set_Acceleration_Mode(long int current_Acc, long int average_ACC);
CodeAcceleration.cpp Set_Acceleration_Mode( current_Acc, average_ACC) {
All necessary code to make function work }
Lab3 tests directory – where all tests will be built TestsAcceleration.cpp
TEST(Set_Acceleration_Mode, DEVELOPER_TEST) {
All necessary code to test that function works }
7 / 28
Set_Acceleration_Mode( ) Test Recap#include “../Lab3/lab3prototypes.h”
void Set_Acceleration_Mode(long int current_Acc, long int average_ACC);
extern volatile long int acceleration_changing; // Declared in CodeAcceleration.cpp // Lab3 directory -- global
TEST(Set_Acceleration_Mode, DEVELOPER_TEST)
// acceleration_now == average_acceleration Set_Acceleration_Mode(6 , 6); // current and average acceleration same CHECK(acceleration_changing == ACCELERATION_STEADY);
// acceleration_now < average_acceleration Set_Acceleration_Mode(0 , 6); // current acceleration lower than average CHECK(acceleration_changing == ACCELERATION_DECREASING);
// acceleration_now > average_acceleration Set_Acceleration_Mode(6, 0) CHECK(acceleration_changing == ACCELERATION_INCREASING);
}
Then we wrote the code to satisfy the test
8 / 28
Recap -- test – Ability to calculate Average#include “../Lab3/lab3prototypes.h”
Int CalculateAverage(int previous_values[ ], int N, int *average_value);
TEST(AverageCalculation, DEVELOPER_TEST)
int previous_values[10] = {0, 0, 2, 2, 1, 1, 10, 10, 10, 10}; int average_value = 0; bool result = true;
// Empty array -- invalid number of points as array length result = CalculateAverage(previous_values, 0, &average_value); CHECK(result == false);
// Average first two values
average_value = 6; result = CalculateAverage(previous_values, 2, &average_value); CHECK(result == true); CHECK(average_value == 0);
// Average first four values result = CalculateAverage(previous_values, 4, &average_value); CHECK(result == true); CHECK(average_value == 1);
etc.
Then we wrote the code to satisfy the test
9 / 28
Recap -- Tests for bool AddToArray(int *, int, int)#include “../Lab3/lab3prototypes.h”
bool AddToArray(int previous_values[ ], int MAX_ARRAY_SIZE, int newValue);
TEST(AddToArray, DEVELOPER_TEST) {
#define MAX_ARRAY_SIZE 8 // WOULD THIS BE BETTER DEFINED INSIDE ../Lab3/lab3prototypes.h? int previous_values[MAX_ARRAY_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0}; bool result;
// Have a new acceleration value of 1 – add to the array int expected [MAX_ARRAY_SIZE] = {1, 0, 0, 0, 0, 0, 0, 0}; result = AddToArray(previous_values, MAX_ARRAY_SIZE, 1); CHECK(result == true); ARRAYS_EQUAL(expected1, previous_values, MAX_ARRAY_SIZE);
// Have new acceleration values of 2 and then 3 – add those to the array int expected2[MAX_ARRAY_SIZE] = {1, 2, 3, 0, 0, 0, 0, 0}; result = AddToArray(previous_values, MAX_ARRAY_SIZE, 2); CHECK(result == true);
result = AddToArray(previous_values, MAX_ARRAY_SIZE, 3); CHECK(result == true); ARRAYS_EQUAL(expected2, previous_values, MAX_ARRAY_SIZE);
…………………………MORE TEST CODE ON NEXT PAGE …………………………….
Then we wrote the code to satisfy the test
10 / 28
Calculation the acceleration using information from the hardware
Let us assume that we have the time (in clock pulses) for T1 (T1_high) and T2 (T2_period)
Need to develop the tests to check that correctly calculate the acceleration when the acceleration is in the range +1.7G to -1.7G
bool CalculateAcceleration(int T1_high, int T2_period, int *new_acceleration_value)
Thermometer in Lab. 3 works on exactly the same principle except uses the equationTemperature = A * (T2 – T1) / T1 + B or is it A * T1 / (T2 – T1) + B
11 / 28
Write the tests needed to show that
bool CalculateAcceleration(int T1_high, int T2_period, int *new_acceleration_value)
correctly calculates the acceleration when the acceleration is in the range +1.7G to -1.7G
Through this test design – identify the “design defect” in the current project design concept for the transportation monitoring device
12 / 28
Select a volun-tell to write this testT1 is half of T2 – 50% duty cycle
Manual says result should be 0 gbool CalculateAcceleration(int T1_high, int T2_period, int
*new_acceleration_value)
CalculateAcceleration(1, 2, new_acceleration_value == 0 g)
TEST(HALF_DUTY_CYCLE, DEVELOPER_TEST) {
}
13 / 28
Select a volun-tell to write this test T1 = 0
Manual says A(g) = (0 – 0.5) / 30% = -0.5 / 30% What does -0.5 / 30% mean? Engineering guess – poor description.
Do they mean 30% is to be read as 0.30? T1 = 0 therefore means A(g) = (0 – 0.5 ) / 0.3 = -1.666g. Would make some
sense – since data book says accelerometer works 1.7G to -1.7G
TEST(ZERO_DUTY_CYCLE, DEVELOPER_TEST) {
}
14 / 28
You write the testfor correct result T1 = T2
TEST(HUNDREDPERCENT_DUTY_CYCLE, DEVELOPER_TEST) {
}
15 / 28
You write the testfor correct result Should return false when T2 = 0 or negative Should return false if T1 > T2 or T1 < 0
TEST(BAD_T1_OR_T2, DEVELOPER_TEST) {
}
16 / 28
ADXL213 “tilt sensor” mode info
X 50%Y 50%
X 50% 0gY 80% 1g
X 50% 0gY 20% -1g
17 / 28
You write the testfor tilt mode
TEST(TILT TEST, DEVELOPER_TEST) {
// Should there be 5 asserts to match the known values in Fig. 21?
}
18 / 28
Problem
Some people have all tests pass – depends on the tests written This group would move on, assuming everything is correct However this group has a DESIGN DEFECT which will cause problems later
on as the DEFECT will be very difficult to identify (w.r.t. location)
Some people have most tests fail Some of this group will change their CODE until everything is correct. They
spotted a DESIGN ERROR and fixed it before it caused a problem Some of this group will change their TESTS until everything is correct.
However this group NOW has a DESIGN DEFECT which will cause problems later on as the DEFECT will be very difficult to identify (w.r.t. location)
Correct answer – most tests should be failing
Why the difference? Depends on how you wrote the test
19 / 28
Calculate_Acceleration_Mode( )
20 / 28
Understanding why the errors We need to understand what sort of assembly code
will be generated by the compiler
int new_acceleration = 1000; // Use ridiculous starting values
int expected_value = 1.6666;
CalculateAcceleration(1, 1, &new_acceleration);
CHECK(new_acceleration == expected_value);
CHECK(new_acceleration == 1.666); // ASSERT FAILS
21 / 28
Understanding why the errors // Stack picture // OLD RTS FP + 4 -- needed for P0 = [FP + 4]; JUMP (P0); // OLD FP FP // storage for new_acceleration FP – 4 or SP + 20 // storage for expected _value FP – 8 or SP + 16 LINK (16 + 2 *4); // Need to place two variables on the stack
// int new_acceleration = 1000; // Use ridiculous starting values R3 = 1000 (X);
[FP – 4] = R3; // address of new_acceleration used in subroutine call // Must have value on stack as need AN ADDRESS // int expected_value = 1.6666;
R2 = 1 (X); [FP – 8] = R2; // R2 will be destroyed during subroutine call // Place value on stack as need after subroutine call // CalculateAcceleration(1, 1, &new_acceleration); R2 = FP; R2 += - 4; // Address of new_acceleration on stack – last Friday’s lecture R1 = 1; R0 = R1;
CALL _CalculateAcceleration__FiT1Pi
22 / 28
Understanding why the errors occur // int expected_value = 1.6666;
R2 = 1 (X); [FP – 8] = R4;
This is an integer processor -- floating point number 1.6666 is rounded down to 1 (might be rounded up to 2) by the compiler preprocessor
SOLUTION 1 -- Use floats rather than integers Use float expected_value = 1.6666;
Do all calculations using floating point operations rather than integer
Most integer processor compilers WILL support floating point operations
But this processor is an integer processor, so the compiler will use “software implementation” of floating point operations – roughly 200 to 300 times slower than equivalent integer operations. (Why?)
Remember – will have to modify all operations on temperatures to support
floating point operations – Store-to-array, Calculate-Average, SetMax etc. This could take a lot of development time
Is there an easy solution to provide the correct answer without a lot of extra development work.
23 / 28
Understanding why the errors
// int expected_value = 1.6666;R2 = 1 (X);
[FP – 8] = R4;
This is an integer processor -- floating point number 1.6666 is rounded down to 1 (might be rounded up to 2) by the compiler preprocessor
SOLUTION 2 – Scale values by 0x10000 0g represented by 0x00000 1 g represented by 0x10000 0.5g represented by 0x08000 (which is 0x10000 >> 1) 0.25g represented by 0x04000 (which is 0x10000 >> 2)
Will this work for the processor? Addition works when doing this – ditto subtraction 1.5g represented by 0x18000 (0x10000 + 0x08000)
Multiplication works 0.5g * 2 = 0x8000 * 2 = 0x10000 = 1 gDivision works – if we are careful 1.666666 = 5 / 3 * 0x10000 = 1 * 0x10000 = 0x10000 = 1 – wrong answer
1.666666 = (0x10000 * 5) / 3 = 0x50000 / 3 = 0x1AAAA = 1.66666 g or CLOSE TO IT
NOT ALL POSSIBLE VALUES CAN BE REPRESENTED IN A COMPUTERROUND-OFF ERROR (TRUNCATION ERROR, QUANTIZATION ERROR)
24 / 28
Improved tests and functionAlmost passes tests – Accuracy problem?
25 / 28
REVIEW – How are floating point numbers stored in a computer as a binary values Use VDSP tool to see values displayed as integers
Displayed as floats
Values2020.01010.055.011.0
26 / 28
REVIEW – How are floating point numbers stored in a computer as a binary values Integer 20 = 16 + 4 = 0x14 = b00010100
Floating point 20.0
= 0x14 = b00010100 as integer
= 0x1.4 * 24 = b1.1000 * 24 normalized
Convention – normalized values are in the form
b1.frac * 2exponent
27 / 28
REVIEW – How are floating point numbers stored in a computer as a binary values
Floating point 20.0 = 0x14 = b00010100 as integer = 0x1.4 * 24 = + b1.0100 * 24 normalized
IEEE Convention – normalized values are in the form + b1.frac * 2exponent
IEEE Convention – normalized values are stored as
1 bit 8-bits 23-bitssign bit biased exponent fractional part
exponent + 127
b0 127 + 4 b0100 0000 0000 0000 0000 000 b0 0x7F + 4 b0100 0000 0000 0000 0000 000 b0 0x83 b0100 0000 0000 0000 0000 000 b0 b10000011 b0100 0000 0000 0000 0000 000
b0100 0001 1010 0000 0000 0000 0000 0000 0x4 1 A 0 0 0 0 0
28 / 28
You should be able to convert over decimal values to floating point format 2.5
0.25
128.625
Then use the VDSP register display window to display the values and check if you have the correct answer
29 / 28
Done today Reviewed the Lab. 3 project Identified a major design flaw
Modified the code to fix the design flaw Almost fixed the problem with just one line changed in code Have identified a possible accuracy error
Can we “completely” fix the accuracy problem with further improvements in code design?
Is this a fundamental limitation of the algorithm and the tests need to be modified to incorporate the limitation?
Review of knowledge issues related to design flaw Understand how integer and floating numbers are compared in a
computer program Understand how integer and floating numbers are stored in a
computer program