First part of AP part 3

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
evenbrownie
Date:
Thu Nov 08 20:48:47 2018 +0000
Commit message:
All I put in were the addresses from the beginning

Changed in this revision

main.cpp 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
millis.cpp Show annotated file Show diff for this revision Revisions of this file
millis.h Show annotated file Show diff for this revision Revisions of this file
quaternion.cpp Show annotated file Show diff for this revision Revisions of this file
quaternion.h Show annotated file Show diff for this revision Revisions of this file
sensor_fusion.cpp Show annotated file Show diff for this revision Revisions of this file
sensor_fusion.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f43994f44684 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,12 @@
+#include "mbed.h"
+
+DigitalOut myled(LED1);
+
+int main() {
+    while(1) {
+        myled = 1; // LED is ON
+        wait(0.2); // 200 ms
+        myled = 0; // LED is OFF
+        wait(1.0); // 1 sec
+    }
+}
diff -r 000000000000 -r f43994f44684 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/e95d10626187
\ No newline at end of file
diff -r 000000000000 -r f43994f44684 millis.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/millis.cpp	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,21 @@
+/* 
+ * @author: Natasha Sarkar, 2018
+ */
+
+#include "mbed.h"
+#include "millis.h"
+ 
+volatile unsigned long  _millis;
+ 
+void millis_begin(void) {
+    SysTick_Config(SystemCoreClock / 1000);
+}
+ 
+extern "C" void SysTick_Handler(void) {
+    _millis++;
+}
+ 
+unsigned long millis(void) {
+    return _millis;
+}
+
diff -r 000000000000 -r f43994f44684 millis.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/millis.h	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,22 @@
+/*
+ * @author: Natasha Sarkar, 2018
+ */
+
+#ifndef __MILLIS_H
+#define __MILLIS_H
+
+/**
+ * Starts the clock. Call this function
+ * at the beginning of main.
+ */
+void millis_begin(void);
+
+/**
+ * Returns the number of milliseconds
+ * that have passed since the call
+ * to millis_begin.
+ */
+unsigned long millis(void);
+ 
+#endif
+
diff -r 000000000000 -r f43994f44684 quaternion.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/quaternion.cpp	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,68 @@
+/*
+ * @author: Thomas Garcia, 2017
+ */
+
+#include "quaternion.h"
+#include <math.h>
+#include <string.h>
+
+float vector_normalize(struct vector *raw, struct vector *unit)
+{
+  float mag = sqrt(pow(raw->x, 2) + pow(raw->y, 2) + pow(raw->z, 2));
+  if(mag != 0) {
+      unit->x = raw->x / mag;
+      unit->y = raw->y / mag;
+      unit->z = raw->z / mag;
+  }
+  return mag;
+}
+
+void vector_add(struct vector *v1, struct vector *v2, struct vector *result)
+{
+  result->x = v1->x + v2->x;
+  result->y = v1->y + v2->y;
+  result->z = v1->z + v2->z;
+}
+
+void vector_multiply(struct vector *v, float c, struct vector *result)
+{
+  result->x = v->x * c;
+  result->y = v->y * c;
+  result->z = v->z * c;
+}
+
+void quaternion_create(struct vector *v, float angle, struct quaternion *result)
+{
+  result->r = cos(angle/2);
+  result->i = v->x * sin(angle/2);
+  result->j = v->y * sin(angle/2);
+  result->k = v->z * sin(angle/2);
+}
+
+void quaternion_rotate(struct vector *v, struct quaternion *q, struct vector *result)
+{
+  struct vector n;
+  memcpy(&n, v, sizeof(n));
+  result->x = n.x * (1 - 2*(pow(q->j, 2) + pow(q->k, 2))) + n.y * 2*(q->i * q->j - q->k * q->r) + n.z * 2*(q->i * q->k + q->j * q->r);
+  result->y = n.x * 2*(q->i * q->j + q->k * q->r) + n.y * (1 - 2*(pow(q->i, 2) + pow(q->k, 2))) + n.z * 2*(q->j * q->k - q->i * q->r);
+  result->z = n.x * 2*(q->i * q->k - q->j * q->r) + n.y * 2*(q->j * q->k + q->i * q->r) + n.z * (1 - 2*(pow(q->i, 2) + pow(q->j, 2)));
+}
+
+void quaternion_multiply(struct quaternion *q1, struct quaternion *q2, struct quaternion *result)
+{
+  result->r = q1->r * q2->r - q1->i * q2->i - q1->j * q2->j - q1->k * q2->k;
+  result->i = q1->r * q2->i + q1->i * q2->r + q1->j * q2->k - q1->k * q2->j;
+  result->j = q1->r * q2->j - q1->i * q2->k + q1->j * q2->r + q1->k * q2->i;
+  result->k = q1->r * q2->k + q1->i * q2->j - q1->j * q2->i + q1->k * q2->r;
+}
+
+float vector_roll(struct vector *v)
+{
+  return atan2(v->x, sqrt(pow(v->z, 2) + pow(v->y, 2)));
+}
+
+float vector_pitch(struct vector *v)
+{
+  return -atan2(v->y, v->z);
+}
+
diff -r 000000000000 -r f43994f44684 quaternion.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/quaternion.h	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,91 @@
+/*
+ * @author: Thomas Garcia, 2017
+ */
+
+#ifndef __QUATERNION_H
+#define __QUATERNION_H
+
+struct vector {
+  float x;
+  float y;
+  float z;
+};
+
+struct quaternion {
+  float r;
+  float i;
+  float j;
+  float k;
+};
+
+/**
+ * Normalizes a vector.
+ *
+ * raw: pointer to the vector to be normalized.
+ * unit: pointer to where unit vector dimensions should be stored.
+ *
+ * returns: length of original vector
+ */
+float vector_normalize(struct vector *raw, struct vector *unit);
+
+/**
+ * Adds two vectors together.
+ *
+ * v1: pointer to the first vector to be added.
+ * v2: pointer to the second vector to be added.
+ * result: pointer where the sum of v1 and v2 should be stored.
+ */
+void vector_add(struct vector *v1, struct vector *v2, struct vector *result);
+
+/**
+ * Multiples a vector by a constant.
+ *
+ * v: pointer to the vector to be multiplied.
+ * c: scalar constant to multiply vector by.
+ * result: pointer where the c * v should be stored.
+ */
+void vector_multiply(struct vector *v, float c, struct vector *result);
+
+/**
+ * Creates a quaternion representing a rotation.
+ *
+ * v: unit vector representing the axis of rotation.
+ * angle: angle of rotation.
+ * result: quaternion representing a rotation of degree angle around the unit vector of v.
+ */
+void quaternion_create(struct vector *v, float angle, struct quaternion *result);
+
+/**
+ * Rotates a vector based on a quaternion.
+ *
+ * v: vector to be rotated.
+ * q: quaternion representing the rotation to be performed.
+ * result: The rotated vector.
+ */
+void quaternion_rotate(struct vector *v, struct quaternion *q, struct vector *result);
+
+/**
+ * Multiplies two quaternions together.
+ *
+ * q1: The first quaternion to be multiplied.
+ * q2: The second quaternion to be multiplied.
+ * result: q1 * q2.
+ */
+void quaternion_multiply(struct quaternion *q1, struct quaternion *q2, struct quaternion *result);
+
+/**
+ * Returns the roll, given a vector.
+ *
+ * v: The vector.
+ */
+float vector_roll(struct vector *v);
+
+/**
+ * Returns the pitch, given a vector.
+ *
+ * v: The vector.
+ */
+float vector_pitch(struct vector *v);
+
+#endif
+
diff -r 000000000000 -r f43994f44684 sensor_fusion.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensor_fusion.cpp	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,71 @@
+/* 
+ * @author: Natasha Sarkar, 2018
+ */
+
+#include "mbed.h"
+#include "sensor_fusion.h"
+ 
+MPU6050::MPU6050(PinName sda, PinName scl): i2c_object(sda, scl) {
+    i2c_object.frequency(400000);
+}
+ 
+void MPU6050::start(void) {
+    /** TO DO 
+     * 
+     * CONFIGURE THE FOLLOWING REGISTERS ACCORDING TO THE DATASHEET:
+     *
+     * PWR_MGMT_1 register to take the IMU out of sleep mode
+     * ACCEL_CONFIG register to the smallest possible full-scale range (why might we want to do that?)
+     * GYRO_CONFIG register to the largest possible full-scale range to enable the detection of high-velocity rotations
+     * CONFIG register to the largest possible bandwidth.
+     */
+
+    /** YOUR CODE GOES BELOW */ 
+
+}
+ 
+bool MPU6050::read_raw(float *gx, float *gy, float *gz, float *ax, float *ay, float *az) {
+    /** TO DO
+     * 
+     * GET THE RAW READINGS FROM THE ACCELEROMETER/GYRSCOPE
+     *
+     * Store the readings in the floats pointed to by the given float pointers.
+     */
+
+    /** YOUR CODE GOES BELOW */ 
+
+}
+
+bool MPU6050::data_ready(void) {
+    /** TO DO
+     * 
+     * CHECK THE INT_STATUS REGISTER TO DETERMINE IF DATA IS READY
+     *
+     * Return true if it is ready, false otherwise.
+     */
+
+    /** YOUR CODE GOES BELOW */ 
+}
+
+bool MPU6050::write_reg(int addr, int reg, char buf) {
+    /** TO DO
+     * 
+     * IMPELEMENT THIS FUNCTION
+     *
+     * See the documentation in sensor_fusion.h for detail.
+     */
+
+    /** YOUR CODE GOES BELOW */ 
+}
+ 
+bool MPU6050::read_reg(char addr, char reg, char *buf, int length) {
+    /** TO DO
+     * 
+     * IMPLEMENT THIS FUNCTION
+     * 
+     * See the documentation in sensor_fusion.h for detail.
+     */
+
+    /** YOUR CODE GOES BELOW */ 
+}
+
diff -r 000000000000 -r f43994f44684 sensor_fusion.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensor_fusion.h	Thu Nov 08 20:48:47 2018 +0000
@@ -0,0 +1,93 @@
+/* 
+ * @author: Natasha Sarkar, 2018
+ */
+
+#ifndef __MPU6050_H
+#define __MPU6050_H
+ 
+#include "mbed.h"
+
+/** TO DO
+ * DEFINE THESE REGISTERS. 
+ * THE ADDRESS AND CONFIG REGISTERS HAVE BEEN DONE FOR YOU AS AN EXAMPLE.
+ *
+ * You will need to look at the register map.
+ */
+ 
+#define SDA                      PB_7   //the pin used for SDA                            
+#define SCL                      PB_6   //the pin used for SCL                    
+#define ADDRESS                  0xD1   //the slave address of the IMU
+#define INT_STATUS               0x3A   //the interrupt status register 
+#define PWR_MGMT_1               0x6B   //power management 1
+#define CONFIG                   0x1A   //the IMU config register
+#define GYRO_CONFIG              0x1B   //the gyroscope config register    
+#define ACCEL_CONFIG             0x1C   //the accelerometer config register        
+#define GYRO_X                   0x44   //the register that stores the first bit of the gyroscope x value          
+#define ACCEL_X                  0x3C   //the register that stores the first bit of the accelerometer x value
+
+class MPU6050 {
+
+public:
+
+    /** 
+     * Creates an MPU6050 object
+     * 
+     * sda: pin name of the sda pin
+     * scl: pin name of the scl pin
+     */
+    MPU6050(PinName sda, PinName scl);
+
+    /** 
+     * Called before using the MPU6050.
+     * 
+     * Sets up the I2C by configuring registers 
+     * as described in the spec (calls write_reg).
+     */
+    void start(void);
+
+    /** 
+     * Gets the readings from the gyroscope and accelerometer (calls read_reg).
+     * 
+     * Parameters: pointers to addresses where these readings should be stored.
+     *
+     * Returns true upon success, and false upon failure.
+     */
+    bool read_raw(float *gx, float *gy, float *gz, float *ax, float *ay, float *az);
+    
+    /**
+     * Reads the interrupt status register (calls read_reg).
+     *
+     * Returns true if data is ready, false otherwise.
+     */
+    bool data_ready(void);
+
+private:
+
+    I2C i2c_object; //instance of an i2c class
+
+    /** 
+     * Writes 1 byte of data to a specific address
+     * 
+     * addr: the i2c address of the slave device
+     * reg: the register number to write to
+     * buf: the data to write
+     *
+     * Returns true upon success, and false upon failure.
+     */
+    bool write_reg(int addr, int reg, char buf);
+
+    /** 
+     * Reads data from a specific address
+     * 
+     * addr: the i2c address of the slave device
+     * reg: the register numer to read from
+     * buf: an array to store the data read
+     * length: length of buf (how much to read)
+     *
+     * Returns true upon success, and false upon failure.
+     */
+    bool read_reg(char addr, char reg, char *buf, int length);
+};
+ 
+#endif
+