Turning a LED on and off with an Arduino, a HC-06 and Android

Although I use a HC-06 in the below examples the HC-05 in slave mode can also be used.

Using MITs app inventor it is fairly easy to create an app that can turn a LED on and off from an Android device.

This is a fairly simply example of sending commands to the Arduino to turn a LED either on or off. The Android app sends ascii codes to the Arduino via the HC-06 BT module; “ON” for on and “OF” for off.

Load the app, connect to the HC-06 and then use the LED button to turn the LED on and off.


You can also open the serial monitor to see the commands as they are received

The steps involved are:
1. create a circuit that includes a Bluetooth module and a LED
2. create an Arduino sketch that can receive commands from the HC-06 and turn a LED on and off
3. create an Android app that sends commands over Bluetooth

The circuit

The circuit is the same as the one used in Arduino and HC-06 (ZS-040) except the addition of a LED + resistor connected to pin D12. I used a 220 ohm resistor because that is what I had to hand but similar values will be OK.

Based on ohm’s law; using a source of 5V, a green LED with a forward voltage drop of 2.2v and a forward current of 20mA a 150 ohm resistor is recommended. So any value from 180ohm to around 680 ohms will be OK.



Arduino Sketch

The sketch receives data from the Bluetooth module via software serial. It then checks the data for “ON” and “OF” commands. When “ON” is received the LED is turned on and when “OF” is received the LED is turned off.

To ensure that data is received correctly the data is surrounded by start and end markers. This example uses “<" and ">“. I use the function recvWithStartEndMarkers which was posted on the Arduino forum by Robin2. I simply copied the function and did not need to change it.

The recvWithStartEndMarkers() function takes at the data received from the serial connection and copies anything it finds between the start and end markers to the receivedChars variable. When it has found something it sets the newData variable to true.

In the main loop we keep calling the recvWithStartEndMarkers() function until newData has been set. When newData is True we know we have a new command so we call parseData() to deal with it. Inside parseData() we reset newData to false and the process continues.

void loop() 
     if (BTserial.available() > 0)     {  recvWithStartEndMarkers(); }
     if (newData) { parseData(); }

The full sketch:

// Bluetooth sketch HC-06_02
// Turn a LED on and off from an Android app
// App can be downloaded from www.martyncurrey.com
// Pins
// 2 Software serial - RX
// 3 Software serial - TX
// 12 LED
boolean debug = true;
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX
// Connect the HC-06 TX to the Arduino RX. 
// Connect the HC-06 RX to the Arduino TX through a voltage divider.
// max length of command is 20 chrs
const byte numChars = 20;
char receivedChars[numChars];
boolean newData = false;
byte LEDpin = 12;
void setup() 
     pinMode(LEDpin, OUTPUT); 
     Serial.println("<Arduino is ready>");
     // The default baud rate for the HC-06s I have is 9600. Other modules may have a different speed. 38400 is common.
void loop() 
     if (BTserial.available() > 0)     {  recvWithStartEndMarkers(); }
     if (newData) { parseData(); }
void parseData()
        newData = false;    
        if (debug) {  Serial.println( receivedChars ); }
        if (receivedChars[0] == 'O'  && receivedChars[1] == 'N' )  { digitalWrite(LEDpin,HIGH);  }
        if (receivedChars[0] == 'O'  && receivedChars[1] == 'F' )  { digitalWrite(LEDpin,LOW);   }       
void recvWithStartEndMarkers() 
     // function recvWithStartEndMarkers by Robin2 of the Arduino forums
     // See  http://forum.arduino.cc/index.php?topic=288234.0
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '<';
     char endMarker = '>';
     char rc;
     if (BTserial.available() > 0) 
          rc = BTserial.read();
          if (recvInProgress == true) 
               if (rc != endMarker) 
                    receivedChars[ndx] = rc;
                    if (ndx >= numChars) { ndx = numChars - 1; }
                     receivedChars[ndx] = '\0'; // terminate the string
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
          else if (rc == startMarker) { recvInProgress = true; }

Android App

I created the Android app in MITs app inventor. This was fairly easy once I had figured out how to use Bluetooth.

The app is very basic, it simply sends commands. There are no checks to see if the Arduino has actually received the commands or not. The screen is also very simple; it has a button for connecting to Bluetooth and a on/off button to control the LED. The app uses a ListPicker to store the available Bluetooth devices which is not displayed on screen. It is initiated from the connect button.


The app has 4 blocks and a list:

Block 1

This handles the connect button. When the button is clicked the block/function first checks to see if Bluetooth is enabled and then checks to see if there is already a Bluetooth connection. If Bluetooth is not turned on an error message is displayed. If there is already an active connection the user is asked if they would like to close it. The user reply is handled in Block3, Notifier1.AfterChoosing

If Bluetooth is on and there isn’t a current connection the paired Bluetooth devices are copied to the Bluetooth pairedDevices List. If the list has at least 1 item the contents of the list are copied to the ListPicker. The ListPicker is then activated to allow the user to select a Bluetooth device. I use the pairedDevices list so that I can count the number paired devices. I could not find a way of doing this when using just a ListPicker. If the list is empty an error message is displayed saying there are no paired devices.


Block 2

Block 2, BT_LP.AfterPicking handles the List Picker after the user has selected one of the paired Bluetooth devices. It takes the selected item and tries to connect. If successful the text on the Bluetooth button is changed to “Connected”. If a connection cannot be established an error message is displayed.

Once a connection is established the app waits for the LED button to be pressed.


Block 3

Block 3 handles a Notifier dialogue that asks the user if they wish to close the connection

Block 4

Block 4, LED_BUTTON_btn.Click, handles the LED button. By checking the button text we can determine what command to send. If the text says “ON” then the LED is on and we need to turn it off so we send an “OF” command. If the text says “OFF”, the LED is off so we send an “ON” command to turn it on. The actual commands are “<ON>” and “<OF>”. The button text and background colour are updated to reflect the new LED status.

An error message is displayed if the LED button is clicked and there is no active connection.




Download the zip file containing the Arduino sketch, the ardiunoBTcontrol app and the appinventor aia file.

In part 2 we add 2-way communication and the facility to control the LED from the Arduino as well as the app.

Add an auto-connect function to an App Inventor app. https://www.martyncurrey.com/android-mit-app-inventor-auto-connect-to-bluetooth/


59 thoughts on “Turning a LED on and off with an Arduino, a HC-06 and Android”

  1. Hello, and first off thank you for this helpful blog. I was able to use it and make my own app to control my arduino through my Bluetooth shield. I’ve spent weeks before I came across this and within 1 night was able to get everything working. My questions now is my project has an auto off built into the code, is there any way to send a signal to the app to change the button states to show off. Thanks again

  2. dear Martyn, your simplified illustration and work is really appreciable, i have made this circuit and its working completely. but i have one query that can we made HC-06 as auto connect after we paired it first time ? actually its really annoying that every time we have to connect the phone to HC-06, likewise wifi can we do auto connect, please correct me and guide. thanks for your awesome work .

  3. Hi prashant pitroda,

    yes this is possible although I do not have an example to post at the moment.

    The simplest way would be to change the address used in the “BluetoothClient1.Connect” block. At present the address comes from the Listpicker selected item “address BT_LP.Selection”. Change this to the address of your HC-06.

    To take this further, I would allow the user to connect as per the above then add the facility to remember the paired & connected address. Then on start up, if there was a remembered address try to connect.

  4. I tryed a timer block (100ms):

    And this code sends serial data from the arduino board to the phone when the LED is switched on/off:
    if(dataFromBt == ‘3’){

    Now, the phone receive the status of the LED and update the LED button status (on or off) , but the app freezes if it doesn’t receive anything (phone is out of range).
    I get a pop up message saying ” Error 516: Unable to write: Broken pipe ” and I can’t work with the app any longer.

  5. sir I’m getting an” error 516: unable to write:[JSR82] write: write() failed. what should I do. BT is connecting to app but led is not responding.
    PLZZZ….. help

  6. Hello,
    I have done a program with sliders in app inventor 2 to control RGB led strip and when i move the slider to change the color of the RGB led strip in serial monitor i get only symbols in serial monitor of the ardruino and not numbers. what is the problem?

    Note: if i send a number from the bluetooth terminal on my android phone i receive the number correct in serial monitor of the ardruino

    • 2 things to check.

      1. the baud rate between the Arduino and the BT module
      2. the format of the data being sent. It could be you are sending actual values (1,2,3 etc) and then treating them as ascii on the Arduino.

      Convert the value from the sliders to ascii then send. The format I use is <Srrrgggbbb>

      S for slider
      rrr – the decimal red value in acsii
      ggg – the decimal green value in acsii
      bbb – the decimal rblue value in acsii

      See https://www.martyncurrey.com/arduinobtcontrol/. I created my own sliders but you can use the built in sliders exactly the same.

  7. Hi guys , I have a proble that is about error message is on the screen since longer time and I want to decrease this time and after the message seems , it should lost on the screen, please helppp

      • “”Broken pipe “”or “”error 502″” like these. I want to when this message shown on my phone ,this message shouldn’t long time on the screen ,it must take about 5 second but it takes too longer time ,what can i do please help

  8. Hi Martin!

    I would like to ask, at the block 1, where did you get the global pairedDevices? I would like to do a similar program which control more led. If I want to do that the led is only on when the user pushes the button than should i use the “when led_button.touchdown”?
    Thanks in advance!

        • Hy Martin!

          Can I ask you something more? I did what you suggested, and it works fine, but can I make the platform somehow multi touch? I mean how can I setup that I want to turn on two leds on the same time?

          Thanks in advance!

          • Do you mean have more buttons to control more LEDS?

            If yes then you just need to extend the app and the commands used.

            In the app add extra buttons; some like LED1, LED2, LED3 etc.
            When each of these are clicked send the commands
            <L1ON> or <L1OF>
            <L2ON> or <L2OF>
            <L3ON> or <L3OF>

            In the Arduino sketch, in the parseData function check receivedChars for the commands and set pins HIGH or LOW accordingly.

            As the commands get longer it would better to use strcmp.

            if (strcmp (“L1ON”,receivedChars) == 0)
            if (strcmp (“L1OF”,receivedChars) == 0)

            • if (receivedChars[0] == ‘O’ && receivedChars[1] == ‘N’ ) { digitalWrite(LEDpin,HIGH); }
              if (receivedChars[0] == ‘O’ && receivedChars[1] == ‘F’ ) { digitalWrite(LEDpin,LOW); }
              if (receivedChars[1] == ‘O’ && receivedChars[1] == ‘N’ ) { digitalWrite(LED1,HIGH); }
              if (receivedChars[1] == ‘O’ && receivedChars[1] == ‘F’ ) { digitalWrite(LED1,LOW); }

              can i use this for more LED?

          • I mean to push two button at the same time, and both LEDs turn on. So, kind of multitouch. It realize when we push two button on the same time

  9. Sir, thankou very much for your examples, I just bought an HC-06 and followed your basic setup page, works flawlessly, now I am trying this one but I am pleased to have found so much infos in one place.
    You are the man!

  10. I may have missed the instructions, but how do I install the apk file on my phone once I downloaded it from your site please Martyn?

    • Ah wait, Dr Google to the rescue. I found a way on stackexchange, where it was suggested I email the apk to my Gmail, open the mail on the phone, download the apk from the email. Then it recognised it as an apk and offered me the choice to install, which I did…. works a treat, thanks for this tutorial.

      (Is that how you would download an apk?)


      • I would normally copy the apk using a usb cable. After it is copied I using a file manager app to click on the apk and install it. You need to allow install from untrusted/unknown sources.

  11. Hi
    I just found your website and decided to give App2Inventor a try. I love it. I am studying for OCAJP and was already dabbling a little in Android studio. the blocky code makes coding even complex tasks a breeze. Really enjoyed. Quick question tho. Within a short couple hours I was able to get my hello world pet the kitty upgraded to a bluetooth app that controls my leds with all of the functionality that my code allows. However I noticed that in order to use the bluetooth logic I needed to have the bluetooth client embedded “hidden” in the second screen I am using. I am using the same logic for buttons to the second screen as I did on the first with no errors ie if button press if serial connect send serial text send this char array etc., however the buttons arent working on the second screen and when I go back to the main screen I find the bluetoothconnection has failed. I looked into this but a google search leads me to app2inventor setup FAQ’s and general bluetooth nonsense for starting out. do you have any idea why I am losing my bluetooth connection going between the 2 screens I am using? thanks for any response

  12. Hi!
    I have some problems with my bluetooth connection based app.
    The app is working well but after a minute I get a message from the app saying ” Error 516: Unable to write: Broken pipe ” and I can work with the app but bluetooth module disconnects from my mobile.
    I think it could be a problem related to the baud rate, I’m using Serial.begin(38400) in my Arduino code and the bluetooth module is also configured at 38400 b/s but i don’t know, my app sends 2 bytes number (two “Call BluetoothClient send1byteNumber” one after another) and maybe the baud rate is too much.


    • The baud rate is used for the communication between the Arduino and the Bluetooth module only.
      The baud rate used by the BT module to talk to the mobile phone is automatic and handled by the phone. You cannot change this.

      The Broken Pipe error means you have lost the connection. Are you moving around or are you using the module in a wireless noisy environment?

      You can trap the errors with the Screen1.ErrorOccurred block.
      Test for error 516 and then try to reconnect. Or have a popup that says the connection is broken and would you like to try and reconnect.

  13. Genial, Muy buen articulo, mil gracias.
    Amazing, very nice tutorial, Thanks so much…

    Danilo Bolaños.
    Costa Rica.

  14. Hi
    i like this project. I want to do someting and need that arduino remember led after disconeting the power. I know that needs eeprom but I dont know how to write it in to te sketch. If you can help me and write in to the scatch, Thank you

  15. Hi I have the solution for the , broken pipe or error 516 , 517. The solution is use this blocks to prevent errors showing on the screen.

    ( İf BT working and errors making problem then use it. I guess it shuts all errors on the screen xD so you will not be able to see android errors anymore but still the programs all BT options working which is enough :) )
    By the way the website is my friend’s website so help him out, there is so much free course notes for computer engineering :D

    When screen1.ErrorOccured
    Do for each item in list get errorNumber
    Do close screen with value result get errorNumber

  16. Good day to you !

    just wanted to say a MASSIVE Thank-You for showing how to design an app, i guess ya can teach an old dog new tricks haha !

    i find it very difficult to get me head around these things so when i tell you that its been a pleasure to work thru your tutorials, all info needed, sketches, schematics, code, online website converter links etc, youve thought of it all !

    Well done and once more, thank you ever so much for all the diligence, hard work and awesome ingenuity for making your blog, its totally awesome !

    have a great day :)

    kindest regards,

    Anil Jr ;)

  17. Hi Martyn,

    How about if i want to control the brightness of Leds? I have tried using the slider in tht mit app however, it didn’t work.. help me figure this out please. Thanks

  18. Hi,

    I love your post and thanks for information.
    I would want to know how you could send bluetooth signals to a smartphone with the push buttons, in your video on youtube. (https://www.youtube.com/watch?v=aL-rZLptRHQ)

    I want to send bluetooth signals to a smartphone through buttons on the circuit as you did in the video.
    If I connect the bluetooth module on D2, D3 and two buttons on D5, D6, would the signals from buttons (if I push them) go to the bluetooth module? (for controlling the APP)


Leave a Reply to Martyn Cancel reply