Source code for the Curilights Controller. See http://www.saccade.com/writing/projects/CuriController/ for details.
Dependencies: FatFileSystem mbed
This is the source code for the Curilights controller. This lets you interactively control a string of Curilights. It provides a simple click-wheel user interface for changing colors, brightness and behavior. It responds to movement and lighting.
Finished Controller
System Block Diagram
main.cpp
- Committer:
- isonno
- Date:
- 2012-01-16
- Revision:
- 2:965388eecf95
- Parent:
- 1:d1da77023e6a
File content as of revision 2:965388eecf95:
// // CuriLights Controller firmware // #include "mbed.h" // Lives in http://mbed.org/projects/libraries/svn/mbed/trunk #include "SerialConnect.h" #include "ZMotionDetector.h" #include "SDFileSystem.h" #include "NokiaLCD.h" #include "RotaryEncoder.h" #include "HoldInterrupts.h" #include "PinDetect.h" #include "LightString.h" #include "PushButton.h" #include "SystemState.h" #include "UserInterface.h" #include "SettingsMenu.h" #include "RGBLED.h" #include <string> // Blinking LEDs on the mbed board are used // for light/motion sensor diagnostics const int NumLEDs = 4; DigitalOut leds[NumLEDs] = { DigitalOut(LED1), DigitalOut(LED2), DigitalOut(LED3), DigitalOut(LED4) }; void cycleLEDs() { static int curLED = 0; leds[curLED] = 0; curLED = (curLED + 1) % NumLEDs; leds[curLED] = 1; } // Light sensor wrapper class LightSensor { public: LightSensor() : fLightPin( p19 ) {}; // int light() { return (int)(fLightPin.read() * 1000); } int32_t light() {HoldInterrupts noirq; float a = fLightPin.read(); return (int)(a * 1000); } private: AnalogIn fLightPin; }; // This is a version of Timeout that you simply // poll to see if the timeout is still in effect class MotionDelay : public Timeout { public: MotionDelay() : Timeout() { fWaiting = false; } bool IsWaiting() { return fWaiting; } void Start( int seconds ) { detach(); // Reset the time attach( this, &MotionDelay::Completed, seconds ); fWaiting = true; } private: void Completed() { fWaiting = false; } bool fWaiting; }; // We want to be able to download files over USB, but only // look for them on the SD Card. So at startup, we move // any .CRI files found on the local drive to the SD card. void CopyPatternFilesToSD() { SDFileSystem sdcard( p5, p6, p7, p8, "sdcard" ); LocalFileSystem local("local"); DIR * localDir = opendir("/local"); struct dirent *p; while ((p = readdir( localDir )) != NULL) { string srcName = string("/local/") + string(p->d_name); printf("Examining %s\r\n", srcName.c_str() ); if (srcName.rfind( ".CRI") != string::npos) { printf("Copying %s to SD Card\r\n", srcName.c_str()); string dstName = string("/sdcard/") + string(p->d_name); FILE * src = fopen( srcName.c_str(), "rb" ); FILE * dst = fopen( dstName.c_str(), "wb" ); if (!src) { printf("Can't open: %s\r\n", srcName.c_str() ); continue; } if (!dst) { printf("Can't open %s\r\n", dstName.c_str() ); fclose( src ); continue; } // Copy the data while (! feof(src)) { char buffer[1024]; uint32_t numRead = fread( buffer, 1, sizeof( buffer ), src ); fwrite( buffer, 1, numRead, dst ); } fclose(src); fclose(dst); remove(srcName.c_str()); // Wham! We only look for these on the sdcard } } } RGBLED gDebugLED( p22, p23, p24 ); void CheckDownloadedPattern( LightString& lightString ) { static time_t activeTime; static bool active = false; bool nowActive = lightString.Snoop()->IsActive(); static bool saved = false; int lightValue = 0; if (active) lightValue = 700; if (saved) lightValue += 70; if (nowActive) lightValue += 7; gDebugLED.Set( lightValue ); if (!active && nowActive) { activeTime = time( NULL ); active = true; } else if (active && nowActive) { activeTime = time( NULL ); } else if (active && !nowActive && (time( NULL ) - activeTime > 2)) { active = false; lightString.Snoop()->SaveSnoop(); saved = true; } } int main() { printf("Welcome\r\n"); CopyPatternFilesToSD(); gSystemState.LoadState(); // Create hardware objects CheapLCD lcd( p11, p13, p14, p12 ); // mosi, sclk, cs, rst lcd.erase(); lcd.switch_backlight( true ); ZMotionDetector mdetect( p28, p27 ); mdetect.SetExtendedRange( true ); leds[0] = leds[1] = leds[2] = leds[3] = 0; leds[0] = 1; LightString curiLights( p9, 58 ); leds[1] = 1; curiLights.InitLights(); leds[2] = 1; curiLights.AttachUSBSerial(); leds[3] = 1; RotaryEncoder knob( p17, p18 ); PushButton knobButton( p30, "Knob" ); LightSensor lightSensor; MotionDelay motionDelay; // Set up the User Interface HomeMenu homeMenu( &lcd, &curiLights ); homeMenu.ConnectDevices( &knob, &knobButton ); homeMenu.Display( true ); // Infinite loop watches the light sensor and // the motion detector. All other input is // handled via interrupts. leds[0] = leds[1] = leds[2] = leds[3] = 0; gDebugLED.Set(0); while(1) { cycleLEDs(); wait(lightSensor.light() * 0.0004 ); // printf( "LightSensor: %d\r\n", lightSensor.light() ); // CheckDownloadedPattern( curiLights ); homeMenu.SetLightsOn( (lightSensor.light() < 800) || motionDelay.IsWaiting() ); if (mdetect.IsMotionDetected()) { motionDelay.Start( 10 ); leds[0] = 1; leds[1] = 1; leds[2] = 1; leds[3] = 1; wait(0.6); } } }