Search code examples
carduinobluetoothconnectionbluez

How to establish a continuous Bluetooth connection with BlueZ so I can transfer to and receive data from an Arduino?


I've been making a map making robot car with Arduino for class. I want to make a user interface for it in C (on a PC running Linux) that would work like this: the user can press a Start and a Stop button, or click a specific area of the map to send the robot to there. Right now my test setup code looks like this: Arduino: `

if (BTSerial.available() > 0) {
    c = BTSerial.readStringUntil('\n').toInt();
    BTSerial.write(c);
    if(c == 8) {
      Buzzing(SOS);
      BTSerial.println("eight");
    }
  }

**PC program**:

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>

int main(int argc, char **argv)
{
    struct sockaddr_rc addr = { 0 };
    int s, status;
    char dest[18] = "98:DA:60:03:F2:92";

    // allocate a socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

    // set the connection parameters (who to connect to)
    addr.rc_family = AF_BLUETOOTH;
    addr.rc_channel = (uint8_t) 1;
    str2ba( dest, &addr.rc_bdaddr );

    // connect to server
    status = connect(s, (struct sockaddr *)&addr, sizeof(addr));

    // send a message
    if( status == 0 ) {
        status = write(s, "8", 2);
    }

    if( status < 0 ) perror("uh oh");

    int client, bytes_read;
    char buf[1024] = { 0 };
    // put socket into listening mode
    listen(s, 1);

    // read data from the client
    bytes_read = read(client, buf, sizeof(buf));
    if( bytes_read > 0 ) {
        printf("received [%s]\n", buf);
    }

    close(s);
    return 0;
}

` Ideally if I send the number 8 to the Arduino it would send back the string "eight". When I run my PC program, my PC connects to the Arduino (I get a notification from the OS that my PC is connected and also the led on my HC-06 Bluetooth module connected to the Arduino stops blinking signaling that a device was connected to it) and the buzzer connected to the Arduino starts buzzing the morse code of SOS as expected. However after a second my program terminates, the Bluetooth connection ends (I get a notification that my PC is disconnected and the led on the Bluetooth module starts blinking again) and I don't get back the expected "eight" string. I'm still just a beginner when it comes to the C language and since I can not find a detailed documentation of BlueZ, I'm kind of stuck. Any help would be greatly appreciated!

I tried to combine the server and the client code from this site: https://people.csail.mit.edu/albert/bluez-intro/x502.html#rfcomm-server.c

I also tested my code on the Arduino using Putty on PC and it worked with it properly.


Solution

  • So after a bit of work I finally could get it working. I only needed to change the first parameter of the read() function. Here's my final code:

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/rfcomm.h>
    
    int main(int argc, char **argv)
    {
        struct sockaddr_rc addr = { 0 }, rem_addr = { 0 };
        int s, status;
        char dest[18] = "98:DA:60:03:F2:92";
    
        // allocate a socket
        s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    
        // set the connection parameters (who to connect to)
        addr.rc_family = AF_BLUETOOTH;
        addr.rc_channel = (uint8_t) 1;
        str2ba( dest, &addr.rc_bdaddr );
    
        // connect to server
        status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
    
        // send a message
        if( status == 0 ) {
            status = write(s, "8", 2);
        }
    
        if( status < 0 ) perror("uh oh");
    
        int bytes_read;
        char buf[1024] = { 0 };
    
        // read data from the client
        bytes_read = read(s, buf, sizeof(buf));
        if( bytes_read > 0 ) {
            printf("%s", buf);
        }
    
        close(s);
        return 0;
    }
    

    This code sends the number "8" to the Arduino, to which the Arduino replies with the string "eight". It's probably not the nicest C code for Bluetooth connection, but at least it's working I guess.