DIY BLUETOOTH SPEAKER

a simple guide to building your own bluetooth speaker on a budget.

I had an idea to build a bluetooth speaker for a long time and last month got the time and components to start the work. Every teen guy here wanted to have loud sounds with high base in the 20s. I guess still we aren’t changed much on that subject. Here is a guide to building a one on your own at a cheap.

Below are the components you need to buy on your next run to the local electronics store. If not you can simply ebay them.
1. bluetooth / USB / FM decoder module
2. PAM8403 amplifier module
3. 2 speakers (4Ω 3W preferable)
4. 5V AC to DC converter

If you have an old radio lying around, you can use those speakers too. Also, I acquired all the items from local electronics store and they are more cheaper than ebay listings. Total cost for the components for me is around 1000 LKR. One thing to note about the decoder module is that it supports many modes including FM, line in, USB MP3, TF card MP3.

Wiring the components are pretty much simple. Refer below image as a guide. Here I didn’t include wiring of 5V supply, you have to solder one end to a AC plug and use the DC output end to power the decoder module and the amplifier. For that, I used an old 2 pin AC plug from a broken soldering iron.

component wiring diagram

After everything is connected, connect the converter to AC and check the decoder module. It will show the current mode on 7-segment display and speak the selected mode out loud. Use the IR remote which came with the decoder to change the mode. Once you are on bluetooth mode, it will speak out loud as “bluetooth mode”. Now the moment of truth 😉

Take your phone and turn on bluetooth and scan for nearby device. Your precious newly made speaker will show as BT-SPEAKER. Tap to pair, select Yes for the initial pin exchange. Once you are paired, the speaker will respond as “paired”. Hit play on your favorite song, make sure both speakers are working.

your speaker will show as ‘BT-SPEAKER’

If everything goes Okey, now it is time to make it pretty. You can use your imagination for that to make it much better than mine. I used a pizza box to house all my components and a glue gun to glue speakers and decoder on to the box.

speaker proudly lying on table.

DEAL WITH YOUR “NOT WORKING” POWER BUTTON – ANDROID

If you own a pretty cheap android phone like xiaomi or any other, after some time (say 1 year) your buttons will stop working one by one. Currently in my redmi note 2, all buttons are not pressable anymore. 😀

You get what you get for your money, can’t expect more.

Usually, if your phone comes with plastic buttons for power and volumes +/- buttons, well give it some time and observe. You’ll need this article someday. 😛

cheap plastic buttons on RN2. picture courtesy: http://www.gsmarena.com/xiaomi_redmi_note_2-pictures-6992.php

The actual reason for buttons not working is not actually with the button materials itself, but it reflects the quality of the internal accessory. 😀 Real reason behind this is flex cable getting jammed. If you can remove the phone’s back cover and look at the place where buttons actually lie, you can see a small cable fixed-in, in that area with small 3 bubbles which represent the hardware keys in your mobile.

flex cable which can be found in RN2.

So if your power button is not working anymore, you’ll find lots of troubles. You can’t power off / on the phone from the hardware button, especially when the battery is drained and connected to the charger. you can’t wake /lock your screen ? The troubles will get really embarrassing if you didn’t go for a solution quickly.

Owkey. time to explore solutions. 😉

1. PERMANENT SOLUTION

Just replace the flex cable with a new one. If you are a DIY fan, you can order a one from ebay, watch some DIY videos on youtube and get it done by yourself. It’s not that hard, but here you have to find a temporary solution till your flex cable arrives and till u get some free time to do it.
I am still having this problem, my flex cable didn’t arrive yet. So I had to go with below steps to get my device working till then.

2. TEMPORARY SOLUTION, OR IS IT ?

So your power buttons and volume buttons are not working. Can’t turn the screen on or off. Can’t boot the device? Let’s solve one by one.

2.1 CAN’T WAKE / LOCK SCREEN

A solution for this would be using alternative ways to wake/lock the screen.

2.1.1 WAKING UP
2.1.1.1 WAKE WITH VOLUME BUTTONS

You can use volume buttons (if working) to wake up the screen. In MIUI (xiaomi ROM) this functionality can be enabled in settings. But in my case my volumes buttons are also not working, so had to dig deeper.

2.1.1.2 DOUBLE TAP TO WAKE

Another way is to use a mechanism like double tap to wake. So you double tap on screen while its off, and the screen will wake up. Some ROM vendors had integrated this functionality inside their ROM. If so it’s recommended to enable it from there, rather than depending on a third party app. In MIUI 8 (xiaomi) this functionality can be enabled in settings.

I found an app called knockon which provides the same functionality. Didn’t test in on my device though.

2.1.1.3 WAKE WITH MOTION

Imagine a scenario, your device will automatically wake up when you needed and it’ll automatically lock when you are not using the phone. This solution is very effective even if your buttons are working, but you are too bored to press it every time you need to wake it up.

Using your phone’s inbuilt sensors (context) and with sensor fusion this app (gravity screen) can do an educated guess whether you are holding your phone, lying it on table, it’s in your pocket, you are watching something, etc.
So depending on the conclusion, the app will automatically wake the screen or lock the screen. I was using it for a couple of weeks and it’s surprisingly reliable.

gravity screen app configurations.

Once you configured the app as you need, you will never have to press your power button anymore. 😉 (even if it’s working)

2.1.2 TURN OFF SCREEN

This is simple, because unlike in waking up the screen you can be the one whom in-charge of this action.

2.1.2.1 TOGGLE BUTTON WIDGET

Just place a toggle widget to turn off the screen on your home screen.

2.1.2.2 ASSISTIVE TOUCH

Or you can be more creative and use an app like assistive touch to have a assitive touch ball on your android like in ios and lock the screen using that.
MIUI 8 (xiaomi) users can enable this feature without any third party app by simply enabling the quick ball feature in settings.

using both toggle widget and assistive touch.
2.1.2.3 LET SENSORS DECIDE

As described in 2.1.1.3 section, you can use gravity screen app to automatically turn off screen when you are not using the phone. Just put the phone lying down once you are done, it’ll automatically turn off.

2.2 TURN ON (BOOT) DEVICE

All the solutions i explained earlier are solved using software approaches. but when your device is powered off, we should look at another way to get it booted. 😛

Okay, let’s approach it step by step. first of all, when do u need to power on your device? it should be one of below.

  1. your battery is empty and it was switched off
  2. you intentionally turned it off

 

2.2.1 BATTERY IS EMPTY AND SWITCHED OFF

The first thing you have to do when the battery is empty is to plug your phone to the charger.
When you connect the charger to your phone while it’s switched off, it’ll show a charging indicator but won’t power on. So what if, we could modify that functionality and make it boot when the charger is connected instead of showing the charging indicator screen.

This can be done. For that you will need to first boot the device into fastboot mode and modify some configurations. You need adb tools installed in your PC to continue. If not install them. Also, make sure you have enabled developer mode and USB debugging in your phone as well.

Now connect your phone to PC (while it’s ON), carefully issue below commands. First lets get it booted to fastboot mode.

adb reboot-bootloader

Now, your device will reboot into fastboot mode, which we continue to do our modifications.

Issue below command and see if your device is identified.

fastboot devices

Issue below command and it will print all the system variables on the terminal. Examine the value returned to off-mode-charge. it should be 1.

fastboot getvar all

..
(bootloader) off-mode-charge: 1  # if its disabled

Now we have to set off-mode-charge in to 0 in order to boot the device while the charger is connected. Issue below command and verify that you get similar output.

fastboot getvar all
fastboot oem off-mode-charge 0

..

Next reboot the device. Issue below command.

fastboot reboot

Time to check if it’s working. Turn off the phone with assistive touch or any other method and plug in the charger. Now your device should boot instead of showing you the charging indicator. 🙂
voila.

2.2.2 INTENTIONALLY TURNED IT OFF

Simple, just connect the charger, USB cable or a power bank to phone. 😛 It’ll turn on now according to section 2.2.1.

There is always an alternative way. all you have to do it dig deeper. 😉

references:

CREATE YOUR OWN SMS GATEWAY

Here i am gonna show you how to setup a simple sms gateway from a 3G USB dongle using python. the work-flow here is very simple. But before that let’s go through with some basics of 3G USB dongle.

In our gateway once a valid request from the internet is received to our gateway, it should communicate with the dongle and send the message included in the request to the relevant number in the request. So the most important part in this would be communicating with the dongle when the gateway receives some request.

Basically, your 3G dongle consists with a 3G modem and USB to serial converter. 3G modem is something like below image. to communicate with the modem, it needs a serial (RS-232) connection and this is where USB to serial converter comes to play.
As all modern laptops are consists of USBs this converter is also integrated inside the dongle so we can easily plug it and communicate. So the catch from here is that we can use RS-232 / serial to communicate with our dongle.

GSM / 3G modem module. a tiny compact module is used in a dongle
GSM / 3G modem module. a tiny compact module is used in a dongle

First, let’s try to communicate with our dongle with the terminal and if it succeed we can automate that with python to use in our SMS gateway.

GSM / 3G module communication flow.
GSM / 3G module communication flow. source: http://www.engineersgarage.com/articles/gsm-gprs-modules

testing on terminal

First, plug the dongle (assuming that you have inserted a sim card with credit in it 😛 ) and find out the port it opened. Open terminal and issue dmesg | grep tty command to find out connected USB devices.
you will obtain an output like below.

[   14.124879] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB0
[   14.126676] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB1
[   14.127795] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB2

Now, let’s try to communicate with the dongle with the serial connection (RS 232). Here we have to use AT commands to communicate. You can find the complete list of AT command set GSM/ 3G modems support from here.

We will be using picocom terminal program to communicate with the dongle via serial. Install it as below.

sudo apt-get install picocom

Now open the serial port. make sure the substitute relevant port of the dongle.

picocom /dev/ttyUSB0 -b 115200 -l

picocom v1.7

port is        : /dev/gsmmodem
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : yes
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready

Try issuing AT command first. you should get an output like following if everything so far alright. 🙂 issue following AT commands as well to make enable text mode for SMS.

AT
OK

AT+CMGF=1
OK

Now let’s try to send a message. Enter message in the following format.
AT+CMGS="phonenumber"<CR>the message to send<ctrl+z>
after the number and the end of double quote hit enter, then type the message. hit ctrl + z.

It’ll give u a OK response and in a while you should receive a text message to your specified number. If all is good, its time to write our gateway piece. 😀

building the gateway

I’ll be using flask for the REST API and a python module called python-messaging for encoding text messages to PDU format.

First install those packages by:

pip install flask
pip install git+https://github.com/pmarti/python-messaging.git

Now, let’s get into coding. open a new file, say gateway.py. Let’s first write a function to open the serial port and issue relevant AT command to send the message.

from messaging.sms import SmsSubmit
import serial


def send_text(number, text, path='/dev/ttyUSB0'):
    sms = SmsSubmit(number, text)
    pdu = sms.to_pdu()[0]

    # print len(sms.to_pdu())

    # open the modem port (assumes Linux)
    ser = serial.Serial(path, timeout=1)
    # write the PDU length and wait 1 second till the
    # prompt appears (a more robust implementation
    # would wait till the prompt appeared)
    ser.write('AT+CMGS=%d\r' % pdu.length)
    print ser.readlines()
    # write the PDU and send a ctrl+z escape
    ser.write('%s\x1a' % pdu.pdu)
    ser.close()

Next, let’s attach this as a response to a valid POST request. We’ll use HTTP basic auth for authentication.
1. first let’s write a simple function to check user name and password.
2. then basic auth handler to be used in POST request
3. finally the POST request

from flask import Flask, jsonify, request
from functools import wraps
app = Flask(__name__)

def check_auth(username, password):
    """check username / pass"""
    return username == 'user' and password == 'mypassword'


def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return jsonify({'message': 'not logged in'}), 404
        return f(*args, **kwargs)
    return decorated


@app.route("/")
def hello():
    return "python sms gateway :)"

# POST request handler
@app.route('/send', methods=['POST'])
@requires_auth
def create_task():
    if not request.json or not 'number' in request.json:
        return jsonify({'message': 'no number provided'}), 400

    send_text(request.json['number'], request.json['text'])
    return jsonify({'message': 'message queued'}), 201

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=4000)

so the full code for the gateway will look like below.

gateway.py

from messaging.sms import SmsSubmit
import serial
from flask import Flask, jsonify, request
from functools import wraps
app = Flask(__name__)


def check_auth(username, password):
    """check username / pass"""
    return username == 'user' and password == 'mypassword'


def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return jsonify({'message': 'not logged in'}), 404
        return f(*args, **kwargs)
    return decorated


def send_text(number, text, path='/dev/ttyUSB0'):
    sms = SmsSubmit(number, text)
    pdu = sms.to_pdu()[0]

    # print len(sms.to_pdu())

    # open the modem port (assumes Linux)
    ser = serial.Serial(path, timeout=1)
    # write the PDU length and wait 1 second till the
    # prompt appears (a more robust implementation
    # would wait till the prompt appeared)
    ser.write('AT+CMGS=%d\r' % pdu.length)
    print ser.readlines()
    # write the PDU and send a ctrl+z escape
    ser.write('%s\x1a' % pdu.pdu)
    ser.close()




@app.route("/")
def hello():
    return "python sms gateway :)"


@app.route('/send', methods=['POST'])
@requires_auth
def create_task():
    if not request.json or not 'number' in request.json:
        return jsonify({'message': 'no number provided'}), 400

    send_text(request.json['number'], request.json['text'])
    return jsonify({'message': 'message queued'}), 201

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=4000)

Now run the gateway by issuing python gateway.py. Our gateway server now would be running on http://localhost:4000 in the host machine. Next, let’s use postman to send a test request and ensure that our gateway is working. Download postman from chrome web store if you don’t have it installed.

Format the request as below. 😛

postman_1

postman_3

If all is good, you should now receive a text from the dongle.

you can find the complete source code of the project from https://github.com/wathmal/sms-gateway.

references:
* https://myraspberryandme.wordpress.com/2013/09/13/short-message-texting-sms-with-huawei-e220/
* https://github.com/pmarti/python-messaging/blob/master/doc/tutorial/sms.rst