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

/media/uploads/isonno/nxp3872_controllerclose.jpg

System Block Diagram

/media/uploads/isonno/blockdiagram.png

Committer:
isonno
Date:
Mon Feb 11 05:04:18 2013 +0000
Revision:
4:cfef06d8bb96
Parent:
3:0ac64c4ca40f
Minor changes to add backlight routines.  Not hooked up yet, shouldn't affect build operation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
isonno 0:6da5625a6946 1 //
isonno 0:6da5625a6946 2 // CuriLights Controller firmware
isonno 0:6da5625a6946 3 //
isonno 0:6da5625a6946 4
isonno 0:6da5625a6946 5 #include "mbed.h" // Lives in http://mbed.org/projects/libraries/svn/mbed/trunk
isonno 0:6da5625a6946 6
isonno 0:6da5625a6946 7 #include "SerialConnect.h"
isonno 0:6da5625a6946 8 #include "ZMotionDetector.h"
isonno 0:6da5625a6946 9 #include "SDFileSystem.h"
isonno 0:6da5625a6946 10 #include "NokiaLCD.h"
isonno 0:6da5625a6946 11 #include "RotaryEncoder.h"
isonno 0:6da5625a6946 12 #include "HoldInterrupts.h"
isonno 0:6da5625a6946 13 #include "PinDetect.h"
isonno 0:6da5625a6946 14 #include "LightString.h"
isonno 0:6da5625a6946 15 #include "PushButton.h"
isonno 0:6da5625a6946 16 #include "SystemState.h"
isonno 0:6da5625a6946 17 #include "UserInterface.h"
isonno 1:d1da77023e6a 18 #include "SettingsMenu.h"
isonno 0:6da5625a6946 19
isonno 0:6da5625a6946 20 #include "RGBLED.h"
isonno 3:0ac64c4ca40f 21 #include "DebugLED.h"
isonno 0:6da5625a6946 22
isonno 0:6da5625a6946 23 #include <string>
isonno 0:6da5625a6946 24
isonno 0:6da5625a6946 25 // Light sensor wrapper
isonno 0:6da5625a6946 26 class LightSensor
isonno 0:6da5625a6946 27 {
isonno 0:6da5625a6946 28 public:
isonno 0:6da5625a6946 29 LightSensor() : fLightPin( p19 ) {};
isonno 0:6da5625a6946 30
isonno 0:6da5625a6946 31 // int light() { return (int)(fLightPin.read() * 1000); }
isonno 3:0ac64c4ca40f 32 int32_t light() {volatile float a = fLightPin.read(); return (int)(a * 1000); }
isonno 0:6da5625a6946 33
isonno 0:6da5625a6946 34 private:
isonno 0:6da5625a6946 35 AnalogIn fLightPin;
isonno 0:6da5625a6946 36 };
isonno 0:6da5625a6946 37
isonno 0:6da5625a6946 38 // This is a version of Timeout that you simply
isonno 0:6da5625a6946 39 // poll to see if the timeout is still in effect
isonno 0:6da5625a6946 40 class MotionDelay : public Timeout
isonno 0:6da5625a6946 41 {
isonno 0:6da5625a6946 42 public:
isonno 0:6da5625a6946 43 MotionDelay() : Timeout()
isonno 0:6da5625a6946 44 { fWaiting = false; }
isonno 0:6da5625a6946 45
isonno 0:6da5625a6946 46 bool IsWaiting() { return fWaiting; }
isonno 0:6da5625a6946 47
isonno 0:6da5625a6946 48 void Start( int seconds )
isonno 0:6da5625a6946 49 {
isonno 0:6da5625a6946 50 detach(); // Reset the time
isonno 0:6da5625a6946 51 attach( this, &MotionDelay::Completed, seconds );
isonno 0:6da5625a6946 52 fWaiting = true;
isonno 0:6da5625a6946 53 }
isonno 0:6da5625a6946 54
isonno 0:6da5625a6946 55 private:
isonno 0:6da5625a6946 56 void Completed() { fWaiting = false; }
isonno 0:6da5625a6946 57
isonno 0:6da5625a6946 58 bool fWaiting;
isonno 0:6da5625a6946 59 };
isonno 0:6da5625a6946 60
isonno 0:6da5625a6946 61 // We want to be able to download files over USB, but only
isonno 0:6da5625a6946 62 // look for them on the SD Card. So at startup, we move
isonno 0:6da5625a6946 63 // any .CRI files found on the local drive to the SD card.
isonno 0:6da5625a6946 64 void CopyPatternFilesToSD()
isonno 0:6da5625a6946 65 {
isonno 0:6da5625a6946 66 SDFileSystem sdcard( p5, p6, p7, p8, "sdcard" );
isonno 0:6da5625a6946 67 LocalFileSystem local("local");
isonno 0:6da5625a6946 68
isonno 0:6da5625a6946 69 DIR * localDir = opendir("/local");
isonno 0:6da5625a6946 70
isonno 0:6da5625a6946 71 struct dirent *p;
isonno 0:6da5625a6946 72
isonno 0:6da5625a6946 73 while ((p = readdir( localDir )) != NULL)
isonno 0:6da5625a6946 74 {
isonno 0:6da5625a6946 75 string srcName = string("/local/") + string(p->d_name);
isonno 0:6da5625a6946 76 printf("Examining %s\r\n", srcName.c_str() );
isonno 0:6da5625a6946 77 if (srcName.rfind( ".CRI") != string::npos)
isonno 0:6da5625a6946 78 {
isonno 0:6da5625a6946 79 printf("Copying %s to SD Card\r\n", srcName.c_str());
isonno 0:6da5625a6946 80
isonno 0:6da5625a6946 81 string dstName = string("/sdcard/") + string(p->d_name);
isonno 0:6da5625a6946 82
isonno 0:6da5625a6946 83 FILE * src = fopen( srcName.c_str(), "rb" );
isonno 0:6da5625a6946 84 FILE * dst = fopen( dstName.c_str(), "wb" );
isonno 0:6da5625a6946 85
isonno 0:6da5625a6946 86 if (!src)
isonno 0:6da5625a6946 87 {
isonno 0:6da5625a6946 88 printf("Can't open: %s\r\n", srcName.c_str() );
isonno 0:6da5625a6946 89 continue;
isonno 0:6da5625a6946 90 }
isonno 0:6da5625a6946 91 if (!dst)
isonno 0:6da5625a6946 92 {
isonno 0:6da5625a6946 93 printf("Can't open %s\r\n", dstName.c_str() );
isonno 0:6da5625a6946 94 fclose( src );
isonno 0:6da5625a6946 95 continue;
isonno 0:6da5625a6946 96 }
isonno 0:6da5625a6946 97
isonno 0:6da5625a6946 98 // Copy the data
isonno 0:6da5625a6946 99 while (! feof(src))
isonno 0:6da5625a6946 100 {
isonno 0:6da5625a6946 101 char buffer[1024];
isonno 0:6da5625a6946 102 uint32_t numRead = fread( buffer, 1, sizeof( buffer ), src );
isonno 0:6da5625a6946 103 fwrite( buffer, 1, numRead, dst );
isonno 0:6da5625a6946 104 }
isonno 0:6da5625a6946 105 fclose(src);
isonno 0:6da5625a6946 106 fclose(dst);
isonno 0:6da5625a6946 107 remove(srcName.c_str()); // Wham! We only look for these on the sdcard
isonno 0:6da5625a6946 108 }
isonno 0:6da5625a6946 109 }
isonno 0:6da5625a6946 110 }
isonno 0:6da5625a6946 111
isonno 0:6da5625a6946 112 RGBLED gDebugLED( p22, p23, p24 );
isonno 0:6da5625a6946 113
isonno 0:6da5625a6946 114 void CheckDownloadedPattern( LightString& lightString )
isonno 0:6da5625a6946 115 {
isonno 0:6da5625a6946 116 static time_t activeTime;
isonno 0:6da5625a6946 117 static bool active = false;
isonno 0:6da5625a6946 118 bool nowActive = lightString.Snoop()->IsActive();
isonno 0:6da5625a6946 119 static bool saved = false;
isonno 0:6da5625a6946 120
isonno 0:6da5625a6946 121
isonno 0:6da5625a6946 122 int lightValue = 0;
isonno 0:6da5625a6946 123
isonno 0:6da5625a6946 124 if (active)
isonno 0:6da5625a6946 125 lightValue = 700;
isonno 0:6da5625a6946 126
isonno 0:6da5625a6946 127 if (saved)
isonno 0:6da5625a6946 128 lightValue += 70;
isonno 0:6da5625a6946 129
isonno 0:6da5625a6946 130 if (nowActive)
isonno 0:6da5625a6946 131 lightValue += 7;
isonno 0:6da5625a6946 132
isonno 0:6da5625a6946 133 gDebugLED.Set( lightValue );
isonno 0:6da5625a6946 134
isonno 0:6da5625a6946 135 if (!active && nowActive)
isonno 0:6da5625a6946 136 {
isonno 0:6da5625a6946 137 activeTime = time( NULL );
isonno 0:6da5625a6946 138 active = true;
isonno 0:6da5625a6946 139 }
isonno 0:6da5625a6946 140 else
isonno 0:6da5625a6946 141 if (active && nowActive)
isonno 0:6da5625a6946 142 {
isonno 0:6da5625a6946 143 activeTime = time( NULL );
isonno 0:6da5625a6946 144 }
isonno 0:6da5625a6946 145 else
isonno 0:6da5625a6946 146 if (active && !nowActive
isonno 0:6da5625a6946 147 && (time( NULL ) - activeTime > 2))
isonno 0:6da5625a6946 148 {
isonno 0:6da5625a6946 149 active = false;
isonno 0:6da5625a6946 150 lightString.Snoop()->SaveSnoop();
isonno 0:6da5625a6946 151 saved = true;
isonno 0:6da5625a6946 152 }
isonno 0:6da5625a6946 153 }
isonno 0:6da5625a6946 154
isonno 0:6da5625a6946 155 int main() {
isonno 0:6da5625a6946 156 printf("Welcome\r\n");
isonno 0:6da5625a6946 157 CopyPatternFilesToSD();
isonno 0:6da5625a6946 158
isonno 0:6da5625a6946 159 gSystemState.LoadState();
isonno 0:6da5625a6946 160
isonno 0:6da5625a6946 161 // Create hardware objects
isonno 0:6da5625a6946 162
isonno 0:6da5625a6946 163 CheapLCD lcd( p11, p13, p14, p12 ); // mosi, sclk, cs, rst
isonno 0:6da5625a6946 164
isonno 0:6da5625a6946 165 lcd.erase();
isonno 0:6da5625a6946 166 lcd.switch_backlight( true );
isonno 0:6da5625a6946 167
isonno 0:6da5625a6946 168 ZMotionDetector mdetect( p28, p27 );
isonno 0:6da5625a6946 169 mdetect.SetExtendedRange( true );
isonno 0:6da5625a6946 170
isonno 0:6da5625a6946 171 LightString curiLights( p9, 58 );
isonno 0:6da5625a6946 172 curiLights.InitLights();
isonno 0:6da5625a6946 173
isonno 0:6da5625a6946 174 RotaryEncoder knob( p17, p18 );
isonno 0:6da5625a6946 175 PushButton knobButton( p30, "Knob" );
isonno 0:6da5625a6946 176
isonno 0:6da5625a6946 177 LightSensor lightSensor;
isonno 0:6da5625a6946 178 MotionDelay motionDelay;
isonno 0:6da5625a6946 179
isonno 0:6da5625a6946 180 // Set up the User Interface
isonno 0:6da5625a6946 181 HomeMenu homeMenu( &lcd, &curiLights );
isonno 0:6da5625a6946 182 homeMenu.ConnectDevices( &knob, &knobButton );
isonno 0:6da5625a6946 183 homeMenu.Display( true );
isonno 0:6da5625a6946 184
isonno 0:6da5625a6946 185 // Infinite loop watches the light sensor and
isonno 0:6da5625a6946 186 // the motion detector. All other input is
isonno 0:6da5625a6946 187 // handled via interrupts.
isonno 0:6da5625a6946 188
isonno 3:0ac64c4ca40f 189 gLeds[0] = gLeds[1] = gLeds[2] = gLeds[3] = 0;
isonno 0:6da5625a6946 190 gDebugLED.Set(0);
isonno 0:6da5625a6946 191
isonno 0:6da5625a6946 192 while(1) {
isonno 0:6da5625a6946 193 cycleLEDs();
isonno 0:6da5625a6946 194 wait(lightSensor.light() * 0.0004 );
isonno 0:6da5625a6946 195 // printf( "LightSensor: %d\r\n", lightSensor.light() );
isonno 0:6da5625a6946 196
isonno 0:6da5625a6946 197 // CheckDownloadedPattern( curiLights );
isonno 3:0ac64c4ca40f 198 // If the lightSensor shows enough light, OR the light sensor is disabled.
isonno 3:0ac64c4ca40f 199 bool lightSensorState = (lightSensor.light() < 800) || (gSystemState.GetLightSensor() == 0);
isonno 0:6da5625a6946 200
isonno 3:0ac64c4ca40f 201 homeMenu.SetLightsOn( lightSensorState || motionDelay.IsWaiting() );
isonno 0:6da5625a6946 202
isonno 0:6da5625a6946 203 if (mdetect.IsMotionDetected())
isonno 0:6da5625a6946 204 {
isonno 0:6da5625a6946 205 motionDelay.Start( 10 );
isonno 3:0ac64c4ca40f 206 gLeds[0] = 1; gLeds[1] = 1; gLeds[2] = 1; gLeds[3] = 1;
isonno 0:6da5625a6946 207 wait(0.6);
isonno 0:6da5625a6946 208 }
isonno 3:0ac64c4ca40f 209
isonno 3:0ac64c4ca40f 210 curiLights.FlushOutput();
isonno 0:6da5625a6946 211 }
isonno 0:6da5625a6946 212 }