Cubic Hand project for EECS 249A course.

Dependencies:   MMA8451Q TSI cc3000_hostdriver_mbedsocket NVIC_set_all_priorities mbed Multi_WS2811

Revision:
56:f95ec9baa4cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LedCube.cpp	Mon Dec 15 23:55:15 2014 +0000
@@ -0,0 +1,298 @@
+/*
+ * Neopixel LED Cube library
+ * by Robert Bui and Jose Oyola
+ * UC Berkeley 2014
+ */
+
+#include "mbed.h"
+#include "WS2811.h"
+#include "Colors.h"
+#include "TSISensor.h"
+#include "MMA8451Q.h"
+#include "LedCube.h"
+
+
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+#define PANEL1             0
+#define PANEL2             1
+#define PANEL3             2
+#define nLEDs              200 //MAX_LEDS_PER_STRIP;
+#define MAX_SIZE           10
+#define nROWs              10  //number of rows per cube panel 
+#define nCOLs              10  //number of columns per cube panel
+#define DATA_OUT_PIN1      2   // PTD2
+#define DATA_OUT_PIN2      3   // PTD3 
+
+
+LedCube::LedCube():X(0),Y(1),Z(2),ledStrip1(nLEDs, DATA_OUT_PIN1),ledStrip2(nLEDs/2, DATA_OUT_PIN2)
+{
+}
+
+LedCube::~LedCube()
+{
+}
+
+/*Sets the initial size and position of the lighted cube*/ 
+void LedCube::Init(int x, int y, int z)
+{
+    size = 2;
+    prevSize = size;
+    pos[X] = prevPos[X] = x;
+    pos[Y] = prevPos[Y] = y;
+    pos[Z] = prevPos[Z] = z;
+    r = 255*0.1;
+    g = 255*0.1;
+    b = 255*0.1;
+
+    brightness = 0.5/8;
+    saturation = 1.0;
+    
+    ledStrip1.begin();
+    ledStrip2.begin();
+}
+
+/* Returns the index of the LED given the cartesian 
+ * coordinates of the LED on a given panel. The origin 
+ * is the led at the bottom left of panel 1 when using 
+ * a three panel cube.
+     ________
+    /       /|
+   /   3   / |
+  /_______/ 2|
+  |       |  | 
+  |   1   | /
+  |       |
+  --------      
+  
+  Z    Y
+  |   /
+  |  /
+  | /
+  |/
+   -------X   
+
+ */
+int LedCube::getLedIndex(int panel, int x, int y) {
+    if (panel == PANEL1) {
+        if (y % 2 == 0) {
+            return nCOLs*2 * y + x;
+        }
+        else {
+            return nCOLs*2 * y + nCOLs + ((nCOLs - 1) - x);
+        }
+    }
+
+    if (panel == PANEL2) {
+        if (y % 2 == 0) {
+            return nCOLs*2 * y + nCOLs + x;
+        }
+        else {
+            return nCOLs*2 * y + ((nCOLs - 1) - x);
+        }
+    }
+    
+    if (panel == PANEL3) {
+        if (y % 2 == 0) {
+            return nCOLs * y + x;
+        }
+        else {
+            return nCOLs * y + ((nCOLs - 1) - x);
+        }
+    }
+    
+    else return -1;
+}  
+
+/*
+ * Lights up (if on) or turns off (if !on) the LEDs on the LED cube 
+ * corresponding to the location of the square. All panels will show 
+ * the cube, with brightness depending on the distance from the 
+ * square to the panel.
+ */
+void LedCube::updateLEDs(bool on, int size, int x, int y, int z) {
+    //Panel 1
+    double bright;
+    bright = 1.0 / ((y + 1) * (y + 1));
+    for(int i = x; i < x + size; i++) {
+        for(int j = z; j < z + size; j++) {
+            int led = getLedIndex(PANEL1, i, j);
+            if(on) {
+                ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright);
+            } else {
+                ledStrip1.setPixelColor(led, 0, 0, 0);
+            }
+        }
+    }
+    
+    //Panel 2
+    bright = 1.0 / (((nCOLs-1) - x - (size-1) + 1) * ((nCOLs-1) - x - (size-1) + 1));
+    for(int i = y; i < y + size; i++) {
+        for(int j = z; j < z + size; j++) {
+            int led = getLedIndex(PANEL2, i, j);
+            if(on) {
+                ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright);
+            } else {
+                ledStrip1.setPixelColor(led, 0, 0, 0);
+            }
+        }
+    }
+    
+    //Panel 3
+    bright = 1.0 / (((nCOLs-1) - z - (size-1) + 1) * ((nCOLs-1) - z - (size-1) + 1));   
+    for(int i = x; i < x + size; i++) {
+        for(int j = y; j < y + size; j++) {
+            int led = getLedIndex(PANEL3, i, j);
+            if(on) {
+                ledStrip2.setPixelColor(led, r*bright, g*bright, b*bright);
+            } else {
+                ledStrip2.setPixelColor(led, 0, 0, 0);
+            }
+        }
+    }
+}
+
+void LedCube::updateLEDsOld(bool on, int size, int x, int y, int z) {
+    //Panel 1
+    if(y == 0) {
+        for(int i = x; i < x + size; i++) {
+            for(int j = z; j < z + size; j++) {
+                int led = getLedIndex(PANEL1, i, j);
+                if(on) {
+                    ledStrip1.setPixelColor(led, r, g, b);
+                } else {
+                    ledStrip1.setPixelColor(led, 0, 0, 0);
+                }
+            }
+        }
+    }
+    
+    //Panel 2
+    if(x + size - 1 == (nCOLs - 1)) {
+        for(int i = y; i < y + size; i++) {
+            for(int j = z; j < z + size; j++) {
+                int led = getLedIndex(PANEL2, i, j);
+                if(on) {
+                    ledStrip1.setPixelColor(led, r, g, b);
+                } else {
+                    ledStrip1.setPixelColor(led, 0, 0, 0);
+                }
+            }
+        }
+    }
+    
+    //Panel 3
+    if(z + size - 1 == (nCOLs - 1)) {
+        for(int i = x; i < x + size; i++) {
+            for(int j = y; j < y + size; j++) {
+                int led = getLedIndex(PANEL3, i, j);
+                if(on) {
+                    ledStrip2.setPixelColor(led, r, g, b);
+                } else {
+                    ledStrip2.setPixelColor(led, 0, 0, 0);
+                }
+            }
+        }
+    }
+}
+
+/*
+ * Updates the LED cube.
+ */
+void LedCube::cubeUpdate() {
+    updateLEDs(false, prevSize, prevPos[X], prevPos[Y], prevPos[Z]); //Turn off LEDs from previous state
+    updateLEDs(true, size, pos[X], pos[Y], pos[Z]); //Turn on new LEDs for new state
+    prevSize = size;
+    prevPos[X] = pos[X];
+    prevPos[Y] = pos[Y];
+    prevPos[Z] = pos[Z];
+    ledStrip1.show();
+    ledStrip2.show();
+    ledStrip1.startDMA();
+    ledStrip2.startDMA();
+}
+
+/*
+ * Moves the square inside the cube by deltaX in the x-axis,
+ * by deltaY in the y-axis, and deltaZ in the z-axis. Returns
+ * 1 if movement occured, and -1 if no movement occured.
+ */
+int LedCube::move(int deltaX, int deltaY, int deltaZ) {
+    int retVal = -1;
+    //Moving in X direction
+    if((pos[X] + size + deltaX - 1) < nCOLs && (pos[X] + deltaX) >= 0) {
+        pos[X] += deltaX;
+        if (deltaX != 0) retVal = 1;
+    }
+    
+    //Moving in Y direction
+    if((pos[Y] + size + deltaY - 1) < nCOLs && (pos[Y] + deltaY) >= 0) {
+        pos[Y] += deltaY;
+        if (deltaY != 0) retVal = 1;
+    }
+    
+    //Moving in Z direction
+    if((pos[Z] + size + deltaZ - 1) < nCOLs && (pos[Z] + deltaZ) >= 0) {
+        pos[Z] += deltaZ;
+        if (deltaZ != 0) retVal = 1;
+    }
+    return retVal;
+}
+
+/*
+ * Changes the color of the square in the LED cube to the given hue.
+ */
+void LedCube::changeColor(float hue){
+    Colors::HSBtoRGB(hue, saturation, brightness, &r, &g, &b);
+}
+
+/*
+ * Changes the size of the square in the LED cube to the given size.
+ * The minimum size is 1, corresponding to a square of a single LED.
+ * A size of 2 corresponds to a 2x2 LED square, 3 corresponds to 3x3 
+ * and so forth. If square is on an edge, it moves accordingly in 
+ * order to be able to increase size.
+ */
+void LedCube::changeSize(int newSize) {
+    if(newSize > 0 && newSize <= MAX_SIZE) {
+        if ((pos[X] + newSize) <= nCOLs && (pos[Y] + newSize) <= nCOLs && (pos[Z] + newSize) <= nCOLs) {
+            size = newSize;
+            return;
+        }
+        else {
+            int delta_x = 0;
+            int delta_y = 0;
+            int delta_z = 0;
+            if ((pos[X] + newSize) > nCOLs) {
+                delta_x = nCOLs - (pos[X] + newSize);
+            }
+            if ((pos[Y] + newSize) > nCOLs) {
+                delta_y = nCOLs - (pos[Y] + newSize);
+            }
+            if ((pos[Z] + newSize) > nCOLs) {
+                delta_z = nCOLs - (pos[Z] + newSize);
+            }
+            move(delta_x, delta_y, delta_z);
+            size = newSize;
+            return;
+        }
+    }   
+}
+
+/*
+ * Updates the LED cube given the size, hue and offsets in the X, Y and Z axes.
+ */
+void LedCube::UpdateCube(int ledSize, int deltaX, int deltaY, int deltaZ, float hue) {
+     changeSize(ledSize);
+     move(deltaX, deltaY, deltaZ); 
+     changeColor(hue); 
+     cubeUpdate();
+}
+
+/*
+ * Updates the LED cube given parameters in a CubeUpdateParameters struct.
+ */
+void LedCube::UpdateCube2(CubeUpdateParameters cubeParams){
+    UpdateCube(cubeParams.size, cubeParams.deltaX, cubeParams.deltaY, cubeParams.deltaZ, cubeParams.hue); 
+}
+