APP 1 S5.

Dependencies:   mbed

Committer:
vinbel93
Date:
Mon Jan 11 19:34:58 2016 +0000
Revision:
11:eafa5c07f060
Parent:
7:b00843da0530
Child:
12:4961ec71bc8f
UART with mbed.h - final version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vinbel93 11:eafa5c07f060 1 // APP.cpp
vinbel93 11:eafa5c07f060 2 // Vincent Belanger - belv1802
vinbel93 11:eafa5c07f060 3 // Jeremy Pare - parj2713
vinbel93 11:eafa5c07f060 4
vinbel93 7:b00843da0530 5 #include <math.h>
vinbel93 7:b00843da0530 6 #include <stdint.h>
vinbel93 7:b00843da0530 7
vinbel93 7:b00843da0530 8 #include "mbed.h"
vinbel93 7:b00843da0530 9 #include "APP.h"
vinbel93 7:b00843da0530 10
vinbel93 7:b00843da0530 11
vinbel93 7:b00843da0530 12 static I2C i2c(p28, p27);
vinbel93 7:b00843da0530 13 static Serial uart(p9, p10);
vinbel93 7:b00843da0530 14
vinbel93 7:b00843da0530 15 void setup()
vinbel93 7:b00843da0530 16 {
vinbel93 7:b00843da0530 17 // Setup UART and I2C.
vinbel93 7:b00843da0530 18 uart.format(8, Serial::None, 1);
vinbel93 7:b00843da0530 19 uart.baud(9600);
vinbel93 7:b00843da0530 20 i2c.frequency(100000);
vinbel93 7:b00843da0530 21
vinbel93 7:b00843da0530 22 // Clear display
vinbel93 7:b00843da0530 23 uart.putc(0x76);
vinbel93 7:b00843da0530 24
vinbel93 7:b00843da0530 25 // Decimal point for display
vinbel93 7:b00843da0530 26 uart.putc(0x77);
vinbel93 7:b00843da0530 27 uart.putc(0x02);
vinbel93 7:b00843da0530 28
vinbel93 7:b00843da0530 29 // Maximum brightness
vinbel93 7:b00843da0530 30 uart.putc(0x7A);
vinbel93 7:b00843da0530 31 uart.putc(0xFF);
vinbel93 7:b00843da0530 32 }
vinbel93 7:b00843da0530 33
vinbel93 7:b00843da0530 34 void activateAccelerometer()
vinbel93 7:b00843da0530 35 {
vinbel93 7:b00843da0530 36 uint8_t data[2] = {CTRL_REG, 0x01};
vinbel93 7:b00843da0530 37 i2c.write(ACC_ADDRESS, (char*) data, 2);
vinbel93 7:b00843da0530 38 }
vinbel93 7:b00843da0530 39
vinbel93 7:b00843da0530 40 uint8_t readStatus()
vinbel93 7:b00843da0530 41 {
vinbel93 7:b00843da0530 42 uint8_t result[1];
vinbel93 7:b00843da0530 43 uint8_t reg[1] = {STATUS_REG};
vinbel93 7:b00843da0530 44 i2c.write(ACC_ADDRESS, (char*) reg, 1, true);
vinbel93 7:b00843da0530 45 i2c.read(ACC_ADDRESS, (char*) result, 1);
vinbel93 7:b00843da0530 46
vinbel93 7:b00843da0530 47 return result[0];
vinbel93 7:b00843da0530 48 }
vinbel93 7:b00843da0530 49
vinbel93 7:b00843da0530 50 int16_t convertToAcceleration(uint8_t hi, uint8_t lo)
vinbel93 7:b00843da0530 51 {
vinbel93 7:b00843da0530 52 int16_t value = (lo >> 2) | (hi << 6);
vinbel93 7:b00843da0530 53 if (value > UINT14_MAX/2)
vinbel93 7:b00843da0530 54 {
vinbel93 7:b00843da0530 55 value -= UINT14_MAX;
vinbel93 7:b00843da0530 56 }
vinbel93 7:b00843da0530 57
vinbel93 7:b00843da0530 58 return value;
vinbel93 7:b00843da0530 59 }
vinbel93 7:b00843da0530 60
vinbel93 7:b00843da0530 61 uint32_t squareRoot(uint32_t input)
vinbel93 7:b00843da0530 62 {
vinbel93 7:b00843da0530 63 uint32_t op = input;
vinbel93 7:b00843da0530 64 uint32_t res = 0;
vinbel93 7:b00843da0530 65 uint32_t one = 1UL << 30;
vinbel93 7:b00843da0530 66
vinbel93 7:b00843da0530 67 while (one > op)
vinbel93 7:b00843da0530 68 {
vinbel93 7:b00843da0530 69 one >>= 2;
vinbel93 7:b00843da0530 70 }
vinbel93 7:b00843da0530 71
vinbel93 7:b00843da0530 72 while (one != 0)
vinbel93 7:b00843da0530 73 {
vinbel93 7:b00843da0530 74 if (op >= res + one)
vinbel93 7:b00843da0530 75 {
vinbel93 7:b00843da0530 76 op = op - (res + one);
vinbel93 7:b00843da0530 77 res = res + 2 * one;
vinbel93 7:b00843da0530 78 }
vinbel93 7:b00843da0530 79
vinbel93 7:b00843da0530 80 res >>= 1;
vinbel93 7:b00843da0530 81 one >>= 2;
vinbel93 7:b00843da0530 82 }
vinbel93 7:b00843da0530 83
vinbel93 7:b00843da0530 84 return res;
vinbel93 7:b00843da0530 85 }
vinbel93 7:b00843da0530 86
vinbel93 7:b00843da0530 87 int16_t readAndComputeAngle()
vinbel93 7:b00843da0530 88 {
vinbel93 7:b00843da0530 89 uint8_t result[6];
vinbel93 7:b00843da0530 90 uint8_t reg[1] = {ACC_X_REG};
vinbel93 7:b00843da0530 91 i2c.write(ACC_ADDRESS, (char*) reg, 1, true);
vinbel93 7:b00843da0530 92 i2c.read(ACC_ADDRESS, (char*) result, 6);
vinbel93 7:b00843da0530 93 int16_t accX = convertToAcceleration(result[0], result[1]);
vinbel93 7:b00843da0530 94 int16_t accY = convertToAcceleration(result[2], result[3]);
vinbel93 7:b00843da0530 95 int16_t accZ = convertToAcceleration(result[4], result[5]);
vinbel93 7:b00843da0530 96
vinbel93 7:b00843da0530 97 uint32_t modulus = squareRoot(accX*accX + accY*accY + accZ*accZ);
vinbel93 7:b00843da0530 98 float angle = acos((float) accZ / modulus) * 180.0 / PI;
vinbel93 7:b00843da0530 99
vinbel93 7:b00843da0530 100 // To use integer operations instead of floating-point arithmetic, the angle is multiplied by 100.
vinbel93 7:b00843da0530 101 // This allows for two decimals of precision on the display.
vinbel93 7:b00843da0530 102 int16_t angleHundreds = angle * 100;
vinbel93 7:b00843da0530 103 if (angleHundreds > 9000)
vinbel93 7:b00843da0530 104 {
vinbel93 7:b00843da0530 105 angleHundreds = 18000 - angleHundreds;
vinbel93 7:b00843da0530 106 }
vinbel93 7:b00843da0530 107
vinbel93 7:b00843da0530 108 return angleHundreds;
vinbel93 7:b00843da0530 109 }
vinbel93 7:b00843da0530 110
vinbel93 7:b00843da0530 111 void updateDisplay(int16_t angle)
vinbel93 7:b00843da0530 112 {
vinbel93 7:b00843da0530 113 uint8_t digits[4];
vinbel93 7:b00843da0530 114 sprintf((char*) digits, "%d", angle);
vinbel93 7:b00843da0530 115
vinbel93 7:b00843da0530 116 if (angle < 1000)
vinbel93 7:b00843da0530 117 {
vinbel93 7:b00843da0530 118 uart.putc(0);
vinbel93 7:b00843da0530 119 uart.putc(digits[0]);
vinbel93 7:b00843da0530 120 uart.putc(digits[1]);
vinbel93 7:b00843da0530 121 uart.putc(digits[2]);
vinbel93 7:b00843da0530 122 }
vinbel93 7:b00843da0530 123 else
vinbel93 7:b00843da0530 124 {
vinbel93 7:b00843da0530 125 uart.putc(digits[0]);
vinbel93 7:b00843da0530 126 uart.putc(digits[1]);
vinbel93 7:b00843da0530 127 uart.putc(digits[2]);
vinbel93 7:b00843da0530 128 uart.putc(digits[3]);
vinbel93 7:b00843da0530 129 }
vinbel93 7:b00843da0530 130 }
vinbel93 7:b00843da0530 131
vinbel93 7:b00843da0530 132 int32_t main()
vinbel93 7:b00843da0530 133 {
vinbel93 7:b00843da0530 134 setup();
vinbel93 7:b00843da0530 135 activateAccelerometer();
vinbel93 7:b00843da0530 136
vinbel93 7:b00843da0530 137 while (true)
vinbel93 7:b00843da0530 138 {
vinbel93 7:b00843da0530 139 // Read bit 3 from the status register
vinbel93 7:b00843da0530 140 int8_t status = (readStatus() >> 3) & 0x01;
vinbel93 7:b00843da0530 141
vinbel93 7:b00843da0530 142 if (status == 1)
vinbel93 7:b00843da0530 143 {
vinbel93 7:b00843da0530 144 // Get accelerations, compute angle
vinbel93 7:b00843da0530 145 uint16_t angle = readAndComputeAngle();
vinbel93 7:b00843da0530 146
vinbel93 7:b00843da0530 147 // Update 7 segment display
vinbel93 7:b00843da0530 148 updateDisplay(angle);
vinbel93 7:b00843da0530 149 }
vinbel93 7:b00843da0530 150
vinbel93 7:b00843da0530 151 wait(0.4);
vinbel93 7:b00843da0530 152 }
vinbel93 7:b00843da0530 153 }