Arduino Led: Control RGB led using Android app

Arduino Led or in other words how to control a RGB led connected to Arduino is and interesting topic. This post describes how to control RGB led using Android and Arduino. This is an interesting topic because it mixes two ecosystems together. Moreover, what we want to obtain is picking a color from Android smartphone UI and make Arduino turning on an RGB led with the same color we picked from the Android UI.

To make things working 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, it is necessary to send data to Arduino. The data is built by the three color values (Red, Green, Blue). One the Arduino side, the RGB led controller, we have to create a server that receives the three colors values and controls RGB led.

First of all, if you are new to Internet of things project, you should read Internet of things project with Arduino and Android, so that you get introduced to IoT projects.
The final result is shown below:

Project Overview

Before digging into the project details, it is useful to have a project overview:
control rgb led connected to arduino using Android app
In a previous post we talked about how to turn on and off a led connected to Arduino using 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

Now we know what to do let’s start.

Android color picker View

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 Arduino led (RGB). Let us start from the final Android UI result:

android color picker

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 Android Floating Action Button:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"	 	 
 android:paddingLeft="@dimen/activity_horizontal_margin"	 	 
 android:paddingRight="@dimen/activity_horizontal_margin"	 	 
 android:paddingTop="@dimen/activity_vertical_margin"	 	 
 app:layout_behavior="@string/appbar_scrolling_view_behavior"	 	
 tools:context="com.survivingwithandroid.rgbcontroller.MainActivity"	 	 
 tools:showIn="@layout/activity_main">	 	 
 <TextView	 	 
 android:layout_width="wrap_content"	 	 
 android:layout_height="wrap_content"	 	 
 android:text="Control Arduino RGB Led"	 	 
 android:layout_centerInParent="true"	 	 
 android:textSize="25sp"/>	 	 
 <TextView	 	 
 android:layout_width="wrap_content"	 	 
 android:layout_height="wrap_content"	 	 
 android:layout_alignParentBottom="true"	 	 
 android:layout_alignParentLeft="true"	 	 
 android:layout_marginLeft="5dp"	 	 
 android:id="@+id/msg"/>	 	 
</RelativeLayout>

As a result, when user presses the FAB the app has to show the Color picker dialog:

@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 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) &amp;amp; 0xFF;
   int g = (selectedColor >> 8) &amp;amp; 0xFF;
   int b = (selectedColor >> 0) &amp;amp; 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 button the app extracts the Red, Green and Blue component and sends it to Arduino.

Android HTTP client

To send data to Arduino, it is necessary to create a simple HTTP client that sends Red, Green and Blue component as JSON string.Arduino will use this information to control 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 colors 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 RGB led connected to Arduino.

How to control Arduino led (RGB)

Now the Android client side is ready, it is time to build the Arduino side so that it can control an Arduino led. The first step is creating the Arduino sketch. This tutorial uses 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:
arduino led: control RGB led using android app
The three led pins are connected to Arduino PWM using a 300-ohm resistance.
That’s all, the “hardware” part is ready to be used. If you want to test the Arduino led to know if everything works correctly you can write a simple sketch to check if the Arduino RGB is working properly.
In the diagram above, the ethernet shield is not shown to simplify the diagram. Of course, to connect Arduino to Internet is necessary to have an ethernet shield or a WI-FI shield. This tutorial uses the ethernet shield.

Arduino HTTP Server

In addition to the “hardware” part, Arduino has to accept HTTP connection because the Android client sends data (the RGB values) using HTTP. Therefore, 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 initialise 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...");
}

Finally, it is time to accept incoming requests and parse them.

Parse HTTP request

To parse the HTTP request and extract data, we can use this piece of code:

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();

     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("");
   client.println(""); delay(1);
   break; 
  }

  if (c == '\n' &amp;&amp; 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 Arduino 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.

Conclusion

There are a lot of Internet of things project based on Arduino using cloud: the limit is your fantasy. There are other ways to exchange data with Arduino: one method is based on Arduino Rest API.

At the end of this post, you know how to send data from Android app to Arduino and how to control  RGB led. In other words, Android app remotely controls the Arduino board that in turn is the Arduino led controller.

 

  • JJ

    Nice Article – Thanks
    But how did you connect the Arduino to the internet?

    • You can connect to Internet using an Ethernet shield or Ethernet WiFI

  • meccip

    Hi,
    Nice project. I am working on something like that but i am having some problems, maybe you can help me.
    I am using NetIO app (http://netio.davideickhoff.de/de/) to send and receive data with my arduino.
    I was able to control brightness for one led with a slider (send value to arduino from 0 to 255… “set brightness {value}”).
    My problem is that i want to control brightness of 3 leds (R,G,B). NetIO have a colorpicker widget and sends 3 values at the same time “set {value} {value} {value}”

    This is my code for arduino to control brightness of 1 led. Can you please help me with some ideas to control 3 leds. Thank you.

    #include
    #include
    // end include library
    #define BUFSIZ 64

    //global variable
    byte mac[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; // mac address of Ethernet shield
    IPAddress ip(192, 168, 1, 112); // IP address, may need to change depending on network
    EthernetServer androidServer(2562); // set port number for android netIO

    int fadeLed = 7;
    int brightness = 0;

    void setup(){

    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);

    Serial.begin(9600); //for debug
    Ethernet.begin(mac, ip); // initialize Ethernet device
    androidServer.begin(); // start the server for android netIO

    pinMode(fadeLed, OUTPUT);

    }

    void loop()
    {
    androidInterface();

    }

    void androidInterface() { // connection with netIO

    int index = 0;
    char Remote[BUFSIZ];

    EthernetClient client = androidServer.available();
    if (client) {
    if (client.connected()) {
    while (client.available()) {
    char c = client.read();
    //Serial.print(c); // print to the screen
    if (c != ‘\n’ && c != ‘\r’) { // no linefeed or CR so keep reading
    Remote[index] = c;
    index++;
    if (index >= BUFSIZ)
    index = BUFSIZ -1;
    continue;
    }
    Remote[index] = 0;
    }
    Serial.println(” “);
    Serial.print(“String received from android: “);
    Serial.println(Remote);

    if (strstr(Remote, “set brightness”)) { // is it a slider value
    client.println(“OK”);
    brightness = ledDimm (Remote);
    analogWrite(fadeLed, brightness);
    delay(30);
    }

    if (strstr(Remote, “get brightness”)) { // set the slider to last brightness value
    client.println(brightness);
    }

    } //—– End of if client.connected
    } //——- End of if client
    } //——— End of iPadInterface()

    int ledDimm(String command)
    {
    // Get the Value xx from string set brightness xx
    String substring = command.substring(15, command.length());

    // Create a Char Array to Store the Substring for conversion
    char valueArray[substring.length() + 1];

    // Copy the substring into the array
    substring.toCharArray(valueArray, sizeof(valueArray));

    // Convert char array to an int value
    int value = atoi(valueArray);

    return value;

    }

    • I guess i’m missing something. If you use a RGB led you should have 4 pins (1 is the ground) the other 3 are RGB component.
      Maybe are you using a different RGB led? with only one color pin? In this case i guess you should use bit shifting to create the color.
      Let me know more about your components.
      Btw i don’t know NetIO.

      • meccip

        With NetIO you can make a page on your android with buttons, label, sliders, switches, png backgrounds…..you can add to this different functions as send, reads, release, responses, connections with server……..(for example I am using this app for controlling my home lights, PIR sensors, door switches and more)

        For this code I am using simple white led stripe. Arduino pwm pin 7 is connected to N-Mosfet. Led stripe is connected to Mosfet and +12v. Values received from NetIO slider (0 to 255) control brightness of led stripe. When connection android-arduino is made the value is received like this (set brightness 150) and then send back for slider read as (get brightness 150). This is just an example, slider can send value between 0-255.

        For my RGB project, I will have 3 pwm pins (5,6,7 – red,green,blue ) all connected to N-Mosfets and common +12v.
        I try to use 3 sliders to send values to arduino (set brightness1….set brightness2….set brightness3) and I multiply int ledDimm(String command)….( int ledDimm1……. int ledDimm2…… int ledDimm3….). It is working but you have to make colors by adjusting sliders manually.

        The colorpicker widget send 3 values at the same time “set {value} {value} {value}” and my code is not working with this value received. I need to add something to this and i dont know what..

        ……….
        if (strstr(Remote, “set brightness”)) { // is it a slider value
        client.println(“OK”);
        brightness = ledDimm (Remote);
        analogWrite(fadeLed, brightness);
        delay(30);
        }

        if (strstr(Remote, “get brightness”)) { // set the slider to last brightness value
        client.println(brightness);
        }

        } //—– End of if client.connected
        } //——- End of if client
        } //——— End of iPadInterface()

        int ledDimm(String command)
        {
        // Get the Value xx from string set brightness xx
        String substring = command.substring(15, command.length());

        // Create a Char Array to Store the Substring for conversion
        char valueArray[substring.length() + 1];

        // Copy the substring into the array
        substring.toCharArray(valueArray, sizeof(valueArray));

        // Convert char array to an int value
        int value = atoi(valueArray);

        return value;

        }

        • Ok…so you would like to have a color picker that create three component from the color you selected.
          If so you can use bit shifting…if you have the color in HEX (like the widget i used in the example): the first two letters are Red component, the second two are Green, and the last two Blue.
          Then you should send these values as you send the values from your slider.

  • nice blog. hi i want to ask you how to to control rgb led by using esp8266 from android app.in case i want to make app to kontrol it?

  • Nice article. Just share with you my project of GRB LED strip with Arduino http://www.instructables.com/id/RGB-LED-With-Arduino/
    It is designed on EasyEDA which is a great online tool for helping you complete your design from schematic to the finished PCB in the shortest time and easiest way. Try it at https://easyeda.com for free

  • redim

    Nice tutorial. Hi i want control turn off/on led using android apps to arduino over ubidots. Can you give me example for that?
    I’ve done create switch on Ubidots. Switch always send value 1.0 for turn on or 0.0 for turn off.
    I hope you can help me
    Thanks 🙂