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

main.cpp

Committer:
Elecia
Date:
2016-05-25
Revision:
1:0a051df78be2
Parent:
0:21fea82c85fc

File content as of revision 1:0a051df78be2:

/*
  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
        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 using an Adafruit sound fx board
  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/

*/
#include "mbed.h"
#include "neopixel.h"
#include "LedArrayController.h"

#include <stdlib.h>     /* srand, rand */


BusIn mColorWires(
    p22, p19, p18, p21, p16, p15    // six color, two each, RGB
);
typedef union {
    struct {
        uint32_t green:2;
        uint32_t blue:2;
        uint32_t red:2;
        uint32_t junk:26;
    };
    uint32_t value;
} tledColorWires;

BusIn mBlinkConfig(
    p14, p13, p20,                  // three timing: indexes into mBlinkTiming
    p30, p29 );                     // two for blink type

Serial SerialToAudio(p9, p10); // tx, rx

BusIn mLedPatternConfig (p23, p35, p36);
                        // 000   001   010  011   100    101   110 111
uint8_t mLedPattern[] = { 0x01, 0xF0, 0x0F, 0xAA, 0x55, 0x0F, 0xF0, 0xFF };


char *mAudioPlaylist[] = {
     "PBITEDUSTOGG\n" ,  // another one bites the dust
     "PDANGW   OGG\n" ,     // danger will robinson
     "PHASTA   OGG\n" ,     // hasta la vista baby
     "PHELPME  OGG\n" ,    // help me obiwan kenobi, you are my only hope
     "PNODISA  OGG\n" ,  // no disassembly
     "PNOESCAPEOGG\n" ,  // there'll be no escape for the princess this time
     "POMG     OGG\n" ,  // Oh my god (bender)
     "PPRESSUREOGG\n" ,   // simpsons bomb disposal robot
     "PSTILLALIOGG\n" ,  // this was a triumph
     "PLAUGH   OGG\n" ,     // robo laugh
     "PCOMPUTE OGG\n" ,   // does not compute
     "PEMBEDDEDOGG\n" ,   // embedded.fm
     };
   
int mNumAudioInPlaylist = 12;

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);


void InitializePins(void)
{
    mColorWires.mode(PullUp);
    mLedPatternConfig.mode(PullUp);
    mBlinkConfig.mode(PullUp);
    SerialToAudio.baud(9600);        
}

void OnChangeMode(neopixel::PixelArray *array)
{
    // all black, zap, then white
    array->update(SetLeds, NLED, COLOR_BLACK);

    SerialToAudio.printf("Q\n");
    SerialToAudio.printf("q\n");
    wait_ms(50);
    // P and then the file name zap.ogg with no dot
    SerialToAudio.printf("PZAP     OGG\n");
    wait_ms(350);
    array->update(SetLeds, NLED, COLOR_WHITE);
    wait_ms(100);
    SerialToAudio.printf("Q\n");
    SerialToAudio.printf("q\n");
    wait_ms(500);    
    int audioListIndex = rand() % mNumAudioInPlaylist;
    SerialToAudio.printf(mAudioPlaylist[audioListIndex]);
}

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)
{
    bool thisOneOn = false;
    uint32_t indexMask = 1u << index;
    indexMask &= mLedPattern[mLedPatternConfig];

    if ( (color == COLOR_BLACK) || (color == COLOR_WHITE) )
    {
        thisOneOn = true;
}    
    if (indexMask) { // if this one set
        thisOneOn = true;
    }

    if (thisOneOn) 
    {
        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)
{
    tledColorWires 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 &= mLedPattern[mLedPatternConfig];
    if (indexMask) { // if this one set
        thisOneOn = true;
    }
    if (thisOneOn) {
        *out = GetCurrentColor(wireConfig);
    } else {
        AllOneColorLeds(out, index, COLOR_BLACK);
    }
}


int main()
{
    uint32_t ledColorWires;
    uint32_t ledPatternConfig;
    uint32_t ledBlinkConfig;
    bool change = false;
    AnalogIn analog (p20);
    srand(analog*65535*analog);

    InitializePins();
    neopixel::PixelArray mPixelArray(p5);
    LedArrayController ledArrayController(&mBlinkConfig, &mPixelArray);

    ledColorWires    = mColorWires       & mColorWires.mask();
    ledPatternConfig = mLedPatternConfig & mLedPatternConfig.mask();
    ledBlinkConfig   = mBlinkConfig      & mBlinkConfig.mask();
    ledArrayController.OnChangeMode(GetCurrentColorU32(ledColorWires));
    mPixelArray.update(SetLeds, NLED, ledColorWires);

    while (1) {
        if ( 
        ( ledColorWires    != ( mColorWires       & mColorWires.mask()       ) )  ||
        ( ledPatternConfig != ( mLedPatternConfig & mLedPatternConfig.mask() ) )  ||
        ( ledBlinkConfig   != ( mBlinkConfig      & mBlinkConfig.mask()      ) )  ){
            change = true;
        }
        if (change) {
            change = false;

            ledArrayController.Stop();
            OnChangeMode(&mPixelArray);
            ledArrayController.OnChangeMode(GetCurrentColorU32(ledColorWires));

            ledColorWires    = mColorWires       & mColorWires.mask();
            ledPatternConfig = mLedPatternConfig & mLedPatternConfig.mask();
            ledBlinkConfig   = mBlinkConfig      & mBlinkConfig.mask();

            mPixelArray.update(SetLeds, NLED, ledColorWires);
        }

        wait_ms(10);
    }
}