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
- Committer:
- Elecia
- Date:
- 2016-05-15
- Revision:
- 0:21fea82c85fc
- Child:
- 1:0a051df78be2
File content as of revision 0:21fea82c85fc:
/* Fist full of wires! The intention here is to make a ball of wires that someone can reach in and grab, changing the behavior of the system. So we read in the free IO lines, build up a variable. If it has changed, do the change actions: make a bzzzzt sound vibrate the motor turn off all of the LEDs for a brief instant Use the created variable to choose the neopixel pattern and the sound pattern to output to the audio (intermittent beeps) This program depends on neopixel library. http://developer.mbed.org/users/JacobBramley/code/PixelArray/ Audio (R2D2 sounds) from Szilard Liptak: https://developer.mbed.org/users/Szilard/notebook/mbed-r2d2-robot/ Sounds in general: https://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/ Todo: Blinking needs a timer attachment */ #include "mbed.h" #include "neopixel.h" #include "SongPlayer.h" #include <stdlib.h> /* srand, rand */ #define NLED (8) #define ONE_COLOR BusIn mColorWires( p20, p19, p18, p17, p16, p15 // six color, two each, RGB ); BusIn mBlinkConfig( p14, p13, p12, // three timing: indexes into mBlinkTiming p30, p29 ); // two for blink type typedef union { struct { uint32_t green:2; uint32_t blue:2; uint32_t red:2; uint32_t junk:26; }; uint32_t value; } tLedBehaviorWires; 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 #define COLOR_WHITE 0xFFFFFF #define COLOR_BLACK 0x000000 void InitializePins(void); void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color); void OnChangeMode(neopixel::PixelArray array); neopixel::Pixel GetCurrentColor(uint32_t wireConfig); void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig); class LedArrayController { public: LedArrayController(BusIn *bus, neopixel::PixelArray *array) : mBus(bus), mArray(array) { mBus->mode(PullUp); srand (time(NULL)); } void OnChangeMode(uint32_t baseColor) { // 000 001 010 011 100 101 110, 111 const float mBlinkTiming[] = {1.0, 0.1, 0.5, 0.0, 2.0, 0.0, 0.0, 5.0}; mBaseColor = baseColor; mIsBaseColor = false; mBehavior.value = *mBus; Update(); mTiming = mBlinkTiming[mBehavior.timingIndex]; if (mTiming > 0.0f) { mTimer.attach(this, &LedArrayController::Update, mTiming); } else { mTimer.detach(); } } void Update() { // called by timer for updating LEDs: if (mIsBaseColor) { switch (mBehavior.type) { case (BLINK_TO_WHITE): mArray->update(AllOneColorLeds, NLED, COLOR_WHITE); break; case (BLINK_TO_BLACK): mArray->update(AllOneColorLeds, NLED, COLOR_BLACK); break; case (BLINK_TO_RANDOM): mArray->update(AllOneColorLeds, NLED, (rand() & COLOR_WHITE)); break; case (BLINK_TO_OPPOSITE): mArray->update(AllOneColorLeds, NLED, ~mBaseColor); break; } mIsBaseColor = false; } else { // set to base color mArray->update(AllOneColorLeds, NLED, mBaseColor); mIsBaseColor = true; } mTimer.attach(this, &LedArrayController::Update, mTiming); } private: float mTiming; BusIn *mBus; neopixel::PixelArray *mArray; Timeout mTimer; bool mIsBaseColor; uint32_t mBaseColor; typedef enum {BLINK_TO_WHITE=0, BLINK_TO_BLACK=1, BLINK_TO_RANDOM=2, BLINK_TO_OPPOSITE=3 } eBlinkType; union { struct { uint32_t timingIndex:3; uint32_t type:2; uint32_t junk:28; }; uint32_t value; } mBehavior; }; void InitializePins(void) { mColorWires.mode(PullUp); mLedBitmask.mode(PullUp); mBlinkConfig.mode(PullUp); } void OnChangeMode(neopixel::PixelArray array) { // FIXME play bzzzt sound // all white, delay all black array.update(AllOneColorLeds, NLED, COLOR_WHITE); wait_ms(200); array.update(AllOneColorLeds, NLED, COLOR_BLACK); wait_ms(200); // FIXME mBlinkTimer.detach(); // clear timer functionality } uint8_t MakeColorFromWires(uint32_t singleColorWireConfig) { uint8_t color; if (singleColorWireConfig == 3u) { color = 0xFF; } else if (singleColorWireConfig == 0u) { color = 0x00; } else /* one bit on */ { color = 0x80; } return color; } void AllOneColorLeds(neopixel::Pixel * out, uint32_t index, uintptr_t color) { out->red = (color >> 16) & 0xFF; out->green = (color >> 8 ) & 0xFF; out->blue = (color ) & 0xFF; } uint32_t GetCurrentColorU32(uint32_t wireConfig) { neopixel::Pixel pix; uint32_t out; pix = GetCurrentColor(wireConfig); out = pix.blue + (pix.green << 8) + (pix.red << 16); return out; } neopixel::Pixel GetCurrentColor(uint32_t wireConfig) { tLedBehaviorWires config; neopixel::Pixel out; config.value = wireConfig; if ( (config.red == 0u) && (config.green == 0u) && (config.blue == 0u) ) { out.red = 0x10u; out.green = 0x10u; out.blue = 0x10u; } else { out.red = MakeColorFromWires(config.red); out.green = MakeColorFromWires(config.green); out.blue = MakeColorFromWires(config.blue); } return out; } void SetLeds(neopixel::Pixel * out, uint32_t index, uintptr_t wireConfig) { bool thisOneOn = false; uint32_t indexMask = 1u << index; indexMask &= mLedBitmask; if (indexMask) // if this one set { thisOneOn = true; } else if (mLedBitmask == 0u) // all wires plugged in, let all LEDs turn on { thisOneOn = true; } if (thisOneOn) { *out = GetCurrentColor(wireConfig); } else { AllOneColorLeds(out, index, COLOR_BLACK); } } int main() { uint32_t ledBehaviorWires; uint32_t ledBitMask; uint32_t ledBlinkConfig; bool change = true; neopixel::PixelArray array(p5); LedArrayController ledArrayController(&mBlinkConfig, &array); // SongPlayer mySpeaker(p21); InitializePins(); // 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 // 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 // float note[18]= {1568.0,1396.9,1244.5,1244.5,1396.9,1568.0,1568.0,1568.0,1396.9, // 1244.5,1396.9,1568.0,1396.9,1244.5,1174.7,1244.5,1244.5, 0.0 // }; //float duration[18]= {0.48,0.24,0.72,0.48,0.24,0.48,0.24,0.24,0.24, // 0.24,0.24,0.24,0.24,0.48,0.24,0.48,0.48, 0.0 // }; // uint32_t val = 0; while (1) { if ((ledBehaviorWires != mColorWires) || (ledBitMask != mLedBitmask) || (ledBlinkConfig != mBlinkConfig) ) { change = true; } if (change) { change = false; ledBehaviorWires = mColorWires; ledBitMask = mLedBitmask; ledBlinkConfig = mBlinkConfig; ledArrayController.OnChangeMode(GetCurrentColorU32(ledBehaviorWires)); // OnChangeMode(array); array.update(SetLeds, NLED, ledBehaviorWires); } // mySpeaker.PlaySong(note,duration); //play R2D2 sound effects wait_ms(10); } }