Intro: Bluetooth Mobile Phone Accessory for Missed Calls and SMS
When at home, I do not carry my phone with me everywhere... so sometimes phone rings or an SMS comes in and I do not hear that. With the volume of music played by the teenagers at home, that is not a surprise :-) so I decided to build a small accessory that will show up the number of missed calls and unread SMS. In order to ensure it is very visible I use a 7 Segment LED display so it can be viewed from distance.
The display shows up the battery status, Missed calls count and Unread SMS on 8 digits 7 Segment display module. The communication with the accessory is using Bluetooth and one Arduino board that interfaces with the display and the Bluetooth unit.
You need to run the program once (per boot of the phone), and even if the program is in the background, when the accessory and the phone are in range of Bluetooth communication, the display will show the status of your phone. Pretty much like Car hands free set, that automatically connects with your phone.
The code runs on Android phone and source code of the Arduino accessory and the Android phone code are shared here in step 4.
Updated code can be found in here:
Made several small enhancements and fixed an issue some where complaining about, where connection was not always made from phone to the device. The problem as I learned was in new Firmware of RN-42 that required a bit of configuration to work with Android. Those changes include using commands SI,0200 and SJ,0200 for the BT module.
Step 1: What You Need to Assemble It?
1. Arduino board: You can use Arduino Pro Mini (5V) or Uno or a Mega with this sketch. Mega made it easy to debug, but Arduino pro-mini is cheaper (~$ 10 on eBay). Cost for Mini is ~ $ 19 at Sparkfun. Any Arduino board should work fine (328, not sure the 168 are good enough). Use 5V flavors as the 7Segment Display requires 5V and not 3.3V
2. Bluetooth module like this one, cost is ~$ 40 at Sparkfun. To use cheaper one ($ 10 on eBay) you will need minor code modifications which I tend to do for a new assembly of this.
3. 7 Segment display , cost is ~ $10 (or LED Matrix for $3 a piece)
4. Wires for connecting and potentially a power supply for driving the accessory and enclosure. I did not complete this part yet.
Do yourself a favor and look for the items on eBay. It will save you money.
Total cost, if assembled by items you shop on eBay can be about $ 30. If you go for traditional on-line stores, cost will be higher.
Step 2: How to Assemble?
Below are the steps for connecting the hardware pieces
1. Connect the Bluetooth module to Arduino serial port:
Module Pin Arduino Pin
Tx-o Rx (if Mega, connect to 18, if other Arduino, connect to Digital 0)
Rx-I Tx (if Mega, connect to 17, if other Arduino, connect to Digital 1)
2. Connect the display module to Arduino (you can reassign pins in the code if you like)
Module Pin Arduin Pin
DIN Digital 4
CS Digital 5
CLK Digital 6
Step 3: Pairing the Devices
On the phone go to "Settings|Wireless and networks|Bluetooth settings" touch the "Scan for devices" and select the "RN-42-4376" device. The pairing code is "1234". The pictures here shows all the screens in this process.
After initial pairing was done, you need to setup the the Bluetooth module to always connect to your phone. To do that you can use an Arduino Mega for the setup, an FTDI or some other tool. In every step below, unless specifically written, you need to type something and press Enter.
If you are using Arduino Mega.
- Load the MultiSerialMega sketch to your assembly
- Open a Terminal like Tera-Term with connection to your Arduino Mega port (the Arduino IDE built-in terminal is not good enough)
- Press $$$ (no enter), the module will reply back with CMD
- Make your phone discoverable
- Type I on the terminal connected to your Bluetooth module
- The module will reply with "Inquiry, COD=0 then it should find your device and list the MAC address of your Bluetooth,firendly name of your device. See portion of terminal window below for an example
- Type SR,<the address> into the terminal
- Then type C in the terminal
If you do not have Arduino Mega, but have FTDI:
- Connect the BT module through an FTDI to your PC (3.3V, and remember to cross Tx and Rx between FTDI and the Bluetooth module).
- Then open a terminal like Tera-Term with connection to your FTDI. Then continue form step 3 above.
- Get the MAC address of the Bluetooth of your phone (see below)
- Modify the Arduino source so that the line 'initString in function setup() contains your Phone Bluetooth MAC address
- Add InitString as the first item in initVector, before initString1
- Un-comment the line the line for the initString
- The above steps will make the accessory hard-coded with your phone.
The PhoneInfo Android application I wrote here have a menu option to list the MAC address of your phone. This can help you setup the accessory as above.
Also, you can download a program from Google Play that is a Terminal application over Bluetooth (I worked with SENA BTerm and it seems to work nicely).
Step 4: Loading Software to Arduino and Android
In the attached ZIP file of sources you have
Arduino\ with all sources for Arduino
Standard\ sub directory with code for standard Arduino (non Mega) code.
Copy the content of Modified sub directory to libraries\LedControl sub directory of the Arduino IDE installation.
Load the right sketch for your Arduino to the IDE and then upload it to the board you have. if all is connected as it should, you will see the 7 Segment display showing 'dcon' message on it (meaning the Phone is not connected).
I will not explain here how to install Eclipse for Android development, but if you are new to this like I was... do expect to spend time on installing the basic package. You can connect the phone to your PC and copy the APK file from 'Android\myPhoneInfoWithService\bin' sub directory to your phone and install it there. Make sure to enable "Unknown Sources" on the Android phone in by "Settings|Applications" of your phone.
Step 5: What Was Tested?
The Android application was tested on Android 2.2 and Android 2.3.6 devices, LG Optimus 2X and Samsung Note respectively.
I believe based on what the code does that it should work fine on other devices too, but can't be sure about that. If you have any issue with your device, please let me know, and preferably include the logging information as the Android program is well populated with debug logging.
The Android application for Android v2.2 is the same as for Android 2.3 although some changes to the Bluetooth interface were made by Google. From my testing the 2.2 code continues to work on the 2.3 device without any issue. Colors on the other hand might look somewhat different between the Android versions. Have no clue why, but the UI in this application is the least important in my view, so did not spent cycles investigating that. I suspect it has to do with colors defined on 2.3 but not on 2.2
Step 6: How This Works?
First, lets talk about Bluetooth:
The protocol is more than simple wireless communication, it also includes pairing and like USB communication some application protocol identification. The Bluetooth has a UUID for each protocol, some well known and some up to you to implement. I used the Serial over Bluetooth for simplicity of course rather than implementing a brand new one. Next, in Bluetooth like in USB there is the notion of Host and client. The host is waiting for calls while clients generate them. For me, it took some time to figure this out, and placed the Phone in host mode and the accessory in client mode. The accessory that is expected to be powered by a power supply will try connecting all the time, and the phone which is obviously battery powered will do the less power consuming task of waiting for a Bluetooth connection.
Well if you are an Arduino programmer this might look very strange to you, but programs in Android are not monolithic like in Arduino. An application is really a collection of code fragments that gets executed in certain conditions or cases. Of course the language to use is Java, so that too would be different. Let me give you an example: To have the information about battery state (how much you have left, if it is full or not etc.) there is no API function to call and poll it. You actually register a function/method you write that gets called by the system once something about the battery changes. Same thing about missed calls, you don't get that information from a query to an API... you register a callback function with the system so that once there is a change to the call log database on the system, it will also call your registered function. When your Android app. wants to examine these logs of calls or SMS or the listen to Battery broadcasts, you also need to add permissions to your application so that it can do that. Otherwise, the system will silently ignore your request to be notified or be a listener to these message.
Next, I wanted the accessory to auto-connect once the phone is in range, to do that you need to have something working in the background as I am not expecting the application to be the active application all the time. For that it is not enough to write an Android activity, but you need to have an Android service too. The service gets executed by the Android activity as it starts. But to display things on the phone screen... you need an Activity and not a service. OK, so service needs to tell the activity about what it found. To do that it sends information in a publish-subscribe mechanism to which the activity registered earlier. The service is also the piece of code that communicates over Bluetooth with the accessory. That is important because it is not wise to call blocking calls (like network or wireless read and writes) from the activity. Activity has to be there fully ready to interact with the end user.
Last, I wanted to have the phone controlling the intensity of the display. To do that the activity that is a UI component, needs to tell the service what the user decided the intensity to be. Another thing to register for... But how do I know what the intensity is now? Well, for that I had the Arduino code answer to query by the phone, the Service will issue this query on connection, and update the activity about the current intensity level. Sounds complex? Not really but certainly tedious to implement.
To get the information about Battery, I register a BroadcastReceiver and found that it is getting called every 30 seconds.
The missed calls thing works perfect, but the SMS information is somewhat tricky. There is a notification about new incoming SMS, but no notification when user reads an SMS. So, I am polling the SMS log every time I am getting the battery notification too. That means that on incoming SMS the display will update immediately to show there is one, but once you read the SMS it might take up to 30 seconds for the display to show there are no unread SMS messages anymore. For me this is an acceptable compromise and if I will find a better way, I will use it.
Please bare in mind that this is actually my first Android program. It has been quite a while since I wrote any Java code too (more than a decade). I never did anything with Bluetooth either... The code got started from existing Android sample code too, mainly the BluetoothChat example.