A somewhat silly project that uses an LPC11U24 to control the system, a Neopixel stick to provide light, and a sound FX board with a small speaker to make noise. I set the pins to inputs with pull-ups then connected 14 jumper wires to ground. Every time a wire was disconnected, the system changed its lighting pattern: color, blink timing, blink pattern (blink to white, black, random, or opposite the main color). The system also played a random audio clip. More details on http://embedded.fm/blog/2016/5/24/fistful-of-wires License: CC-A-NC
main.cpp@1:0a051df78be2, 2016-05-25 (annotated)
- Committer:
- Elecia
- Date:
- Wed May 25 03:42:25 2016 +0000
- Revision:
- 1:0a051df78be2
- Parent:
- 0:21fea82c85fc
As demonstrated at Bring-A-Hack.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Elecia | 0:21fea82c85fc | 1 | /* |
Elecia | 0:21fea82c85fc | 2 | Fist full of wires! |
Elecia | 1:0a051df78be2 | 3 | The intention here is to make a ball of wires that someone can reach in and |
Elecia | 1:0a051df78be2 | 4 | grab, changing the behavior of the system. |
Elecia | 1:0a051df78be2 | 5 | |
Elecia | 0:21fea82c85fc | 6 | So we read in the free IO lines, build up a variable. |
Elecia | 0:21fea82c85fc | 7 | If it has changed, |
Elecia | 0:21fea82c85fc | 8 | do the change actions: |
Elecia | 0:21fea82c85fc | 9 | make a bzzzzt sound |
Elecia | 0:21fea82c85fc | 10 | turn off all of the LEDs for a brief instant |
Elecia | 1:0a051df78be2 | 11 | |
Elecia | 0:21fea82c85fc | 12 | Use the created variable to choose the neopixel pattern |
Elecia | 0:21fea82c85fc | 13 | and the sound pattern to output to the audio (intermittent beeps) |
Elecia | 0:21fea82c85fc | 14 | |
Elecia | 1:0a051df78be2 | 15 | |
Elecia | 0:21fea82c85fc | 16 | This program depends on neopixel library. |
Elecia | 0:21fea82c85fc | 17 | http://developer.mbed.org/users/JacobBramley/code/PixelArray/ |
Elecia | 1:0a051df78be2 | 18 | |
Elecia | 1:0a051df78be2 | 19 | Audio using an Adafruit sound fx board |
Elecia | 0:21fea82c85fc | 20 | https://developer.mbed.org/users/Szilard/notebook/mbed-r2d2-robot/ |
Elecia | 0:21fea82c85fc | 21 | Sounds in general: https://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/ |
Elecia | 0:21fea82c85fc | 22 | |
Elecia | 0:21fea82c85fc | 23 | */ |
Elecia | 0:21fea82c85fc | 24 | #include "mbed.h" |
Elecia | 0:21fea82c85fc | 25 | #include "neopixel.h" |
Elecia | 1:0a051df78be2 | 26 | #include "LedArrayController.h" |
Elecia | 1:0a051df78be2 | 27 | |
Elecia | 1:0a051df78be2 | 28 | #include <stdlib.h> /* srand, rand */ |
Elecia | 1:0a051df78be2 | 29 | |
Elecia | 1:0a051df78be2 | 30 | |
Elecia | 0:21fea82c85fc | 31 | BusIn mColorWires( |
Elecia | 1:0a051df78be2 | 32 | p22, p19, p18, p21, p16, p15 // six color, two each, RGB |
Elecia | 1:0a051df78be2 | 33 | ); |
Elecia | 0:21fea82c85fc | 34 | typedef union { |
Elecia | 1:0a051df78be2 | 35 | struct { |
Elecia | 0:21fea82c85fc | 36 | uint32_t green:2; |
Elecia | 0:21fea82c85fc | 37 | uint32_t blue:2; |
Elecia | 0:21fea82c85fc | 38 | uint32_t red:2; |
Elecia | 0:21fea82c85fc | 39 | uint32_t junk:26; |
Elecia | 0:21fea82c85fc | 40 | }; |
Elecia | 0:21fea82c85fc | 41 | uint32_t value; |
Elecia | 1:0a051df78be2 | 42 | } tledColorWires; |
Elecia | 1:0a051df78be2 | 43 | |
Elecia | 1:0a051df78be2 | 44 | BusIn mBlinkConfig( |
Elecia | 1:0a051df78be2 | 45 | p14, p13, p20, // three timing: indexes into mBlinkTiming |
Elecia | 1:0a051df78be2 | 46 | p30, p29 ); // two for blink type |
Elecia | 1:0a051df78be2 | 47 | |
Elecia | 1:0a051df78be2 | 48 | Serial SerialToAudio(p9, p10); // tx, rx |
Elecia | 1:0a051df78be2 | 49 | |
Elecia | 1:0a051df78be2 | 50 | BusIn mLedPatternConfig (p23, p35, p36); |
Elecia | 1:0a051df78be2 | 51 | // 000 001 010 011 100 101 110 111 |
Elecia | 1:0a051df78be2 | 52 | uint8_t mLedPattern[] = { 0x01, 0xF0, 0x0F, 0xAA, 0x55, 0x0F, 0xF0, 0xFF }; |
Elecia | 1:0a051df78be2 | 53 | |
Elecia | 0:21fea82c85fc | 54 | |
Elecia | 1:0a051df78be2 | 55 | char *mAudioPlaylist[] = { |
Elecia | 1:0a051df78be2 | 56 | "PBITEDUSTOGG\n" , // another one bites the dust |
Elecia | 1:0a051df78be2 | 57 | "PDANGW OGG\n" , // danger will robinson |
Elecia | 1:0a051df78be2 | 58 | "PHASTA OGG\n" , // hasta la vista baby |
Elecia | 1:0a051df78be2 | 59 | "PHELPME OGG\n" , // help me obiwan kenobi, you are my only hope |
Elecia | 1:0a051df78be2 | 60 | "PNODISA OGG\n" , // no disassembly |
Elecia | 1:0a051df78be2 | 61 | "PNOESCAPEOGG\n" , // there'll be no escape for the princess this time |
Elecia | 1:0a051df78be2 | 62 | "POMG OGG\n" , // Oh my god (bender) |
Elecia | 1:0a051df78be2 | 63 | "PPRESSUREOGG\n" , // simpsons bomb disposal robot |
Elecia | 1:0a051df78be2 | 64 | "PSTILLALIOGG\n" , // this was a triumph |
Elecia | 1:0a051df78be2 | 65 | "PLAUGH OGG\n" , // robo laugh |
Elecia | 1:0a051df78be2 | 66 | "PCOMPUTE OGG\n" , // does not compute |
Elecia | 1:0a051df78be2 | 67 | "PEMBEDDEDOGG\n" , // embedded.fm |
Elecia | 1:0a051df78be2 | 68 | }; |
Elecia | 1:0a051df78be2 | 69 | |
Elecia | 1:0a051df78be2 | 70 | int mNumAudioInPlaylist = 12; |
Elecia | 0:21fea82c85fc | 71 | |
Elecia | 0:21fea82c85fc | 72 | void InitializePins(void); |
Elecia | 0:21fea82c85fc | 73 | void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color); |
Elecia | 1:0a051df78be2 | 74 | void OnChangeMode(neopixel::PixelArray *array); |
Elecia | 0:21fea82c85fc | 75 | neopixel::Pixel GetCurrentColor(uint32_t wireConfig); |
Elecia | 0:21fea82c85fc | 76 | void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig); |
Elecia | 0:21fea82c85fc | 77 | |
Elecia | 0:21fea82c85fc | 78 | |
Elecia | 0:21fea82c85fc | 79 | void InitializePins(void) |
Elecia | 0:21fea82c85fc | 80 | { |
Elecia | 0:21fea82c85fc | 81 | mColorWires.mode(PullUp); |
Elecia | 1:0a051df78be2 | 82 | mLedPatternConfig.mode(PullUp); |
Elecia | 0:21fea82c85fc | 83 | mBlinkConfig.mode(PullUp); |
Elecia | 1:0a051df78be2 | 84 | SerialToAudio.baud(9600); |
Elecia | 0:21fea82c85fc | 85 | } |
Elecia | 0:21fea82c85fc | 86 | |
Elecia | 1:0a051df78be2 | 87 | void OnChangeMode(neopixel::PixelArray *array) |
Elecia | 0:21fea82c85fc | 88 | { |
Elecia | 1:0a051df78be2 | 89 | // all black, zap, then white |
Elecia | 1:0a051df78be2 | 90 | array->update(SetLeds, NLED, COLOR_BLACK); |
Elecia | 0:21fea82c85fc | 91 | |
Elecia | 1:0a051df78be2 | 92 | SerialToAudio.printf("Q\n"); |
Elecia | 1:0a051df78be2 | 93 | SerialToAudio.printf("q\n"); |
Elecia | 1:0a051df78be2 | 94 | wait_ms(50); |
Elecia | 1:0a051df78be2 | 95 | // P and then the file name zap.ogg with no dot |
Elecia | 1:0a051df78be2 | 96 | SerialToAudio.printf("PZAP OGG\n"); |
Elecia | 1:0a051df78be2 | 97 | wait_ms(350); |
Elecia | 1:0a051df78be2 | 98 | array->update(SetLeds, NLED, COLOR_WHITE); |
Elecia | 1:0a051df78be2 | 99 | wait_ms(100); |
Elecia | 1:0a051df78be2 | 100 | SerialToAudio.printf("Q\n"); |
Elecia | 1:0a051df78be2 | 101 | SerialToAudio.printf("q\n"); |
Elecia | 1:0a051df78be2 | 102 | wait_ms(500); |
Elecia | 1:0a051df78be2 | 103 | int audioListIndex = rand() % mNumAudioInPlaylist; |
Elecia | 1:0a051df78be2 | 104 | SerialToAudio.printf(mAudioPlaylist[audioListIndex]); |
Elecia | 0:21fea82c85fc | 105 | } |
Elecia | 0:21fea82c85fc | 106 | |
Elecia | 0:21fea82c85fc | 107 | uint8_t MakeColorFromWires(uint32_t singleColorWireConfig) |
Elecia | 0:21fea82c85fc | 108 | { |
Elecia | 0:21fea82c85fc | 109 | uint8_t color; |
Elecia | 1:0a051df78be2 | 110 | if (singleColorWireConfig == 3u) { |
Elecia | 1:0a051df78be2 | 111 | color = 0xFF; |
Elecia | 1:0a051df78be2 | 112 | } else if (singleColorWireConfig == 0u) { |
Elecia | 1:0a051df78be2 | 113 | color = 0x00; |
Elecia | 1:0a051df78be2 | 114 | } else { /* one bit on */ |
Elecia | 1:0a051df78be2 | 115 | color = 0x80; |
Elecia | 1:0a051df78be2 | 116 | } |
Elecia | 0:21fea82c85fc | 117 | return color; |
Elecia | 0:21fea82c85fc | 118 | } |
Elecia | 0:21fea82c85fc | 119 | |
Elecia | 0:21fea82c85fc | 120 | void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color) |
Elecia | 0:21fea82c85fc | 121 | { |
Elecia | 1:0a051df78be2 | 122 | bool thisOneOn = false; |
Elecia | 1:0a051df78be2 | 123 | uint32_t indexMask = 1u << index; |
Elecia | 1:0a051df78be2 | 124 | indexMask &= mLedPattern[mLedPatternConfig]; |
Elecia | 1:0a051df78be2 | 125 | |
Elecia | 1:0a051df78be2 | 126 | if ( (color == COLOR_BLACK) || (color == COLOR_WHITE) ) |
Elecia | 1:0a051df78be2 | 127 | { |
Elecia | 1:0a051df78be2 | 128 | thisOneOn = true; |
Elecia | 1:0a051df78be2 | 129 | } |
Elecia | 1:0a051df78be2 | 130 | if (indexMask) { // if this one set |
Elecia | 1:0a051df78be2 | 131 | thisOneOn = true; |
Elecia | 1:0a051df78be2 | 132 | } |
Elecia | 1:0a051df78be2 | 133 | |
Elecia | 1:0a051df78be2 | 134 | if (thisOneOn) |
Elecia | 1:0a051df78be2 | 135 | { |
Elecia | 1:0a051df78be2 | 136 | out->red = (color >> 16) & 0xFF; |
Elecia | 1:0a051df78be2 | 137 | out->green = (color >> 8 ) & 0xFF; |
Elecia | 1:0a051df78be2 | 138 | out->blue = (color ) & 0xFF; |
Elecia | 1:0a051df78be2 | 139 | } |
Elecia | 0:21fea82c85fc | 140 | } |
Elecia | 0:21fea82c85fc | 141 | |
Elecia | 0:21fea82c85fc | 142 | uint32_t GetCurrentColorU32(uint32_t wireConfig) |
Elecia | 0:21fea82c85fc | 143 | { |
Elecia | 0:21fea82c85fc | 144 | neopixel::Pixel pix; |
Elecia | 0:21fea82c85fc | 145 | uint32_t out; |
Elecia | 0:21fea82c85fc | 146 | pix = GetCurrentColor(wireConfig); |
Elecia | 0:21fea82c85fc | 147 | out = pix.blue + (pix.green << 8) + (pix.red << 16); |
Elecia | 0:21fea82c85fc | 148 | return out; |
Elecia | 0:21fea82c85fc | 149 | } |
Elecia | 0:21fea82c85fc | 150 | |
Elecia | 0:21fea82c85fc | 151 | |
Elecia | 0:21fea82c85fc | 152 | neopixel::Pixel GetCurrentColor(uint32_t wireConfig) |
Elecia | 0:21fea82c85fc | 153 | { |
Elecia | 1:0a051df78be2 | 154 | tledColorWires config; |
Elecia | 0:21fea82c85fc | 155 | neopixel::Pixel out; |
Elecia | 0:21fea82c85fc | 156 | config.value = wireConfig; |
Elecia | 1:0a051df78be2 | 157 | if ( (config.red == 0u) && (config.green == 0u) && (config.blue == 0u) ) { |
Elecia | 1:0a051df78be2 | 158 | out.red = 0x10u; |
Elecia | 0:21fea82c85fc | 159 | out.green = 0x10u; |
Elecia | 0:21fea82c85fc | 160 | out.blue = 0x10u; |
Elecia | 0:21fea82c85fc | 161 | } else { |
Elecia | 0:21fea82c85fc | 162 | out.red = MakeColorFromWires(config.red); |
Elecia | 0:21fea82c85fc | 163 | out.green = MakeColorFromWires(config.green); |
Elecia | 0:21fea82c85fc | 164 | out.blue = MakeColorFromWires(config.blue); |
Elecia | 0:21fea82c85fc | 165 | } |
Elecia | 0:21fea82c85fc | 166 | return out; |
Elecia | 0:21fea82c85fc | 167 | } |
Elecia | 1:0a051df78be2 | 168 | void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig) |
Elecia | 1:0a051df78be2 | 169 | { |
Elecia | 0:21fea82c85fc | 170 | bool thisOneOn = false; |
Elecia | 0:21fea82c85fc | 171 | uint32_t indexMask = 1u << index; |
Elecia | 1:0a051df78be2 | 172 | |
Elecia | 1:0a051df78be2 | 173 | indexMask &= mLedPattern[mLedPatternConfig]; |
Elecia | 1:0a051df78be2 | 174 | if (indexMask) { // if this one set |
Elecia | 0:21fea82c85fc | 175 | thisOneOn = true; |
Elecia | 0:21fea82c85fc | 176 | } |
Elecia | 1:0a051df78be2 | 177 | if (thisOneOn) { |
Elecia | 0:21fea82c85fc | 178 | *out = GetCurrentColor(wireConfig); |
Elecia | 0:21fea82c85fc | 179 | } else { |
Elecia | 1:0a051df78be2 | 180 | AllOneColorLeds(out, index, COLOR_BLACK); |
Elecia | 0:21fea82c85fc | 181 | } |
Elecia | 1:0a051df78be2 | 182 | } |
Elecia | 1:0a051df78be2 | 183 | |
Elecia | 1:0a051df78be2 | 184 | |
Elecia | 1:0a051df78be2 | 185 | int main() |
Elecia | 1:0a051df78be2 | 186 | { |
Elecia | 1:0a051df78be2 | 187 | uint32_t ledColorWires; |
Elecia | 1:0a051df78be2 | 188 | uint32_t ledPatternConfig; |
Elecia | 0:21fea82c85fc | 189 | uint32_t ledBlinkConfig; |
Elecia | 1:0a051df78be2 | 190 | bool change = false; |
Elecia | 1:0a051df78be2 | 191 | AnalogIn analog (p20); |
Elecia | 1:0a051df78be2 | 192 | srand(analog*65535*analog); |
Elecia | 1:0a051df78be2 | 193 | |
Elecia | 0:21fea82c85fc | 194 | InitializePins(); |
Elecia | 1:0a051df78be2 | 195 | neopixel::PixelArray mPixelArray(p5); |
Elecia | 1:0a051df78be2 | 196 | LedArrayController ledArrayController(&mBlinkConfig, &mPixelArray); |
Elecia | 1:0a051df78be2 | 197 | |
Elecia | 1:0a051df78be2 | 198 | ledColorWires = mColorWires & mColorWires.mask(); |
Elecia | 1:0a051df78be2 | 199 | ledPatternConfig = mLedPatternConfig & mLedPatternConfig.mask(); |
Elecia | 1:0a051df78be2 | 200 | ledBlinkConfig = mBlinkConfig & mBlinkConfig.mask(); |
Elecia | 1:0a051df78be2 | 201 | ledArrayController.OnChangeMode(GetCurrentColorU32(ledColorWires)); |
Elecia | 1:0a051df78be2 | 202 | mPixelArray.update(SetLeds, NLED, ledColorWires); |
Elecia | 1:0a051df78be2 | 203 | |
Elecia | 1:0a051df78be2 | 204 | while (1) { |
Elecia | 1:0a051df78be2 | 205 | if ( |
Elecia | 1:0a051df78be2 | 206 | ( ledColorWires != ( mColorWires & mColorWires.mask() ) ) || |
Elecia | 1:0a051df78be2 | 207 | ( ledPatternConfig != ( mLedPatternConfig & mLedPatternConfig.mask() ) ) || |
Elecia | 1:0a051df78be2 | 208 | ( ledBlinkConfig != ( mBlinkConfig & mBlinkConfig.mask() ) ) ){ |
Elecia | 0:21fea82c85fc | 209 | change = true; |
Elecia | 0:21fea82c85fc | 210 | } |
Elecia | 1:0a051df78be2 | 211 | if (change) { |
Elecia | 0:21fea82c85fc | 212 | change = false; |
Elecia | 1:0a051df78be2 | 213 | |
Elecia | 1:0a051df78be2 | 214 | ledArrayController.Stop(); |
Elecia | 1:0a051df78be2 | 215 | OnChangeMode(&mPixelArray); |
Elecia | 1:0a051df78be2 | 216 | ledArrayController.OnChangeMode(GetCurrentColorU32(ledColorWires)); |
Elecia | 1:0a051df78be2 | 217 | |
Elecia | 1:0a051df78be2 | 218 | ledColorWires = mColorWires & mColorWires.mask(); |
Elecia | 1:0a051df78be2 | 219 | ledPatternConfig = mLedPatternConfig & mLedPatternConfig.mask(); |
Elecia | 1:0a051df78be2 | 220 | ledBlinkConfig = mBlinkConfig & mBlinkConfig.mask(); |
Elecia | 1:0a051df78be2 | 221 | |
Elecia | 1:0a051df78be2 | 222 | mPixelArray.update(SetLeds, NLED, ledColorWires); |
Elecia | 0:21fea82c85fc | 223 | } |
Elecia | 1:0a051df78be2 | 224 | |
Elecia | 1:0a051df78be2 | 225 | wait_ms(10); |
Elecia | 0:21fea82c85fc | 226 | } |
Elecia | 0:21fea82c85fc | 227 | } |