Control RGB LEDs Using Android and Arduino
This is an interesting topic because two ecosystems are mixed together and integrated. By picking a color from an app running on your Android smartphone, we will make an Arduino switch on a RGB LED of that same color.
Join the DZone community and get the full member experience.
Join For Freeto make everything work there are several aspects to consider: first it is necessary to create an android app so that we can select the color we want. then, we need to send that data to arduino. the data is built by the three colour values (red, green, blue). on the arduino side, we have to create a server that receives the three colours values and controls an rgb led.
as a final result, we will get something like this:
before digging into the project details, it is useful to have a project overview:
in a previous post we talked about
how to turn on and off an led connected to an arduino using an android app
, now it is time to make things a little more complex.
to build this project, we need:
android side:
- colour picker view
- http client that sends data
arduino side:
- http server to get data
- simple json parser
- rgb led handler
to control rgb led, the first step is creating an android color picker ui so that the user can pick the color to turn on the rgb led. let us start from the final android ui result:
to create this interface we used an interesting open source project called color picker . this component is very easy to use.
at the first step, we create the main layout based on the android floating action button:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.coordinatorlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitssystemwindows="true"
tools:context="com.survivingwithandroid.rgbcontroller.mainactivity"
android:id="@+id/mainlyt">
<android.support.design.widget.appbarlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/apptheme.appbaroverlay">
<android.support.v7.widget.toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionbarsize"
android:background="?attr/colorprimary"
app:popuptheme="@style/apptheme.popupoverlay" />
</android.support.design.widget.appbarlayout>
<include layout="@layout/content_main" />
<android.support.design.widget.floatingactionbutton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_input_get" />
</android.support.design.widget.coordinatorlayout>
now when a user presses the fab, the app will show the color picker dialogue:
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
toolbar toolbar = (toolbar) findviewbyid(r.id.toolbar);
setsupportactionbar(toolbar);
......
floatingactionbutton fab = (floatingactionbutton) findviewbyid(r.id.fab);
fab.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view view) {
// handle fab click event
}
}
}
it is time to show the color picker dialog that will control the rgb led in the
onclick
method:
colorpickerdialogbuilder
.with(mainactivity.this)
.settitle("choose rgb color")
.initialcolor(color.white)
.wheeltype(colorpickerview.wheel_type.flower)
.lightnessslideronly()
.density(12)
.setoncolorselectedlistener(new oncolorselectedlistener() {
@override
public void oncolorselected(int selectedcolor) {
// nothing to do...
}
})
.setpositivebutton("ok", new colorpickerclicklistener() {
@override
public void onclick(dialoginterface dialog, int selectedcolor, integer[] allcolors) {
int r = (selectedcolor >> 16) & 0xff;
int g = (selectedcolor >> 8) & 0xff;
int b = (selectedcolor >> 0) & 0xff;
log.d("rgb", "r [" + r + "] - g [" + g + "] - b [" + b + "]");
sendcolor(r,g,b);
}
})
.setnegativebutton("cancel", new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog, int which) {
}
})
.build()
.show();
as you can see this component is very simple to use, when the user clicks ok, the app extracts the red, green, and blue components and sends them to arduino.
to send data to arduino, we need to create a simple http client that sends the red, green, and blue components as a json string. arduino will use this information to control the rgb led. the android http client is very simple and it is based on okhttp .
private void sendcolor(int r, int g, int b) {
log.d("rgb", "sending data to arduino....");
request req = new request.builder()
.url(url)
.post(requestbody.create(json, createjson(r,g,b)))
.build();
tv.settext("sending data to arduino...");
client.newcall(req).enqueue(new callback() {
@override
public void onfailure(call call, ioexception e) {
// handle call failure
}
@override
public void onresponse(call call, response response) throws ioexception {
// ok response...inform the user
}
});
}
where
createjson
method is very simple:
private string createjson(int r, int g, int b) {
return "{\"color\": [" + r + "," + g + "," + b + "]}";
}
it returns the three color values.
the android side is completed, as you can see with a few lines of code we created a nice android app that will control an rgb led connected to arduino.
now the android client side is ready, it is time to build the arduino side. the first step is creating the arduino sketch. this tutorial uses a
common anode
rgb led, that means the vcc is connected to the anode. if you use a
common cathode led
the cathode must be connected to the ground.
the arduino sketch is shown below:
the three led pins are connected to arduino pwm using a 300 ohm resistor. that’s all, the “hardware” part is ready to be used. if you want to test the arduino to know if everything works correctly you can use this arduino sketch.
in the diagram above, the ethernet shield is not shown to simplify the diagram. of course, to connect arduino to the internet, it's necessary to have an ethernet shield or a wi-fi shield. this tutorial uses the ethernet shield .
now that the “hardware” part is ready, arduino has to accept the http connection so that the android client can send data (the rgb values). it is necessary to build, then, a simple http server that parses the incoming requests and extracts the values.
in the
setup
method of the sketch, we initialize the arduino pins to control the rgb led and the ethernet ip.
void setup() {
// put your setup code here, to run once:
serial.begin(9600);
// pin mode
pinmode(redpin, output);
pinmode(bluepin, output);
pinmode(greenpin, output);
serial.print("ready...");
//
ethernet.begin(mac, ip);
server.begin();
serial.println("begin...");
}
now it is time to accept incoming requests and parse them:
void loop() {
ethernetclient client = server.available(); // is there a client (our android smartphone)
if (client) {
// let's start reading
boolean islastline = true;
boolean isbody = false;
header = "";
reqdata = "";
int contentlen = 0;
serial.print("client connected!");
while (client.connected()) {
if (client.available()) {
// read data
char c = client.read();
// serial.print(c);
if (contentsize == contentlen) {
serial.println("body ["+reqdata+"]");
// extract the json string like [r,g,b]
int pos1 = reqdata.indexof("[");
int pos2 = reqdata.lastindexof("]");
// parse the string looking for ,
string colors = reqdata.substring(pos1 + 1, pos2);
serial.println("colors ["+colors+"]");
int idx1 = colors.indexof(',');
int idx2 = colors.indexof(',', idx1+1);
int idx3 = colors.indexof(',', idx2+1);
string sred = colors.substring(0, idx1);
string sgreen = colors.substring(idx1 + 1, idx2);
string sblue = colors.substring(idx2 + 1, idx3);
// convert the red, green and blue string values to int
int red = sred.toint();
int green = sgreen.toint();
int blue = sblue.toint();
// set the rgb led color according to the values sent by the android client
setcolor(red, green,blue);
// create the response to client
client.println("http/1.1 200 ok");
client.println("content-type: text/html");
client.println("connection: close");
client.println();
// send web page
client.println("<!doctype html>");
client.println("<html>");
delay(1);
break;
}
if (c == '\n' && islastline) {
isbody = true;
int pos = header.indexof(content_length_txt);
string tmp = header.substring(pos, header.length());
//serial.println("tmp ["+tmp+"]");
int pos1 = tmp.indexof("\r\n");
string size = tmp.substring(content_length_txt.length(), pos1);
serial.println("size ["+size+"]");
contentsize = size.toint();
}
if (isbody) {
reqdata += c;
contentlen++;
}
else {
header += c;
}
if (c == '\n' ) {
islastline = true;
}
else if (c != '\r' ) {
islastline = false;
}
}
}
// close connection
serial.println("stop..");
client.stop();
}
}
the source code seems to be complex but it is very simple if you look at it carefully. it is always an http arduino server.
the last part is setting the rgb led color:
void setcolor(int red, int green, int blue) {
#ifdef common_anode
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogwrite(redpin, red);
analogwrite(bluepin, green);
analogwrite(greenpin, blue);
}
notice that if we use a
common anode
, we have to invert the values.
source code available soon.
Published at DZone with permission of Francesco Azzola, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments