APP 1 S5.

Dependencies:   mbed

Committer:
vinbel93
Date:
Mon Jan 11 19:32:05 2016 +0000
Revision:
10:f58cbb203c59
Parent:
9:f35a5cde61a3
UART without mbed.h - final version

Who changed what in which revision?

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