The basic idea of ??the project that the robotics team of the 3rd Gymnasium of Amaliada had to implement was the construction of a radio-controlled robot that could play football on a pitch-track that we would build and which would have dimensions similar to those of the slopes WRO competitions.

After we first imagined and then built our robot, we thought to implement it with wired connection and we did it without much difficulty. This Arduino wearing the firmware provided by Scratch for Arduino (s4a.cat), which you can download from here, can be programmed with Scratch. To do this, you must download and install a special version of Scratch that you will find on the same site (s4a.cat).


For this reason, we also have the relevant video:

With button events and engine commands provided by S4A, we have been able to handle our robot from our computer keyboard. But because the best is the enemy of the good, at first we decided to try to wirelessly connect our robot with a computer and then investigate if this could be done with a mobile phone.

That’s why we bought the HC-05 Bluetooth Module for Arduino and connected it to the Arduino Leonardo that contains our package.

The basic difficulty in building this particular project was to connect the Arduino Leonardo board that contains the GIGO S4A via Bluetooth to any device. Bluetooth connectivity with the computer or any other device was successful, but the s4a scratch application could not locate the board. We have not been able to resolve this problem. Besides, when the s4a was opened the Bluetooth connection was not stable (there were continuous disconnections).

So we abandoned the idea of ??connecting the computer with a wireless connection to the board and thus handling the robot, just as we did with the cable. Then the idea of ??creating an app in App Inventor, with which we will handle the robot, fell to the table. We found that the HC-05 Module was connected to any android mobile, so why not make a similar application to what we had already done for the LEGO robot. The challenge was that app inventor has ready-made blocks for handling the LEGO EV3 engines and sensors, but in our case we would have to find other ways of communicating the application with our robot.

That is why we should have planned Arduino from the beginning. The first move we had to do was to establish a Bluetooth connection that we would use to communicate the mobile phone with our robot. That’s why we used the SoftwareSerial.h library to replace the arduino’s default serial communication pins with others (the function of which was simulated with software) so we can take advantage of the Bluetooth Module.

Our code looked something like this:

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
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 8
#define TxD 7
SoftwareSerial blueToothSerial(RxD,TxD);

void setup() {
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
setupBlueToothConnection();
Serial1.begin(9600);
}
void loop() {

}

void setupBlueToothConnection()
{
blueToothSerial.begin(9600); //Set BluetoothBee BaudRate to (9600) the default baud rate is 38400
blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blueToothSerial.print("\r\n+STNA=SeedBT\r\n"); //set the bluetooth name as "SeedBT"
blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
delay(2000); // This delay is required.
blueToothSerial.flush();
}

Then, after testing the Bluetooth connection, we modeled the Scratch For Arduino firmware mode and used some of the functions it used to control the motors and sensors. So we added the initialization functions of the pins configurePins () and resetPins (), as well as the sendUpdateServomotors (), servo () and pulse () engines.

Our code, at this point, looked something like this:

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 8
#define TxD 7
SoftwareSerial blueToothSerial(RxD,TxD);
String voice;
typedef enum {
input, servomotor, pwm, digital }
pinType;
typedef struct pin {
pinType type; //Type of pin
int state; //State of an output
//byte value; //Value of an input. Not used by now. TODO
};
pin arduinoPins[14]; //Array of struct holding 0-13 pins information
unsigned long lastDataReceivedTime = millis();
void setup() {
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
setupBlueToothConnection();
Serial1.begin(9600);
configurePins();
resetPins();
}
void loop() {

while (Serial1.available())
{
delay(10);
char c = Serial1.read();
voice += c;
}

sendUpdateServomotors();
}

void configurePins()
{
arduinoPins[0].type=input;
arduinoPins[1].type=input;
arduinoPins[2].type=input;
arduinoPins[3].type=input;
arduinoPins[4].type=servomotor;
arduinoPins[5].type=pwm;
arduinoPins[6].type=pwm;
arduinoPins[7].type=servomotor;
arduinoPins[8].type=servomotor;
arduinoPins[9].type=pwm;
arduinoPins[10].type=digital;
arduinoPins[11].type=digital;
arduinoPins[12].type=digital;
arduinoPins[13].type=digital;
}
void resetPins() {
for (byte index=0; index <=13; index++)
{
if (arduinoPins[index].type!=input)
{
pinMode(index, OUTPUT);
if (arduinoPins[index].type==servomotor)
{
arduinoPins[index].state = 255;
servo (index, 255);
}
else
{
arduinoPins[index].state=0;
digitalWrite(index,LOW);
}
}
}
}

void sendUpdateServomotors()
{
for (byte p = 0; p < 10; p++)
if (arduinoPins[p].type == servomotor) servo(p, arduinoPins[p].state);
}
void servo (byte pinNumber, byte angle)
{
if (angle != 255)
pulse(pinNumber, (angle * 10) + 100);
}

void pulse (byte pinNumber, unsigned int pulseWidth)
{
digitalWrite(pinNumber, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(pinNumber, LOW);
}

void setupBlueToothConnection()
{
blueToothSerial.begin(9600); //Set BluetoothBee BaudRate to (9600) the default baud rate is 38400
blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blueToothSerial.print("\r\n+STNA=SeedBT\r\n"); //set the bluetooth name as "SeedBT"
blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
delay(2000); // This delay is required.
blueToothSerial.flush();
}

All that has been left over is to build the communication language between the application and the robot. The concept is very simple as the application through the Bluetooth connection sends specific messages to the robot and it should perform different functions depending on the input received.

So we trained our robot when it receives the F1 message then the two engines move forward with the same force, when the two engines receive the message B1 to reverse with the same force while when it receives the message L1 and R1 the two engines to move in opposite directions, so that the robot turns left and right respectively. Moreover, when it receives message K1 stretching the front arm and when it receives message K2 it gathers the front arm. Finally, when the robot receives message 0 then it must stop. The logic behind the Arduino programming is that we load the value at each pin (pin) and through a function that runs continuously controls the values ??and accordingly drives the motors. For example, if the pin4 is loaded at pin4 then the motor connected to pin4 will rotate 100 degrees in the time unit, and if set to -100 degrees, it will rotate 100 degrees counterclockwise. Finally, if we set the value of 255 then the engines stop.

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
if (voice.length() > 0)
{
Serial1.println(voice);
if(voice == "F1") //μπροστά
{

arduinoPins[4].state=100;
arduinoPins[7].state=100;
}
if(voice == "0") //σταμάτημα
{
arduinoPins[4].state=255;
arduinoPins[7].state=255;
}
if(voice == "L1") //αριστερά
{
arduinoPins[4].state=-100;
arduinoPins[7].state=100;

}
if(voice == "R1") //δεξιά
{
arduinoPins[4].state=100;
arduinoPins[7].state=-100;

}
if(voice == "B1") //πίσω
{
arduinoPins[4].state=-100;
arduinoPins[7].state=-100;

}
if(voice == "K1") //κλωτσιά άνοιγμα
{
arduinoPins[8].state=-100;
}
if(voice == "K2") //κλωτσιά μάζεμα
{
arduinoPins[8].state=100;
}
if(voice == "K0") //κλωτσιά σταμάτημα
{
arduinoPins[8].state=255;
}
voice="";
}

The final code we’ve uploaded  in Arduino is:

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 8
#define TxD 7
SoftwareSerial blueToothSerial(RxD,TxD);
String voice;
typedef enum {
input, servomotor, pwm, digital }
pinType;
typedef struct pin {
pinType type; //Type of pin
int state; //State of an output
//byte value; //Value of an input. Not used by now. TODO
};
pin arduinoPins[14]; //Array of struct holding 0-13 pins information
unsigned long lastDataReceivedTime = millis();
void setup() {
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
setupBlueToothConnection();
Serial1.begin(9600);
configurePins();
resetPins();
}
void loop() {

while (Serial1.available())
{
delay(10);
char c = Serial1.read();
voice += c;
}
if (voice.length() > 0)
{
Serial1.println(voice);
if(voice == "F1")
{

arduinoPins[4].state=100;
arduinoPins[7].state=100;
}
if(voice == "0")
{
arduinoPins[4].state=255;
arduinoPins[7].state=255;
}
if(voice == "L1")
{
arduinoPins[4].state=-100;
arduinoPins[7].state=100;

}
if(voice == "R1")
{
arduinoPins[4].state=100;
arduinoPins[7].state=-100;

}
if(voice == "B1")
{
arduinoPins[4].state=-100;
arduinoPins[7].state=-100;

}
if(voice == "K1")
{
arduinoPins[8].state=-100;
}
if(voice == "K2")
{
arduinoPins[8].state=100;
}
if(voice == "K0")
{
arduinoPins[8].state=255;
}
voice="";
}
sendUpdateServomotors();
}

void configurePins()
{
arduinoPins[0].type=input;
arduinoPins[1].type=input;
arduinoPins[2].type=input;
arduinoPins[3].type=input;
arduinoPins[4].type=servomotor;
arduinoPins[5].type=pwm;
arduinoPins[6].type=pwm;
arduinoPins[7].type=servomotor;
arduinoPins[8].type=servomotor;
arduinoPins[9].type=pwm;
arduinoPins[10].type=digital;
arduinoPins[11].type=digital;
arduinoPins[12].type=digital;
arduinoPins[13].type=digital;
}
void resetPins() {
for (byte index=0; index <=13; index++)
{
if (arduinoPins[index].type!=input)
{
pinMode(index, OUTPUT);
if (arduinoPins[index].type==servomotor)
{
arduinoPins[index].state = 255;
servo (index, 255);
}
else
{
arduinoPins[index].state=0;
digitalWrite(index,LOW);
}
}
}
}

void sendUpdateServomotors()
{
for (byte p = 0; p < 10; p++)
if (arduinoPins[p].type == servomotor) servo(p, arduinoPins[p].state);
}
void servo (byte pinNumber, byte angle)
{
if (angle != 255)
pulse(pinNumber, (angle * 10) + 100);
}

void pulse (byte pinNumber, unsigned int pulseWidth)
{
digitalWrite(pinNumber, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(pinNumber, LOW);
}

void setupBlueToothConnection()
{
blueToothSerial.begin(9600); //Set BluetoothBee BaudRate to (9600) the default baud rate is 38400
blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blueToothSerial.print("\r\n+STNA=SeedBT\r\n"); //set the bluetooth name as "SeedBT"
blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
delay(2000); // This delay is required.
blueToothSerial.flush();
}

 

And we are now coming to the mobile app (here things are simpler) where we used  App Inventor‘s educational platform.

We first created the app’s graphical interface, where we added the four-way buttons (front, back, left, right), a kick button, a list of connected Bluetooth devices, and a disconnect button. We also needed a Bluetoothclient and a clock (timer).

After we properly shaped the appearance of the objects we would use then we dealt with their programming. So, through BlutoothClient, we first detect all Bluetooth devices that are near us and selecting some of the devices to establish a connection between them. Then we set a message (in text format) for each button that will send to our robot so that, according to the above, the robot responds appropriately.

The only noteworthy point here is the way the kick is done, after pressing the corresponding button except for the arm spread message, activates a timer, which after a second sends an arm reset message and finally sends its stop message.

Below is the program we use for the implementation.

The video below shows a successful attempt to execute a penalty!

Special Thanks to the English Teacher of our school Mrs Tagiou E. for the translation of this post.

Arduino Leonardo Remote Controlled Robot with Mobile Phone Connection via Bluetooth

Αφήστε μια απάντηση

Η ηλ. διεύθυνση σας δεν δημοσιεύεται. Τα υποχρεωτικά πεδία σημειώνονται με *