Rotate the Cube Puck to invoke actions on your smartphone. Built on the Puck IOT platform.

Dependencies:   Puck MPU6050 mbed

The Cube Puck is an innovative bluetooth-enabled remote control device. It is a six-sided cube that can be rotated to any of its sides to invoke actions linked to that side. The cube puck is completely customizable and therefore also quite versatile.

A tutorial for the Cube Puck is available on GitHub.

Tutorials and in-depth documentation for the Puck platform is available at the project's GitHub page

main.cpp

Committer:
sigveseb
Date:
2014-07-25
Revision:
4:6a2b306b6b41
Parent:
3:6a7310ea51f7
Child:
6:4f2aaa06ff44
Child:
9:fc59099597cd

File content as of revision 4:6a2b306b6b41:

#include "MPU6050.h"
#include <math.h>

#define LOG_LEVEL_INFO
#include "Puck.h"

Puck* puck = &Puck::getPuck();

const UUID CUBE_SERVICE_UUID = UUID(stringToUUID("bftj cube       "));
const UUID DIRECTION_UUID = UUID(stringToUUID("bftj cube dirctn"));

enum Direction {
    UP,
    DOWN,
    LEFT,
    RIGHT,
    FRONT,
    BACK,
    UNDEFINED
};

const static int16_t ACCELERATION_EXITATION_THRESHOLD = 15000;

MPU6050 mpu;

int16_t ax, ay, az;
int16_t gx, gy, gz;

Direction direction = UNDEFINED;

void log_direction(Direction direction) {
    switch(direction) {
        case UP: LOG_INFO("Direction UP\n"); break;
        case DOWN: LOG_INFO("Direction DOWN\n"); break;
        case LEFT: LOG_INFO("Direction LEFT\n"); break;
        case RIGHT: LOG_INFO("Direction RIGHT\n"); break;
        case BACK: LOG_INFO("Direction BACK\n"); break;
        case FRONT: LOG_INFO("Direction FRONT\n"); break;
        default: LOG_INFO("Direction UNSET\n"); break;
    }
}

int16_t direction_if_exited(int16_t acceleration) {
    if (acceleration > ACCELERATION_EXITATION_THRESHOLD) {
        return 1;
    }
    if (acceleration < -ACCELERATION_EXITATION_THRESHOLD) {
        return -1;
    }
    return 0;
}

void updateCubeDirection(void) {
    mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    int16_t x = direction_if_exited(ax);
    int16_t y = direction_if_exited(ay);
    int16_t z = direction_if_exited(az);

    int16_t sum = abs(x) + abs(y) + abs(z);
    if (sum != 1) {
        return;
    }

    Direction new_direction = UNDEFINED;
    if (z == 1) {
        new_direction = UP;
    } else if (z == -1) {
        new_direction = DOWN;
    } else if (y == 1) {
        new_direction = LEFT;
    } else if (y == -1) {
        new_direction = RIGHT;
    } else if (x == 1) {
        new_direction = BACK;
    } else if (x == -1) {
        new_direction = FRONT;
    }

    if (direction == new_direction) {
        return;
    }

    direction = new_direction;

    log_direction(direction);
    uint8_t directionAsInteger = direction;
    int length = 1;
    puck->updateCharacteristicValue(DIRECTION_UUID, &directionAsInteger, length);
}


int main() {
    

    LOG_VERBOSE("MPU6050 test startup:\n");

    mpu.initialize();
    LOG_VERBOSE("TestConnection\n");

    if (mpu.testConnection()) {
        LOG_INFO("MPU initialized.\n");
    } else {
        LOG_ERROR("MPU not properly initialized!\n");
    }

    int characteristicValueLength = 1;
    puck->addCharacteristic(
        CUBE_SERVICE_UUID,
        DIRECTION_UUID,
        characteristicValueLength,
        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
    
    puck->init(0xC0BE);
    
    
    Ticker ticker;
    ticker.attach(updateCubeDirection, 1);
    LOG_INFO("Started listening to orientation changes.\n");

    while(puck->drive());
}