Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: X_NUCLEO_IKS01A1 mbed
Revision 0:d9a14a63c3ed, committed 2018-08-15
- Comitter:
- jbindin
- Date:
- Wed Aug 15 15:04:32 2018 +0000
- Commit message:
- snntst
Changed in this revision
diff -r 000000000000 -r d9a14a63c3ed X_NUCLEO_IKS01A1.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IKS01A1.lib Wed Aug 15 15:04:32 2018 +0000 @@ -0,0 +1,1 @@ +http://os.mbed.com/teams/ST/code/X_NUCLEO_IKS01A1/#d1c67d482bad
diff -r 000000000000 -r d9a14a63c3ed main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Aug 15 15:04:32 2018 +0000 @@ -0,0 +1,211 @@ +/* +This programme reads an accelerometer every 1/10 of a second. +The data is then stored in a ring buffer, for each sample the previous sample +is subtraced away from the current sample and a moving average of the past 10 +samples are taken. + +this moving average is then passed to a struct which is then passed to a message +queue. thread1 passes a signal to thread2 so it can process the values from the +struct. + +thread2 works out the mean of the past 10 values and outputs it serially to a +console. This works out as one output per second (althouch not exact). + +the project was made with MBEDs online compiler +*/ + +// imports +#include "mbed.h" +#include "rtos.h" +#include "x_nucleo_iks01a1.h" + +//to pass signal from threads (easier to read) +#define READ 1 + +//to show maximum ammount of samples stored +#define COUNTMAX 10 + +//declarations +Serial pc(USBTX, USBRX); +Thread* thread1; +Thread* thread2; + +//struct to store x, y and z values from the accelerometer. +typedef struct { + float xVal; + float yVal; + float zVal; +} accMessage_t; + +//declarations of additional functions used. +float movingAverage(float newSample, float previousSample, float rBuffer[]); +float average(float values[10]); + +//used to collect samples from the expantion boards sensors +static X_NUCLEO_IKS01A1 *expBoard = X_NUCLEO_IKS01A1::Instance(D14, D15); +static MotionSensor *accelerometer = expBoard->GetAccelerometer(); + +//array to store x,y,z values in thread1 +int accVals[3]; + +//used to store samples +float valuesX[COUNTMAX]; +float valuesY[COUNTMAX]; +float valuesZ[COUNTMAX]; + +//flag to discard the first output. the array is not populated yet so this output +//is not as accurate +bool arrayPopulated = false; + +//queue and memory pool to create structs and pass messages efficiently +Queue<accMessage_t, 20> que; +MemoryPool<accMessage_t, 20> memPool; + +/*this function is used by thread1, it samples values, passes them to the +movingAverage function, uses the memory pool to store them as structs +the structs are passed to a queue and sets a message to thread2 to allow it to +be active*/ +void producer() +{ + //collects data as previous values to make average more accurate + accelerometer->get_x_axes(accVals); + float previousX = accVals[0]; + float previousY = accVals[1]; + float previousZ = accVals[2]; + + //thread loop involves a 10ms delay + while(1) { + Thread::wait(100); + //sample data from accelerometer + accelerometer->get_x_axes(accVals); + + float newAverageX = movingAverage((float)accVals[0], (float)previousX, valuesX); + float newAverageY = movingAverage((float)accVals[1], (float)previousY, valuesY); + float newAverageZ = movingAverage((float)accVals[2], (float)previousZ, valuesZ); + previousX = accVals[0]; + previousY = accVals[1]; + previousZ = accVals[2]; + + //adds values to struct + accMessage_t *message = memPool.alloc(); + message->xVal = newAverageX; + message->yVal = newAverageY; + message->zVal = newAverageZ; + + //passes structs to queue and sets thread2s signal + que.put(message); + thread2->signal_set(READ); + } +} + +/* +function is used by thread2. it gets structs to the queue. Every 10 stucts +recieved calls the average function which returns the mean of the past 10 values. +this is done for the x,y and z axes. +the average is outputted although the first output is discarded to ensure the +first set of data is populated. +*/ +void consumer() +{ + int count = 0; + //stores structs data in arrays so the values can be averaged later + float valuesReadX[10]; + float valuesReadY[10]; + float valuesReadZ[10]; + + while(1) + { + //waits for thread1 + Thread::signal_wait(READ); + + osEvent evt = que.get(); + if(evt.status == osEventMessage) + { + accMessage_t *message = (accMessage_t*)evt.value.p; + valuesReadX[count] = message->xVal; + valuesReadY[count] = message->yVal; + valuesReadZ[count] = message->zVal; + + memPool.free(message); + + if(count >= 9) + { + if(arrayPopulated == true){ + + //output averages seperated by commas to ensure data can be + //easily read and processed + pc.printf("%.2f,\t %.2f,\t %.2f\n\r", average(valuesReadX), average(valuesReadY), average(valuesReadZ)); + } + count = 0; + arrayPopulated = true; + } + } + count++; + } +} + +//main function +main() +{ + //attaching thereads to their functions + thread1 = new Thread(&producer); + thread2 = new Thread(&consumer); + + while(1) { + wait(50000); + } +} +/* +calculats the moving average for the past 10 values. it also is responsible +for keeping the array ring buffered and subtracting the previous sample from +the current. +*/ +float movingAverage(float newSample, float previousSample, float rBuffer[]) +{ + float ave = 0.0; + + // to calculate the change in acceleration + newSample = newSample - previousSample; + + //move up every value in the array + for(int i = (COUNTMAX-1); i > 0; i--) { + rBuffer[i] = rBuffer[i-1]; + } + + //add new value + rBuffer[0] = newSample; + + //summing every value in the array + for(int i = 0; i < COUNTMAX; i++) { + ave = ave + rBuffer[i]; + } + + //divide the sum by 10 to work out the mean + ave = ave / (float)COUNTMAX; + + //return the mean value + return ave; +} + +/* +used to work out the final average that is to be ouputted every second +*/ +float average(float values[10]) +{ + float sum = 0; + float result = 0; + for(int i = 0; i < 10; i++) + { + sum = values[i] + sum; + } + result = sum / 10; + + //returns the final mean value + return result; + +} + + +// please note an attempt to use a Ticker as an interupt was used to make the +// samples more accurate however the command "accelerometer->get_x_axes(accVals);" +// only returned 0 so two threads were used insted. \ No newline at end of file
diff -r 000000000000 -r d9a14a63c3ed mbed-os.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Wed Aug 15 15:04:32 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#98ba8acb83cfc65f30a8a0771a27c71443ab093a
diff -r 000000000000 -r d9a14a63c3ed mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Aug 15 15:04:32 2018 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/a7c7b631e539 \ No newline at end of file