Monday, February 28, 2011

Bluetooth HCI

There are various protocols used in Bluetooth. One of them is the HCI(Host/Controller interface) protocol, which is used in the communication between the host stack(BlueZ or Affix) and the controller(Bluetooth chip). Today using the "scanner" program from the previous article and the "hcidump" tool we will see how the HCI protocol packets look like. The "hcidump" tool dumps HCI data coming from and going to a Bluetooth controller (Ubuntu users can install it by "sudo apt-get install bluez-hcidump"). To view dumped files we need the wireshark program also (Ubuntu users: sudo apt-get install wireshark).
Run hcidump in background mode and then run the "scanner"
$ sudo hcidump -i hci0 -w dump &
$ ./scanner

By the -i option Bluetooth device is specified and by the -w option the output file is specified.
When "scanner" finish, kill the background hcidump and then open "dump" file with wireshark program:
WireShark 
In the screenshot you can see two type of HCI packets: HCI_CMD -- computer sends commands to the controller and HCI_EVT -- the controller sends the result. The info column of HCI_CMD packets shows the command sent within a packed. Two type of commands shown in screenshot: "Inquiry" (op code: 0x0401) and "Remote Name Request" (op code: 0x0419). They are the commands sent when the "hci_inquiry" and the "hci_read_remote_name" functions where called(see the source code of "scanner").

The selected packet is a description of the device find by the scanner (as we can see from the fields "BD_ADDR" and "Class of Device" it is a Nokia mobile phone).

Sunday, February 27, 2011

Linux and Bluetooth

There are 2 widespread Bluetooth stack implementations in Linux: BlueZ and Affix. Today we will use the BlueZ library for writing a simple "nearby device finder" program. Before you start, make sure you have installed the necessary Bluetooth packages. Ubuntu users can install them by running:
    sudo apt-get install bluez libbluetooth-dev
At first we need to include the following BlueZ header files
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

To work with a Bluetooth device we need a device id, which can be retrieved by "hci_get_route"  function: if pass NULL argument to "hci_get_route", it will return the id of first available device, or -1 if there isn't any. Now we can use "hci_get_route" function, which search the nearby Bluetooth devices and return basic information about them in a "inquiry_info" structure:
typedef struct {
  bdaddr_t  bdaddr;
  uint8_t   pscan_rep_mode;
  uint8_t   pscan_period_mode;
  uint8_t   pscan_mode;
  uint8_t   dev_class[3];
  uint16_t  clock_offset;
} __attribute__ ((packed)) inquiry_info;

The "bdaddr" member contains the address of a device (it is like a MAC address of network devices, by the way they have the same syntax).
There are 2 functions to convert between strigns and "bdaddr_t" structures.
int str2ba( const char *str, bdaddr_t *ba );
int ba2str( const bdaddr_t *ba, char *str );
The address of remote Bluetooth device is enough to work with it, but the end users usually work with the device names. The "hci_read_remote_name" function retrieve the name of remote device using it's address. But "hci_open_dev" require an open socket. The "hci_open_dev" function opens an appropriate Bluetooth socket. And at last we can use "hci_open_dev" function to get the name and address of the local Bluetooth device.
See the source code for details:

Tuesday, February 15, 2011

Arduino and EEPROM

  EEPROM is a non-volatile memory on the Arduino. It's like a HDD in the computer, can hold the data when board is turned off, but has too little memory :(. The EEPROM size of Arduino Duemilanove's Atmega328 is only 1024 byte.
  Arduino IDE has simple EEPROM library, which has only 2 functions: "read" and "write". Lets write a demo program which will save to EEPROM anything received from serial port and if the 's' symbol is received it will return all stored symbols.

Monday, February 14, 2011

ADXL335 Accelerometer

Accelerometer is a sensor that measure linear acceleration. Today we will use ADXL335 accelerometer, we will write a program to display the measured values of acceleration of all 3 axes.
ADXL335 on a board(Manufactured by Sparkfun.com)
You can see axis scheme on the board, the x and y axises directions are clear, and the z axis direction is point out of the board. Remember this sensor has a sensing range of +/-3g, so you can't measure a higher accelerations :). But it is not a big disadvantage, because the calculation shows that more than 100 km/h we can get during 1 second of 3g acceleration. If you want to check it but you are lazy to do, you can use http://www.wolframalpha.com(3 * gravitational acceleration * 1 second in km/h).
The interface of this device is analog: The voltages on X(Y,Z) port depends on the linear acceleration throughout X(Y,Z) axis. The Arduino board has 6 analog-in ports, we can use 3 of them(0,1,2) to connect to X,Y,Z ports of ADXL335.
Analog ports

So lets open the Arduino IDE and write a simple program, which will periodically read the values on analog ports and send trough the Serial port.

In this program analogRead function read the voltage on the pin and return the integer value between 0 and 1023.
On the computer side we will read the information coming through Serial port an show the values on 3 horizontal progress bars.

This is C# code of program

Be careful, connect ADXL335 to the Arduino board, before connecting them to the PC, otherwise the board will hang and only solution is reconnecting.

This is a short video how it runs.