Cubic Hand project for EECS 249A course.

Dependencies:   MMA8451Q TSI cc3000_hostdriver_mbedsocket NVIC_set_all_priorities mbed Multi_WS2811

Committer:
joseoyola
Date:
Mon Dec 15 23:55:15 2014 +0000
Revision:
56:f95ec9baa4cb
Changes to LedCube.h and LedCube.cpp; ; Renamed ledCube.h and ledCube.cpp to LedCube.h and LedCube.cpp, added documentation to both, added logic to move cube to allow changing size regardless of current position.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joseoyola 56:f95ec9baa4cb 1 /*
joseoyola 56:f95ec9baa4cb 2 * Neopixel LED Cube library
joseoyola 56:f95ec9baa4cb 3 * by Robert Bui and Jose Oyola
joseoyola 56:f95ec9baa4cb 4 * UC Berkeley 2014
joseoyola 56:f95ec9baa4cb 5 */
joseoyola 56:f95ec9baa4cb 6
joseoyola 56:f95ec9baa4cb 7 #include "mbed.h"
joseoyola 56:f95ec9baa4cb 8 #include "WS2811.h"
joseoyola 56:f95ec9baa4cb 9 #include "Colors.h"
joseoyola 56:f95ec9baa4cb 10 #include "TSISensor.h"
joseoyola 56:f95ec9baa4cb 11 #include "MMA8451Q.h"
joseoyola 56:f95ec9baa4cb 12 #include "LedCube.h"
joseoyola 56:f95ec9baa4cb 13
joseoyola 56:f95ec9baa4cb 14
joseoyola 56:f95ec9baa4cb 15 #define MMA8451_I2C_ADDRESS (0x1d<<1)
joseoyola 56:f95ec9baa4cb 16
joseoyola 56:f95ec9baa4cb 17 #define PANEL1 0
joseoyola 56:f95ec9baa4cb 18 #define PANEL2 1
joseoyola 56:f95ec9baa4cb 19 #define PANEL3 2
joseoyola 56:f95ec9baa4cb 20 #define nLEDs 200 //MAX_LEDS_PER_STRIP;
joseoyola 56:f95ec9baa4cb 21 #define MAX_SIZE 10
joseoyola 56:f95ec9baa4cb 22 #define nROWs 10 //number of rows per cube panel
joseoyola 56:f95ec9baa4cb 23 #define nCOLs 10 //number of columns per cube panel
joseoyola 56:f95ec9baa4cb 24 #define DATA_OUT_PIN1 2 // PTD2
joseoyola 56:f95ec9baa4cb 25 #define DATA_OUT_PIN2 3 // PTD3
joseoyola 56:f95ec9baa4cb 26
joseoyola 56:f95ec9baa4cb 27
joseoyola 56:f95ec9baa4cb 28 LedCube::LedCube():X(0),Y(1),Z(2),ledStrip1(nLEDs, DATA_OUT_PIN1),ledStrip2(nLEDs/2, DATA_OUT_PIN2)
joseoyola 56:f95ec9baa4cb 29 {
joseoyola 56:f95ec9baa4cb 30 }
joseoyola 56:f95ec9baa4cb 31
joseoyola 56:f95ec9baa4cb 32 LedCube::~LedCube()
joseoyola 56:f95ec9baa4cb 33 {
joseoyola 56:f95ec9baa4cb 34 }
joseoyola 56:f95ec9baa4cb 35
joseoyola 56:f95ec9baa4cb 36 /*Sets the initial size and position of the lighted cube*/
joseoyola 56:f95ec9baa4cb 37 void LedCube::Init(int x, int y, int z)
joseoyola 56:f95ec9baa4cb 38 {
joseoyola 56:f95ec9baa4cb 39 size = 2;
joseoyola 56:f95ec9baa4cb 40 prevSize = size;
joseoyola 56:f95ec9baa4cb 41 pos[X] = prevPos[X] = x;
joseoyola 56:f95ec9baa4cb 42 pos[Y] = prevPos[Y] = y;
joseoyola 56:f95ec9baa4cb 43 pos[Z] = prevPos[Z] = z;
joseoyola 56:f95ec9baa4cb 44 r = 255*0.1;
joseoyola 56:f95ec9baa4cb 45 g = 255*0.1;
joseoyola 56:f95ec9baa4cb 46 b = 255*0.1;
joseoyola 56:f95ec9baa4cb 47
joseoyola 56:f95ec9baa4cb 48 brightness = 0.5/8;
joseoyola 56:f95ec9baa4cb 49 saturation = 1.0;
joseoyola 56:f95ec9baa4cb 50
joseoyola 56:f95ec9baa4cb 51 ledStrip1.begin();
joseoyola 56:f95ec9baa4cb 52 ledStrip2.begin();
joseoyola 56:f95ec9baa4cb 53 }
joseoyola 56:f95ec9baa4cb 54
joseoyola 56:f95ec9baa4cb 55 /* Returns the index of the LED given the cartesian
joseoyola 56:f95ec9baa4cb 56 * coordinates of the LED on a given panel. The origin
joseoyola 56:f95ec9baa4cb 57 * is the led at the bottom left of panel 1 when using
joseoyola 56:f95ec9baa4cb 58 * a three panel cube.
joseoyola 56:f95ec9baa4cb 59 ________
joseoyola 56:f95ec9baa4cb 60 / /|
joseoyola 56:f95ec9baa4cb 61 / 3 / |
joseoyola 56:f95ec9baa4cb 62 /_______/ 2|
joseoyola 56:f95ec9baa4cb 63 | | |
joseoyola 56:f95ec9baa4cb 64 | 1 | /
joseoyola 56:f95ec9baa4cb 65 | |
joseoyola 56:f95ec9baa4cb 66 --------
joseoyola 56:f95ec9baa4cb 67
joseoyola 56:f95ec9baa4cb 68 Z Y
joseoyola 56:f95ec9baa4cb 69 | /
joseoyola 56:f95ec9baa4cb 70 | /
joseoyola 56:f95ec9baa4cb 71 | /
joseoyola 56:f95ec9baa4cb 72 |/
joseoyola 56:f95ec9baa4cb 73 -------X
joseoyola 56:f95ec9baa4cb 74
joseoyola 56:f95ec9baa4cb 75 */
joseoyola 56:f95ec9baa4cb 76 int LedCube::getLedIndex(int panel, int x, int y) {
joseoyola 56:f95ec9baa4cb 77 if (panel == PANEL1) {
joseoyola 56:f95ec9baa4cb 78 if (y % 2 == 0) {
joseoyola 56:f95ec9baa4cb 79 return nCOLs*2 * y + x;
joseoyola 56:f95ec9baa4cb 80 }
joseoyola 56:f95ec9baa4cb 81 else {
joseoyola 56:f95ec9baa4cb 82 return nCOLs*2 * y + nCOLs + ((nCOLs - 1) - x);
joseoyola 56:f95ec9baa4cb 83 }
joseoyola 56:f95ec9baa4cb 84 }
joseoyola 56:f95ec9baa4cb 85
joseoyola 56:f95ec9baa4cb 86 if (panel == PANEL2) {
joseoyola 56:f95ec9baa4cb 87 if (y % 2 == 0) {
joseoyola 56:f95ec9baa4cb 88 return nCOLs*2 * y + nCOLs + x;
joseoyola 56:f95ec9baa4cb 89 }
joseoyola 56:f95ec9baa4cb 90 else {
joseoyola 56:f95ec9baa4cb 91 return nCOLs*2 * y + ((nCOLs - 1) - x);
joseoyola 56:f95ec9baa4cb 92 }
joseoyola 56:f95ec9baa4cb 93 }
joseoyola 56:f95ec9baa4cb 94
joseoyola 56:f95ec9baa4cb 95 if (panel == PANEL3) {
joseoyola 56:f95ec9baa4cb 96 if (y % 2 == 0) {
joseoyola 56:f95ec9baa4cb 97 return nCOLs * y + x;
joseoyola 56:f95ec9baa4cb 98 }
joseoyola 56:f95ec9baa4cb 99 else {
joseoyola 56:f95ec9baa4cb 100 return nCOLs * y + ((nCOLs - 1) - x);
joseoyola 56:f95ec9baa4cb 101 }
joseoyola 56:f95ec9baa4cb 102 }
joseoyola 56:f95ec9baa4cb 103
joseoyola 56:f95ec9baa4cb 104 else return -1;
joseoyola 56:f95ec9baa4cb 105 }
joseoyola 56:f95ec9baa4cb 106
joseoyola 56:f95ec9baa4cb 107 /*
joseoyola 56:f95ec9baa4cb 108 * Lights up (if on) or turns off (if !on) the LEDs on the LED cube
joseoyola 56:f95ec9baa4cb 109 * corresponding to the location of the square. All panels will show
joseoyola 56:f95ec9baa4cb 110 * the cube, with brightness depending on the distance from the
joseoyola 56:f95ec9baa4cb 111 * square to the panel.
joseoyola 56:f95ec9baa4cb 112 */
joseoyola 56:f95ec9baa4cb 113 void LedCube::updateLEDs(bool on, int size, int x, int y, int z) {
joseoyola 56:f95ec9baa4cb 114 //Panel 1
joseoyola 56:f95ec9baa4cb 115 double bright;
joseoyola 56:f95ec9baa4cb 116 bright = 1.0 / ((y + 1) * (y + 1));
joseoyola 56:f95ec9baa4cb 117 for(int i = x; i < x + size; i++) {
joseoyola 56:f95ec9baa4cb 118 for(int j = z; j < z + size; j++) {
joseoyola 56:f95ec9baa4cb 119 int led = getLedIndex(PANEL1, i, j);
joseoyola 56:f95ec9baa4cb 120 if(on) {
joseoyola 56:f95ec9baa4cb 121 ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright);
joseoyola 56:f95ec9baa4cb 122 } else {
joseoyola 56:f95ec9baa4cb 123 ledStrip1.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 124 }
joseoyola 56:f95ec9baa4cb 125 }
joseoyola 56:f95ec9baa4cb 126 }
joseoyola 56:f95ec9baa4cb 127
joseoyola 56:f95ec9baa4cb 128 //Panel 2
joseoyola 56:f95ec9baa4cb 129 bright = 1.0 / (((nCOLs-1) - x - (size-1) + 1) * ((nCOLs-1) - x - (size-1) + 1));
joseoyola 56:f95ec9baa4cb 130 for(int i = y; i < y + size; i++) {
joseoyola 56:f95ec9baa4cb 131 for(int j = z; j < z + size; j++) {
joseoyola 56:f95ec9baa4cb 132 int led = getLedIndex(PANEL2, i, j);
joseoyola 56:f95ec9baa4cb 133 if(on) {
joseoyola 56:f95ec9baa4cb 134 ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright);
joseoyola 56:f95ec9baa4cb 135 } else {
joseoyola 56:f95ec9baa4cb 136 ledStrip1.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 137 }
joseoyola 56:f95ec9baa4cb 138 }
joseoyola 56:f95ec9baa4cb 139 }
joseoyola 56:f95ec9baa4cb 140
joseoyola 56:f95ec9baa4cb 141 //Panel 3
joseoyola 56:f95ec9baa4cb 142 bright = 1.0 / (((nCOLs-1) - z - (size-1) + 1) * ((nCOLs-1) - z - (size-1) + 1));
joseoyola 56:f95ec9baa4cb 143 for(int i = x; i < x + size; i++) {
joseoyola 56:f95ec9baa4cb 144 for(int j = y; j < y + size; j++) {
joseoyola 56:f95ec9baa4cb 145 int led = getLedIndex(PANEL3, i, j);
joseoyola 56:f95ec9baa4cb 146 if(on) {
joseoyola 56:f95ec9baa4cb 147 ledStrip2.setPixelColor(led, r*bright, g*bright, b*bright);
joseoyola 56:f95ec9baa4cb 148 } else {
joseoyola 56:f95ec9baa4cb 149 ledStrip2.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 150 }
joseoyola 56:f95ec9baa4cb 151 }
joseoyola 56:f95ec9baa4cb 152 }
joseoyola 56:f95ec9baa4cb 153 }
joseoyola 56:f95ec9baa4cb 154
joseoyola 56:f95ec9baa4cb 155 void LedCube::updateLEDsOld(bool on, int size, int x, int y, int z) {
joseoyola 56:f95ec9baa4cb 156 //Panel 1
joseoyola 56:f95ec9baa4cb 157 if(y == 0) {
joseoyola 56:f95ec9baa4cb 158 for(int i = x; i < x + size; i++) {
joseoyola 56:f95ec9baa4cb 159 for(int j = z; j < z + size; j++) {
joseoyola 56:f95ec9baa4cb 160 int led = getLedIndex(PANEL1, i, j);
joseoyola 56:f95ec9baa4cb 161 if(on) {
joseoyola 56:f95ec9baa4cb 162 ledStrip1.setPixelColor(led, r, g, b);
joseoyola 56:f95ec9baa4cb 163 } else {
joseoyola 56:f95ec9baa4cb 164 ledStrip1.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 165 }
joseoyola 56:f95ec9baa4cb 166 }
joseoyola 56:f95ec9baa4cb 167 }
joseoyola 56:f95ec9baa4cb 168 }
joseoyola 56:f95ec9baa4cb 169
joseoyola 56:f95ec9baa4cb 170 //Panel 2
joseoyola 56:f95ec9baa4cb 171 if(x + size - 1 == (nCOLs - 1)) {
joseoyola 56:f95ec9baa4cb 172 for(int i = y; i < y + size; i++) {
joseoyola 56:f95ec9baa4cb 173 for(int j = z; j < z + size; j++) {
joseoyola 56:f95ec9baa4cb 174 int led = getLedIndex(PANEL2, i, j);
joseoyola 56:f95ec9baa4cb 175 if(on) {
joseoyola 56:f95ec9baa4cb 176 ledStrip1.setPixelColor(led, r, g, b);
joseoyola 56:f95ec9baa4cb 177 } else {
joseoyola 56:f95ec9baa4cb 178 ledStrip1.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 179 }
joseoyola 56:f95ec9baa4cb 180 }
joseoyola 56:f95ec9baa4cb 181 }
joseoyola 56:f95ec9baa4cb 182 }
joseoyola 56:f95ec9baa4cb 183
joseoyola 56:f95ec9baa4cb 184 //Panel 3
joseoyola 56:f95ec9baa4cb 185 if(z + size - 1 == (nCOLs - 1)) {
joseoyola 56:f95ec9baa4cb 186 for(int i = x; i < x + size; i++) {
joseoyola 56:f95ec9baa4cb 187 for(int j = y; j < y + size; j++) {
joseoyola 56:f95ec9baa4cb 188 int led = getLedIndex(PANEL3, i, j);
joseoyola 56:f95ec9baa4cb 189 if(on) {
joseoyola 56:f95ec9baa4cb 190 ledStrip2.setPixelColor(led, r, g, b);
joseoyola 56:f95ec9baa4cb 191 } else {
joseoyola 56:f95ec9baa4cb 192 ledStrip2.setPixelColor(led, 0, 0, 0);
joseoyola 56:f95ec9baa4cb 193 }
joseoyola 56:f95ec9baa4cb 194 }
joseoyola 56:f95ec9baa4cb 195 }
joseoyola 56:f95ec9baa4cb 196 }
joseoyola 56:f95ec9baa4cb 197 }
joseoyola 56:f95ec9baa4cb 198
joseoyola 56:f95ec9baa4cb 199 /*
joseoyola 56:f95ec9baa4cb 200 * Updates the LED cube.
joseoyola 56:f95ec9baa4cb 201 */
joseoyola 56:f95ec9baa4cb 202 void LedCube::cubeUpdate() {
joseoyola 56:f95ec9baa4cb 203 updateLEDs(false, prevSize, prevPos[X], prevPos[Y], prevPos[Z]); //Turn off LEDs from previous state
joseoyola 56:f95ec9baa4cb 204 updateLEDs(true, size, pos[X], pos[Y], pos[Z]); //Turn on new LEDs for new state
joseoyola 56:f95ec9baa4cb 205 prevSize = size;
joseoyola 56:f95ec9baa4cb 206 prevPos[X] = pos[X];
joseoyola 56:f95ec9baa4cb 207 prevPos[Y] = pos[Y];
joseoyola 56:f95ec9baa4cb 208 prevPos[Z] = pos[Z];
joseoyola 56:f95ec9baa4cb 209 ledStrip1.show();
joseoyola 56:f95ec9baa4cb 210 ledStrip2.show();
joseoyola 56:f95ec9baa4cb 211 ledStrip1.startDMA();
joseoyola 56:f95ec9baa4cb 212 ledStrip2.startDMA();
joseoyola 56:f95ec9baa4cb 213 }
joseoyola 56:f95ec9baa4cb 214
joseoyola 56:f95ec9baa4cb 215 /*
joseoyola 56:f95ec9baa4cb 216 * Moves the square inside the cube by deltaX in the x-axis,
joseoyola 56:f95ec9baa4cb 217 * by deltaY in the y-axis, and deltaZ in the z-axis. Returns
joseoyola 56:f95ec9baa4cb 218 * 1 if movement occured, and -1 if no movement occured.
joseoyola 56:f95ec9baa4cb 219 */
joseoyola 56:f95ec9baa4cb 220 int LedCube::move(int deltaX, int deltaY, int deltaZ) {
joseoyola 56:f95ec9baa4cb 221 int retVal = -1;
joseoyola 56:f95ec9baa4cb 222 //Moving in X direction
joseoyola 56:f95ec9baa4cb 223 if((pos[X] + size + deltaX - 1) < nCOLs && (pos[X] + deltaX) >= 0) {
joseoyola 56:f95ec9baa4cb 224 pos[X] += deltaX;
joseoyola 56:f95ec9baa4cb 225 if (deltaX != 0) retVal = 1;
joseoyola 56:f95ec9baa4cb 226 }
joseoyola 56:f95ec9baa4cb 227
joseoyola 56:f95ec9baa4cb 228 //Moving in Y direction
joseoyola 56:f95ec9baa4cb 229 if((pos[Y] + size + deltaY - 1) < nCOLs && (pos[Y] + deltaY) >= 0) {
joseoyola 56:f95ec9baa4cb 230 pos[Y] += deltaY;
joseoyola 56:f95ec9baa4cb 231 if (deltaY != 0) retVal = 1;
joseoyola 56:f95ec9baa4cb 232 }
joseoyola 56:f95ec9baa4cb 233
joseoyola 56:f95ec9baa4cb 234 //Moving in Z direction
joseoyola 56:f95ec9baa4cb 235 if((pos[Z] + size + deltaZ - 1) < nCOLs && (pos[Z] + deltaZ) >= 0) {
joseoyola 56:f95ec9baa4cb 236 pos[Z] += deltaZ;
joseoyola 56:f95ec9baa4cb 237 if (deltaZ != 0) retVal = 1;
joseoyola 56:f95ec9baa4cb 238 }
joseoyola 56:f95ec9baa4cb 239 return retVal;
joseoyola 56:f95ec9baa4cb 240 }
joseoyola 56:f95ec9baa4cb 241
joseoyola 56:f95ec9baa4cb 242 /*
joseoyola 56:f95ec9baa4cb 243 * Changes the color of the square in the LED cube to the given hue.
joseoyola 56:f95ec9baa4cb 244 */
joseoyola 56:f95ec9baa4cb 245 void LedCube::changeColor(float hue){
joseoyola 56:f95ec9baa4cb 246 Colors::HSBtoRGB(hue, saturation, brightness, &r, &g, &b);
joseoyola 56:f95ec9baa4cb 247 }
joseoyola 56:f95ec9baa4cb 248
joseoyola 56:f95ec9baa4cb 249 /*
joseoyola 56:f95ec9baa4cb 250 * Changes the size of the square in the LED cube to the given size.
joseoyola 56:f95ec9baa4cb 251 * The minimum size is 1, corresponding to a square of a single LED.
joseoyola 56:f95ec9baa4cb 252 * A size of 2 corresponds to a 2x2 LED square, 3 corresponds to 3x3
joseoyola 56:f95ec9baa4cb 253 * and so forth. If square is on an edge, it moves accordingly in
joseoyola 56:f95ec9baa4cb 254 * order to be able to increase size.
joseoyola 56:f95ec9baa4cb 255 */
joseoyola 56:f95ec9baa4cb 256 void LedCube::changeSize(int newSize) {
joseoyola 56:f95ec9baa4cb 257 if(newSize > 0 && newSize <= MAX_SIZE) {
joseoyola 56:f95ec9baa4cb 258 if ((pos[X] + newSize) <= nCOLs && (pos[Y] + newSize) <= nCOLs && (pos[Z] + newSize) <= nCOLs) {
joseoyola 56:f95ec9baa4cb 259 size = newSize;
joseoyola 56:f95ec9baa4cb 260 return;
joseoyola 56:f95ec9baa4cb 261 }
joseoyola 56:f95ec9baa4cb 262 else {
joseoyola 56:f95ec9baa4cb 263 int delta_x = 0;
joseoyola 56:f95ec9baa4cb 264 int delta_y = 0;
joseoyola 56:f95ec9baa4cb 265 int delta_z = 0;
joseoyola 56:f95ec9baa4cb 266 if ((pos[X] + newSize) > nCOLs) {
joseoyola 56:f95ec9baa4cb 267 delta_x = nCOLs - (pos[X] + newSize);
joseoyola 56:f95ec9baa4cb 268 }
joseoyola 56:f95ec9baa4cb 269 if ((pos[Y] + newSize) > nCOLs) {
joseoyola 56:f95ec9baa4cb 270 delta_y = nCOLs - (pos[Y] + newSize);
joseoyola 56:f95ec9baa4cb 271 }
joseoyola 56:f95ec9baa4cb 272 if ((pos[Z] + newSize) > nCOLs) {
joseoyola 56:f95ec9baa4cb 273 delta_z = nCOLs - (pos[Z] + newSize);
joseoyola 56:f95ec9baa4cb 274 }
joseoyola 56:f95ec9baa4cb 275 move(delta_x, delta_y, delta_z);
joseoyola 56:f95ec9baa4cb 276 size = newSize;
joseoyola 56:f95ec9baa4cb 277 return;
joseoyola 56:f95ec9baa4cb 278 }
joseoyola 56:f95ec9baa4cb 279 }
joseoyola 56:f95ec9baa4cb 280 }
joseoyola 56:f95ec9baa4cb 281
joseoyola 56:f95ec9baa4cb 282 /*
joseoyola 56:f95ec9baa4cb 283 * Updates the LED cube given the size, hue and offsets in the X, Y and Z axes.
joseoyola 56:f95ec9baa4cb 284 */
joseoyola 56:f95ec9baa4cb 285 void LedCube::UpdateCube(int ledSize, int deltaX, int deltaY, int deltaZ, float hue) {
joseoyola 56:f95ec9baa4cb 286 changeSize(ledSize);
joseoyola 56:f95ec9baa4cb 287 move(deltaX, deltaY, deltaZ);
joseoyola 56:f95ec9baa4cb 288 changeColor(hue);
joseoyola 56:f95ec9baa4cb 289 cubeUpdate();
joseoyola 56:f95ec9baa4cb 290 }
joseoyola 56:f95ec9baa4cb 291
joseoyola 56:f95ec9baa4cb 292 /*
joseoyola 56:f95ec9baa4cb 293 * Updates the LED cube given parameters in a CubeUpdateParameters struct.
joseoyola 56:f95ec9baa4cb 294 */
joseoyola 56:f95ec9baa4cb 295 void LedCube::UpdateCube2(CubeUpdateParameters cubeParams){
joseoyola 56:f95ec9baa4cb 296 UpdateCube(cubeParams.size, cubeParams.deltaX, cubeParams.deltaY, cubeParams.deltaZ, cubeParams.hue);
joseoyola 56:f95ec9baa4cb 297 }
joseoyola 56:f95ec9baa4cb 298