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:
3:0ac64c4ca40f
Add SettingsMenu functionality.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
isonno 0:6da5625a6946 1 //
isonno 0:6da5625a6946 2 // UIMenu - Click-knob menu implementation
isonno 0:6da5625a6946 3 //
isonno 0:6da5625a6946 4
isonno 0:6da5625a6946 5 #include "NokiaLCD.h"
isonno 0:6da5625a6946 6 #include "UIMenu.h"
isonno 0:6da5625a6946 7 #include "HoldInterrupts.h"
isonno 0:6da5625a6946 8
isonno 0:6da5625a6946 9 static Timeout gScreenTimer;
isonno 0:6da5625a6946 10
isonno 0:6da5625a6946 11 void PushKnobUI::ConnectDevices( RotaryEncoder * knob, PushButton * button )
isonno 0:6da5625a6946 12 {
isonno 0:6da5625a6946 13 HoldInterrupts holdint();
isonno 0:6da5625a6946 14
isonno 0:6da5625a6946 15 if (! knob && fKnob) // Disconnect
isonno 0:6da5625a6946 16 {
isonno 0:6da5625a6946 17 fKnob->detach();
isonno 0:6da5625a6946 18 fKnob = NULL;
isonno 0:6da5625a6946 19 }
isonno 0:6da5625a6946 20 if (! button && fKnobButton)
isonno 0:6da5625a6946 21 {
isonno 0:6da5625a6946 22 fKnobButton->detach();
isonno 0:6da5625a6946 23 fKnobButton = NULL;
isonno 0:6da5625a6946 24 }
isonno 0:6da5625a6946 25
isonno 0:6da5625a6946 26 if (knob && !fKnob)
isonno 0:6da5625a6946 27 {
isonno 0:6da5625a6946 28 fKnob = knob;
isonno 0:6da5625a6946 29 //fKnob->attach( this, &UIMenu::KnobMoved );
isonno 0:6da5625a6946 30 AttachKnob( fKnob );
isonno 0:6da5625a6946 31 }
isonno 0:6da5625a6946 32 if (button && !fKnobButton)
isonno 0:6da5625a6946 33 {
isonno 0:6da5625a6946 34 fKnobButton = button;
isonno 0:6da5625a6946 35 //fKnobButton->attach( this, &UIMenu::KnobPushed );
isonno 0:6da5625a6946 36 AttachButton( fKnobButton );
isonno 0:6da5625a6946 37 }
isonno 0:6da5625a6946 38 }
isonno 0:6da5625a6946 39
isonno 1:d1da77023e6a 40 void PushKnobUI::SwitchControl( PushKnobUI * other )
isonno 0:6da5625a6946 41 {
isonno 0:6da5625a6946 42 other->ConnectDevices( fKnob, fKnobButton );
isonno 0:6da5625a6946 43 fKnob = NULL;
isonno 0:6da5625a6946 44 fKnobButton = NULL;
isonno 0:6da5625a6946 45 }
isonno 0:6da5625a6946 46
isonno 0:6da5625a6946 47 int32_t PushKnobUI::KnobMoved( int32_t step )
isonno 0:6da5625a6946 48 {
isonno 0:6da5625a6946 49 printf("Knob moved %d\r\n", step );
isonno 0:6da5625a6946 50 Wake();
isonno 0:6da5625a6946 51 return step;
isonno 0:6da5625a6946 52 }
isonno 0:6da5625a6946 53
isonno 0:6da5625a6946 54 void PushKnobUI::KnobPushed()
isonno 0:6da5625a6946 55 {
isonno 0:6da5625a6946 56 Wake();
isonno 0:6da5625a6946 57 printf("Button pushed\r\n");
isonno 0:6da5625a6946 58 }
isonno 0:6da5625a6946 59
isonno 0:6da5625a6946 60 void PushKnobUI::Wake()
isonno 0:6da5625a6946 61 {
isonno 0:6da5625a6946 62 fLCD->fade_backlight( true );
isonno 0:6da5625a6946 63 gScreenTimer.detach();
isonno 0:6da5625a6946 64 gScreenTimer.attach( this, &PushKnobUI::Sleep, 10 );
isonno 0:6da5625a6946 65 }
isonno 0:6da5625a6946 66
isonno 0:6da5625a6946 67 void PushKnobUI::Sleep()
isonno 0:6da5625a6946 68 {
isonno 0:6da5625a6946 69 fLCD->fade_backlight( false );
isonno 0:6da5625a6946 70 gScreenTimer.detach();
isonno 0:6da5625a6946 71 }
isonno 0:6da5625a6946 72
isonno 0:6da5625a6946 73
isonno 0:6da5625a6946 74 //----------------------------------------------------
isonno 0:6da5625a6946 75
isonno 0:6da5625a6946 76 UIMenu::UIMenu( CheapLCD * lcd, const char * header, bool upMenuItem ) : PushKnobUI( lcd ),
isonno 0:6da5625a6946 77 fHeader( header ),
isonno 0:6da5625a6946 78 fDisplayOn( false ),
isonno 0:6da5625a6946 79 fUpMenuItem( upMenuItem ),
isonno 0:6da5625a6946 80 fSelectedItem( kNoSelection ),
isonno 0:6da5625a6946 81 fLCD( lcd )
isonno 0:6da5625a6946 82 {}
isonno 0:6da5625a6946 83
isonno 0:6da5625a6946 84 void UIMenu::AddItem( const char * label )
isonno 0:6da5625a6946 85 {
isonno 0:6da5625a6946 86 fLabels.push_back( string( label ));
isonno 0:6da5625a6946 87 if (fDisplayOn)
isonno 0:6da5625a6946 88 Display( true ); // Refresh
isonno 0:6da5625a6946 89 }
isonno 0:6da5625a6946 90
isonno 0:6da5625a6946 91 void UIMenu::ChangeItem( int item, const char * label )
isonno 0:6da5625a6946 92 {
isonno 0:6da5625a6946 93 if ((item > 0) && (item < fLabels.size()))
isonno 0:6da5625a6946 94 {
isonno 0:6da5625a6946 95 fLabels[item] = string( label );
isonno 0:6da5625a6946 96 DrawItem( item );
isonno 0:6da5625a6946 97 }
isonno 0:6da5625a6946 98 }
isonno 0:6da5625a6946 99
isonno 0:6da5625a6946 100 int32_t UIMenu::KnobMoved( int32_t step )
isonno 0:6da5625a6946 101 {
isonno 0:6da5625a6946 102 Wake();
isonno 0:6da5625a6946 103
isonno 0:6da5625a6946 104 if (fSelectedItem == kNoSelection)
isonno 0:6da5625a6946 105 {
isonno 0:6da5625a6946 106 fSelectedItem = (step > 0) ? 0 : fLabels.size() - 1;
isonno 0:6da5625a6946 107 DrawItem( fSelectedItem );
isonno 0:6da5625a6946 108 }
isonno 0:6da5625a6946 109 else
isonno 0:6da5625a6946 110 {
isonno 0:6da5625a6946 111 int lastItem = fSelectedItem;
isonno 0:6da5625a6946 112 fSelectedItem += step;
isonno 0:6da5625a6946 113 // Handle wrap-around
isonno 0:6da5625a6946 114 if (fSelectedItem < 0)
isonno 0:6da5625a6946 115 fSelectedItem = fLabels.size() - 1;
isonno 0:6da5625a6946 116 if (fSelectedItem == fLabels.size())
isonno 0:6da5625a6946 117 fSelectedItem = 0;
isonno 0:6da5625a6946 118
isonno 0:6da5625a6946 119 DrawItem( lastItem );
isonno 0:6da5625a6946 120 DrawItem( fSelectedItem );
isonno 0:6da5625a6946 121 }
isonno 0:6da5625a6946 122
isonno 0:6da5625a6946 123 return 0;
isonno 0:6da5625a6946 124 }
isonno 0:6da5625a6946 125
isonno 0:6da5625a6946 126 void UIMenu::KnobPushed()
isonno 0:6da5625a6946 127 {
isonno 0:6da5625a6946 128 Wake();
isonno 0:6da5625a6946 129 printf("Selected %s\n\r", fLabels[fSelectedItem].c_str() );
isonno 0:6da5625a6946 130 }
isonno 1:d1da77023e6a 131
isonno 1:d1da77023e6a 132 void UIMenu::SwitchTo( UIMenu * nextMenu )
isonno 1:d1da77023e6a 133 {
isonno 1:d1da77023e6a 134 Display( false );
isonno 1:d1da77023e6a 135 SwitchControl( nextMenu );
isonno 1:d1da77023e6a 136 nextMenu->Display( true );
isonno 1:d1da77023e6a 137 }
isonno 0:6da5625a6946 138
isonno 0:6da5625a6946 139 // Parameters controlling the display layout
isonno 0:6da5625a6946 140 const int kLineSpace = 20;
isonno 0:6da5625a6946 141 const int kTopGap = 4;
isonno 0:6da5625a6946 142 const int kIndent = 12;
isonno 0:6da5625a6946 143 #define MEDGREEN 0x0A0 // "medium" green
isonno 0:6da5625a6946 144
isonno 0:6da5625a6946 145 void UIMenu::DrawItem( int i )
isonno 0:6da5625a6946 146 {
isonno 0:6da5625a6946 147 if (! fDisplayOn)
isonno 0:6da5625a6946 148 return;
isonno 0:6da5625a6946 149
isonno 0:6da5625a6946 150 uint32_t foreColor = WHITE;
isonno 0:6da5625a6946 151 uint32_t backColor = (i == fSelectedItem) ? MEDGREEN : BLACK;
isonno 0:6da5625a6946 152
isonno 0:6da5625a6946 153 fLCD->clear( backColor,
isonno 0:6da5625a6946 154 0, i * kLineSpace + kLineSpace + kTopGap,
isonno 0:6da5625a6946 155 131, (i+1) * kLineSpace + kLineSpace + kTopGap );
isonno 0:6da5625a6946 156 fLCD->draw_glyph_text( foreColor, backColor,
isonno 0:6da5625a6946 157 kIndent, (i+2) * kLineSpace,
isonno 0:6da5625a6946 158 fLabels[i].c_str() );
isonno 0:6da5625a6946 159 }
isonno 0:6da5625a6946 160
isonno 0:6da5625a6946 161 void UIMenu::Display( bool on )
isonno 0:6da5625a6946 162 {
isonno 0:6da5625a6946 163
isonno 0:6da5625a6946 164 if (on)
isonno 0:6da5625a6946 165 {
isonno 0:6da5625a6946 166 fDisplayOn = true;
isonno 1:d1da77023e6a 167 fLCD->clear( BLACK, 0, 0, 131, kLineSpace + kTopGap );
isonno 0:6da5625a6946 168 fLCD->clear( GRAY, 0, kLineSpace + kTopGap-1, 131, kLineSpace + kTopGap );
isonno 0:6da5625a6946 169 if (! fHeader.empty())
isonno 0:6da5625a6946 170 fLCD->draw_glyph_text( WHITE, BLACK, 2, kLineSpace-2, fHeader.c_str() );
isonno 0:6da5625a6946 171
isonno 0:6da5625a6946 172 int maxLines = std::min( (int)((131 - (kLineSpace + kTopGap)) / kLineSpace), (int)fLabels.size() );
isonno 0:6da5625a6946 173
isonno 0:6da5625a6946 174 for (int i = 0; i < maxLines; ++i)
isonno 0:6da5625a6946 175 DrawItem( i );
isonno 0:6da5625a6946 176 }
isonno 0:6da5625a6946 177 else
isonno 0:6da5625a6946 178 fDisplayOn = false;
isonno 0:6da5625a6946 179 }
isonno 0:6da5625a6946 180