james bindin / Mbed 2 deprecated SOFT261_CW

Dependencies:   X_NUCLEO_IKS01A1 mbed

Files at this revision

API Documentation at this revision

Comitter:
jbindin
Date:
Wed Aug 15 15:04:32 2018 +0000
Commit message:
snntst

Changed in this revision

X_NUCLEO_IKS01A1.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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