├── LICENSE ├── README.md ├── images ├── SWIM_Interface.jpg └── cpu.jpg ├── orsala_hack.hex └── src └── orsala_hack └── orsala_hack.ino /LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------ 3 | * "THE BEERWARE LICENSE" (Revision 42): 4 | * wrote this code. As long as you retain this 5 | * notice, you can do whatever you want with this stuff. If we 6 | * meet someday, and you think this stuff is worth it, you can 7 | * buy me a beer in return. 8 | * ------------------------------------------------------------ 9 | */ 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # orsala_hack 2 | https://github.com/j-zero/orsala_hack 3 | 4 | Alternative firmware for IKEA ORSALA lamp (https://www.ikea.com/de/de/p/orsala-arbeitsleuchte-led-dimmbar-weiss-00482904/) 5 | 6 | ## but why? 7 | The ORSALA lamp from IKEA is a nice desktop lamp but has a very strange user experience. It features one rotary encoeder with button to control the brightness, color temperature and an on/off switch. 8 | 9 | ### On the original firmware the following functions are implemented: 10 | 11 | If lamp is turned off: 12 | * Tap the encoder to turn on the lamp. 13 | 14 | If lamp is turned on: 15 | * Press the encoder for about 750ms to turn off the lamp. 16 | * Tap the rotary encoder to switch between brightness and temperature control. 17 | * Turn the rotary encoder in to change brightness or color temperature according to the current mode. 18 | 19 | Also the lamp does not save the brightness or color temperature on power loss. 20 | 21 | ### This firmware fixes the user experience in the following way: 22 | 23 | If lamp is turned off: 24 | * Tap the rotary encoder to turn on the Lamp 25 | * Turn the rotary encoder clockwise to turn on the lamp 26 | 27 | If lamp is turned on: 28 | * Tap the rotary encoder to turn off the lamp 29 | * Turn rotary encoder to change the brightness 30 | * Turn the rotary encoder below minimum brightness to turn off the lamp 31 | * Press and turn the rotary encoder to change color temperature 32 | * Internal LED flashes if minimum/maximum temperature/brightness is reached 33 | 34 | The current color and brightness is saved in EEPROM on power off the lamp. 35 | 36 | ## Information 37 | The IKEA ORSALA lamp contains a STM8S003F3P6 (https://www.st.com/resource/en/datasheet/stm8s003f3.pdf) cpu and two TTP932 led drivers for the warm and cold white leds. 38 | The SWIM Interface is lead out to pads with 2mm spacing: 39 | 40 | ![SWIM Interface](https://datenpir.at/images/orsala_hack/SWIM_Interface.jpg) 41 | ![CPU](https://datenpir.at/images/orsala_hack/CPU.jpg) 42 | 43 | ``` 44 | + VSS (VCC) 3.3V on STLINKv2 45 | R NRST (Reset) RST on STLINKv2 46 | S SWIM (SWIM) SWIM on STLINKv2 47 | - VDD (GND) GND on STLINKv2 48 | ``` 49 | 50 | ## Pinout 51 | 52 | ``` 53 | PD4 internal led 54 | PA3 warm white leds (via TTP932) 55 | PD3 cold white leds (via TTP932) 56 | PA1 encoder pin 1 57 | PA2 encoder pin 2 58 | PB5 encoder button 59 | ``` 60 | 61 | ## Requirements 62 | ### Build 63 | Sduino Arduino API Ports to STM8S https://tenbaht.github.io/sduino/ 64 | 65 | ### Flash 66 | stm8flash (https://github.com/tenbaht/stm8flash/) 67 | 68 | STLINKv2 (https://www.st.com/en/development-tools/st-link-v2.html) 69 | 70 | ## Flash firmware 71 | 72 | * Connect your STLINKv2 to the pads on the pcb (VCC is not needed if lamp is powered) 73 | * Flash firmware: 74 | ```bash 75 | ./stm8flash -c stlinkv2 -p stm8s003f3 -w orsala_hack.hex 76 | ``` 77 | -------------------------------------------------------------------------------- /images/SWIM_Interface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j-zero/orsala_hack/f2adcdc3f7f9816ff48c15dc1b0d36157d73adfc/images/SWIM_Interface.jpg -------------------------------------------------------------------------------- /images/cpu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j-zero/orsala_hack/f2adcdc3f7f9816ff48c15dc1b0d36157d73adfc/images/cpu.jpg -------------------------------------------------------------------------------- /orsala_hack.hex: -------------------------------------------------------------------------------- 1 | :108000008200806B8200000082000000820000007D 2 | :10801000820000008200858A8200858F820085941C 3 | :10802000820085998200859E820000008200000007 4 | :108030008200000082000000820085A38200000010 5 | :1080400082000000820000008200000082008A514D 6 | :1080500082008A3B82000000820000008200000053 7 | :0B80600082000000820087A8CC854B46 8 | :10806B00AE00342707724F00005A26F9AE002A27BC 9 | :0A807B0009D680FDD700345A26F71D 10 | :03808500CC806844 11 | :10808800000050025007500C5011000050005005DD 12 | :10809800500A500F000050015006500B50100101BB 13 | :1080A8000102020303030303040404040404020496 14 | :1080B800082010081020408002040810204000000A 15 | :1080C800050000010200000000000403000002FF98 16 | :1080D800FFFFFF0304FF0506525A525B530753087C 17 | :1080E80053090000051001100100525D525D530A4A 18 | :0680F800530A530B0000C7 19 | :1080FE00854B4080010100000000000000000000E0 20 | :10810E0000000001856385638563856385638563F0 21 | :0A811E00856385638563800000011E 22 | :1081280052024B0DCD8E5B849F6B01A0014F496BB2 23 | :1081380002884B0DCD85A85B024B645F894B00CD4F 24 | :108148008CBA5B047B01884B0DCD85A85B024B6420 25 | :108158005F894B00CD8CBA5B047B02884B0DCD85C3 26 | :10816800A85B024B645F894B00CD8CBA5B047B0132 27 | :10817800884B0DCD85A85B0481720000480220035E 28 | :10818800CC819DCC818E72010048022003CD8128CC 29 | :108198003501004881720000480220193B00375F12 30 | :1081A80089CD84325B033B00384B014B00CD8432D0 31 | :1081B8005B03CD8128725F004881C60037970D03A5 32 | :1081C8002711C60037A1FA22079FAB05C7003781E0 33 | :1081D800CC8128C60037A10625079FA005C7003710 34 | :1081E80081725D0037260181CC819DC60038970DCC 35 | :1081F800032711C60038A1F522079FAB0AC700382C 36 | :1082080081CC8128C60038A10A25079FA00AC7008B 37 | :108218003881CC812852085FC6003797905FC60026 38 | :10822800386B080F070F060F058990895F895F89EA 39 | :108238004BFF5F894B005F895F891E17891E17896D 40 | :10824800CD899C5B149FC70039C600376B040F03A8 41 | :108258000F020F01C600386B080F0790AE00FF72BF 42 | :10826800F20717077B07494FA2006B066B051E0331 43 | :10827800891E03895F895F894BFF5F894B005F898E 44 | :108288005F891E17891E1789CD899C5B149FC700BB 45 | :108298003A5B08815FC6003997894B02CD88475BF6 46 | :1082A800035FC6003A97894B0CCD88475B03817200 47 | :1082B80000004802201A0D04270D7B03A0014F4936 48 | :1082C80088CD81F38420107B0388CD81C284200768 49 | :1082D8000D032703CD818E3501003DCC821D4B0156 50 | :1082E8004B0DCD8C275B024B014B02CD8C275B02DB 51 | :1082F8004B014B0CCD8C275B024B004B00CD8C27E0 52 | :108308005B024B004B01CD8C275B024B024B03CD2C 53 | :108318008C275B02C64000C70037C64001C700383B 54 | :108328008152044B03CD8E5B84CF00424B00CD8E2F 55 | :108338005B849FC7003C725D003B2626C6003C4A12 56 | :108348002620CE00421D00014F496B044B01CD8E03 57 | :108358005B84A300014F49977B04889F88CD82B72F 58 | :108368005B0255003C003BCE0040C300422710CDC5 59 | :1083780087D3CF004690CF0044CE0042CF0040CDF7 60 | :1083880087D35172B2004617039FC200456B029E05 61 | :10839800C200446B01AE003213034F12024F1201A8 62 | :1083A800243BC60043884B0DCD85A85B02CE003E1A 63 | :1083B8005A260BCE00422606725F003D2019CE00D9 64 | :1083C8003E2614CE00425A260E7201003D022007B6 65 | :1083D800CD8181725F003DCE0042CF003E72000029 66 | :1083E80048022005CD829C20125F894B0CCD88471E 67 | :1083F8005B035F894B02CD88475B035B04811E03E7 68 | :10840800A302802501811C40001F03F611052601E7 69 | :108418008189CD848785C6505FA5082601817B05A3 70 | :10842800F7C6505FA408C7505F81CD8487C6505FE8 71 | :10843800A5082601811E031C40007B05F7C6505F76 72 | :10844800A408C7505F81C6505FA408C7505F811E4B 73 | :1084580003A3027F2301811E0772FB03A30280236B 74 | :1084680008AE028072F0031F071E031C40001605A9 75 | :108478007B08887B0888899089CD8BC85B0681C674 76 | :10848800505FA50827018135AE5064355650648188 77 | :1084980052091E0CA3028024601E1072FB0CA3025A 78 | :1084A800802308AE028072F00C1F101E0C1C4000C6 79 | :1084B8001F0CCD8487C6505FA508273D160C1704EE 80 | :1084C800160E1706161017081E081608905A1708D1 81 | :1084D8005D271E1604170193F66B031E06F611039B 82 | :1084E80027031E01F71E045C1F041E065C1F0620DE 83 | :1084F800D7C6505FA408C7505F5B098152021E05AA 84 | :10850800A30280243B1E0972FB05A302802308AE48 85 | :10851800028072F0051F09CD8487C6505FA5082721 86 | :108528001F160717011E051C40001609908916031F 87 | :10853800908989CD8BC85B06C6505FA408C7505F79 88 | :108548005B0281CD85F7CD8BC7CD82E6CD832972BD 89 | :108558005D000127F7CD8AAA20F281817B03A1095A 90 | :108568002501815F7B0397581604DF0049817B034F 91 | :10857800A1092501815F7B03975890AE8563DF00D1 92 | :108588004981CE0049FD80CE004BFD80CE004DFDD7 93 | :1085980080CE004FFD80CE0051FD80CE0053FD807F 94 | :1085A80052035F7B06971C80C6F66B015F7B0697BC 95 | :1085B8001C80B6F66B025F7B06971C80A6F66B03E1 96 | :1085C800272A0D0127077B0188CD8E11845F7B0345 97 | :1085D80097581C8092FE9BF66B030D0726087B02BA 98 | :1085E800431403F720057B031A02F79A5B038135CE 99 | :1085F800017F60350050C64B004B50CD8C185B0294 100 | :108608004B054B50CD8C185B024B0A4B50CD8C1848 101 | :108618005B024B0F4B50CD8C185B024B144B50CD6B 102 | :108628008C185B024B194B50CD8C185B02CD8B9C80 103 | :10863800CD87DD3506534735F9534835FE53447227 104 | :10864800105343C65340AA01C75340CD86B64B00CA 105 | :108658004BFF4B004B004B3F4B00CD8DDE5B06358F 106 | :1086680000525C3500525D3578525835785259358C 107 | :1086780078525A3578525B350152503580526DCD5B 108 | :10868800874F4BFF4B004B06CD8E425B03350053A3 109 | :108698000A3500530B356853073568530835685356 110 | :1086A8000935015300CD8D16356054019A81350086 111 | :1086B8005250350052513500525235005253350050 112 | :1086C8005254350052563500525C3500525D350122 113 | :1086D8005258350152593501525A3501525B35000D 114 | :1086E800525C3500525D35005258350052593500FC 115 | :1086F800525A3500525B3500525E3500525F3500E4 116 | :1087080052603500526135FF526235FF52633500C1 117 | :10871800526535005266350052673500526835009B 118 | :1087280052693500526A3500526B3500526C35007B 119 | :10873800526F350152573500526E3500526D350073 120 | :1087480052643500525581350053003500530335C6 121 | :108758000053053500530A3500530B3500530A35CD 122 | :1087680000530B35005307350053083500530935BE 123 | :1087780000530C3500530D3500530E35FF530F359C 124 | :10878800FF5310350053113500531235005313357C 125 | :108798000053143500531535005316350053048122 126 | :1087A800CE000890CE00065C2602905CCF000890B0 127 | :1087B800CF0006CE000490CE00025C2602905CCF6B 128 | :1087C800000490CF000235FE5344809BCE000890F1 129 | :1087D800CE00069A81350053403500534335005387 130 | :1087E800463500534735FF534835005344815204FA 131 | :1087F8007B07A10624047B07200B5F7B07971D00DE 132 | :10880800061C80D6F6A40FC75400721654027210C4 133 | :10881800540172105401C654002AFB721F5400C63A 134 | :10882800540597C6540495721154014F0F02416BB9 135 | :1088380004410F037B021A04021A03955B04814B5F 136 | :10884800017B0488CD8C275B021E04260B4B007B22 137 | :108858000488CD85A85B02811E04A300FF2F0B4B63 138 | :10886800017B0488CD85A85B02815F7B03971C8010 139 | :10887800C6F6A1052303CC8903617B05615F975880 140 | :10888800DE888CFC8903889888AB88C488D788EAF6 141 | :108898007210525D3568525A35005269AE526A906C 142 | :1088A8009FF781C6525DA4CFAA10C7525D356852A2 143 | :1088B8005B3500526BAE526C909FF7817210530A71 144 | :1088C8003568530735005311AE5312909FF7813521 145 | :1088D8006853087218530A35005313AE5314909F07 146 | :1088E800F781C6530BA4FCAA01C7530B356853097B 147 | :1088F80035005315AE5316909FF7811E04A30080D0 148 | :108908002E0B4B007B0488CD85A85B02814B017B35 149 | :108918000488CD85A85B02811E0526051E03260155 150 | :10892800811E0589CD8DD05B028152041E0926085F 151 | :108938001E072604905F2022CD8D471F037B034925 152 | :108948004FA2006B026B0116099089160990891EC7 153 | :1089580007891E0789CD8A855B085B04811E05137C 154 | :10896800097B0412087B0312072F051E05160381D5 155 | :10897800160972F2057B081204977B07120395907B 156 | :108988008989CD89325B045172F9059F190402194E 157 | :108998000395518152081E0D72F0111F037B0C12B2 158 | :1089A800106B027B0B120F6B011E1D72F0191F0753 159 | :1089B8007B1C12186B067B1B12176B051E07891E82 160 | :1089C80007891E07891E0789CD8EA05B081F031E15 161 | :1089D8001572F0111F077B1412106B067B13120F10 162 | :1089E8006B051E07891E07891E07899089CD8B1B79 163 | :1089F8005B085172F9199F191802191795515B08EC 164 | :108A0800815206160A1701931C00101F03FE5C9F73 165 | :108A1800A40F974F95511E01EE1217051305271045 166 | :108A28001E03FE72FB017B09F71E03FF35010001DF 167 | :108A38005B0681C6523197C6523044250B4B0B4B0F 168 | :108A4800009F88CD8A095B03805202CE002F1F0148 169 | :108A580090AE003193FE1301260A725F0033721F35 170 | :108A68005235201693FE1C001FF693FE5C889FA4C7 171 | :108A78000F974F958490FFC752315B02801E0916ED 172 | :108A8800072A03CD8F1C8990891E0916072A03CD52 173 | :108A98008F1C899089CD8AAB5B087B032A03CD8F15 174 | :108AA8001C818152030F030F017B0A484F494D2651 175 | :108AB8002E160C1E0A905859170C1F0A1E08130C64 176 | :108AC8007B07120B7B06120A240D160C1E0A549003 177 | :108AD80056170C1F0A20080C017B016B0320CA7B68 178 | :108AE800036B021E0872F00C7B07120B90977B0633 179 | :108AF800120A25061F0890951706160C1E0A549090 180 | :108B080056170C1F0A7B020A024D26D71E081606A6 181 | :108B18005B03811E0916072A03CD8F1C8990891EC5 182 | :108B28000916072A03CD8F1C899089CD8B425B08D3 183 | :108B38007B0318072A03CD8F1C8152065F1F051F70 184 | :108B480003A6206B027B09484F496B01160B1E09CF 185 | :108B5800905859170B1F0916051E039058591705E9 186 | :108B68001F030D0127067B06AA016B061E0572F07E 187 | :108B78000F7B04120E90977B03120D250C1F059096 188 | :108B88009517037B0CAA016B0C0A0226B81E0B165C 189 | :108B9800095B0681C65230C6523135005233350062 190 | :108BA80052323500523435005235350052363500D0 191 | :108BB800523735005238350052393500523A8181E2 192 | :108BC80016031E05040706082406F690F75C905C59 193 | :108BD80004070608240CF690F75C905CF690F75CA6 194 | :108BE800905C0D08260D0A072B2320071C00047231 195 | :108BF800A90004F690F7E60190E701E60290E70283 196 | :108C0800E60390E7030A0826E30A072ADF1E038122 197 | :108C18001603907F935C5C7F936F03936F04815F6F 198 | :108C28007B0397891C80B6F69097439095851C80A6 199 | :108C3800A6F627375F48971C8092FE7B04272D4AAB 200 | :108C4800270E4A273C4A270F4A4A274A4A4A274DAD 201 | :108C58009B909FEA0320059B909EE403E703909E68 202 | :108C6800E404E704909FEA02E7029A819B909EE45D 203 | :108C780004E704909EE403E703909EE402E7029A67 204 | :108C8800819B909EE404E704909EE402E702909F93 205 | :108C9800EA03E7039A819B909FEA0320059B909E35 206 | :108CA800E403E703909FEA02E702909FEA04E704DF 207 | :108CB8009A815208CD8F27160D2604160B274C894A 208 | :108CC800CD8F271F098516071701160D1705160BD7 209 | :108CD80017031F0716052604160327DB160172F271 210 | :108CE8000790A303E825D01E051D00011F057B047E 211 | :108CF800A2006B047B03A2006B031605170D160375 212 | :108D0800170B1E071C03E81F0720C95B08813500E5 213 | :108D18005400350054013500540235005403350021 214 | :108D280054063500540735FF5408350354093500F7 215 | :108D3800540A3500540B3500540E3500540F815237 216 | :108D480008CE005D1F03CE005B1F01160217077BCC 217 | :108D5800016B060F05040606070608040606070643 218 | :108D6800087B041808977B031807957B0218068868 219 | :108D78007B0218069095841F066B050F08080809E2 220 | :108D88000709060905180690979F180802180795FD 221 | :108D9800909E180590951F0317017B016B080F071C 222 | :108DA8000F060F0504087B041808977B031807951E 223 | :108DB8007B02180690977B0118059095CF005D906F 224 | :108DC800CF005B58545B088116035F58995690CFC3 225 | :108DD800005DCF005B81897B086B020F017B02C7B6 226 | :108DE80052627B09C752637B056B020F017B02C786 227 | :108DF80052607B06C75261C65250A48F1A07C752E9 228 | :108E080050AE52647B0AF7858152037B064A6B0297 229 | :108E1800494FA2006B0116019058931C80E0FEF6A2 230 | :108E2800A48FF7931C80F2FEF66B03160172A980DB 231 | :108E3800EC90F6431403F75B038189AE530E7B0570 232 | :108E4800F77B066B020F017B02C7530F7B07C753E3 233 | :108E580010858152035F7B06971C80C6F66B015F05 234 | :108E68007B06971C80B6F66B025F7B06971C80A674 235 | :108E7800F66B0326035F201D0D0127077B0188CDB4 236 | :108E88008E11845F7B0397581C809CFEF614022782 237 | :108E9800035F5C215F5B03815F89897B0A977B0E97 238 | :108EA800421F037B09977B0E4272FB021F024FA9E8 239 | :108EB800006B017B0A977B0D4272FB021F024F1960 240 | :108EC800016B017B0A977B0C4272FB011F017B0936 241 | :108ED800977B0D4272FB011F017B08977B0E427244 242 | :108EE800FB011F017B07977B0E429F1B016B017BD8 243 | :108EF8000A977B0B429F1B016B017B09977B0C42F6 244 | :108F08009F1B016B017B08977B0D429F1B016B0127 245 | :108F18009085858190535D2703535C81905C8152D5 246 | :108F2800089BCE000490CE0002C653466B08C65379 247 | :108F38004444240B7B08A1F924055C2602905C9A22 248 | :108F48008990894BFA5F894B00CD8EA05B087B081E 249 | :108F58006B040F030F020F0172FB031F07909F1989 250 | :108F68000297909E1901160788A602905841494118 251 | :0B8F780009014A26F68495515B088130 252 | :040000030000806B0E 253 | :00000001FF 254 | -------------------------------------------------------------------------------- /src/orsala_hack/orsala_hack.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------ 3 | * "THE BEERWARE LICENSE" (Revision 42): 4 | * wrote this code. As long as you retain this 5 | * notice, you can do whatever you want with this stuff. If we 6 | * meet someday, and you think this stuff is worth it, you can 7 | * buy me a beer in return. 8 | * ------------------------------------------------------------ 9 | */ 10 | 11 | #include 12 | 13 | #define LED_INT PD4 // internal led 14 | #define LED_WARM PA3 // warm white leds 15 | #define LED_COLD PD3 // cold white leds 16 | #define ENC_1 PA1 // encoder pin 1 17 | #define ENC_2 PA2 // encoder pin 2 18 | #define ENC_BTN PB5 // encoder button pin 19 | 20 | #define TEMPERATURE_STEPS 10 // temperature crossover factor 21 | #define BRIGHTNESS_STEPS 5 // brightnes factor 22 | #define MIN_BRIGHTNESS 1 // minimal lamp brightness 23 | #define MAX_BRIGHTNESS 255 // maximal lamp brightness 24 | 25 | 26 | uint8_t brightness = 64; 27 | uint8_t temperature = 128; 28 | uint8_t warm_value = MIN_BRIGHTNESS; 29 | uint8_t cold_value = MIN_BRIGHTNESS; 30 | 31 | uint8_t enc_pin_last = LOW; 32 | uint8_t encoder_state = LOW; 33 | bool encoder_has_changed = false; 34 | 35 | int button_last_state = LOW; 36 | int button_last_flickerable_state = LOW; 37 | int button_state = LOW; 38 | unsigned long button_last_debounce_time = 0; 39 | 40 | bool lamp_on = true; 41 | 42 | void blink_internal_led(){ 43 | uint8_t val = digitalRead(LED_INT); 44 | digitalWrite(LED_INT, !val); 45 | delay(100); 46 | digitalWrite(LED_INT, val); 47 | delay(100); 48 | digitalWrite(LED_INT, !val); 49 | delay(100); 50 | digitalWrite(LED_INT, val); 51 | } 52 | 53 | void toggle_lamp(){ 54 | if(lamp_on) 55 | turn_lamp_off(); 56 | else 57 | turn_lamp_on(); 58 | } 59 | 60 | void turn_lamp_on(){ 61 | if(!lamp_on){ // is off, turn on 62 | blink_internal_led(); 63 | } 64 | lamp_on = true; 65 | } 66 | 67 | void turn_lamp_off(){ 68 | if(lamp_on){ // is on, turn off 69 | EEPROM_write(0, brightness); // save brightness to first byte in eeprom 70 | EEPROM_write(1, temperature); // save temperature to first byte in eeprom 71 | blink_internal_led(); 72 | } 73 | lamp_on = false; 74 | } 75 | 76 | void add_brightness(bool direction){ 77 | if(direction){ 78 | if(brightness <= MAX_BRIGHTNESS - BRIGHTNESS_STEPS) 79 | brightness += BRIGHTNESS_STEPS; 80 | else 81 | blink_internal_led(); 82 | } 83 | else{ 84 | if(brightness >= MIN_BRIGHTNESS + BRIGHTNESS_STEPS) 85 | brightness -= BRIGHTNESS_STEPS; 86 | else if(brightness > 0) 87 | turn_lamp_off(); 88 | } 89 | 90 | } 91 | 92 | void add_temperature(bool direction){ 93 | if(direction){ 94 | if(temperature <= 255 - TEMPERATURE_STEPS) 95 | temperature += TEMPERATURE_STEPS; 96 | else 97 | blink_internal_led(); 98 | } 99 | else{ 100 | if(temperature >= TEMPERATURE_STEPS) 101 | temperature -= TEMPERATURE_STEPS; 102 | else 103 | blink_internal_led(); 104 | } 105 | } 106 | 107 | void set_temperature(){ 108 | warm_value = map(temperature,0,255,0,brightness); 109 | cold_value = map(255-temperature,0,255,0,brightness); 110 | } 111 | 112 | void set_lamp_leds(){ 113 | analogWrite(LED_WARM, warm_value); 114 | analogWrite(LED_COLD, cold_value); 115 | } 116 | 117 | void encoder_callback(bool direction, bool btn_pressed){ 118 | if(lamp_on){ 119 | if(btn_pressed){ 120 | add_temperature(!direction); 121 | } 122 | else{ 123 | add_brightness(direction); 124 | } 125 | } 126 | else{ 127 | if(direction) 128 | turn_lamp_on(); 129 | } 130 | encoder_has_changed = true; 131 | set_temperature(); 132 | } 133 | 134 | void setup() { 135 | 136 | FLASH_SetLowPowerMode(FLASH_LPMODE_POWERDOWN); 137 | // define pin modes 138 | pinMode(LED_INT, OUTPUT); 139 | pinMode(LED_WARM, OUTPUT); 140 | pinMode(LED_COLD, OUTPUT); 141 | pinMode(ENC_1, INPUT); 142 | pinMode(ENC_2, INPUT); 143 | pinMode(ENC_BTN, INPUT_PULLUP); 144 | 145 | // read from eeprom on power loss 146 | brightness = EEPROM_read(0); 147 | temperature = EEPROM_read(1); 148 | 149 | 150 | } 151 | 152 | void loop() { 153 | 154 | // read button/encoder 155 | button_state = digitalRead(ENC_BTN); 156 | encoder_state = digitalRead(ENC_1); 157 | 158 | // encoder 159 | if ((enc_pin_last == LOW) && (encoder_state == HIGH)) { 160 | encoder_callback(!digitalRead(ENC_2), !button_state); 161 | } 162 | enc_pin_last = encoder_state; 163 | 164 | // button 165 | if (button_state != button_last_flickerable_state) { 166 | button_last_debounce_time = millis(); 167 | button_last_flickerable_state = button_state; 168 | } 169 | 170 | if ((millis() - button_last_debounce_time) > 50) { 171 | digitalWrite(LED_INT, button_state); 172 | if(button_last_state == HIGH && button_state == LOW) 173 | encoder_has_changed = false; 174 | 175 | else if(button_last_state == LOW && button_state == HIGH){ 176 | if(!encoder_has_changed){ 177 | toggle_lamp(); 178 | encoder_has_changed = false; 179 | } 180 | } 181 | button_last_state = button_state; 182 | } 183 | 184 | // lamp 185 | if(lamp_on){ 186 | set_lamp_leds(); 187 | } 188 | else{ 189 | analogWrite(LED_COLD, 0); 190 | analogWrite(LED_WARM, 0); 191 | } 192 | 193 | } 194 | --------------------------------------------------------------------------------