Home Development for Android Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth

Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth

by admin

This article is a semi-sequel to the work of Love, Death and Robots "Arduino Machine Controlled by Android Device via Bluetooth – Full Cycle, " a two-part paper ( times , two ). The things described there have been a little tweaked-reworked, and the robot itself has turned from a riding machine into a soccer player. All in all, there is some interesting stuff about how not to do things.
The previous instruction was divided into two parts : software and physical. There were not many changes in both directions, so this time everything is in one copy. I will briefly remind you why the described part is needed, but for a complete understanding it is better to run through the first two parts.

Physical part

All the same principles described in the first article are taken as a basis :

  • sandwich from Arduino Uno and Motor Shield.
  • Two motors connected to the Motor Shield.

And here are the changes :

  • the striking part, oddly enough, responsible for hitting the ball, appeared.
  • The body is now completely its own, 3D-printed.


The shape is a circle that accommodates both the board and the two wheels. The extension is for the part where the shock will stand.
Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth
When constructing a similar one, pay attention to :

  • High Bounds. Robots collide during play, the boards protect not only your wires, but also your opponents from your wires.
  • Center of gravity and stability. The center of gravity is of course where the board is. The wheels are near it, so it won’t slip. Plus there is a battery on top of the board.
  • So that the robot doesn’t peck its nose or backside, we put both here and there the balls coming from the amp set (if you don’t have them, you can replace them with any other sliding construction).
  • Structural Stiffness. The platform should not sag under the weight of the boards and motors. Don’t be stingy, either use hard materials (plywood) or reinforce the plastic construction with slats

Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth

And now the basic nonsense

The balls added to avoid "pecking" raised the platform so that the wheels would not reach the floor. To avoid this, we either use larger diameter wheels or shorten the support structures. In general, calculate it in advance!
The striking part. It doesn’t hit. It does, but it’s not cool enough. In our first model we had a servo machine which was connected to what looked like a snowplow bucket. By changing the servo position (from 0 to 30 degrees) it was possible to simulate a kick. But the servos turned out to be slow, so the kick comes out to two.
There are two ways out: add jerk on impact or replace the servos with solenoids. The first option is to increase the momentum by feeding the speed to the wheels during the impact. In practice, it is like this: the user presses the kick button, the robot starts up (just a little) and makes a kick at the same time.
The second option is that the solenoids push the shock part and here everything depends on the power (speed) of the shock, which in turn depends on the characteristics of the solenoid.
Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth

Software part

According to the good tradition, which is already one article, we will divide this section into two parts. First the Android application, then the Arduino sketch.


Let me remind you, I wrote the application from scratch. In the past six months, I’ve gotten a little more into this business, so I’ll describe how got it figured out.
First, let’s go to simplification. Now the communication protocol is as follows: "opening character" + "value" + "closing character" (To understand how I get these values and what we’re talking about, see the full breakdown of the application here ). This works for both the velocity value and the angle value. Since there is only one hit type, it doesn’t need that kind of wisdom, so the command consists of a single character "/" (about the hit command through the paragraph).

private void sendCommand(String speed, String angle) {String speedCommand = "#" + speed + "#"; //adding the start and end charactersString angleCommand = "@" + angle + "@";try {outputStream.write(speedCommand.getBytes()); //sending both commandsoutputStream.write(angleCommand.getBytes());} catch(Exception e) {e.printStackTrace();}}

A typical command would look like this: #125#@180@, where 125 is speed and 180 is angle. Of course, this could still be simplified, but one of the goals was to keep it easy and readable, so that it could be easily explained later, including to children.
There is a new command sendHit(), which is triggered when the hit button is pressed. It sends a single sign "/". Since conventional bluetooth 2.0+ does not suffer from data coming in simultaneously, i.e. it knows how to queue them up and not lose them, we do not need to control this. If you are going to work with Bluetooth Low Energy 4.0+ (just in case), you will have to organize the queue manually, otherwise data will be lost.

..bHit = findViewById(R.id.b_high_hit); //finding the strike buttonbHit.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {threadCommand.sendHit(); //when pressed, we call the sending of the command "blow quot;}});...private void sendHit() {try {outputStream.write("/".getBytes()); //sending one character}catch (Exception e) {e.printStackTrace();}}}


So the protocol for sending commands has changed and so has the algorithm for receiving commands. It’s been simplified. Also, one if was added which tracks the kick. Here is the full breakdown of the sketch here
bt.read() reads one character. If it is "#" then the speed characters start. Read them until the closing character "#" appears. The for loop cannot be used here, because the length of the velocity is unknown beforehand (it can be a one-, two-, or three-digit number). We write the obtained value into a variable.
The same thing happens with turn. After both speed and angle are read, we pass everything to the turn(int speed, int angle) function.

void loop() {if(BTSerial.available() > 0) {//if there are sent characterschar a = BTSerial.read(); //read first characterif(a == '#') { //the speed startssp="";char b = BTSerial.read();while( b != '#') {//as long as not closing character, add characters to the variablesp+=b;b = BTSerial.read();}} else if (a == '@') { //the corner beginsval = "";char b = BTSerial.read();while(b != '@') { //until the closing characterval+=b; //add symbol to the variableb = BTSerial.read();}turn(val.toInt(), sp.toInt()); //speed and angle read, start action} else if (a == '/') { //oops, we have to take a blowSerial.println(a);servo.write(30); //make a kickdelay(150);servo.write(0); //return to initial position}lastTakeInformation = millis();} else {if(millis() - lastTakeInformation > 150) {//if the commands didn't come for over 150 ms//stop the robotlastTakeInformation = 0;analogWrite(speedRight, 0);analogWrite(speedLeft, 0);}}delay(5);}

The turn() function determines which way to go (forward, backward) and which way to turn (right, left, straight ahead). The if(speed > 0 speed < 70) constraint is needed so that the robot does not slow down if bytes are lost. I faced this problem when I increased transmission speed (I played with 100-300ms delays between commands) – sometimes speed didn’t reach 0, 40 (although it was actually sending 240). Crutch, but it works.
You could call it "protection against uncontrollable factors".

void turn(int angle, int speed) {if(speed > = 0 speed < 70) return;if(speed > 0) {digitalWrite(dirLeft, HIGH);digitalWrite(dirRight, HIGH);} else if (sp < 0) {digitalWrite(dirLeft, LOW);digitalWrite(dirRight, LOW);}if(angle > 149) {analogWrite(speedLeft, speed);analogWrite(speedRight, speed - 65); //turn right} else if (angle < 31) {analogWrite(speedLeft, speed - 65); //turn leftanalogWrite(speedRight, speed);} else {analogWrite(speedLeft, speed);analogWrite(speedRight, speed);}}

Competitions at MIPT instead of totals

With our robot we went to the robo-football competition, which was organized and held at MIPT University, Dolgoprudny, 14.04.2019. We managed to get into the 14 finals, but we didn’t get any further.
Robo-football player from beginners.Competitions at MIPT. Android& Arduino& Bluetooth
The process itself was interesting to us, and here I will describe the conclusions I was able to draw from looking at the robot in the field :

  • needs more power. Preferably four wheels or more powerful engines and other wheels. Although, of course, it was the four-wheeled models that looked more advantageous.
  • control is not a buzzkill. You have to translate the robot to a tank turn (turn at one point due to the wheels spinning in opposite directions), otherwise the turning radius is too big. Yes and in general a four-arrow option, not a circle with proportional speed, for soccer is preferable. Described option is better suited for racing, where you drive continuously, but here you need clarity (you turn 10 degrees around your axis, aim at the ball and press the button forward. But then, when you’ve already caught the ball, you want to maneuver flexibly, and here you need proportional speed… you have to somehow combine the things).

Comments and suggestions will be very welcome. Under previous articles, comments are sometimes more interesting than the article itself. Thanks for the work to me , Sasha and Dana

You may also like