Bluetooth Presence Detection

Today something else, presence detection in a room. There are a lot of possible solutions to solve this problem. A traditional way is to connect 2 PIR (Passive Infrared Sensors) sensors in the door opening and count the amount of people who enter or leave the room. Another way is to use a RFID chip or even ultrasound. I decided to use Bluetooth to look for active devices.

BlueSmirf Bluetooth Module

BlueSmirf Bluetooth Module

Presence detection with Bluetooth, the connection

First I need a Bluetooth module. My old one broke down (5V is NOT 3.3V). I decided to buy a Bluetooth Mate Silver (WRL-10393) from Sparkfun. An advantage of the Bluetooth Mate is that it can be easily configured.

Connecting the Bluetooth module is fairly easily, just connect 5V, ground and cross TX and RX and it will work. The CTS-I and RTS-0 are not used, some people say you should connect them to each other but in the sparkfun tutorial they clearly say to leave them alone. So I did.

## Configuring the Bluetooth Mate Before I can start programming I need to change some configuration settings. A complete list of all the AT commands can be found here. When the Bluetooth mate is switched in command mode there is a possibility to check for active Bluetooth devices. Using this command I’m able to see if my device is in the room (or 30m radius).

First I use a pass through script so the data I send to my Arduino is passed along the Bluetooth Mate and vice versa.

A pass-through script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

void setup()
{
 // Open serial communications to PC and wait for port to open:
  Serial.begin(115200);

  Serial.println("Connected to PC");

  // set the data rate for the Bluetooth port
  Serial1.begin(115200);
}

void loop() // run over and over
{
  if (Serial1.available())
    Serial.write(Serial1.read());
  if (Serial.available())
    Serial1.write(Serial.read());
}

The default baud rate is 115200, now I can configure my Bluetooth module by entering the commands in a serial terminal on my computer.

First $$$ should be send in the first minute the Arduino starts, this enables command mode. This command should be send without a new line, all other commands need a new line at the end. I then changed the name of the Bluetooth Mate with the command SN,<name>. Typing d (or in some cases D) gives detailed information about the Bluetooth Mate. By using the command IN,2 it’s possible to start an inquiry scan. It’s a search for other active Bluetooth devices. I wrote down the serial number of my cellphone and laptop. The last command I used is ST,255so I can always start command mode.

Programming the Bluetooth Mate for Presence detection

So lets start with the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

#include
// The ID's I found during the set up,
// change these value's to match your Bluetooth Devices
char cell[] = "E4EC1064DAE4,5A0204";
char laptop[] = "2C8158B16919,6E010C";
unsigned long lastTime;
unsigned long interval = 10000;
void setup()
{
    Serial.begin(115200);  // Begin the serial monitor at 9600bps
    Serial1.begin(115200);
    Serial1.println("---"); // make sure the device is not in command mode
    Serial.println("Started....");
}

void loop()
{
    // Get current millis();
    unsigned long currentTime = millis();
    // Check if its already time for our process
    if((currentTime - lastTime) > interval) {
        lastTime = currentTime;
        // Enter command mode
        Serial1.print("$$$");
                //Wait a bit for the module to respond
        delay(200);
                // Start the inquiry scan
        Serial1.println("IN,2");
        delay(5000);
        int h = Serial1.available();
        if(h >= 42) { // we know there is a bluetooth device
            char *id = readSerial(h);
            char *str;
            while((str = strtok_r(id, "\n", &id)) != NULL) {
                if(strncmp(str, cell,19) == 0) {
                    Serial.print("Found Fritz cellphone with id: ");
                    Serial.println(str);
                } else if(strncmp(str,laptop,19) == 0) {
                    Serial.print("Found Fritz laptop with id: ");
                    Serial.println(str);
                }
            }
        } else if(h <= 21) { // we know there is no bluetooth device
            Serial.println("No device found");
        }
        Serial1.println("---");

    }
    clearAll();
}

void clearAll() {
    for(int i = 0; i < Serial1.available(); i++) {
        Serial1.read();
    }
}

// a bit hacked...
char* readSerial(int h) {
    char input;
    char buffer[100];
    if (Serial1.available() > 0) {
        int j = 0;
        for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
            input = (char)Serial1.read();
            if(i >= 21) {
                buffer[j] = input;
                buffer[j+1] = '\0';
                j++;
            }
        }
        return buffer;
    } else {
        return "No Data";
    }
}

In setup I start my serial connections. A small note, I have an Arduino Mega 2560 and I can use 115200 baud. When using the SoftSerial library always use a lower baud rate, the software emulation of the serial connection can’t handle high baud rates.

I use a timer so I only search for Bluetooth devices every 10 seconds. On line 24 I start command mode (note the .print and not .println!), I delay a bit for the response and setup time, and then I send the command to start the inquiry scan. This command takes a parameter (after the comma) and this means the scan should take 2 seconds. I delay for 5 seconds because I found out that the scan does take 2 seconds but gathering the results takes longer.

I check the length in the buffer, if its longer then 42 characters I know that the Bluetooth module found a device, else I know that no device could be found. It’s a bit of a hack but works wonderfully. Next in the while loop I split the readSerial string in new lines and for every newline I check if the first 19 characters match one of my ID’s. If it does then we print a small line saying we found the cellphone or the laptop.

There are a bit of problems like the delays but I don’t see how I can do it without making the code extreme complex. I created an easy way to do presence detection using a Bluetooth mate.