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
--- /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
--- /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
--- /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
--- /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