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:
Sun Jan 15 09:07:04 2012 +0000
Revision:
1:d1da77023e6a
Parent:
0:6da5625a6946
Child:
2:965388eecf95
Child:
3:0ac64c4ca40f
Add SettingsMenu functionality.

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