├── AmbilWarna
├── res
│ ├── drawable
│ │ ├── ambilwarna_hue.png
│ │ ├── ambilwarna_cursor.png
│ │ ├── ambilwarna_target.png
│ │ ├── ambilwarna_arrow_down.png
│ │ └── ambilwarna_arrow_right.png
│ ├── drawable-hdpi
│ │ ├── ambilwarna_cursor.png
│ │ ├── ambilwarna_target.png
│ │ ├── ambilwarna_arrow_down.png
│ │ └── ambilwarna_arrow_right.png
│ ├── drawable-ldpi
│ │ ├── ambilwarna_cursor.png
│ │ ├── ambilwarna_target.png
│ │ ├── ambilwarna_arrow_down.png
│ │ └── ambilwarna_arrow_right.png
│ ├── drawable-xhdpi
│ │ ├── ambilwarna_cursor.png
│ │ ├── ambilwarna_target.png
│ │ ├── ambilwarna_arrow_down.png
│ │ └── ambilwarna_arrow_right.png
│ ├── values-land
│ │ └── dimen.xml
│ ├── values-xlarge-land
│ │ └── dimen.xml
│ ├── values
│ │ └── dimen.xml
│ ├── layout
│ │ ├── ambilwarna_pref_widget.xml
│ │ └── ambilwarna_dialog.xml
│ └── layout-land
│ │ └── ambilwarna_dialog.xml
├── AndroidManifest.xml
├── project.properties
└── src
│ └── yuku
│ └── ambilwarna
│ ├── AmbilWarnaKotak.java
│ └── AmbilWarnaDialog.java
├── ColorLightsController
├── ic_launcher-web.png
├── libs
│ └── android-support-v4.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── menu
│ │ └── activity_main.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── layout
│ │ └── activity_main.xml
├── project.properties
├── AndroidManifest.xml
└── src
│ └── tkjelectronics
│ └── arduino
│ └── colorlightscontroller
│ └── MainActivity.java
├── OpenWrt
├── README.md
└── www
│ ├── cgi-bin
│ └── color
│ └── color
│ ├── css
│ └── farbtastic.css
│ ├── index.html
│ └── js
│ └── farbtastic.js
├── .gitignore
├── EEPROMAnything.h
├── README.md
└── AndroidControllableLights.ino
/AmbilWarna/res/drawable/ambilwarna_hue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable/ambilwarna_hue.png
--------------------------------------------------------------------------------
/ColorLightsController/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/ic_launcher-web.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable/ambilwarna_cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable/ambilwarna_cursor.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable/ambilwarna_target.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable/ambilwarna_target.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-hdpi/ambilwarna_cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-hdpi/ambilwarna_cursor.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-hdpi/ambilwarna_target.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-hdpi/ambilwarna_target.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-ldpi/ambilwarna_cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-ldpi/ambilwarna_cursor.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-ldpi/ambilwarna_target.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-ldpi/ambilwarna_target.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable/ambilwarna_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable/ambilwarna_arrow_down.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable/ambilwarna_arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable/ambilwarna_arrow_right.png
--------------------------------------------------------------------------------
/ColorLightsController/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-xhdpi/ambilwarna_cursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-xhdpi/ambilwarna_cursor.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-xhdpi/ambilwarna_target.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-xhdpi/ambilwarna_target.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-hdpi/ambilwarna_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-hdpi/ambilwarna_arrow_down.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-hdpi/ambilwarna_arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-hdpi/ambilwarna_arrow_right.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-ldpi/ambilwarna_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-ldpi/ambilwarna_arrow_down.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-ldpi/ambilwarna_arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-ldpi/ambilwarna_arrow_right.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-xhdpi/ambilwarna_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-xhdpi/ambilwarna_arrow_down.png
--------------------------------------------------------------------------------
/ColorLightsController/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ColorLightsController/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/ColorLightsController/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AmbilWarna/res/drawable-xhdpi/ambilwarna_arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/AmbilWarna/res/drawable-xhdpi/ambilwarna_arrow_right.png
--------------------------------------------------------------------------------
/ColorLightsController/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/AndroidControllableLights/master/ColorLightsController/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AmbilWarna/res/values-land/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 240dp
4 | 120dp
5 |
--------------------------------------------------------------------------------
/AmbilWarna/res/values-xlarge-land/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 240dp
4 | 240dp
5 |
--------------------------------------------------------------------------------
/ColorLightsController/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Color Lights Controller
5 | Hello world!
6 | Settings
7 |
8 |
--------------------------------------------------------------------------------
/AmbilWarna/res/values/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 240dp
4 | 240dp
5 | 30dp
6 | 8dp
7 |
8 |
--------------------------------------------------------------------------------
/ColorLightsController/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/AmbilWarna/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
12 |
13 |
--------------------------------------------------------------------------------
/OpenWrt/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | Web interface running on an OpenWrt router using a serial converter on /dev/ttyUSB0 connected to an Arduino Pro Mini running the AndroidControllableLights.ino sketch. So now we can operate the lights from any web enabled device, Android or otherwise.
4 |
--------------------------------------------------------------------------------
/ColorLightsController/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/ColorLightsController/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/AmbilWarna/res/layout/ambilwarna_pref_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Links
2 |
3 | # built application files
4 | *.ap_
5 |
6 | # files for the dex VM
7 | *.dex
8 |
9 | # Java class files
10 | *.class
11 |
12 | # generated files
13 | bin/
14 | gen/
15 | lint.xml
16 |
17 | # Local configuration file (sdk path, etc)
18 | local.properties
19 |
20 | # Eclipse project files
21 | .classpath
22 | .project
23 | .settings
24 | .checkstyle
25 |
26 | #Ant
27 | build.xml
28 | ant.properties
29 | local.properties
30 | proguard.cfg
31 | proguard-project.txt
--------------------------------------------------------------------------------
/AmbilWarna/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | android.library=true
11 | # Indicates whether an apk should be generated for each density.
12 | split.density=false
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/OpenWrt/www/cgi-bin/color:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # It is not necessary to use lua/luci for very simple web interfaces
5 | # See http://wiki.openwrt.org/doc/howto/http.httpd
6 | #
7 |
8 | # Always need to send this header
9 | echo "Content-type: text/html"
10 | echo ""
11 |
12 | # Send command to serial port
13 | # NOTE: For me this works only if we do "cat /dev/ttyUSB0" somewhere
14 | COMMAND=$(echo "$QUERY_STRING" | cut -d "=" -f 2)
15 | replaced=$(echo $COMMAND | sed -e 's|0x|\\x|g' | sed -e 's|%3B|;|g')
16 | # echo "$replaced"
17 | echo -en "$replaced" > /dev/ttyUSB0
18 |
19 | ###
20 | # Note that this could be INSECURE - only use this in trusted internal networks
21 | ###
22 |
--------------------------------------------------------------------------------
/ColorLightsController/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 | android.library.reference.1=../AmbilWarna
16 |
--------------------------------------------------------------------------------
/ColorLightsController/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/ColorLightsController/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/EEPROMAnything.h:
--------------------------------------------------------------------------------
1 | #ifndef _eepromanything_h_
2 | #define _eepromanything_h_
3 |
4 | #include
5 |
6 | // Source: http://playground.arduino.cc/Code/EEPROMWriteAnything
7 | // Modified to use the standard eeprom library and added 'eeprom_busy_wait()'
8 | // Also added EEPROM_updateAnything to limit number of write/erase cycles
9 | // By: Krisitan Lauszus, TKJ Electronics
10 |
11 | template uint16_t EEPROM_writeAnything(uint16_t addr, const T& value) {
12 | eeprom_busy_wait(); // Wait until the eeprom is ready
13 | const uint8_t *p = (const uint8_t*)(const void*)&value;
14 | uint16_t i;
15 | for (i = 0; i < sizeof(value); i++)
16 | eeprom_write_byte((uint8_t*)addr++, *p++);
17 | return i;
18 | }
19 | template uint16_t EEPROM_updateAnything(uint16_t addr, const T& value) {
20 | eeprom_busy_wait(); // Wait until the eeprom is ready
21 | const uint8_t *p = (const uint8_t*)(const void*)&value;
22 | uint16_t i;
23 | for (i = 0; i < sizeof(value); i++) {
24 | if (eeprom_read_byte((uint8_t*)addr) != *p) // Limits number of write/erase cycles
25 | eeprom_write_byte((uint8_t*)addr, *p);
26 | addr++;
27 | p++;
28 | }
29 | return i;
30 | }
31 | template uint16_t EEPROM_readAnything(uint16_t addr, T& value) {
32 | eeprom_busy_wait(); // Wait until the eeprom is ready
33 | uint8_t *p = (uint8_t*)(void*)&value;
34 | uint16_t i;
35 | for (i = 0; i < sizeof(value); i++)
36 | *p++ = eeprom_read_byte((uint8_t*)addr++);
37 | return i;
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/AmbilWarna/src/yuku/ambilwarna/AmbilWarnaKotak.java:
--------------------------------------------------------------------------------
1 | package yuku.ambilwarna;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.ComposeShader;
8 | import android.graphics.LinearGradient;
9 | import android.graphics.Paint;
10 | import android.graphics.PorterDuff;
11 | import android.graphics.Shader;
12 | import android.graphics.Shader.TileMode;
13 | import android.util.AttributeSet;
14 | import android.view.View;
15 |
16 | public class AmbilWarnaKotak extends View {
17 | Paint paint;
18 | Shader luar;
19 | final float[] color = { 1.f, 1.f, 1.f };
20 |
21 | public AmbilWarnaKotak(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | }
24 |
25 | public AmbilWarnaKotak(Context context, AttributeSet attrs, int defStyle) {
26 | super(context, attrs, defStyle);
27 | }
28 |
29 | @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) {
30 | super.onDraw(canvas);
31 | if (paint == null) {
32 | paint = new Paint();
33 | luar = new LinearGradient(0.f, 0.f, 0.f, this.getMeasuredHeight(), 0xffffffff, 0xff000000, TileMode.CLAMP);
34 | }
35 | int rgb = Color.HSVToColor(color);
36 | Shader dalam = new LinearGradient(0.f, 0.f, this.getMeasuredWidth(), 0.f, 0xffffffff, rgb, TileMode.CLAMP);
37 | ComposeShader shader = new ComposeShader(luar, dalam, PorterDuff.Mode.MULTIPLY);
38 | paint.setShader(shader);
39 | canvas.drawRect(0.f, 0.f, this.getMeasuredWidth(), this.getMeasuredHeight(), paint);
40 | }
41 |
42 | void setHue(float hue) {
43 | color[0] = hue;
44 | invalidate();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/OpenWrt/www/color/css/farbtastic.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Farbtastic Color Picker 1.2
3 | * © 2008 Steven Wittens
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | .farbtastic {
20 | position: relative;
21 | }
22 | .farbtastic * {
23 | position: absolute;
24 | cursor: crosshair;
25 | }
26 | .farbtastic, .farbtastic .wheel {
27 | width: 195px;
28 | height: 195px;
29 | }
30 | .farbtastic .color, .farbtastic .overlay {
31 | top: 47px;
32 | left: 47px;
33 | width: 101px;
34 | height: 101px;
35 | }
36 | .farbtastic .wheel {
37 | background: url('https://farbtastic.googlecode.com/svn/branches/farbtastic-1/wheel.png') no-repeat;
38 | width: 195px;
39 | height: 195px;
40 | }
41 | .farbtastic .overlay {
42 | background: url('https://farbtastic.googlecode.com/svn/branches/farbtastic-1/mask.png') no-repeat;
43 | }
44 | .farbtastic .marker {
45 | width: 17px;
46 | height: 17px;
47 | margin: -8px 0 0 -8px;
48 | overflow: hidden;
49 | background: url('https://farbtastic.googlecode.com/svn/branches/farbtastic-1/marker.png') no-repeat;
50 | }
51 |
--------------------------------------------------------------------------------
/AmbilWarna/res/layout-land/ambilwarna_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
24 |
30 |
37 |
43 |
44 |
51 |
53 |
58 |
67 |
68 |
75 |
76 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AmbilWarna/res/layout/ambilwarna_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
23 |
24 |
32 |
33 |
39 |
40 |
46 |
47 |
56 |
57 |
62 |
63 |
69 |
70 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Controllable Lights
2 |
3 | Developed by Thomas Jespersen, TKJ Electronics 2013
4 | Modified for simple RGB strips by probono 2013
5 |
6 | The code is released under the GNU General Public License.
7 |
8 | This is the code is for controlling a simple RGB LED strip (not WS2801 based) with your Arduino using your Android phone with Bluetooth as remote control.
9 |
10 | You can check out a video demonstration of the project here: but please note that a simple RGB strip you can only modify the entire LED strip at once, so not all effects are available.
11 |
12 | For more information see the blog post at .
13 |
14 | ## Commands
15 |
16 | The first byte of a command package is the command byte, descriping the command of the package. The next bytes are all parameters as described below. Each parameter is terminated with a ‘;’ character, also when only one parameter is needed.
17 |
18 | * 0x0F = Color command [Parameters: 3 bytes of 3 char each]
19 | * 0x01 = Add fade color [Parameters: 3 bytes of 3 char each]
20 | * 0x02 = Reset fade colors [Parameters: None]
21 | * 0x03 = Set speed delay [Parameters: 1 integer of 5 chars]
22 | * 0x04 = Enable Fade effect [Parameters: None]
23 | * 0x05 = Add Snap color [Parameters: 3 bytes of 3 char each]
24 | * 0x06 = Reset snap colors [Parameters: None]
25 | * 0x07 = Enable Snap effect [Parameters: None]
26 | * 0x08 = Add Running color (requires WS2801, hence disabled here) [Parameters: 3 bytes of 3 char each]
27 | * 0x09 = Reset Running colors (requires WS2801, hence disabled here) [Parameters: None]
28 | * 0x0A = Enable Running effect (requires WS2801, hence disabled here) [Parameters: None]
29 | * 0x0B = Add Running Fade color (requires WS2801, hence disabled here) [Parameters: 3 bytes of 3 char each]
30 | * 0x0C = Reset Running Fade colors (requires WS2801, hence disabled here) [Parameters: None]
31 | * 0x0D = Enable Running Fade effect (requires WS2801, hence disabled here) [Parameters: None]
32 | * 0x0E = Disable any effect [Parameters: None]
33 | * 0x1A = Invalidate EEProm
34 |
35 | I can successfully send commands using
36 | ```
37 | stty -F /dev/ttyUSB0 speed 57600 cs8 -cstopb -parenb -echo # Configure serial connection
38 | cat /dev/ttyUSB0 & # Otherwise sending does NOT work!
39 | echo -en '0 ' > /dev/ttyUSB0 # Reset the Arduino
40 | sleep 2
41 | echo -en '\x0f255;255;255;' > /dev/ttyUSB0 # Set all white
42 | sleep 1
43 | echo -en '\x0f255;000;000;' > /dev/ttyUSB0 # Set all red
44 | sleep 1
45 | echo -en '\x0f000;255;000;' > /dev/ttyUSB0 # Set all green
46 | sleep 1
47 | echo -en '\x0f000;000;255;' > /dev/ttyUSB0 # Set all blue
48 | killall cat # Do not forget this
49 |
50 | #
51 | # Set warm white color after and save to EEPROM
52 | #
53 |
54 | cat /dev/ttyUSB0 & # Otherwise sending does NOT work!
55 | echo -en '\x02' > /dev/ttyUSB0 # Reset fade colors
56 | echo -en '\x01255;180;100;' > /dev/ttyUSB0 # Add warm white fade color
57 | echo -en '\x04' > /dev/ttyUSB0 # Enable fade effect
58 | echo -en '0 ' > /dev/ttyUSB0 # Reset
59 | killall cat # Do not forget this
60 |
61 | #
62 | # Do the same in 1 line
63 | #
64 |
65 | cat /dev/ttyUSB0 & # Otherwise sending does NOT work!
66 | echo -en '\x02\x01255;180;100;\x040 ' > /dev/ttyUSB0
67 | killall cat # Do not forget this
68 |
69 | #
70 | # More examples
71 | #
72 |
73 | When the app sends the 0x0f "white" command it looks like this:
74 | 00000220 32 3b 0f 32 35 32 3b 32 35 32 3b 32 35 32 3b 0f |2;.252;252;252;.|
75 | 00000230 32 35 32 3b 32 35 32 3b 32 35 32 3b 0f 32 35 32 |252;252;252;.252|
76 | 00000240 3b 32 35 32 3b 32 35 32 3b 0f 32 35 32 3b 32 35 |;252;252;.252;25|
77 | 00000250 32 3b 32 35 32 3b 0f 32 35 32 3b 32 35 32 3b 32 |2;252;.252;252;2|
78 | 00000260 35 32 3b 0f 32 35 32 3b 32 35 32 3b 32 35 32 3b |52;.252;252;252;|
79 | 00000270 0f 32 35 32 3b 32 35 32 3b 32 35 32 3b 0f 32 35 |.252;252;252;.25|
80 |
81 | When the app sends the 0x0f "black" command it looks like this:
82 | 00000310 3b 30 30 30 3b 30 30 30 3b 0f 30 30 30 3b 30 30 |;000;000;.000;00|
83 | 00000320 30 3b 30 30 30 3b 0f 30 30 30 3b 30 30 30 3b 30 |0;000;.000;000;0|
84 | 00000330 30 30 3b 0f 30 30 30 3b 30 30 30 3b 30 30 30 3b |00;.000;000;000;|
85 | 00000340 0f 30 30 30 3b 30 30 30 3b 30 30 30 3b 0f 30 30 |.000;000;000;.00|
86 | 00000350 30 3b 30 30 30 3b 30 30 30 3b 0f 30 30 30 3b 30 |0;000;000;.000;0|
87 | 00000360 30 30 3b 30 30 30 3b 0f 30 30 30 3b 30 30 30 3b |00;000;.000;000;|
88 |
89 | When the app sends the 0x03 "set speed delay" command to 100 it looks like this:
90 | 00000000 03 30 30 31 30 30 3b 03 30 30 31 30 30 3b 03 30 |.00100;.00100;.0|
91 |
92 | ```
93 |
--------------------------------------------------------------------------------
/OpenWrt/www/color/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
46 |
145 |
146 |
147 |
148 |
149 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 | 0
165 |
166 |
167 | 0
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/AmbilWarna/src/yuku/ambilwarna/AmbilWarnaDialog.java:
--------------------------------------------------------------------------------
1 | package yuku.ambilwarna;
2 |
3 | import android.app.*;
4 | import android.content.*;
5 | import android.content.DialogInterface.OnCancelListener;
6 | import android.graphics.*;
7 | import android.view.*;
8 | import android.widget.*;
9 |
10 | public class AmbilWarnaDialog {
11 | public interface OnAmbilWarnaListener {
12 | void onCancel(AmbilWarnaDialog dialog);
13 | void onOk(AmbilWarnaDialog dialog, int color);
14 | void onChange(AmbilWarnaDialog dialog, int color);
15 | }
16 |
17 | final AlertDialog dialog;
18 | final OnAmbilWarnaListener listener;
19 | final View viewHue;
20 | final AmbilWarnaKotak viewSatVal;
21 | final ImageView viewCursor;
22 | final View viewOldColor;
23 | final View viewNewColor;
24 | final ImageView viewTarget;
25 | final ViewGroup viewContainer;
26 | final float[] currentColorHsv = new float[3];
27 |
28 | /**
29 | * create an AmbilWarnaDialog. call this only from OnCreateDialog() or from a background thread.
30 | *
31 | * @param context
32 | * current context
33 | * @param color
34 | * current color
35 | * @param listener
36 | * an OnAmbilWarnaListener, allowing you to get back error or
37 | */
38 | public AmbilWarnaDialog(final Context context, int color, OnAmbilWarnaListener listener) {
39 | this.listener = listener;
40 | Color.colorToHSV(color, currentColorHsv);
41 |
42 | final View view = LayoutInflater.from(context).inflate(R.layout.ambilwarna_dialog, null);
43 | viewHue = view.findViewById(R.id.ambilwarna_viewHue);
44 | viewSatVal = (AmbilWarnaKotak) view.findViewById(R.id.ambilwarna_viewSatBri);
45 | viewCursor = (ImageView) view.findViewById(R.id.ambilwarna_cursor);
46 | viewOldColor = view.findViewById(R.id.ambilwarna_warnaLama);
47 | viewNewColor = view.findViewById(R.id.ambilwarna_warnaBaru);
48 | viewTarget = (ImageView) view.findViewById(R.id.ambilwarna_target);
49 | viewContainer = (ViewGroup) view.findViewById(R.id.ambilwarna_viewContainer);
50 |
51 | viewSatVal.setHue(getHue());
52 | viewOldColor.setBackgroundColor(color);
53 | viewNewColor.setBackgroundColor(color);
54 |
55 | viewHue.setOnTouchListener(new View.OnTouchListener() {
56 | @Override public boolean onTouch(View v, MotionEvent event) {
57 | if (event.getAction() == MotionEvent.ACTION_MOVE
58 | || event.getAction() == MotionEvent.ACTION_DOWN
59 | || event.getAction() == MotionEvent.ACTION_UP) {
60 |
61 | float y = event.getY();
62 | if (y < 0.f) y = 0.f;
63 | if (y > viewHue.getMeasuredHeight()) y = viewHue.getMeasuredHeight() - 0.001f; // to avoid looping from end to start.
64 | float hue = 360.f - 360.f / viewHue.getMeasuredHeight() * y;
65 | if (hue == 360.f) hue = 0.f;
66 | setHue(hue);
67 |
68 | // update view
69 | viewSatVal.setHue(getHue());
70 | moveCursor();
71 | viewNewColor.setBackgroundColor(getColor());
72 | if (AmbilWarnaDialog.this.listener != null) {
73 | AmbilWarnaDialog.this.listener.onChange(AmbilWarnaDialog.this, getColor());
74 | }
75 |
76 | return true;
77 | }
78 | return false;
79 | }
80 | });
81 | viewSatVal.setOnTouchListener(new View.OnTouchListener() {
82 | @Override public boolean onTouch(View v, MotionEvent event) {
83 | if (event.getAction() == MotionEvent.ACTION_MOVE
84 | || event.getAction() == MotionEvent.ACTION_DOWN
85 | || event.getAction() == MotionEvent.ACTION_UP) {
86 |
87 | float x = event.getX(); // touch event are in dp units.
88 | float y = event.getY();
89 |
90 | if (x < 0.f) x = 0.f;
91 | if (x > viewSatVal.getMeasuredWidth()) x = viewSatVal.getMeasuredWidth();
92 | if (y < 0.f) y = 0.f;
93 | if (y > viewSatVal.getMeasuredHeight()) y = viewSatVal.getMeasuredHeight();
94 |
95 | setSat(1.f / viewSatVal.getMeasuredWidth() * x);
96 | setVal(1.f - (1.f / viewSatVal.getMeasuredHeight() * y));
97 |
98 | // update view
99 | moveTarget();
100 | viewNewColor.setBackgroundColor(getColor());
101 | if (AmbilWarnaDialog.this.listener != null) {
102 | AmbilWarnaDialog.this.listener.onChange(AmbilWarnaDialog.this, getColor());
103 | }
104 |
105 | return true;
106 | }
107 | return false;
108 | }
109 | });
110 |
111 | dialog = new AlertDialog.Builder(context)
112 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
113 | @Override public void onClick(DialogInterface dialog, int which) {
114 | if (AmbilWarnaDialog.this.listener != null) {
115 | AmbilWarnaDialog.this.listener.onOk(AmbilWarnaDialog.this, getColor());
116 | }
117 | }
118 | })
119 | .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
120 | @Override public void onClick(DialogInterface dialog, int which) {
121 | if (AmbilWarnaDialog.this.listener != null) {
122 | AmbilWarnaDialog.this.listener.onCancel(AmbilWarnaDialog.this);
123 | }
124 | }
125 | })
126 | .setOnCancelListener(new OnCancelListener() {
127 | // if back button is used, call back our listener.
128 | @Override public void onCancel(DialogInterface paramDialogInterface) {
129 | if (AmbilWarnaDialog.this.listener != null) {
130 | AmbilWarnaDialog.this.listener.onCancel(AmbilWarnaDialog.this);
131 | }
132 |
133 | }
134 | })
135 | .create();
136 | // kill all padding from the dialog window
137 | dialog.setView(view, 0, 0, 0, 0);
138 |
139 | // move cursor & target on first draw
140 | ViewTreeObserver vto = view.getViewTreeObserver();
141 | vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
142 | @Override public void onGlobalLayout() {
143 | moveCursor();
144 | moveTarget();
145 | view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
146 | }
147 | });
148 | }
149 |
150 | protected void moveCursor() {
151 | float y = viewHue.getMeasuredHeight() - (getHue() * viewHue.getMeasuredHeight() / 360.f);
152 | if (y == viewHue.getMeasuredHeight()) y = 0.f;
153 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewCursor.getLayoutParams();
154 | layoutParams.leftMargin = (int) (viewHue.getLeft() - Math.floor(viewCursor.getMeasuredWidth() / 2) - viewContainer.getPaddingLeft());
155 | ;
156 | layoutParams.topMargin = (int) (viewHue.getTop() + y - Math.floor(viewCursor.getMeasuredHeight() / 2) - viewContainer.getPaddingTop());
157 | ;
158 | viewCursor.setLayoutParams(layoutParams);
159 | }
160 |
161 | protected void moveTarget() {
162 | float x = getSat() * viewSatVal.getMeasuredWidth();
163 | float y = (1.f - getVal()) * viewSatVal.getMeasuredHeight();
164 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewTarget.getLayoutParams();
165 | layoutParams.leftMargin = (int) (viewSatVal.getLeft() + x - Math.floor(viewTarget.getMeasuredWidth() / 2) - viewContainer.getPaddingLeft());
166 | layoutParams.topMargin = (int) (viewSatVal.getTop() + y - Math.floor(viewTarget.getMeasuredHeight() / 2) - viewContainer.getPaddingTop());
167 | viewTarget.setLayoutParams(layoutParams);
168 | }
169 |
170 | private int getColor() {
171 | return Color.HSVToColor(currentColorHsv);
172 | }
173 |
174 | private float getHue() {
175 | return currentColorHsv[0];
176 | }
177 |
178 | private float getSat() {
179 | return currentColorHsv[1];
180 | }
181 |
182 | private float getVal() {
183 | return currentColorHsv[2];
184 | }
185 |
186 | private void setHue(float hue) {
187 | currentColorHsv[0] = hue;
188 | }
189 |
190 | private void setSat(float sat) {
191 | currentColorHsv[1] = sat;
192 | }
193 |
194 | private void setVal(float val) {
195 | currentColorHsv[2] = val;
196 | }
197 |
198 | public void show() {
199 | dialog.show();
200 | }
201 |
202 | public AlertDialog getDialog() {
203 | return dialog;
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/ColorLightsController/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
43 |
44 |
45 |
54 |
55 |
60 |
61 |
66 |
67 |
72 |
73 |
81 |
82 |
83 |
92 |
93 |
98 |
99 |
104 |
105 |
110 |
111 |
119 |
120 |
121 |
130 |
131 |
137 |
138 |
144 |
145 |
146 |
155 |
156 |
164 |
165 |
170 |
171 |
176 |
177 |
178 |
184 |
185 |
186 |
194 |
195 |
200 |
201 |
206 |
207 |
208 |
216 |
217 |
222 |
223 |
228 |
229 |
230 |
239 |
240 |
245 |
246 |
251 |
252 |
257 |
258 |
266 |
267 |
268 |
--------------------------------------------------------------------------------
/OpenWrt/www/color/js/farbtastic.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Farbtastic Color Picker 1.2
3 | * © 2008 Steven Wittens
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | jQuery.fn.farbtastic = function (callback) {
21 | $.farbtastic(this, callback);
22 | return this;
23 | };
24 |
25 | jQuery.farbtastic = function (container, callback) {
26 | var container = $(container).get(0);
27 | return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
28 | }
29 |
30 | jQuery._farbtastic = function (container, callback) {
31 | // Store farbtastic object
32 | var fb = this;
33 |
34 | // Insert markup
35 | $(container).html('');
36 | var e = $('.farbtastic', container);
37 | fb.wheel = $('.wheel', container).get(0);
38 | // Dimensions
39 | fb.radius = 84;
40 | fb.square = 100;
41 | fb.width = 194;
42 |
43 | // Fix background PNGs in IE6
44 | if (navigator.appVersion.match(/MSIE [0-6]\./)) {
45 | $('*', e).each(function () {
46 | if (this.currentStyle.backgroundImage != 'none') {
47 | var image = this.currentStyle.backgroundImage;
48 | image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
49 | $(this).css({
50 | 'backgroundImage': 'none',
51 | 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
52 | });
53 | }
54 | });
55 | }
56 |
57 | /**
58 | * Link to the given element(s) or callback.
59 | */
60 | fb.linkTo = function (callback) {
61 | // Unbind previous nodes
62 | if (typeof fb.callback == 'object') {
63 | $(fb.callback).unbind('keyup', fb.updateValue);
64 | }
65 |
66 | // Reset color
67 | fb.color = null;
68 |
69 | // Bind callback or elements
70 | if (typeof callback == 'function') {
71 | fb.callback = callback;
72 | }
73 | else if (typeof callback == 'object' || typeof callback == 'string') {
74 | fb.callback = $(callback);
75 | fb.callback.bind('keyup', fb.updateValue);
76 | if (fb.callback.get(0).value) {
77 | fb.setColor(fb.callback.get(0).value);
78 | }
79 | }
80 | return this;
81 | }
82 | fb.updateValue = function (event) {
83 | if (this.value && this.value != fb.color) {
84 | fb.setColor(this.value);
85 | }
86 | }
87 |
88 | /**
89 | * Change color with HTML syntax #123456
90 | */
91 | fb.setColor = function (color) {
92 | var unpack = fb.unpack(color);
93 | if (fb.color != color && unpack) {
94 | fb.color = color;
95 | fb.rgb = unpack;
96 | fb.hsl = fb.RGBToHSL(fb.rgb);
97 | fb.updateDisplay();
98 | }
99 | return this;
100 | }
101 |
102 | /**
103 | * Change color with HSL triplet [0..1, 0..1, 0..1]
104 | */
105 | fb.setHSL = function (hsl) {
106 | fb.hsl = hsl;
107 | fb.rgb = fb.HSLToRGB(hsl);
108 | fb.color = fb.pack(fb.rgb);
109 | fb.updateDisplay();
110 | return this;
111 | }
112 |
113 | /////////////////////////////////////////////////////
114 |
115 | /**
116 | * Retrieve the coordinates of the given event relative to the center
117 | * of the widget.
118 | */
119 | fb.widgetCoords = function (event) {
120 | var x, y;
121 | var el = event.target || event.srcElement;
122 | var reference = fb.wheel;
123 |
124 | if (typeof event.offsetX != 'undefined') {
125 | // Use offset coordinates and find common offsetParent
126 | var pos = { x: event.offsetX, y: event.offsetY };
127 |
128 | // Send the coordinates upwards through the offsetParent chain.
129 | var e = el;
130 | while (e) {
131 | e.mouseX = pos.x;
132 | e.mouseY = pos.y;
133 | pos.x += e.offsetLeft;
134 | pos.y += e.offsetTop;
135 | e = e.offsetParent;
136 | }
137 |
138 | // Look for the coordinates starting from the wheel widget.
139 | var e = reference;
140 | var offset = { x: 0, y: 0 }
141 | while (e) {
142 | if (typeof e.mouseX != 'undefined') {
143 | x = e.mouseX - offset.x;
144 | y = e.mouseY - offset.y;
145 | break;
146 | }
147 | offset.x += e.offsetLeft;
148 | offset.y += e.offsetTop;
149 | e = e.offsetParent;
150 | }
151 |
152 | // Reset stored coordinates
153 | e = el;
154 | while (e) {
155 | e.mouseX = undefined;
156 | e.mouseY = undefined;
157 | e = e.offsetParent;
158 | }
159 | }
160 | else {
161 | // Use absolute coordinates
162 | var pos = fb.absolutePosition(reference);
163 | x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
164 | y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
165 | }
166 | // Subtract distance to middle
167 | return { x: x - fb.width / 2, y: y - fb.width / 2 };
168 | }
169 |
170 | /**
171 | * Mousedown handler
172 | */
173 | fb.mousedown = function (event) {
174 | // Capture mouse
175 | if (!document.dragging) {
176 | $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
177 | document.dragging = true;
178 | }
179 |
180 | // Check which area is being dragged
181 | var pos = fb.widgetCoords(event);
182 | fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
183 |
184 | // Process
185 | fb.mousemove(event);
186 | return false;
187 | }
188 |
189 | /**
190 | * Mousemove handler
191 | */
192 | fb.mousemove = function (event) {
193 | // Get coordinates relative to color picker center
194 | var pos = fb.widgetCoords(event);
195 |
196 | // Set new HSL parameters
197 | if (fb.circleDrag) {
198 | var hue = Math.atan2(pos.x, -pos.y) / 6.28;
199 | if (hue < 0) hue += 1;
200 | fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
201 | }
202 | else {
203 | var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
204 | var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
205 | fb.setHSL([fb.hsl[0], sat, lum]);
206 | }
207 | return false;
208 | }
209 |
210 | /**
211 | * Mouseup handler
212 | */
213 | fb.mouseup = function () {
214 | // Uncapture mouse
215 | $(document).unbind('mousemove', fb.mousemove);
216 | $(document).unbind('mouseup', fb.mouseup);
217 | document.dragging = false;
218 | }
219 |
220 | /**
221 | * Update the markers and styles
222 | */
223 | fb.updateDisplay = function () {
224 | // Markers
225 | var angle = fb.hsl[0] * 6.28;
226 | $('.h-marker', e).css({
227 | left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
228 | top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
229 | });
230 |
231 | $('.sl-marker', e).css({
232 | left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
233 | top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
234 | });
235 |
236 | // Saturation/Luminance gradient
237 | $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
238 |
239 | // Linked elements or callback
240 | if (typeof fb.callback == 'object') {
241 | // Set background/foreground color
242 | $(fb.callback).css({
243 | backgroundColor: fb.color,
244 | color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
245 | });
246 |
247 | // Change linked value
248 | $(fb.callback).each(function() {
249 | if (this.value && this.value != fb.color) {
250 | this.value = fb.color;
251 | }
252 | });
253 | }
254 | else if (typeof fb.callback == 'function') {
255 | fb.callback.call(fb, fb.color);
256 | }
257 | }
258 |
259 | /**
260 | * Get absolute position of element
261 | */
262 | fb.absolutePosition = function (el) {
263 | var r = { x: el.offsetLeft, y: el.offsetTop };
264 | // Resolve relative to offsetParent
265 | if (el.offsetParent) {
266 | var tmp = fb.absolutePosition(el.offsetParent);
267 | r.x += tmp.x;
268 | r.y += tmp.y;
269 | }
270 | return r;
271 | };
272 |
273 | /* Various color utility functions */
274 | fb.pack = function (rgb) {
275 | var r = Math.round(rgb[0] * 255);
276 | var g = Math.round(rgb[1] * 255);
277 | var b = Math.round(rgb[2] * 255);
278 | return '#' + (r < 16 ? '0' : '') + r.toString(16) +
279 | (g < 16 ? '0' : '') + g.toString(16) +
280 | (b < 16 ? '0' : '') + b.toString(16);
281 | }
282 |
283 | fb.unpack = function (color) {
284 | if (color.length == 7) {
285 | return [parseInt('0x' + color.substring(1, 3)) / 255,
286 | parseInt('0x' + color.substring(3, 5)) / 255,
287 | parseInt('0x' + color.substring(5, 7)) / 255];
288 | }
289 | else if (color.length == 4) {
290 | return [parseInt('0x' + color.substring(1, 2)) / 15,
291 | parseInt('0x' + color.substring(2, 3)) / 15,
292 | parseInt('0x' + color.substring(3, 4)) / 15];
293 | }
294 | }
295 |
296 | fb.HSLToRGB = function (hsl) {
297 | var m1, m2, r, g, b;
298 | var h = hsl[0], s = hsl[1], l = hsl[2];
299 | m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
300 | m1 = l * 2 - m2;
301 | return [this.hueToRGB(m1, m2, h+0.33333),
302 | this.hueToRGB(m1, m2, h),
303 | this.hueToRGB(m1, m2, h-0.33333)];
304 | }
305 |
306 | fb.hueToRGB = function (m1, m2, h) {
307 | h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
308 | if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
309 | if (h * 2 < 1) return m2;
310 | if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
311 | return m1;
312 | }
313 |
314 | fb.RGBToHSL = function (rgb) {
315 | var min, max, delta, h, s, l;
316 | var r = rgb[0], g = rgb[1], b = rgb[2];
317 | min = Math.min(r, Math.min(g, b));
318 | max = Math.max(r, Math.max(g, b));
319 | delta = max - min;
320 | l = (min + max) / 2;
321 | s = 0;
322 | if (l > 0 && l < 1) {
323 | s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
324 | }
325 | h = 0;
326 | if (delta > 0) {
327 | if (max == r && max != g) h += (g - b) / delta;
328 | if (max == g && max != b) h += (2 + (b - r) / delta);
329 | if (max == b && max != r) h += (4 + (r - g) / delta);
330 | h /= 6;
331 | }
332 | return [h, s, l];
333 | }
334 |
335 | // Install mousedown handler (the others are set on the document on-demand)
336 | $('*', e).mousedown(fb.mousedown);
337 |
338 | // Init color
339 | fb.setColor('#000000');
340 |
341 | // Set linked elements/callback
342 | if (callback) {
343 | fb.linkTo(callback);
344 | }
345 | }
346 |
--------------------------------------------------------------------------------
/AndroidControllableLights.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include "EEPROMAnything.h"
3 |
4 | #define BLUE 5
5 | #define GREEN 3
6 | #define RED 6
7 |
8 | char serialInput;
9 | char receiveBuffer[12];
10 | char i;
11 | long timeOut;
12 |
13 | #define TIMEOUT_INTERVAL 5000
14 | unsigned char global_red, global_green, global_blue;
15 | unsigned int commandCount = 0;
16 |
17 | #define ACTION_NONE 0
18 | #define ACTION_FADE 1
19 | #define ACTION_SNAP 2
20 |
21 | // Action definitions/settings
22 | #define FADE_STEPS 100.0
23 |
24 | const uint8_t EEPROM_VERSION = 0xAB;
25 | #define INIT_FLAGS_ADDR 0
26 | #define CONFIG_ADDR 4
27 |
28 | typedef struct
29 | {
30 | char action;
31 |
32 | // Action variables
33 | unsigned int actionDelay;
34 | unsigned int SpeedDelay;
35 |
36 | unsigned char FadeColors[20][3];
37 | unsigned char FadeColorsCount;
38 | unsigned char FadeCurrentColor;
39 | unsigned char FadeCurrentStep;
40 | float FadeRedChange, FadeGreenChange, FadeBlueChange;
41 |
42 | unsigned char SnapColors[20][3];
43 | unsigned char SnapColorsCount;
44 | unsigned char SnapCurrentColor;
45 |
46 | }
47 | stripCfg_t;
48 |
49 | stripCfg_t stripCfg;
50 |
51 | void checkInitializationFlags() {
52 | uint8_t initFlag;
53 | EEPROM_readAnything(INIT_FLAGS_ADDR, initFlag);
54 | if (initFlag != EEPROM_VERSION) { // Check if the EEPROM version matches the current one
55 | InitializeEEPromValues();
56 | EEPROM_updateAnything(INIT_FLAGS_ADDR, EEPROM_VERSION); // After the default values have been restored, set the flags
57 | }
58 | else {
59 | EEPROM_readAnything(CONFIG_ADDR, stripCfg); // Read existing config from EEProm into RAM
60 | }
61 | }
62 |
63 | void InitializeEEPromValues(void)
64 | {
65 | stripCfg.action = ACTION_NONE;
66 | stripCfg.actionDelay = 0;
67 | stripCfg.SpeedDelay = 100;
68 | stripCfg.FadeColorsCount = 0;
69 | stripCfg.FadeCurrentColor = 0;
70 | stripCfg.FadeCurrentStep = 0;
71 | stripCfg.SnapColorsCount = 0;
72 | stripCfg.SnapCurrentColor = 0;
73 |
74 | EEPROM_updateAnything(CONFIG_ADDR, stripCfg);
75 | }
76 |
77 | void saveUpdatedEEPromConfig(void)
78 | {
79 | EEPROM_updateAnything(CONFIG_ADDR, stripCfg);
80 | }
81 |
82 |
83 | void setup() {
84 |
85 | setStripColor(0, 0, 0);
86 |
87 | Serial.begin(57600);
88 |
89 | Serial.println("Checking initialization flags");
90 | checkInitializationFlags();
91 |
92 | Serial.print("Action: ");
93 | Serial.println(stripCfg.action);
94 |
95 | }
96 |
97 | void loop() {
98 | if (Serial.available() > 0) {
99 | serialInput = Serial.read();
100 | checkBootloader(serialInput);
101 |
102 | if (serialInput == 0x0F) { // Color command
103 | timeOut = millis() + TIMEOUT_INTERVAL;
104 | while (Serial.available() < 12 && timeOut > millis());
105 | if (timeOut > millis()) {
106 | for (i = 0; i < 12; i++) {
107 | receiveBuffer[i] = Serial.read();
108 | }
109 | if (receiveBuffer[3] == ';' && receiveBuffer[7] == ';' && receiveBuffer[11] == ';') {
110 | parseColorInput(receiveBuffer);
111 | saveUpdatedEEPromConfig();
112 | setStripColor(global_red, global_green, global_blue);
113 | }
114 | }
115 | }
116 |
117 | else if (serialInput == 0x01) { // Add fade color
118 | timeOut = millis() + TIMEOUT_INTERVAL;
119 | while (Serial.available() < 12 && timeOut > millis());
120 | if (timeOut > millis()) {
121 | for (i = 0; i < 12; i++) {
122 | receiveBuffer[i] = Serial.read();
123 | }
124 | if (receiveBuffer[3] == ';' && receiveBuffer[7] == ';' && receiveBuffer[11] == ';') {
125 | parseColorInput(receiveBuffer);
126 | stripCfg.FadeColors[stripCfg.FadeColorsCount][0] = global_red;
127 | stripCfg.FadeColors[stripCfg.FadeColorsCount][1] = global_green;
128 | stripCfg.FadeColors[stripCfg.FadeColorsCount][2] = global_blue;
129 | stripCfg.FadeColorsCount++;
130 | saveUpdatedEEPromConfig();
131 | }
132 | }
133 | commandCount++;
134 | Serial.print("Command #");
135 | Serial.println(commandCount);
136 | }
137 |
138 | else if (serialInput == 0x02) { // Reset fade colors
139 | stripCfg.FadeColorsCount = 0;
140 | saveUpdatedEEPromConfig();
141 | commandCount++;
142 | Serial.print("Command #");
143 | Serial.println(commandCount);
144 | }
145 |
146 | else if (serialInput == 0x03) { // Set speed delay
147 | timeOut = millis() + TIMEOUT_INTERVAL;
148 | while (Serial.available() < 6 && timeOut > millis());
149 | if (timeOut > millis()) {
150 | for (i = 0; i < 6; i++) {
151 | receiveBuffer[i] = Serial.read();
152 | }
153 | if (receiveBuffer[5] == ';') {
154 | stripCfg.SpeedDelay = (receiveBuffer[0] - '0') * 10000;
155 | stripCfg.SpeedDelay += (receiveBuffer[1] - '0') * 1000;
156 | stripCfg.SpeedDelay += (receiveBuffer[2] - '0') * 100;
157 | stripCfg.SpeedDelay += (receiveBuffer[3] - '0') * 10;
158 | stripCfg.SpeedDelay += (receiveBuffer[4] - '0');
159 | saveUpdatedEEPromConfig();
160 | }
161 | }
162 | commandCount++;
163 | Serial.print("Command #");
164 | Serial.println(commandCount);
165 | }
166 |
167 | else if (serialInput == 0x04) { // Enable Fade effect
168 | stripCfg.action = ACTION_FADE;
169 | stripCfg.FadeCurrentColor = 0;
170 | stripCfg.FadeCurrentStep = 0;
171 | saveUpdatedEEPromConfig();
172 | commandCount++;
173 | Serial.print("Command #");
174 | Serial.println(commandCount);
175 | }
176 |
177 | else if (serialInput == 0x05) { // Add Snap color
178 | timeOut = millis() + TIMEOUT_INTERVAL;
179 | while (Serial.available() < 12 && timeOut > millis());
180 | if (timeOut > millis()) {
181 | for (i = 0; i < 12; i++) {
182 | receiveBuffer[i] = Serial.read();
183 | }
184 | if (receiveBuffer[3] == ';' && receiveBuffer[7] == ';' && receiveBuffer[11] == ';') {
185 | parseColorInput(receiveBuffer);
186 | stripCfg.SnapColors[stripCfg.SnapColorsCount][0] = global_red;
187 | stripCfg.SnapColors[stripCfg.SnapColorsCount][1] = global_green;
188 | stripCfg.SnapColors[stripCfg.SnapColorsCount][2] = global_blue;
189 | stripCfg.SnapColorsCount++;
190 | saveUpdatedEEPromConfig();
191 | }
192 | }
193 | commandCount++;
194 | Serial.print("Command #");
195 | Serial.println(commandCount);
196 | }
197 |
198 | else if (serialInput == 0x06) { // Reset snap colors
199 | stripCfg.SnapColorsCount = 0;
200 | saveUpdatedEEPromConfig();
201 | commandCount++;
202 | Serial.print("Command #");
203 | Serial.println(commandCount);
204 | }
205 |
206 | else if (serialInput == 0x07) { // Enable Snap effect
207 | stripCfg.action = ACTION_SNAP;
208 | stripCfg.SnapCurrentColor = 0;
209 | saveUpdatedEEPromConfig();
210 | commandCount++;
211 | Serial.print("Command #");
212 | Serial.println(commandCount);
213 | }
214 |
215 | else if (serialInput == 0x0E) { // Disable any effect
216 | stripCfg.action = ACTION_NONE;
217 | saveUpdatedEEPromConfig();
218 | commandCount++;
219 | Serial.print("Command #");
220 | Serial.println(commandCount);
221 | }
222 |
223 | else if (serialInput == 0x1A) { // Invalidate EEProm
224 | EEPROM_updateAnything(INIT_FLAGS_ADDR, (uint8_t)0xFF);
225 | commandCount++;
226 | Serial.print("Command #");
227 | Serial.println(commandCount);
228 | }
229 |
230 | }
231 |
232 | if (stripCfg.action != ACTION_NONE && stripCfg.actionDelay > 0) {
233 | delay(1);
234 | stripCfg.actionDelay -= 1;
235 | //saveUpdatedEEPromConfig(); // commented to reduce EEProm bandwidth
236 | }
237 | else if (stripCfg.action == ACTION_NONE && stripCfg.actionDelay > 0) {
238 | stripCfg.actionDelay = 0; // Reset stripCfg.actionDelay while inactive
239 | saveUpdatedEEPromConfig();
240 | }
241 | else if (stripCfg.action != ACTION_NONE) {
242 | if (stripCfg.action == ACTION_FADE && stripCfg.FadeColorsCount > 0) {
243 | DoFade();
244 | stripCfg.actionDelay = stripCfg.SpeedDelay;
245 | //saveUpdatedEEPromConfig(); // commented to reduce EEProm bandwidth
246 | }
247 |
248 | else if (stripCfg.action == ACTION_SNAP && stripCfg.SnapColorsCount > 0) {
249 | DoSnap();
250 | stripCfg.actionDelay = stripCfg.SpeedDelay;
251 | //saveUpdatedEEPromConfig(); // commented to reduce EEProm bandwidth
252 | }
253 | }
254 |
255 |
256 | }
257 |
258 | void parseColorInput(char * serialBuffer)
259 | {
260 | global_red = (serialBuffer[0] - '0') * 100;
261 | global_red += (serialBuffer[1] - '0') * 10;
262 | global_red += (serialBuffer[2] - '0');
263 | global_green = (serialBuffer[4] - '0') * 100;
264 | global_green += (serialBuffer[5] - '0') * 10;
265 | global_green += (serialBuffer[6] - '0');
266 | global_blue = (serialBuffer[8] - '0') * 100;
267 | global_blue += (serialBuffer[9] - '0') * 10;
268 | global_blue += (serialBuffer[10] - '0');
269 | }
270 |
271 | void resetIntoBootloader(void)
272 | {
273 | analogWrite(7, 0);
274 | }
275 |
276 | char bootloaderPrelimary = 0;
277 | void checkBootloader(char serialChar)
278 | {
279 | if (bootloaderPrelimary == 0) {
280 | if (serialChar == '0')
281 | bootloaderPrelimary = 1;
282 | }
283 | else {
284 | if (serialChar == ' ')
285 | resetIntoBootloader();
286 | else
287 | bootloaderPrelimary = 0;
288 | }
289 | }
290 |
291 | void setStripColor(char red, char green, char blue)
292 | {
293 | analogWrite(RED,(int) red);
294 | analogWrite(GREEN,(int) green);
295 | analogWrite(BLUE,(int) blue);
296 | }
297 |
298 | void DoFade(void)
299 | {
300 | if (stripCfg.FadeCurrentStep == 0) {
301 | if (stripCfg.FadeCurrentColor < (stripCfg.FadeColorsCount-1)) {
302 | stripCfg.FadeRedChange = (stripCfg.FadeColors[stripCfg.FadeCurrentColor+1][0] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][0]) / FADE_STEPS;
303 | stripCfg.FadeGreenChange = (stripCfg.FadeColors[stripCfg.FadeCurrentColor+1][1] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][1]) / FADE_STEPS;
304 | stripCfg.FadeBlueChange = (stripCfg.FadeColors[stripCfg.FadeCurrentColor+1][2] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][2]) / FADE_STEPS;
305 | }
306 | else {
307 | stripCfg.FadeRedChange = (stripCfg.FadeColors[0][0] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][0]) / FADE_STEPS;
308 | stripCfg.FadeGreenChange = (stripCfg.FadeColors[0][1] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][1]) / FADE_STEPS;
309 | stripCfg.FadeBlueChange = (stripCfg.FadeColors[0][2] - stripCfg.FadeColors[stripCfg.FadeCurrentColor][2]) / FADE_STEPS;
310 | }
311 | setStripColor(stripCfg.FadeColors[stripCfg.FadeCurrentColor][0], stripCfg.FadeColors[stripCfg.FadeCurrentColor][1], stripCfg.FadeColors[stripCfg.FadeCurrentColor][2]);
312 | }
313 | else {
314 | setStripColor((stripCfg.FadeColors[stripCfg.FadeCurrentColor][0]+(stripCfg.FadeCurrentStep*stripCfg.FadeRedChange)), (stripCfg.FadeColors[stripCfg.FadeCurrentColor][1]+(stripCfg.FadeCurrentStep*stripCfg.FadeGreenChange)), (stripCfg.FadeColors[stripCfg.FadeCurrentColor][2]+(stripCfg.FadeCurrentStep*stripCfg.FadeBlueChange)));
315 | }
316 |
317 | stripCfg.FadeCurrentStep++;
318 | if (stripCfg.FadeCurrentStep > FADE_STEPS) {
319 | if (stripCfg.FadeCurrentColor < (stripCfg.FadeColorsCount-1)) {
320 | stripCfg.FadeCurrentColor++;
321 | }
322 | else {
323 | stripCfg.FadeCurrentColor = 0;
324 | }
325 | stripCfg.FadeCurrentStep = 0;
326 | }
327 | }
328 |
329 | void DoSnap() {
330 | setStripColor(stripCfg.SnapColors[stripCfg.SnapCurrentColor][0], stripCfg.SnapColors[stripCfg.SnapCurrentColor][1], stripCfg.SnapColors[stripCfg.SnapCurrentColor][2]);
331 |
332 | if (stripCfg.SnapCurrentColor < (stripCfg.SnapColorsCount-1)) {
333 | stripCfg.SnapCurrentColor++;
334 | }
335 | else {
336 | stripCfg.SnapCurrentColor = 0;
337 | }
338 | }
339 |
340 |
--------------------------------------------------------------------------------
/ColorLightsController/src/tkjelectronics/arduino/colorlightscontroller/MainActivity.java:
--------------------------------------------------------------------------------
1 | package tkjelectronics.arduino.colorlightscontroller;
2 |
3 | import java.io.InputStream;
4 | import java.io.OutputStream;
5 | import java.util.Set;
6 | import java.util.UUID;
7 | import java.io.IOException;
8 |
9 | import android.os.Bundle;
10 | import android.app.Activity;
11 | import android.view.Menu;
12 | import android.os.Bundle;
13 | import android.os.Handler;
14 |
15 | import android.app.Activity;
16 | import android.bluetooth.BluetoothAdapter;
17 | import android.bluetooth.BluetoothDevice;
18 | import android.bluetooth.BluetoothSocket;
19 | import android.content.Intent;
20 | import android.os.Bundle;
21 | import android.view.*;
22 | import android.view.View.OnClickListener;
23 | import android.widget.Button;
24 | import android.widget.Toast;
25 | import android.widget.TextView;
26 | import android.widget.EditText;
27 |
28 | import yuku.ambilwarna.AmbilWarnaDialog;
29 | import yuku.ambilwarna.AmbilWarnaDialog.OnAmbilWarnaListener;
30 |
31 | public class MainActivity extends Activity {
32 |
33 | TextView statusLabel;
34 | EditText speedText;
35 |
36 | static int fadeColorsCount = 0;
37 | TextView fadeColorsCountLabel;
38 |
39 | static int snapColorsCount = 0;
40 | TextView snapColorsCountLabel;
41 |
42 | static int runColorsCount = 0;
43 | TextView runColorsCountLabel;
44 |
45 | static int runFadeColorsCount = 0;
46 | TextView runFadeColorsCountLabel;
47 |
48 | static int previousColor = 0;
49 | View viewNewColor;
50 |
51 | BluetoothAdapter mBluetoothAdapter;
52 | BluetoothSocket mmSocket;
53 | BluetoothDevice mmDevice = null;
54 | OutputStream mmOutputStream;
55 | InputStream mmInputStream;
56 | Thread workerThread;
57 | byte[] readBuffer;
58 | int readBufferPosition;
59 | int counter;
60 | volatile boolean stopWorker;
61 |
62 | Thread rapidThread;
63 | volatile boolean stopRapidWorker;
64 | private Handler serialHandler = new Handler();
65 |
66 |
67 | @Override
68 | protected void onCreate(Bundle savedInstanceState) {
69 | super.onCreate(savedInstanceState);
70 | setContentView(R.layout.activity_main);
71 |
72 | Button openButton = (Button)findViewById(R.id.btn_open);
73 | Button closeButton = (Button)findViewById(R.id.btn_close);
74 | statusLabel = (TextView)findViewById(R.id.statusText);
75 | viewNewColor = (View) findViewById(R.id.colorView);
76 | Button mShow = (Button) findViewById(R.id.btn_show);
77 | fadeColorsCountLabel = (TextView)findViewById(R.id.fadeCount);
78 | snapColorsCountLabel = (TextView)findViewById(R.id.snapCount);
79 | runColorsCountLabel = (TextView)findViewById(R.id.runCount);
80 | runFadeColorsCountLabel = (TextView)findViewById(R.id.runFadeCount);
81 | Button disableEffectsButton = (Button)findViewById(R.id.btn_disableEffects);
82 | Button enableFadeButton = (Button)findViewById(R.id.btn_startFade);
83 | Button addFadeColorButton = (Button)findViewById(R.id.btn_addFade);
84 | Button fadeResetButton = (Button)findViewById(R.id.btn_fadeReset);
85 | Button enableSnapButton = (Button)findViewById(R.id.btn_startSnap);
86 | Button addSnapColorButton = (Button)findViewById(R.id.btn_addSnap);
87 | Button snapResetButton = (Button)findViewById(R.id.btn_snapReset);
88 |
89 | Button enableRunButton = (Button)findViewById(R.id.btn_startRun);
90 | Button addRunColorButton = (Button)findViewById(R.id.btn_addRun);
91 | Button runResetButton = (Button)findViewById(R.id.btn_runReset);
92 |
93 | Button enableRunFadeButton = (Button)findViewById(R.id.btn_startRunFade);
94 | Button addRunFadeColorButton = (Button)findViewById(R.id.btn_addRunFade);
95 | Button runFadeResetButton = (Button)findViewById(R.id.btn_runFadeReset);
96 |
97 | Button setSpeedButton = (Button)findViewById(R.id.btn_setSpeed);
98 | speedText = (EditText)findViewById(R.id.speedText);
99 | Button blackOutButton = (Button)findViewById(R.id.btn_blackOut);
100 |
101 | // Pick color button
102 | mShow.setOnClickListener(new View.OnClickListener()
103 | {
104 | public void onClick(View v) {
105 | if (isBTconnected()) {
106 | startRapidData();
107 | LiveColorPicker();
108 | }
109 | }
110 | });
111 |
112 | // Open Button
113 | openButton.setOnClickListener(new View.OnClickListener()
114 | {
115 | public void onClick(View v)
116 | {
117 | try
118 | {
119 | findBT();
120 | openBT();
121 | }
122 | catch (IOException ex) { }
123 | }
124 | });
125 |
126 | // Close button
127 | closeButton.setOnClickListener(new View.OnClickListener()
128 | {
129 | public void onClick(View v)
130 | {
131 | try
132 | {
133 | closeBT();
134 | }
135 | catch (IOException ex) { }
136 | }
137 | });
138 |
139 | // Disable effects button
140 | disableEffectsButton.setOnClickListener(new View.OnClickListener()
141 | {
142 | public void onClick(View v)
143 | {
144 | try
145 | {
146 | if (isBTconnected())
147 | DisableEffects();
148 | }
149 | catch (IOException ex) { }
150 | }
151 | });
152 |
153 | // Black out button
154 | blackOutButton.setOnClickListener(new View.OnClickListener()
155 | {
156 | public void onClick(View v)
157 | {
158 | try
159 | {
160 | if (isBTconnected())
161 | DisableEffects();
162 | BlackOut();
163 | }
164 | catch (IOException ex) { }
165 | }
166 | });
167 |
168 | // Enable fade effect button
169 | enableFadeButton.setOnClickListener(new View.OnClickListener()
170 | {
171 | public void onClick(View v)
172 | {
173 | try
174 | {
175 | if (isBTconnected())
176 | EnableFadeEffect();
177 | }
178 | catch (IOException ex) { }
179 | }
180 | });
181 |
182 | // Add fade color button
183 | addFadeColorButton.setOnClickListener(new View.OnClickListener()
184 | {
185 | public void onClick(View v)
186 | {
187 | if (isBTconnected())
188 | FadeColorAdd();
189 | }
190 | });
191 |
192 | // Reset fade colors button
193 | fadeResetButton.setOnClickListener(new View.OnClickListener()
194 | {
195 | public void onClick(View v)
196 | {
197 | try
198 | {
199 | if (isBTconnected())
200 | ResetFadeColors();
201 | fadeColorsCount = 0;
202 | fadeColorsCountLabel.setText(Integer.toString(fadeColorsCount));
203 | }
204 | catch (IOException ex) { }
205 | }
206 | });
207 |
208 | // Reset fade colors button
209 | setSpeedButton.setOnClickListener(new View.OnClickListener()
210 | {
211 | public void onClick(View v)
212 | {
213 | try
214 | {
215 | if (isBTconnected())
216 | SetSpeed(Integer.valueOf(speedText.getText().toString()));
217 | }
218 | catch (IOException ex) { }
219 | }
220 | });
221 |
222 | // Enable snap effect button
223 | enableSnapButton.setOnClickListener(new View.OnClickListener()
224 | {
225 | public void onClick(View v)
226 | {
227 | try
228 | {
229 | if (isBTconnected())
230 | EnableSnapEffect();
231 | }
232 | catch (IOException ex) { }
233 | }
234 | });
235 |
236 | // Add snap color button
237 | addSnapColorButton.setOnClickListener(new View.OnClickListener()
238 | {
239 | public void onClick(View v)
240 | {
241 | if (isBTconnected())
242 | SnapColorAdd();
243 | }
244 | });
245 |
246 | // Reset snap colors button
247 | snapResetButton.setOnClickListener(new View.OnClickListener()
248 | {
249 | public void onClick(View v)
250 | {
251 | try
252 | {
253 | if (isBTconnected())
254 | ResetSnapColors();
255 | snapColorsCount = 0;
256 | snapColorsCountLabel.setText(Integer.toString(snapColorsCount));
257 | }
258 | catch (IOException ex) { }
259 | }
260 | });
261 |
262 | // Enable running effect button
263 | enableRunButton.setOnClickListener(new View.OnClickListener()
264 | {
265 | public void onClick(View v)
266 | {
267 | try
268 | {
269 | if (isBTconnected())
270 | EnableRunEffect();
271 | }
272 | catch (IOException ex) { }
273 | }
274 | });
275 |
276 | // Add running color button
277 | addRunColorButton.setOnClickListener(new View.OnClickListener()
278 | {
279 | public void onClick(View v)
280 | {
281 | if (isBTconnected())
282 | RunColorAdd();
283 | }
284 | });
285 |
286 | // Reset running colors button
287 | runResetButton.setOnClickListener(new View.OnClickListener()
288 | {
289 | public void onClick(View v)
290 | {
291 | try
292 | {
293 | if (isBTconnected())
294 | ResetRunColors();
295 | runColorsCount = 0;
296 | runColorsCountLabel.setText(Integer.toString(runColorsCount));
297 | }
298 | catch (IOException ex) { }
299 | }
300 | });
301 |
302 | // Enable running fade effect button
303 | enableRunFadeButton.setOnClickListener(new View.OnClickListener()
304 | {
305 | public void onClick(View v)
306 | {
307 | try
308 | {
309 | if (isBTconnected())
310 | EnableRunFadeEffect();
311 | }
312 | catch (IOException ex) { }
313 | }
314 | });
315 |
316 | // Add running fade color button
317 | addRunFadeColorButton.setOnClickListener(new View.OnClickListener()
318 | {
319 | public void onClick(View v)
320 | {
321 | if (isBTconnected())
322 | RunFadeColorAdd();
323 | }
324 | });
325 |
326 | // Reset running fade colors button
327 | runFadeResetButton.setOnClickListener(new View.OnClickListener()
328 | {
329 | public void onClick(View v)
330 | {
331 | try
332 | {
333 | if (isBTconnected())
334 | ResetRunFadeColors();
335 | runFadeColorsCount = 0;
336 | runFadeColorsCountLabel.setText(Integer.toString(runFadeColorsCount));
337 | }
338 | catch (IOException ex) { }
339 | }
340 | });
341 | }
342 |
343 |
344 | public void LiveColorPicker() {
345 | AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, (MainActivity.previousColor | 0xFF000000), new OnAmbilWarnaListener() {
346 |
347 | // Executes, when user click Cancel button
348 | @Override
349 | public void onCancel(AmbilWarnaDialog dialog){
350 | stopRapidWorker = true;
351 | //serialHandler.removeCallbacks(mUpdateTimeTask);
352 | }
353 |
354 | // Executes, when user click OK button
355 | @Override
356 | public void onOk(AmbilWarnaDialog dialog, int color) {
357 | //serialHandler.removeCallbacks(mUpdateTimeTask);
358 | stopRapidWorker = true;
359 | }
360 |
361 | @Override
362 | public void onChange(AmbilWarnaDialog dialog, int color) {
363 | MainActivity.previousColor = color;
364 | viewNewColor.setBackgroundColor(color);
365 | }
366 |
367 | });
368 | dialog.show();
369 | }
370 |
371 | public void FadeColorAdd() {
372 | AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, (MainActivity.previousColor | 0xFF000000), new OnAmbilWarnaListener() {
373 |
374 | // Executes, when user click Cancel button
375 | @Override
376 | public void onCancel(AmbilWarnaDialog dialog){
377 |
378 | }
379 |
380 | // Executes, when user click OK button
381 | @Override
382 | public void onOk(AmbilWarnaDialog dialog, int color) {
383 | MainActivity.previousColor = color;
384 | try
385 | {
386 | AddFadeColor(color);
387 | fadeColorsCount++;
388 | fadeColorsCountLabel.setText(Integer.toString(MainActivity.fadeColorsCount));
389 | }
390 | catch (IOException ex) { }
391 | }
392 |
393 | @Override
394 | public void onChange(AmbilWarnaDialog dialog, int color) {
395 |
396 | }
397 |
398 | });
399 | dialog.show();
400 | }
401 |
402 | public void SnapColorAdd() {
403 | AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, (MainActivity.previousColor | 0xFF000000), new OnAmbilWarnaListener() {
404 |
405 | // Executes, when user click Cancel button
406 | @Override
407 | public void onCancel(AmbilWarnaDialog dialog){
408 |
409 | }
410 |
411 | // Executes, when user click OK button
412 | @Override
413 | public void onOk(AmbilWarnaDialog dialog, int color) {
414 | MainActivity.previousColor = color;
415 | try
416 | {
417 | AddSnapColor(color);
418 | snapColorsCount++;
419 | snapColorsCountLabel.setText(Integer.toString(MainActivity.snapColorsCount));
420 | }
421 | catch (IOException ex) { }
422 | }
423 |
424 | @Override
425 | public void onChange(AmbilWarnaDialog dialog, int color) {
426 |
427 | }
428 |
429 | });
430 | dialog.show();
431 | }
432 |
433 | public void RunColorAdd() {
434 | AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, (MainActivity.previousColor | 0xFF000000), new OnAmbilWarnaListener() {
435 |
436 | // Executes, when user click Cancel button
437 | @Override
438 | public void onCancel(AmbilWarnaDialog dialog){
439 |
440 | }
441 |
442 | // Executes, when user click OK button
443 | @Override
444 | public void onOk(AmbilWarnaDialog dialog, int color) {
445 | MainActivity.previousColor = color;
446 | try
447 | {
448 | AddRunColor(color);
449 | runColorsCount++;
450 | runColorsCountLabel.setText(Integer.toString(MainActivity.runColorsCount));
451 | }
452 | catch (IOException ex) { }
453 | }
454 |
455 | @Override
456 | public void onChange(AmbilWarnaDialog dialog, int color) {
457 |
458 | }
459 |
460 | });
461 | dialog.show();
462 | }
463 |
464 | public void RunFadeColorAdd() {
465 | AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, (MainActivity.previousColor | 0xFF000000), new OnAmbilWarnaListener() {
466 |
467 | // Executes, when user click Cancel button
468 | @Override
469 | public void onCancel(AmbilWarnaDialog dialog){
470 |
471 | }
472 |
473 | // Executes, when user click OK button
474 | @Override
475 | public void onOk(AmbilWarnaDialog dialog, int color) {
476 | MainActivity.previousColor = color;
477 | try
478 | {
479 | AddRunFadeColor(color);
480 | runFadeColorsCount++;
481 | runFadeColorsCountLabel.setText(Integer.toString(MainActivity.runFadeColorsCount));
482 | }
483 | catch (IOException ex) { }
484 | }
485 |
486 | @Override
487 | public void onChange(AmbilWarnaDialog dialog, int color) {
488 |
489 | }
490 |
491 | });
492 | dialog.show();
493 | }
494 |
495 |
496 | @Override
497 | public boolean onCreateOptionsMenu(Menu menu) {
498 | // Inflate the menu; this adds items to the action bar if it is present.
499 | getMenuInflater().inflate(R.menu.activity_main, menu);
500 | return true;
501 | }
502 |
503 |
504 | boolean isBTconnected()
505 | {
506 | if (mmDevice == null) return false;
507 | if (mBluetoothAdapter == null) return false;
508 | if (mmSocket == null) return false;
509 | return true;
510 | }
511 |
512 | void findBT()
513 | {
514 | mmDevice = null;
515 | mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
516 | if(mBluetoothAdapter == null)
517 | {
518 | statusLabel.setText("No bluetooth adapter available");
519 | }
520 |
521 | if(!mBluetoothAdapter.isEnabled())
522 | {
523 | Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
524 | startActivityForResult(enableBluetooth, 0);
525 | }
526 |
527 | Set pairedDevices = mBluetoothAdapter.getBondedDevices();
528 | if(pairedDevices.size() > 0)
529 | {
530 | for(BluetoothDevice device : pairedDevices)
531 | {
532 | if(device.getName().equals("quadcopter"))
533 | {
534 | mmDevice = device;
535 | break;
536 | }
537 | }
538 | }
539 | statusLabel.setText("Bluetooth Device Found");
540 | }
541 |
542 | void openBT() throws IOException
543 | {
544 | UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
545 | mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
546 | mmSocket.connect();
547 | mmOutputStream = mmSocket.getOutputStream();
548 | mmInputStream = mmSocket.getInputStream();
549 |
550 | beginListenForData();
551 |
552 | statusLabel.setText("Bluetooth Opened");
553 | }
554 |
555 | void beginListenForData()
556 | {
557 | final Handler handler = new Handler();
558 | final byte delimiter = 10; //This is the ASCII code for a newline character
559 |
560 | stopWorker = false;
561 | readBufferPosition = 0;
562 | readBuffer = new byte[1024];
563 | workerThread = new Thread(new Runnable()
564 | {
565 | public void run()
566 | {
567 | while(!Thread.currentThread().isInterrupted() && !stopWorker)
568 | {
569 | try
570 | {
571 | int bytesAvailable = mmInputStream.available();
572 | if(bytesAvailable > 0)
573 | {
574 | byte[] packetBytes = new byte[bytesAvailable];
575 | mmInputStream.read(packetBytes);
576 | for(int i=0;i> 16) & 0xFF);
655 | green= (int) ((previousColor >> 8) & 0xFF);
656 | blue= (int) ((previousColor >> 0) & 0xFF);
657 | //alpha= (int) ((tempColor >> 24) & 0xFF);
658 | //String msg = Long.toString(tempColor);
659 | String msg = String.format("%c%03d;%03d;%03d;", 0x0F, red, green, blue); // 0x0A = Color command
660 | mmOutputStream.write(msg.getBytes());
661 |
662 | /*buffer[0] = red;
663 | buffer[1] = green;
664 | buffer[2] = blue;
665 | buffer[3] = 0x0A;*/
666 | //mmOutputStream.write(buffer);
667 | }
668 | catch (IOException ex)
669 | {
670 | stopRapidWorker = true;
671 | }
672 |
673 | try {
674 | Thread.sleep(100, 0);
675 | } catch (InterruptedException e) {
676 | stopRapidWorker = true;
677 | }
678 | }
679 | }
680 | });
681 |
682 | rapidThread.start();
683 | }
684 |
685 | void BlackOut() throws IOException
686 | {
687 | String msg = String.format("%c%03d;%03d;%03d;", 0x0F, 0, 0, 0); // 0x0A = Color set command
688 | mmOutputStream.write(msg.getBytes());
689 | }
690 |
691 | void AddFadeColor(int color) throws IOException
692 | {
693 | int red= (int) ((color >> 16) & 0xFF);
694 | int green= (int) ((color >> 8) & 0xFF);
695 | int blue= (int) ((color >> 0) & 0xFF);
696 | //int alpha= (int) ((color >> 24) & 0xFF);
697 |
698 | String msg = String.format("%c%03d;%03d;%03d;", 0x01, red, green, blue); // 0x01 = Fade color command
699 | mmOutputStream.write(msg.getBytes());
700 | }
701 |
702 | void DisableEffects() throws IOException
703 | {
704 | byte buffer[] = new byte[1];
705 | buffer[0] = 0x0E;
706 | mmOutputStream.write(buffer);
707 | }
708 |
709 | void EnableFadeEffect() throws IOException
710 | {
711 | byte buffer[] = new byte[1];
712 | buffer[0] = 0x04;
713 | mmOutputStream.write(buffer);
714 | }
715 |
716 | void ResetFadeColors() throws IOException
717 | {
718 | byte buffer[] = new byte[1];
719 | buffer[0] = 0x02;
720 | mmOutputStream.write(buffer);
721 | }
722 |
723 | void SetSpeed(int speed) throws IOException
724 | {
725 | if (speed < 100000) {
726 | String msg = String.format("%c%05d;", 0x03, speed); // 0x03 = Speed command
727 | mmOutputStream.write(msg.getBytes());
728 | }
729 | }
730 |
731 | void EnableSnapEffect() throws IOException
732 | {
733 | byte buffer[] = new byte[1];
734 | buffer[0] = 0x07;
735 | mmOutputStream.write(buffer);
736 | }
737 |
738 | void ResetSnapColors() throws IOException
739 | {
740 | byte buffer[] = new byte[1];
741 | buffer[0] = 0x06;
742 | mmOutputStream.write(buffer);
743 | }
744 |
745 | void AddSnapColor(int color) throws IOException
746 | {
747 | int red= (int) ((color >> 16) & 0xFF);
748 | int green= (int) ((color >> 8) & 0xFF);
749 | int blue= (int) ((color >> 0) & 0xFF);
750 | //int alpha= (int) ((color >> 24) & 0xFF);
751 |
752 | String msg = String.format("%c%03d;%03d;%03d;", 0x05, red, green, blue); // 0x01 = Snap color command
753 | mmOutputStream.write(msg.getBytes());
754 | }
755 |
756 | void EnableRunEffect() throws IOException
757 | {
758 | byte buffer[] = new byte[1];
759 | buffer[0] = 0x0A;
760 | mmOutputStream.write(buffer);
761 | }
762 |
763 | void ResetRunColors() throws IOException
764 | {
765 | byte buffer[] = new byte[1];
766 | buffer[0] = 0x09;
767 | mmOutputStream.write(buffer);
768 | }
769 |
770 | void AddRunColor(int color) throws IOException
771 | {
772 | int red= (int) ((color >> 16) & 0xFF);
773 | int green= (int) ((color >> 8) & 0xFF);
774 | int blue= (int) ((color >> 0) & 0xFF);
775 | //int alpha= (int) ((color >> 24) & 0xFF);
776 |
777 | String msg = String.format("%c%03d;%03d;%03d;", 0x08, red, green, blue); // 0x01 = Run color command
778 | mmOutputStream.write(msg.getBytes());
779 | }
780 |
781 | void EnableRunFadeEffect() throws IOException
782 | {
783 | byte buffer[] = new byte[1];
784 | buffer[0] = 0x0D;
785 | mmOutputStream.write(buffer);
786 | }
787 |
788 | void ResetRunFadeColors() throws IOException
789 | {
790 | byte buffer[] = new byte[1];
791 | buffer[0] = 0x0C;
792 | mmOutputStream.write(buffer);
793 | }
794 |
795 | void AddRunFadeColor(int color) throws IOException
796 | {
797 | int red= (int) ((color >> 16) & 0xFF);
798 | int green= (int) ((color >> 8) & 0xFF);
799 | int blue= (int) ((color >> 0) & 0xFF);
800 | //int alpha= (int) ((color >> 24) & 0xFF);
801 |
802 | String msg = String.format("%c%03d;%03d;%03d;", 0x0B, red, green, blue); // 0x01 = Run color command
803 | mmOutputStream.write(msg.getBytes());
804 | }
805 |
806 | }
807 |
808 |
--------------------------------------------------------------------------------