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

Dependencies:   PixelArray mbed

Committer:
Elecia
Date:
Sun May 15 18:06:06 2016 +0000
Revision:
0:21fea82c85fc
Child:
1:0a051df78be2
Blinking works, colors work. No speaker yet.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Elecia 0:21fea82c85fc 1 /*
Elecia 0:21fea82c85fc 2 Fist full of wires!
Elecia 0:21fea82c85fc 3 The intention here is to make a ball of wires that someone can reach in and
Elecia 0:21fea82c85fc 4 grab, changing the behavior of the system.
Elecia 0:21fea82c85fc 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 vibrate the motor
Elecia 0:21fea82c85fc 11 turn off all of the LEDs for a brief instant
Elecia 0:21fea82c85fc 12
Elecia 0:21fea82c85fc 13 Use the created variable to choose the neopixel pattern
Elecia 0:21fea82c85fc 14 and the sound pattern to output to the audio (intermittent beeps)
Elecia 0:21fea82c85fc 15
Elecia 0:21fea82c85fc 16
Elecia 0:21fea82c85fc 17 This program depends on neopixel library.
Elecia 0:21fea82c85fc 18 http://developer.mbed.org/users/JacobBramley/code/PixelArray/
Elecia 0:21fea82c85fc 19
Elecia 0:21fea82c85fc 20 Audio (R2D2 sounds) from Szilard Liptak:
Elecia 0:21fea82c85fc 21 https://developer.mbed.org/users/Szilard/notebook/mbed-r2d2-robot/
Elecia 0:21fea82c85fc 22 Sounds in general: https://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/
Elecia 0:21fea82c85fc 23
Elecia 0:21fea82c85fc 24 Todo:
Elecia 0:21fea82c85fc 25 Blinking needs a timer attachment
Elecia 0:21fea82c85fc 26
Elecia 0:21fea82c85fc 27
Elecia 0:21fea82c85fc 28
Elecia 0:21fea82c85fc 29 */
Elecia 0:21fea82c85fc 30 #include "mbed.h"
Elecia 0:21fea82c85fc 31 #include "neopixel.h"
Elecia 0:21fea82c85fc 32 #include "SongPlayer.h"
Elecia 0:21fea82c85fc 33
Elecia 0:21fea82c85fc 34 #include <stdlib.h> /* srand, rand */
Elecia 0:21fea82c85fc 35 #define NLED (8)
Elecia 0:21fea82c85fc 36 #define ONE_COLOR
Elecia 0:21fea82c85fc 37
Elecia 0:21fea82c85fc 38 BusIn mColorWires(
Elecia 0:21fea82c85fc 39 p20, p19, p18, p17, p16, p15 // six color, two each, RGB
Elecia 0:21fea82c85fc 40 );
Elecia 0:21fea82c85fc 41 BusIn mBlinkConfig(
Elecia 0:21fea82c85fc 42 p14, p13, p12, // three timing: indexes into mBlinkTiming
Elecia 0:21fea82c85fc 43 p30, p29 ); // two for blink type
Elecia 0:21fea82c85fc 44
Elecia 0:21fea82c85fc 45 typedef union {
Elecia 0:21fea82c85fc 46 struct
Elecia 0:21fea82c85fc 47 {
Elecia 0:21fea82c85fc 48 uint32_t green:2;
Elecia 0:21fea82c85fc 49 uint32_t blue:2;
Elecia 0:21fea82c85fc 50 uint32_t red:2;
Elecia 0:21fea82c85fc 51 uint32_t junk:26;
Elecia 0:21fea82c85fc 52 };
Elecia 0:21fea82c85fc 53 uint32_t value;
Elecia 0:21fea82c85fc 54 } tLedBehaviorWires;
Elecia 0:21fea82c85fc 55
Elecia 0:21fea82c85fc 56 BusIn mLedBitmask (p11, p10, p9, p8, p36, p35, p34, p33); // eight to for bitmask which LED indexes are on... this is not enough of a difference
Elecia 0:21fea82c85fc 57
Elecia 0:21fea82c85fc 58 #define COLOR_WHITE 0xFFFFFF
Elecia 0:21fea82c85fc 59 #define COLOR_BLACK 0x000000
Elecia 0:21fea82c85fc 60
Elecia 0:21fea82c85fc 61 void InitializePins(void);
Elecia 0:21fea82c85fc 62 void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color);
Elecia 0:21fea82c85fc 63 void OnChangeMode(neopixel::PixelArray array);
Elecia 0:21fea82c85fc 64 neopixel::Pixel GetCurrentColor(uint32_t wireConfig);
Elecia 0:21fea82c85fc 65 void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig);
Elecia 0:21fea82c85fc 66
Elecia 0:21fea82c85fc 67 class LedArrayController {
Elecia 0:21fea82c85fc 68 public:
Elecia 0:21fea82c85fc 69 LedArrayController(BusIn *bus, neopixel::PixelArray *array) : mBus(bus), mArray(array)
Elecia 0:21fea82c85fc 70 {
Elecia 0:21fea82c85fc 71 mBus->mode(PullUp);
Elecia 0:21fea82c85fc 72 srand (time(NULL));
Elecia 0:21fea82c85fc 73 }
Elecia 0:21fea82c85fc 74 void OnChangeMode(uint32_t baseColor)
Elecia 0:21fea82c85fc 75 {
Elecia 0:21fea82c85fc 76 // 000 001 010 011 100 101 110, 111
Elecia 0:21fea82c85fc 77 const float mBlinkTiming[] = {1.0, 0.1, 0.5, 0.0, 2.0, 0.0, 0.0, 5.0};
Elecia 0:21fea82c85fc 78 mBaseColor = baseColor;
Elecia 0:21fea82c85fc 79 mIsBaseColor = false;
Elecia 0:21fea82c85fc 80 mBehavior.value = *mBus;
Elecia 0:21fea82c85fc 81 Update();
Elecia 0:21fea82c85fc 82
Elecia 0:21fea82c85fc 83 mTiming = mBlinkTiming[mBehavior.timingIndex];
Elecia 0:21fea82c85fc 84 if (mTiming > 0.0f)
Elecia 0:21fea82c85fc 85 {
Elecia 0:21fea82c85fc 86 mTimer.attach(this, &LedArrayController::Update, mTiming);
Elecia 0:21fea82c85fc 87 } else {
Elecia 0:21fea82c85fc 88 mTimer.detach();
Elecia 0:21fea82c85fc 89 }
Elecia 0:21fea82c85fc 90 }
Elecia 0:21fea82c85fc 91 void Update() {
Elecia 0:21fea82c85fc 92 // called by timer for updating LEDs:
Elecia 0:21fea82c85fc 93 if (mIsBaseColor)
Elecia 0:21fea82c85fc 94 {
Elecia 0:21fea82c85fc 95 switch (mBehavior.type) {
Elecia 0:21fea82c85fc 96 case (BLINK_TO_WHITE):
Elecia 0:21fea82c85fc 97 mArray->update(AllOneColorLeds, NLED, COLOR_WHITE);
Elecia 0:21fea82c85fc 98 break;
Elecia 0:21fea82c85fc 99 case (BLINK_TO_BLACK):
Elecia 0:21fea82c85fc 100 mArray->update(AllOneColorLeds, NLED, COLOR_BLACK);
Elecia 0:21fea82c85fc 101 break;
Elecia 0:21fea82c85fc 102 case (BLINK_TO_RANDOM):
Elecia 0:21fea82c85fc 103 mArray->update(AllOneColorLeds, NLED, (rand() & COLOR_WHITE));
Elecia 0:21fea82c85fc 104 break;
Elecia 0:21fea82c85fc 105 case (BLINK_TO_OPPOSITE):
Elecia 0:21fea82c85fc 106 mArray->update(AllOneColorLeds, NLED, ~mBaseColor);
Elecia 0:21fea82c85fc 107 break;
Elecia 0:21fea82c85fc 108 }
Elecia 0:21fea82c85fc 109 mIsBaseColor = false;
Elecia 0:21fea82c85fc 110
Elecia 0:21fea82c85fc 111 } else {
Elecia 0:21fea82c85fc 112 // set to base color
Elecia 0:21fea82c85fc 113 mArray->update(AllOneColorLeds, NLED, mBaseColor);
Elecia 0:21fea82c85fc 114 mIsBaseColor = true;
Elecia 0:21fea82c85fc 115 }
Elecia 0:21fea82c85fc 116 mTimer.attach(this, &LedArrayController::Update, mTiming);
Elecia 0:21fea82c85fc 117
Elecia 0:21fea82c85fc 118 }
Elecia 0:21fea82c85fc 119 private:
Elecia 0:21fea82c85fc 120 float mTiming;
Elecia 0:21fea82c85fc 121 BusIn *mBus;
Elecia 0:21fea82c85fc 122 neopixel::PixelArray *mArray;
Elecia 0:21fea82c85fc 123 Timeout mTimer;
Elecia 0:21fea82c85fc 124 bool mIsBaseColor;
Elecia 0:21fea82c85fc 125 uint32_t mBaseColor;
Elecia 0:21fea82c85fc 126 typedef enum {BLINK_TO_WHITE=0, BLINK_TO_BLACK=1, BLINK_TO_RANDOM=2, BLINK_TO_OPPOSITE=3 } eBlinkType;
Elecia 0:21fea82c85fc 127 union {
Elecia 0:21fea82c85fc 128 struct {
Elecia 0:21fea82c85fc 129 uint32_t timingIndex:3;
Elecia 0:21fea82c85fc 130 uint32_t type:2;
Elecia 0:21fea82c85fc 131 uint32_t junk:28;
Elecia 0:21fea82c85fc 132 };
Elecia 0:21fea82c85fc 133 uint32_t value;
Elecia 0:21fea82c85fc 134 } mBehavior;
Elecia 0:21fea82c85fc 135 };
Elecia 0:21fea82c85fc 136
Elecia 0:21fea82c85fc 137
Elecia 0:21fea82c85fc 138 void InitializePins(void)
Elecia 0:21fea82c85fc 139 {
Elecia 0:21fea82c85fc 140 mColorWires.mode(PullUp);
Elecia 0:21fea82c85fc 141 mLedBitmask.mode(PullUp);
Elecia 0:21fea82c85fc 142 mBlinkConfig.mode(PullUp);
Elecia 0:21fea82c85fc 143 }
Elecia 0:21fea82c85fc 144
Elecia 0:21fea82c85fc 145 void OnChangeMode(neopixel::PixelArray array)
Elecia 0:21fea82c85fc 146 {
Elecia 0:21fea82c85fc 147 // FIXME play bzzzt sound
Elecia 0:21fea82c85fc 148
Elecia 0:21fea82c85fc 149 // all white, delay all black
Elecia 0:21fea82c85fc 150 array.update(AllOneColorLeds, NLED, COLOR_WHITE);
Elecia 0:21fea82c85fc 151 wait_ms(200);
Elecia 0:21fea82c85fc 152 array.update(AllOneColorLeds, NLED, COLOR_BLACK);
Elecia 0:21fea82c85fc 153 wait_ms(200);
Elecia 0:21fea82c85fc 154 // FIXME mBlinkTimer.detach(); // clear timer functionality
Elecia 0:21fea82c85fc 155 }
Elecia 0:21fea82c85fc 156
Elecia 0:21fea82c85fc 157 uint8_t MakeColorFromWires(uint32_t singleColorWireConfig)
Elecia 0:21fea82c85fc 158 {
Elecia 0:21fea82c85fc 159 uint8_t color;
Elecia 0:21fea82c85fc 160 if (singleColorWireConfig == 3u) { color = 0xFF; }
Elecia 0:21fea82c85fc 161 else if (singleColorWireConfig == 0u) { color = 0x00; }
Elecia 0:21fea82c85fc 162 else /* one bit on */ { color = 0x80; }
Elecia 0:21fea82c85fc 163 return color;
Elecia 0:21fea82c85fc 164 }
Elecia 0:21fea82c85fc 165
Elecia 0:21fea82c85fc 166 void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color)
Elecia 0:21fea82c85fc 167 {
Elecia 0:21fea82c85fc 168 out->red = (color >> 16) & 0xFF;
Elecia 0:21fea82c85fc 169 out->green = (color >> 8 ) & 0xFF;
Elecia 0:21fea82c85fc 170 out->blue = (color ) & 0xFF;
Elecia 0:21fea82c85fc 171 }
Elecia 0:21fea82c85fc 172
Elecia 0:21fea82c85fc 173 uint32_t GetCurrentColorU32(uint32_t wireConfig)
Elecia 0:21fea82c85fc 174 {
Elecia 0:21fea82c85fc 175 neopixel::Pixel pix;
Elecia 0:21fea82c85fc 176 uint32_t out;
Elecia 0:21fea82c85fc 177 pix = GetCurrentColor(wireConfig);
Elecia 0:21fea82c85fc 178 out = pix.blue + (pix.green << 8) + (pix.red << 16);
Elecia 0:21fea82c85fc 179 return out;
Elecia 0:21fea82c85fc 180 }
Elecia 0:21fea82c85fc 181
Elecia 0:21fea82c85fc 182
Elecia 0:21fea82c85fc 183 neopixel::Pixel GetCurrentColor(uint32_t wireConfig)
Elecia 0:21fea82c85fc 184 {
Elecia 0:21fea82c85fc 185 tLedBehaviorWires config;
Elecia 0:21fea82c85fc 186 neopixel::Pixel out;
Elecia 0:21fea82c85fc 187 config.value = wireConfig;
Elecia 0:21fea82c85fc 188 if ( (config.red == 0u) && (config.green == 0u) && (config.blue == 0u) )
Elecia 0:21fea82c85fc 189 {
Elecia 0:21fea82c85fc 190 out.red = 0x10u;
Elecia 0:21fea82c85fc 191 out.green = 0x10u;
Elecia 0:21fea82c85fc 192 out.blue = 0x10u;
Elecia 0:21fea82c85fc 193 } else {
Elecia 0:21fea82c85fc 194 out.red = MakeColorFromWires(config.red);
Elecia 0:21fea82c85fc 195 out.green = MakeColorFromWires(config.green);
Elecia 0:21fea82c85fc 196 out.blue = MakeColorFromWires(config.blue);
Elecia 0:21fea82c85fc 197 }
Elecia 0:21fea82c85fc 198 return out;
Elecia 0:21fea82c85fc 199 }
Elecia 0:21fea82c85fc 200 void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig)
Elecia 0:21fea82c85fc 201 {
Elecia 0:21fea82c85fc 202 bool thisOneOn = false;
Elecia 0:21fea82c85fc 203 uint32_t indexMask = 1u << index;
Elecia 0:21fea82c85fc 204
Elecia 0:21fea82c85fc 205 indexMask &= mLedBitmask;
Elecia 0:21fea82c85fc 206 if (indexMask) // if this one set
Elecia 0:21fea82c85fc 207 {
Elecia 0:21fea82c85fc 208 thisOneOn = true;
Elecia 0:21fea82c85fc 209 } else if (mLedBitmask == 0u) // all wires plugged in, let all LEDs turn on
Elecia 0:21fea82c85fc 210 {
Elecia 0:21fea82c85fc 211 thisOneOn = true;
Elecia 0:21fea82c85fc 212 }
Elecia 0:21fea82c85fc 213
Elecia 0:21fea82c85fc 214 if (thisOneOn)
Elecia 0:21fea82c85fc 215 {
Elecia 0:21fea82c85fc 216 *out = GetCurrentColor(wireConfig);
Elecia 0:21fea82c85fc 217 } else {
Elecia 0:21fea82c85fc 218 AllOneColorLeds(out, index, COLOR_BLACK);
Elecia 0:21fea82c85fc 219 }
Elecia 0:21fea82c85fc 220 }
Elecia 0:21fea82c85fc 221
Elecia 0:21fea82c85fc 222
Elecia 0:21fea82c85fc 223 int main() {
Elecia 0:21fea82c85fc 224 uint32_t ledBehaviorWires;
Elecia 0:21fea82c85fc 225 uint32_t ledBitMask;
Elecia 0:21fea82c85fc 226 uint32_t ledBlinkConfig;
Elecia 0:21fea82c85fc 227 bool change = true;
Elecia 0:21fea82c85fc 228 neopixel::PixelArray array(p5);
Elecia 0:21fea82c85fc 229 LedArrayController ledArrayController(&mBlinkConfig, &array);
Elecia 0:21fea82c85fc 230 // SongPlayer mySpeaker(p21);
Elecia 0:21fea82c85fc 231
Elecia 0:21fea82c85fc 232 InitializePins();
Elecia 0:21fea82c85fc 233
Elecia 0:21fea82c85fc 234 // float note[18]= {3520, 3135.96, 2637.02, 2093, 2349.32, 3951.07, 2793.83, 4186.01, 3520, 3135.96, 2637.02, 2093, 2349.32, 3951.07, 2793.83, 4186.01}; //R2D2 sound effect
Elecia 0:21fea82c85fc 235 // float duration[18]= {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}; //for a bit of variety, multiple sound samples could be chosen at random
Elecia 0:21fea82c85fc 236
Elecia 0:21fea82c85fc 237 // float note[18]= {1568.0,1396.9,1244.5,1244.5,1396.9,1568.0,1568.0,1568.0,1396.9,
Elecia 0:21fea82c85fc 238 // 1244.5,1396.9,1568.0,1396.9,1244.5,1174.7,1244.5,1244.5, 0.0
Elecia 0:21fea82c85fc 239 // };
Elecia 0:21fea82c85fc 240 //float duration[18]= {0.48,0.24,0.72,0.48,0.24,0.48,0.24,0.24,0.24,
Elecia 0:21fea82c85fc 241 // 0.24,0.24,0.24,0.24,0.48,0.24,0.48,0.48, 0.0
Elecia 0:21fea82c85fc 242 // };
Elecia 0:21fea82c85fc 243
Elecia 0:21fea82c85fc 244 // uint32_t val = 0;
Elecia 0:21fea82c85fc 245 while (1)
Elecia 0:21fea82c85fc 246 {
Elecia 0:21fea82c85fc 247 if ((ledBehaviorWires != mColorWires) ||
Elecia 0:21fea82c85fc 248 (ledBitMask != mLedBitmask) ||
Elecia 0:21fea82c85fc 249 (ledBlinkConfig != mBlinkConfig) )
Elecia 0:21fea82c85fc 250 {
Elecia 0:21fea82c85fc 251 change = true;
Elecia 0:21fea82c85fc 252 }
Elecia 0:21fea82c85fc 253 if (change)
Elecia 0:21fea82c85fc 254 {
Elecia 0:21fea82c85fc 255 change = false;
Elecia 0:21fea82c85fc 256 ledBehaviorWires = mColorWires;
Elecia 0:21fea82c85fc 257 ledBitMask = mLedBitmask;
Elecia 0:21fea82c85fc 258 ledBlinkConfig = mBlinkConfig;
Elecia 0:21fea82c85fc 259 ledArrayController.OnChangeMode(GetCurrentColorU32(ledBehaviorWires));
Elecia 0:21fea82c85fc 260 // OnChangeMode(array);
Elecia 0:21fea82c85fc 261
Elecia 0:21fea82c85fc 262 array.update(SetLeds, NLED, ledBehaviorWires);
Elecia 0:21fea82c85fc 263 }
Elecia 0:21fea82c85fc 264
Elecia 0:21fea82c85fc 265 // mySpeaker.PlaySong(note,duration); //play R2D2 sound effects
Elecia 0:21fea82c85fc 266 wait_ms(10);
Elecia 0:21fea82c85fc 267 }
Elecia 0:21fea82c85fc 268 }