📜 ⬆️ ⬇️

Tank - your robot on the Arduino

Let's program the robot based on Arduino.
I will begin with the theory and description of all that is useful to us.

image

Let me remind you that Arduino is a hardware computing platform, the main components of which are a simple I / O board and the development environment in the language Processing / Wiring. The documentation for the hardware and software code is published under the license “copyleft”, but the developers expressed their desire that the name “Arduino” be a trademark for the official product and not be used for derivative works without permission. The document on the use of the name Arduino emphasizes that the project is open to all comers.
')
Until recently, the creation of robots was considered a very difficult procedure, requiring the developer high qualifications and special education, as well as a long time to develop. But with the advent of Arduino boards, almost everyone who is at least familiar with programming can afford this occupation! Easier nowhere, but first things first.


The Arduino board consists of an Atmel AVR microcontroller and an element strapping for programming and integration with other circuits. Each board must contain a linear voltage regulator 5 V and 16 MHz crystal oscillator. The microcontroller is pre-flashed bootloader, so an external programmer is not needed.

The Arduino project is constantly evolving and has many modifications. At the moment, there are 10 versions of boards available, but the Arduino Diecimila board was used specifically in this project. It is a small electronic board, the core of which is an ATmega168 microcontroller. The board has: 14 digital inputs / outputs, 6 of which can operate in PWM mode (and therefore control analog devices like motors and transfer binary data), 6 analog inputs, a 16 MHz clock generator, power connectors and USB, An ICSP port (something like a serial interface for digital devices), several control LEDs and a reset button. This is quite enough to connect the board to the USB port of the computer, install the necessary software (driver and development environment) and start programming.

image
The appearance of the Arduino Diecimila board.

Brief specification

Microcontroller: ATmega168
Operating voltage: 5 V
Input voltage (recommended): 7-12 V
Input voltage (limits): 6-20 V
Digital I / O ports: 14 ports (including 6 with a PWM signal)
Analog input ports: 6 ports
Current for ports: 40 mA
Current for 3.3V source: 50 mA
PROM (Flash Memory): 16 KB (of which 2 KB are used by the bootloader)
RAM (SRAM): 1 KB
ROM (EEPROM): 512 bytes
Clock frequency: 16 MHz

What is needed to make your robot?

A robot can be assembled, as many enthusiasts do, but you can also rework an existing one. Any toy with moving parts is suitable as a robot. In my case, it is a tank with moving tracks driven by built-in motors (the tank had a remote control). I will manage these motors with the help of the board.

An important step, of course, is getting one of the Arduino boards at your disposal. In my case, this is the Arduino Diecimila board. Also, a USB cable of any length standard AB is required to connect the board to the computer. This cable will exchange data between the computer and the microcontroller, as well as supply power to the board, i.e. external power supply is optional. Another component that is required for motor control is the MotorShield expansion board.

image
MotorShield expansion board and kit parts.

image
What and how to connect to MotorShield.

Next, you need to determine the goals: I need to attach a remote control to an existing toy tank, but not the usual “where I clicked - I went there”, but one in which coordinates would be transmitted to the tank on an imaginary field and it would reach them independently. Those. you need to imagine that the room (or any other area through which the tank will move) is divided into squares, which is a coordinate system. Then the tank will need to transfer the coordinates of a square and it will have to turn to it and travel the required distance to become in this square.

image
Toy tank with a motherboard.

image
The motherboard is clearly more Arduino board :).

There is a tank with motors, there is a board, there is an expansion board. Necessary means for the transfer of coordinates. This will be a program on the user's computer that will transfer data to the tank via Wi-Fi connection. I should note that the Wi-Fi is not understandable to the board, so the tank also has a regular motherboard (later replaced with a laptop), which will transmit data from the Wi-Fi adapter to a COM port through which the connection to the Arduino board will be. From her signals will already come to the expansion card, and the motors will have to spin. The task is to write two programs: one for transferring data from the computer to the Wi-Fi adapter, the other for processing data inside the microcontroller.

image

So let's go!

You can write the program, which is responsible for data exchange between the PC and the microcontroller via the COM port, on anything. Let it be Delphi.

For brevity, I’ll give the source code only for the function that will send commands to the tank that are responsible for turning and moving to the desired angle / distance. The function accepts current coordinates (x0, y0), new coordinates (x1, y1), and the current angle of rotation of the alpha tank. The return function will be the new current angle. Current coordinates and angle are stored outside the function. The code is commented in the right places, so I will not describe.

Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  1. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  2. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  3. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  4. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  5. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  6. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  7. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  8. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  9. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  10. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  11. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  12. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  13. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  14. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  15. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  16. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  17. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  18. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  19. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  20. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  21. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  22. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  23. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  24. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  25. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  26. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  27. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  28. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  29. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  30. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  31. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  32. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  33. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  34. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  35. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  36. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  37. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  38. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  39. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  40. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

  41. Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;

Copy Source | Copy HTML Function MoveTank(x0, y0, x1, y1, alpha: integer ): integer ; var newAlpha: integer ; // FlagsField : byte; // angle_tmp: integer ; TmpStr: string; angle, dist: byte; // , begin // newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // angle_tmp := (360 + newAlpha - alpha) mod 360; // dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1))); FlagsField := 0; // if angle_tmp <= 90 then FlagsField := 0 // , else if angle_tmp < 180 then begin angle_tmp := 180 - angle_tmp; FlagsField := FlagsField or 4; // , end else if angle_tmp < 270 then begin angle_tmp := angle_tmp - 180; FlagsField := FlagsField or 6; // , end else begin angle_tmp := angle_tmp - 270; FlagsField := FlagsField or 2; //, end ; angle := angle_tmp; // COM- , . FlagsField:= FlagsField or 1; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(angle); ComPort_. Write (TmpStr); FlagsField:= FlagsField and 254; // TmpStr := Chr(FlagsField); ComPort_. Write (TmpStr); TmpStr := Chr(dist); ComPort_. Write (TmpStr); Result := newAlpha; end ;



The next step is to write a program for flashing it to the board. All we need is to accept data from the serial port and process the incoming command, including the rotation of the engines of the tank in the right direction. The motors are turned on for a certain time and the duration of this time is achieved by moving to the required distance.

The program for receiving data uses pin number 9 (TxD). Accordingly, the 2nd contact of the motherboard COM port (RxD) must be connected to pin number 9 on the Arduino. Another requirement: you need to configure the motherboard COM port for a speed of 9600 baud.

To control the movement of the tank, we will use two motors - for the left and right tracks (M1 and M2 connectors on the Motor Shield). To simplify the work with motors, we use the AFMotor framework, which is easily connected to our project with one line “#include“ AFMotor.h ””. Motors denote the numbers 1 for the left and 2 for the right tracks. In the code below, it is clear that working with motors is not a big deal.

Copy Source | Copy HTML
  1. #include "AFMotor.h" // library for easy handling of engines
  2. #define TX 9 // pin to Arduino where the output from the COM port is connected
  3. // coding commands from the joystick
  4. #define cmdForward 1
  5. #define cmdBackward 2
  6. #define cmdRapid Left 3
  7. #define cmdRapid Right 4
  8. #define cmd Left 5
  9. #define cmd Right 6
  10. // speed of rotation of engines
  11. // MaxSpeed ​​- normal motion
  12. // MinSpeed ​​- the speed of one of the tracks during a sharp turn
  13. // HalfSpeed ​​- the speed of one of the tracks with a smooth turn
  14. #define MaxSpeed 200
  15. #define MinSpeed 100
  16. #define HalfSpeed 150
  17. // movement of the tank with the speeds of the left and right tracks LTS and RTS
  18. // towards Direction
  19. void MoveTank ( byte LTS, byte RTS, byte Direction );
  20. // read one byte from the COM port
  21. byte COMread ();
  22. // stores the command received from the COM port
  23. byte Command = 0 ;
  24. // current direction of travel
  25. byte Current Direction = FORWARD;
  26. // select the 1st and 2nd connectors on the Motor Shield, where the engines are connected
  27. AF_DCMotor Left Track ( 1, MOTOR12_1KHZ );
  28. AF_DCMotor Right Track ( 2, MOTOR12_1KHZ );
  29. void setup ()
  30. {
  31. Left Track.setSpeed ​​( MaxSpeed );
  32. Right Track.setSpeed ​​( MaxSpeed );
  33. pinMode ( TX, INPUT );
  34. }
  35. void loop ()
  36. {
  37. Command = COMread ();
  38. switch ( Command )
  39. {
  40. case cmdForward:
  41. MoveTank ( MaxSpeed, MaxSpeed, FORWARD );
  42. Current Direction = FORWARD;
  43. break;
  44. case cmdBackward:
  45. MoveTank ( MaxSpeed, MaxSpeed, BACKWARD );
  46. Current Direction = BACKWARD;
  47. break;
  48. case cmdRapid Left :
  49. MoveTank ( MinSpeed, MaxSpeed, CurrentDirection );
  50. break;
  51. case cmdRapid Right :
  52. MoveTank ( MaxSpeed, MinSpeed, CurrentDirection );
  53. break;
  54. case cmd Left :
  55. MoveTank ( HalfSpeed, MaxSpeed, CurrentDirection );
  56. break;
  57. case cmd Right :
  58. MoveTank ( MaxSpeed, HalfSpeed, CurrentDirection );
  59. break;
  60. default :
  61. Left Track.run ( RELEASE ); // stop the engines
  62. Right Track.run ( RELEASE );
  63. break;
  64. }
  65. }
  66. void MoveTank ( byte LTS, byte RTS, byte Direction )
  67. {
  68. Left Track.setSpeed ​​( LTS );
  69. Right Track.setSpeed ​​( RTS );
  70. Left Track.run ( Direction );
  71. Right Track.run ( Direction );
  72. }
  73. byte COMread ()
  74. {
  75. byte val = 0 ;
  76. while ( digitalRead (TX ));
  77. // waiting for the start bit
  78. if ( digitalRead (TX ) == LOW )
  79. {
  80. delayMicroseconds ( 42 );
  81. for ( int k = 0; k <8; k ++ )
  82. {
  83. delayMicroseconds ( 84 );
  84. val | = digitalRead ( TX ) << k;
  85. }
  86. // waiting for the 9th bit and stop
  87. delayMicroseconds ( 168 );
  88. return val;
  89. }
  90. }


It remains only to flash this program in the Arduino (and this is done by pressing a single button in the Arduino IDE interface) and you can have fun sending the tank to the rear of the enemy :).

Conclusion

Of course, you can not be limited to simply sending coordinates. You can add interactivity by using the joystick to control the tank. And using a webcam attached to the turret of the tank, you can watch the movement while sitting at the computer. But this will require additional software. But even this does not make programming Arduino something overwhelming. Working with such a board is easy, easy, and most importantly - affordable! But no, the main thing is to receive a lot of pleasure both from the result and from the process itself!

Source: https://habr.com/ru/post/90590/


All Articles