Cubic Hand project for EECS 249A course.
Dependencies: MMA8451Q TSI cc3000_hostdriver_mbedsocket NVIC_set_all_priorities mbed Multi_WS2811
ledCube.cpp@43:cf824a44a040, 2014-12-11 (annotated)
- Committer:
- robertbui
- Date:
- Thu Dec 11 13:33:29 2014 +0000
- Revision:
- 43:cf824a44a040
- Parent:
- 41:367cab0162de
- Child:
- 49:361833355173
First working code. Lighted led cube moves. color and size doesn't work yet.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
joseoyola | 2:45b90e8d7d82 | 1 | /* |
joseoyola | 16:a3de0c0dbe33 | 2 | * Neopixel LED Cube library |
joseoyola | 5:41f28ce7f5a9 | 3 | * by Robert Bui and Jose Oyola |
joseoyola | 2:45b90e8d7d82 | 4 | * UC Berkeley 2014 |
joseoyola | 2:45b90e8d7d82 | 5 | */ |
joseoyola | 2:45b90e8d7d82 | 6 | |
joseoyola | 2:45b90e8d7d82 | 7 | #include "mbed.h" |
joseoyola | 5:41f28ce7f5a9 | 8 | #include "WS2811.h" |
joseoyola | 5:41f28ce7f5a9 | 9 | #include "Colors.h" |
joseoyola | 5:41f28ce7f5a9 | 10 | #include "TSISensor.h" |
joseoyola | 5:41f28ce7f5a9 | 11 | #include "MMA8451Q.h" |
joseoyola | 16:a3de0c0dbe33 | 12 | #include "ledCube.h" |
joseoyola | 5:41f28ce7f5a9 | 13 | |
joseoyola | 5:41f28ce7f5a9 | 14 | |
joseoyola | 5:41f28ce7f5a9 | 15 | #define MMA8451_I2C_ADDRESS (0x1d<<1) |
joseoyola | 5:41f28ce7f5a9 | 16 | |
joseoyola | 5:41f28ce7f5a9 | 17 | #define PANEL1 0 |
joseoyola | 5:41f28ce7f5a9 | 18 | #define PANEL2 1 |
joseoyola | 5:41f28ce7f5a9 | 19 | #define PANEL3 2 |
robertbui | 30:0933d7f2fe78 | 20 | #define nLEDs 200 //MAX_LEDS_PER_STRIP; |
robertbui | 30:0933d7f2fe78 | 21 | #define nROWs 10 //number of rows per cube panel |
robertbui | 30:0933d7f2fe78 | 22 | #define nCOLs 10 //number of columns per cube panel |
robertbui | 30:0933d7f2fe78 | 23 | #define DATA_OUT_PIN1 2 // PTD2 |
robertbui | 30:0933d7f2fe78 | 24 | #define DATA_OUT_PIN2 3 // PTD3 |
joseoyola | 5:41f28ce7f5a9 | 25 | |
joseoyola | 5:41f28ce7f5a9 | 26 | |
robertbui | 41:367cab0162de | 27 | LedCube::LedCube():X(0),Y(1),Z(2),ledStrip1(nLEDs, DATA_OUT_PIN1),ledStrip2(nLEDs/2, DATA_OUT_PIN2) |
joseoyola | 16:a3de0c0dbe33 | 28 | { |
joseoyola | 16:a3de0c0dbe33 | 29 | } |
joseoyola | 5:41f28ce7f5a9 | 30 | |
joseoyola | 16:a3de0c0dbe33 | 31 | LedCube::~LedCube() |
joseoyola | 16:a3de0c0dbe33 | 32 | { |
joseoyola | 16:a3de0c0dbe33 | 33 | } |
joseoyola | 5:41f28ce7f5a9 | 34 | |
robertbui | 30:0933d7f2fe78 | 35 | /*Sets the initial size and position of the lighted cube*/ |
joseoyola | 16:a3de0c0dbe33 | 36 | void LedCube::Init(int x, int y, int z) |
joseoyola | 16:a3de0c0dbe33 | 37 | { |
joseoyola | 16:a3de0c0dbe33 | 38 | size = 2; |
joseoyola | 16:a3de0c0dbe33 | 39 | prevSize = size; |
joseoyola | 16:a3de0c0dbe33 | 40 | pos[X] = prevPos[X] = x; |
joseoyola | 16:a3de0c0dbe33 | 41 | pos[Y] = prevPos[Y] = y; |
joseoyola | 16:a3de0c0dbe33 | 42 | pos[Z] = prevPos[Z] = z; |
joseoyola | 16:a3de0c0dbe33 | 43 | r = 255*0.1; |
joseoyola | 16:a3de0c0dbe33 | 44 | g = 255*0.1; |
joseoyola | 16:a3de0c0dbe33 | 45 | b = 255*0.1; |
joseoyola | 5:41f28ce7f5a9 | 46 | |
joseoyola | 24:554ea084eddf | 47 | brightness = 0.5; |
joseoyola | 16:a3de0c0dbe33 | 48 | saturation = 1.0; |
joseoyola | 16:a3de0c0dbe33 | 49 | |
joseoyola | 16:a3de0c0dbe33 | 50 | ledStrip1.begin(); |
joseoyola | 16:a3de0c0dbe33 | 51 | ledStrip2.begin(); |
joseoyola | 16:a3de0c0dbe33 | 52 | } |
joseoyola | 5:41f28ce7f5a9 | 53 | |
robertbui | 30:0933d7f2fe78 | 54 | /*Determines which LED should be lit based on its |
robertbui | 30:0933d7f2fe78 | 55 | cartesian coordinate. The origin is the led at |
robertbui | 31:0e341d81ea00 | 56 | bottom left of panel 1 when using a three panel cube |
robertbui | 31:0e341d81ea00 | 57 | ________ |
robertbui | 31:0e341d81ea00 | 58 | / /| |
robertbui | 31:0e341d81ea00 | 59 | / 3 / | |
robertbui | 31:0e341d81ea00 | 60 | /_______/ 2| |
robertbui | 31:0e341d81ea00 | 61 | | | | |
robertbui | 31:0e341d81ea00 | 62 | | 1 | / |
robertbui | 31:0e341d81ea00 | 63 | | | |
robertbui | 31:0e341d81ea00 | 64 | -------- |
robertbui | 31:0e341d81ea00 | 65 | */ |
robertbui | 30:0933d7f2fe78 | 66 | |
joseoyola | 16:a3de0c0dbe33 | 67 | int LedCube::getLedIndex(int panel, int x, int y) { |
joseoyola | 8:c06f5046c9f7 | 68 | if (panel == PANEL1) { |
joseoyola | 8:c06f5046c9f7 | 69 | if (y % 2 == 0) { |
joseoyola | 8:c06f5046c9f7 | 70 | return nCOLs*2 * y + x; |
joseoyola | 8:c06f5046c9f7 | 71 | } |
joseoyola | 8:c06f5046c9f7 | 72 | else { |
joseoyola | 8:c06f5046c9f7 | 73 | return nCOLs*2 * y + nCOLs + ((nCOLs - 1) - x); |
joseoyola | 8:c06f5046c9f7 | 74 | } |
joseoyola | 5:41f28ce7f5a9 | 75 | } |
joseoyola | 8:c06f5046c9f7 | 76 | |
joseoyola | 8:c06f5046c9f7 | 77 | if (panel == PANEL2) { |
joseoyola | 8:c06f5046c9f7 | 78 | if (y % 2 == 0) { |
joseoyola | 8:c06f5046c9f7 | 79 | return nCOLs*2 * y + nCOLs + x; |
joseoyola | 8:c06f5046c9f7 | 80 | } |
joseoyola | 8:c06f5046c9f7 | 81 | else { |
joseoyola | 8:c06f5046c9f7 | 82 | return nCOLs*2 * y + ((nCOLs - 1) - x); |
joseoyola | 8:c06f5046c9f7 | 83 | } |
joseoyola | 5:41f28ce7f5a9 | 84 | } |
joseoyola | 8:c06f5046c9f7 | 85 | |
joseoyola | 8:c06f5046c9f7 | 86 | if (panel == PANEL3) { |
joseoyola | 8:c06f5046c9f7 | 87 | if (y % 2 == 0) { |
joseoyola | 8:c06f5046c9f7 | 88 | return nCOLs * y + x; |
joseoyola | 8:c06f5046c9f7 | 89 | } |
joseoyola | 8:c06f5046c9f7 | 90 | else { |
joseoyola | 8:c06f5046c9f7 | 91 | return nCOLs * y + ((nCOLs - 1) - x); |
joseoyola | 8:c06f5046c9f7 | 92 | } |
joseoyola | 8:c06f5046c9f7 | 93 | } |
joseoyola | 8:c06f5046c9f7 | 94 | |
joseoyola | 8:c06f5046c9f7 | 95 | else return -1; |
joseoyola | 5:41f28ce7f5a9 | 96 | } |
joseoyola | 5:41f28ce7f5a9 | 97 | |
joseoyola | 16:a3de0c0dbe33 | 98 | void LedCube::updateLEDs(bool on, int size, int x, int y, int z) { |
joseoyola | 10:9d87a886f066 | 99 | //Panel 1 |
joseoyola | 24:554ea084eddf | 100 | double bright; |
joseoyola | 24:554ea084eddf | 101 | bright = 1.0 / ((y + 1) * (y + 1)); |
joseoyola | 24:554ea084eddf | 102 | for(int i = x; i < x + size; i++) { |
joseoyola | 24:554ea084eddf | 103 | for(int j = z; j < z + size; j++) { |
joseoyola | 24:554ea084eddf | 104 | int led = getLedIndex(PANEL1, i, j); |
joseoyola | 24:554ea084eddf | 105 | if(on) { |
joseoyola | 24:554ea084eddf | 106 | ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright); |
joseoyola | 24:554ea084eddf | 107 | } else { |
joseoyola | 24:554ea084eddf | 108 | ledStrip1.setPixelColor(led, 0, 0, 0); |
joseoyola | 24:554ea084eddf | 109 | } |
joseoyola | 24:554ea084eddf | 110 | } |
joseoyola | 24:554ea084eddf | 111 | } |
joseoyola | 24:554ea084eddf | 112 | |
joseoyola | 24:554ea084eddf | 113 | //Panel 2 |
joseoyola | 24:554ea084eddf | 114 | bright = 1.0 / (((nCOLs-1) - x - (size-1) + 1) * ((nCOLs-1) - x - (size-1) + 1)); |
joseoyola | 24:554ea084eddf | 115 | for(int i = y; i < y + size; i++) { |
joseoyola | 24:554ea084eddf | 116 | for(int j = z; j < z + size; j++) { |
joseoyola | 24:554ea084eddf | 117 | int led = getLedIndex(PANEL2, i, j); |
joseoyola | 24:554ea084eddf | 118 | if(on) { |
joseoyola | 24:554ea084eddf | 119 | ledStrip1.setPixelColor(led, r*bright, g*bright, b*bright); |
joseoyola | 24:554ea084eddf | 120 | } else { |
joseoyola | 24:554ea084eddf | 121 | ledStrip1.setPixelColor(led, 0, 0, 0); |
joseoyola | 24:554ea084eddf | 122 | } |
joseoyola | 24:554ea084eddf | 123 | } |
joseoyola | 24:554ea084eddf | 124 | } |
joseoyola | 24:554ea084eddf | 125 | |
joseoyola | 24:554ea084eddf | 126 | //Panel 3 |
robertbui | 40:bdd949fc3bc2 | 127 | bright = 1.0 / (((nCOLs-1) - z - (size-1) + 1) * ((nCOLs-1) - z - (size-1) + 1)); |
joseoyola | 24:554ea084eddf | 128 | for(int i = x; i < x + size; i++) { |
joseoyola | 24:554ea084eddf | 129 | for(int j = y; j < y + size; j++) { |
joseoyola | 24:554ea084eddf | 130 | int led = getLedIndex(PANEL3, i, j); |
joseoyola | 24:554ea084eddf | 131 | if(on) { |
joseoyola | 24:554ea084eddf | 132 | ledStrip2.setPixelColor(led, r*bright, g*bright, b*bright); |
joseoyola | 24:554ea084eddf | 133 | } else { |
joseoyola | 24:554ea084eddf | 134 | ledStrip2.setPixelColor(led, 0, 0, 0); |
joseoyola | 24:554ea084eddf | 135 | } |
joseoyola | 24:554ea084eddf | 136 | } |
joseoyola | 24:554ea084eddf | 137 | } |
joseoyola | 24:554ea084eddf | 138 | } |
joseoyola | 24:554ea084eddf | 139 | |
joseoyola | 24:554ea084eddf | 140 | void LedCube::updateLEDsOld(bool on, int size, int x, int y, int z) { |
joseoyola | 24:554ea084eddf | 141 | //Panel 1 |
joseoyola | 16:a3de0c0dbe33 | 142 | if(y == 0) { |
joseoyola | 16:a3de0c0dbe33 | 143 | for(int i = x; i < x + size; i++) { |
joseoyola | 16:a3de0c0dbe33 | 144 | for(int j = z; j < z + size; j++) { |
joseoyola | 10:9d87a886f066 | 145 | int led = getLedIndex(PANEL1, i, j); |
joseoyola | 10:9d87a886f066 | 146 | if(on) { |
joseoyola | 10:9d87a886f066 | 147 | ledStrip1.setPixelColor(led, r, g, b); |
joseoyola | 10:9d87a886f066 | 148 | } else { |
joseoyola | 10:9d87a886f066 | 149 | ledStrip1.setPixelColor(led, 0, 0, 0); |
joseoyola | 10:9d87a886f066 | 150 | } |
joseoyola | 10:9d87a886f066 | 151 | } |
joseoyola | 10:9d87a886f066 | 152 | } |
joseoyola | 10:9d87a886f066 | 153 | } |
joseoyola | 10:9d87a886f066 | 154 | |
joseoyola | 10:9d87a886f066 | 155 | //Panel 2 |
joseoyola | 16:a3de0c0dbe33 | 156 | if(x + size - 1 == (nCOLs - 1)) { |
joseoyola | 16:a3de0c0dbe33 | 157 | for(int i = y; i < y + size; i++) { |
joseoyola | 16:a3de0c0dbe33 | 158 | for(int j = z; j < z + size; j++) { |
joseoyola | 10:9d87a886f066 | 159 | int led = getLedIndex(PANEL2, i, j); |
joseoyola | 10:9d87a886f066 | 160 | if(on) { |
joseoyola | 20:c2bc970bbff8 | 161 | ledStrip1.setPixelColor(led, r, g, b); |
joseoyola | 10:9d87a886f066 | 162 | } else { |
joseoyola | 20:c2bc970bbff8 | 163 | ledStrip1.setPixelColor(led, 0, 0, 0); |
joseoyola | 10:9d87a886f066 | 164 | } |
joseoyola | 10:9d87a886f066 | 165 | } |
joseoyola | 10:9d87a886f066 | 166 | } |
joseoyola | 10:9d87a886f066 | 167 | } |
joseoyola | 10:9d87a886f066 | 168 | |
joseoyola | 10:9d87a886f066 | 169 | //Panel 3 |
joseoyola | 16:a3de0c0dbe33 | 170 | if(z + size - 1 == (nCOLs - 1)) { |
joseoyola | 16:a3de0c0dbe33 | 171 | for(int i = x; i < x + size; i++) { |
joseoyola | 16:a3de0c0dbe33 | 172 | for(int j = y; j < y + size; j++) { |
joseoyola | 10:9d87a886f066 | 173 | int led = getLedIndex(PANEL3, i, j); |
joseoyola | 10:9d87a886f066 | 174 | if(on) { |
joseoyola | 20:c2bc970bbff8 | 175 | ledStrip2.setPixelColor(led, r, g, b); |
joseoyola | 10:9d87a886f066 | 176 | } else { |
joseoyola | 20:c2bc970bbff8 | 177 | ledStrip2.setPixelColor(led, 0, 0, 0); |
joseoyola | 10:9d87a886f066 | 178 | } |
joseoyola | 10:9d87a886f066 | 179 | } |
joseoyola | 10:9d87a886f066 | 180 | } |
joseoyola | 10:9d87a886f066 | 181 | } |
joseoyola | 10:9d87a886f066 | 182 | } |
joseoyola | 10:9d87a886f066 | 183 | |
joseoyola | 10:9d87a886f066 | 184 | |
joseoyola | 16:a3de0c0dbe33 | 185 | void LedCube::cubeUpdate() { |
joseoyola | 16:a3de0c0dbe33 | 186 | updateLEDs(false, prevSize, prevPos[X], prevPos[Y], prevPos[Z]); //Turn off LEDs from previous state |
joseoyola | 16:a3de0c0dbe33 | 187 | updateLEDs(true, size, pos[X], pos[Y], pos[Z]); //Turn on new LEDs for new state |
joseoyola | 16:a3de0c0dbe33 | 188 | prevSize = size; |
joseoyola | 16:a3de0c0dbe33 | 189 | prevPos[X] = pos[X]; |
joseoyola | 16:a3de0c0dbe33 | 190 | prevPos[Y] = pos[Y]; |
joseoyola | 16:a3de0c0dbe33 | 191 | prevPos[Z] = pos[Z]; |
joseoyola | 16:a3de0c0dbe33 | 192 | ledStrip1.show(); |
joseoyola | 16:a3de0c0dbe33 | 193 | ledStrip2.show(); |
joseoyola | 16:a3de0c0dbe33 | 194 | ledStrip1.startDMA(); |
joseoyola | 16:a3de0c0dbe33 | 195 | ledStrip2.startDMA(); |
joseoyola | 10:9d87a886f066 | 196 | } |
joseoyola | 10:9d87a886f066 | 197 | |
joseoyola | 16:a3de0c0dbe33 | 198 | int LedCube::move(int deltaX, int deltaY, int deltaZ) { |
joseoyola | 16:a3de0c0dbe33 | 199 | int retVal = -1; |
joseoyola | 10:9d87a886f066 | 200 | //Moving in X direction |
joseoyola | 16:a3de0c0dbe33 | 201 | if(pos[Y] == 0 || pos[Z] + size - 1 == (nCOLs - 1)) { //Making sure square is "stuck" to panel 1 or 3 |
joseoyola | 16:a3de0c0dbe33 | 202 | if((pos[X] + size + deltaX - 1) < nCOLs && (pos[X] + deltaX) >= 0) { |
joseoyola | 10:9d87a886f066 | 203 | pos[X] += deltaX; |
joseoyola | 16:a3de0c0dbe33 | 204 | if (deltaX != 0) retVal = 1; |
joseoyola | 10:9d87a886f066 | 205 | } |
joseoyola | 10:9d87a886f066 | 206 | } |
joseoyola | 10:9d87a886f066 | 207 | |
joseoyola | 10:9d87a886f066 | 208 | //Moving in Y direction |
joseoyola | 16:a3de0c0dbe33 | 209 | if(pos[X] + size - 1 == (nCOLs - 1) || pos[Z] + size - 1 == (nCOLs - 1)) {//Making sure square is "stuck" to panel 2 or 3 |
joseoyola | 16:a3de0c0dbe33 | 210 | if((pos[Y] + size + deltaY - 1) < nCOLs && (pos[Y] + deltaY) >= 0) { |
joseoyola | 10:9d87a886f066 | 211 | pos[Y] += deltaY; |
joseoyola | 16:a3de0c0dbe33 | 212 | if (deltaY != 0) retVal = 1; |
joseoyola | 10:9d87a886f066 | 213 | } |
joseoyola | 10:9d87a886f066 | 214 | } |
joseoyola | 10:9d87a886f066 | 215 | |
joseoyola | 10:9d87a886f066 | 216 | //Moving in Z direction |
joseoyola | 16:a3de0c0dbe33 | 217 | if(pos[X] + size - 1 == (nCOLs - 1) || pos[Y] == 0) {//Making sure square is "stuck" to panel 1 or 2 |
joseoyola | 16:a3de0c0dbe33 | 218 | if((pos[Z] + size + deltaZ - 1) < nCOLs && (pos[Z] + deltaZ) >= 0) { |
joseoyola | 10:9d87a886f066 | 219 | pos[Z] += deltaZ; |
joseoyola | 16:a3de0c0dbe33 | 220 | if (deltaZ != 0) retVal = 1; |
joseoyola | 10:9d87a886f066 | 221 | } |
joseoyola | 10:9d87a886f066 | 222 | } |
joseoyola | 16:a3de0c0dbe33 | 223 | return retVal; |
joseoyola | 16:a3de0c0dbe33 | 224 | } |
joseoyola | 16:a3de0c0dbe33 | 225 | |
joseoyola | 16:a3de0c0dbe33 | 226 | void LedCube::changeColor(float hue){ |
joseoyola | 20:c2bc970bbff8 | 227 | Colors::HSBtoRGB(hue, saturation, brightness, &r, &g, &b); |
joseoyola | 16:a3de0c0dbe33 | 228 | } |
joseoyola | 16:a3de0c0dbe33 | 229 | |
joseoyola | 16:a3de0c0dbe33 | 230 | void LedCube::changeSize(int newSize) { |
robertbui | 43:cf824a44a040 | 231 | if( newSize > 0 && (pos[X] + newSize) < nCOLs && (pos[Y] + newSize) < nCOLs && (pos[Z] + newSize) < nCOLs) { |
joseoyola | 16:a3de0c0dbe33 | 232 | size = newSize; |
joseoyola | 16:a3de0c0dbe33 | 233 | } |
robertbui | 30:0933d7f2fe78 | 234 | } |
robertbui | 30:0933d7f2fe78 | 235 | |
robertbui | 43:cf824a44a040 | 236 | void LedCube::UpdateCube(int ledSize, int deltaX, int deltaY, int deltaZ, float hue) { |
robertbui | 43:cf824a44a040 | 237 | // if(ledSize == 0 && deltaX == 0 && deltaY == 0 && deltaZ == 0 && hue == 0){ |
robertbui | 43:cf824a44a040 | 238 | // } |
robertbui | 43:cf824a44a040 | 239 | //else{ |
robertbui | 43:cf824a44a040 | 240 | changeSize(ledSize); |
robertbui | 40:bdd949fc3bc2 | 241 | move(deltaX, deltaY, deltaZ); |
robertbui | 40:bdd949fc3bc2 | 242 | changeColor(hue); |
robertbui | 40:bdd949fc3bc2 | 243 | cubeUpdate(); |
robertbui | 43:cf824a44a040 | 244 | // } |
robertbui | 30:0933d7f2fe78 | 245 | } |
robertbui | 30:0933d7f2fe78 | 246 | |
robertbui | 43:cf824a44a040 | 247 | void LedCube::UpdateCube2(CubeUpdateParameters cubeParams){ |
robertbui | 39:e90071c1535a | 248 | UpdateCube(cubeParams.size, cubeParams.deltaX, cubeParams.deltaY, cubeParams.deltaZ, cubeParams.hue); |
robertbui | 39:e90071c1535a | 249 | } |
robertbui | 30:0933d7f2fe78 | 250 |