In this VoiceBot server program, we will first use a socket program to establish a socket connection between the devices. Next, we will receive the incoming data, which is sent from the Android smartphone. Finally, we will move the robot based on the data that is sent. The VoiceBot.c program can be downloaded from the Chapter09 folder of the GitHub repository. Follow these steps:
- First, all the necessary header files are declared as follows:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h> //Socket header file
#include <bluetooth/bluetooth.h> //Bluetooth header file
#include <bluetooth/rfcomm.h> //Radio frequency communication header file
#include <wiringPi.h>
- Next, inside the main() function, the wiringPi pin numbers 0, 2, 3, and 4 are declared as output pins as follows:
pinMode(0,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
To establish RFCOMM with the other device, sockaddr_rc is declared along with the server_address and client_address. The data variable will store and display the incoming data. The s and clientsocket are for storing the values of the server and client socket respectively. The bytes variable will read the incoming byte information. The socklen_t opt contains the size of client_address. This is shown in the following lines of code:
struct sockaddr_rc server_address = { 0 }, client_address = { 0 };
char data[1024] = { 0 };
int s, clientsocket, bytes;
socklen_t opt = sizeof(client_address);
- Next, the s is created with the communication domain set to AF_BLUETOOTH, the communication type set to SOCK_STREAM, and the communication protocol set to BTPROTO_RFCOMM:
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- The RPi's Bluetooth MAC address is then bound to the server socket using the bind function and the s (server socket) enters listening mode as follows:
bind(s, (struct sockaddr *)&server_address, sizeof(server_address));
listen(s, 1);
- Once the connection is accepted, a new client socket is created using the accept function as follows:
clientsocket = accept(s, (struct sockaddr *)&client_address, &opt);
- The incoming byte data is then converted to a string using the ba2str function. After that, the MAC address of the connected Bluetooth is displayed as follows:
ba2str( &client_address.rc_bdaddr, data );
fprintf(stderr, "Connected to %s\n", data);
- After this, inside the for loop, the incoming data is read using the read function. If the value inside the byte variable is greater than 0, we print the data as follows:
for(;;){
bytes = read(clientsocket, data, sizeof(data));
if( bytes > 0 ) {
printf("Alphabet: %s\n", data);
Now, we will use five if conditions to check whether the incoming data contains the letters F, B, L, R, or S, as follows:
if(*data=='F')
{
----Forward Code----
}
else if(*data=='B')
{
----Backward Code----
}
else if(*data=='L')
{
----Axial Left Turn Code----
}
else if(*data=='R')
{
----Axial Right Turn Code----
}
else if(*data=='S')
{
----Stop Code----
}
The preceding code can be explained as follows:
- *data == 'F': The robot will move forward
- *data == 'S': The robot will move backward
- *data == 'L': The robot will take an axial left turn
- *data == 'R': The robot will take an axial right turn
- *data == 'S': The robot will stop
- Finally, to disconnect the devices, the close function is used to close the clientsocket and the s as follows:
close(clientsocket);
close(s);
- Next, since this code contains a socket and a Bluetooth header file, to compile this code, you will need to add the -lbluetooth command inside the Build command. As this is a C program and not a C++ program, you will also have to add the -lwiringPi command to compile the wiringPi code as follows:
Next let's test the code and check the final output.