Fritz-Hut

ArduinoPi v1.5 Bluetooth Dongle Support

A new version and the release of ArduinoPi Python! Today I updated ArduinoPi to support a Bluetooth connection instead of the wired connection. Last time I talked about connecting the Raspberry Pi with a BlueSmirf dongle. I’ve also updated the repository on Github, officially hitting version 1.5.

Preparing your Raspberry Pi for ArduinoPi 1.5

Before trying out the Bluetooth connection make sure you followed my last blog post. We only change one option in the rfcomm.conf file.

root@raspberrypi:/home/pi# nano /etc/bluetooth/rfcomm.conf
# RFCOMM configuration file.
#
rfcomm0 {
        # Automatically bind the device at startup
        bind no;
 
        # Bluetooth address of the device
        device 00:06:66:48:71:B2;
 
        # RFCOMM channel for the connection
        channel 1;
 
        # Description of the connection
        comment "BlueLight Connection";
}

On line six we change the bind option “no” to “yes”. This will automatically bind the device without connecting it, resulting in a locked port you cannot use for anything useful. The fun part, when you disable the automatically binding, is that your Raspberry Pi now automatically will pair with your BlueSmirf. ## Working of ArduinoPi 1.5 Not much is changed but I’ll go over it quick. We don’t need to change anything if we have an active connection with our Bluetooth device. The phpSerial class will work as expected. In the deviceSet function I’ve added the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if ($this->_os === "linux") {
    if (preg_match("@^COM(\d+):?$@i", $device, $matches)) {
        $device = "/dev/ttyS" . ($matches[1] - 1);
    }
 
    if ($this->_exec("stty -F " . $device) === 0) {
        $this->_device = $device;
        $this->_dState = SERIAL_DEVICE_SET;
        return true;
    } elseif (preg_match("/^\/dev\/rfcomm[0-9]+$/", $device, $matches)) {
        // No connection is made with the bluetooth device, so create it.
        $this->_exec_bg("rfcomm connect $device");
        // Wait for the device to connect
        sleep(2.5);
        if ($this->_is_running($this->_bluetooth_pid)) {
            $this->_device = $device;
            $this->_dState = SERIAL_DEVICE_SET;
            return true;
        }
    throw new phpSerialException("Could not connect with Bluetooth Device");
}

So if we can’t open the device (Bluetooth or UART) with stty -F then I’ll look if we have a rfcomm port. If we have a rfcomm port then we connect with it using the new private function _exec_bg. This function will run the rfcomm command in the background and request the PID. Next we sleep for 2.5 seconds, the communication can take a while to set up depending on your Bluetooth dongle. If you have issues or the first command gives back an error then increase the sleep time.

This also means that If no connection is present, the first executed command will take considerable longer than the following commands.

More about the _exec_bg function

1
2
3
4
5
6
7
8
9
private function _exec_bg($cmd)
    {
        $retVal = proc_open("$cmd &> /dev/null 2> /dev/null &", array(), $pid);
        $status = proc_get_status($retVal);
        proc_close($retVal);
        $this->_bluetooth_pid = $status["pid"] + 1;
        return $retVal;
    }

This function is a bit special and took me a while to come up with it. The basic idea is that you assign a new worker with the command proc_open. We ignore all the output and I also don’t want any streams from the command to read or write. The proc_get_status allows us to return the PID of the started process. One note, I increase the PID with one, a know PHP bug and not really the best solution, but it works.

Normally you would read the streams, doing this will result in a hanging script, the same with other PHP commands like exec or shell_exec, they all hang. I also tried to get the right PID by using ps aux | grep and so one but I found out that PHP can’t find his own opened processes. More about this issue is on stackoverflow.

Conclusion

It’s possible to connect the Raspberry Pi and Arduino with a wireless connection using Bluetooth. The ArduinoPi library can be used to control the Arduino wireless from a web-page.