Vincent Belanger
/
APP
APP 1 S5.
APP.cpp
- Committer:
- vinbel93
- Date:
- 2016-01-12
- Revision:
- 12:4961ec71bc8f
- Parent:
- 11:eafa5c07f060
- Child:
- 13:08ef55cd14c6
File content as of revision 12:4961ec71bc8f:
// APP.cpp // Vincent Belanger - belv1802 // Jeremy Pare - parj2713 #include <math.h> #include <stdint.h> #include "mbed.h" #include "APP.h" static I2C i2c(p28, p27); static Serial uart(p9, p10); void setup() { // Setup UART and I2C. uart.format(8, Serial::None, 1); uart.baud(9600); i2c.frequency(100000); // Clear display uart.putc(0x76); // Decimal point for display uart.putc(0x77); uart.putc(0x02); // Maximum brightness uart.putc(0x7A); uart.putc(0xFF); } void activateAccelerometer() { uint8_t data[2] = {CTRL_REG, 0x01}; i2c.write(ACC_ADDRESS, (char*) data, 2); } uint8_t readStatus() { uint8_t result[1]; uint8_t reg[1] = {STATUS_REG}; i2c.write(ACC_ADDRESS, (char*) reg, 1, true); i2c.read(ACC_ADDRESS, (char*) result, 1); return result[0]; } int16_t convertToAcceleration(uint8_t hi, uint8_t lo) { int16_t value = (lo >> 2) | (hi << 6); if (value > UINT14_MAX/2) { value -= UINT14_MAX; } return value; } int16_t readAndComputeAngle() { uint8_t result[6]; uint8_t reg[1] = {ACC_X_REG}; i2c.write(ACC_ADDRESS, (char*) reg, 1, true); i2c.read(ACC_ADDRESS, (char*) result, 6); int16_t accX = convertToAcceleration(result[0], result[1]); int16_t accY = convertToAcceleration(result[2], result[3]); int16_t accZ = convertToAcceleration(result[4], result[5]); float angle = acos((float) accZ / sqrt((float) accX*accX + accY*accY + accZ*accZ)) * 180.0 / PI; // To use integer operations instead of floating-point arithmetic, the angle is multiplied by 100. // This allows for two decimals of precision on the display. int16_t angleHundreds = angle * 100; if (angleHundreds > 9000) { angleHundreds = 18000 - angleHundreds; } return angleHundreds; } void updateDisplay(int16_t angle) { uint8_t digits[4]; sprintf((char*) digits, "%d", angle); if (angle < 100) { uart.putc(0); uart.putc(0); uart.putc(digits[0]); uart.putc(digits[1]); } else if (angle < 1000) { uart.putc(0); uart.putc(digits[0]); uart.putc(digits[1]); uart.putc(digits[2]); } else { uart.putc(digits[0]); uart.putc(digits[1]); uart.putc(digits[2]); uart.putc(digits[3]); } } int32_t main() { setup(); activateAccelerometer(); while (true) { // Read bit 3 from the status register int8_t status = (readStatus() >> 3) & 0x01; if (status == 1) { // Get accelerations, compute angle uint16_t angle = readAndComputeAngle(); // Update 7 segment display updateDisplay(angle); } wait(0.4); } }