In this post I have illustrated a way to get your home wired up with you cell phone via bluetooth. This will be useful when you do not have wifi connection. The project consists of two sections
- Python script that registers a bluetooth server socket on the raspberry pi and controls the GPIO to turn the lights on/off
- An Android app which acts as a client to connect to the Rpi and control the lights
Here is the source code of the project.
A) Python Script: I used the GPIO and bluetooth library of raspberry pi. The GPIO library sets the respective GPIO pins connected to the lights as outputs. It initializes the pins. The library provides a good abstract way to control the GPIO pins by maing high level function calls.
The second part of the python script to interface bluetooth. This code snippet opens up a server socket. The raspberry pi acts as a server to which your cell phone (client) can connect to. The same UUID should be used by the client to connect to the server. Hence the UUID registered in this python script is the one used in the android code. After registering the socket and opening up the connection, it waits for the client to get connected.
This python script should start everytime on boot up so that in case we lose power, we would not have to connect to the raspberry pi everytime to manually start the script. This can be done by creating a launcher script and using crontab to launch this script on boot. The source code link above has the launcher script I created. Then type in sudo crontab -e to open the crontab file and add the following line to your crontab
@reboot sh /home/pi/bbt/launcher.sh >/home/pi/logs/cronlog 2>&1
B) Android Programming
.This piece of code is a bit involved. It has following parts
- Designing a GUI
- Writing handler functions when buttons are pressed
- Registering bluetooth, scanning for devices, pairing with the necessary device and connecting to it
- Handling when app is “minimized”, and closed
Designing a GUI:
In android GUIs are basically layouts. Adnroid has a good documentation on these. These can be linear (vertical/horizontal) and relative layouts. You can either use their graphic tool in android studio to pick and place widgets on the screen or else code them yourself. Every widget (e.g a button here) has varios characteristics. One of the features is the function it should run when it is clicked. This function is the onLight1SwitchClicked() fucntion mentioned below. This will get executed when you click on the light1 button. Other features include height, width, margin, padding, color, background etc for each widget. You can either hardcode these values or can have a separate file (usually named as /strings or /dimens etc) where you can assign variables for the dimensions and instead assign those variables to the widgets. This is a cleaner way to code in the sense that in case there is a common property/feature for multiple widgets, then when modifying it, you only would have to modify it in one place and not multiple places.
Writing handler functions: The functions onLight1SwitchClicked() and onLight2SwitchClicked() are executed when you click on the button objects on the app screen. All these functions do is send a 1 and 0 alternately to the write() fucntion in bluetoothService.java file which then sends this out to the server bluetooth device.
Bluetooth drivers: Bluetooth.java file illustrates how to register the bluetooth, scan for devices and pair to a said device. In MainActivity.java file, I have created an intent (bleService) of this bluetooth binder class.
Intent bleService = new Intent(this, BluetoothService.class);
This line will execute the onStartCommand function in the bluetooth binder class. This is a background thread that runs when you load your app. The function call
bindService(bleService, bleConnection, Context.BIND_AUTO_CREATE);
will start the bluetooth service thread (in bluetoothService.java file) and execute the run() function.
The run() function first checks if you phone has a compatible bluetooth adapter. If it does, then the function proceeds to check if the bluetooth is on and prompts you to turn it on if it is off. Then it queries for paired devices to see if the server bluetooth device (your Raspberry pi) is in the list and can be found. If not, the function executes a scan for all the nearby devices and sees if it can find your server. When the server device is found, the function tries to initiate a connection. After successfully getting connected, the function waits for the app to send or receive data. The received data is but into a buffer and transmitted to the broadcast manager to display on screen.
The write() function sends the data from the app to the server bluetooth device.
The MainActivity.java file also has a function registerReceiver(mMessageReceiver, new IntentFilter(BluetoothService.RX_MSG)); This registeres the receive buffer. The onPause() function temporarily unregisters the receiver and the onResume() function re-registers it again to be able to receive messgaes. This is important so that the app handles the connections properly when it is minimized or the phone screen turns off. This is when the onPause() function gets executed.
- Incase bluetooth device is not getting paired follow the steps after connecting to your raspberry pi. I ran into this issue when I had a paired device (client) and then I ‘forgot’ the server (pi). Then I was not able to re-pair the server (pi) from the client (my phone)
- forget your phone (client)
bt-device -r [address]restart bluetooth
sudo service bluetooth restart
- forget your phone (client)
discoverable on (make bluetooth available)
scan on (you will get the device to connect (phone) address here)
- Sometimes you need to add “Serial Port Profile (SPP)” to your bluetooth setting. This is a one time things while setting up your server. This article illustrates more on it
- This is an article to know how to make your Rpi bluetooth discoverable, pairable etc (via command line)
- Good article on setting up bluetooth server using python
- Article on creating a launcher script and adding it to crontab to start on bootup
- Good illustration if you are having trouble pairing with bluetooth
- TO KNOW MORE ABOUT ANDROID SERVICE AND THREADING
http://codetheory.in/android-intents/ read about intents
http://codetheory.in/android-intent-filters/ read about intentfilters
http://codetheory.in/android-broadcast-receivers/ read about briadcast receivers