Geek Navigation (51, STM32, Smart Car Project, ESP8266, Remote Control System)

Article Records: Geek Navigation

This project is an embedded project in the Geek Navigation Tutorial, a remote control system for smart cars
Code is open source (end of article).

The design system mainly includes (as shown in the diagram)

  • Car owners (51 and STM32)
  • Hardware remote control (master STM32)
  • Mobile phone remote control software (Android design)
  • Computer Control Software (QT Design)

This design does not add too many sensors in the car. First, it mainly implements the main function of the car, which is remote control. For ranging, display, gyroscope, tracing and so on, it can be added after the basic function is realized. In the follow-up of the tutorial, you will write articles such as tracked car, balanced car, exquisite robot, etc., which can refer to the Geek Navigation tutorial system.

Here's a cart made in the past. Now it looks a little ugly. Cars and remote controls can draw PCB and 3D models, which will look good. If you're interested, you can see the auxiliary design section of this tutorial.

Previously designed posters now look and feel good.

I won't say much here. If you're interested, you can support it. In the future, I will also record and make tutorial videos. If you find the articles dull, you can watch videos.

Car owners (51)

The main modules of the car body are L298N motor drive module and ESP8266WiFi module.

L298N motor drive

Core Knowledge Points

  • Channel A and Channel B connect two motors, positive and negative.
  • The 5V input is powered to L298N chips. Some chips will be powered on after the positive pole of the main power supply is connected, so no external connection is needed. Then you can use this voltage to power other single-chip computers.
  • Voltage output from the positive pole of the main power supply to the motor, up to 12V
  • Input 1,2,3,4 controls the forward and reverse of the motor, such as 1 for high level and 2 for low level, the motor will turn and the reverse motor will turn. 12 controls one motor and 34 controls one motor.
  • The A-phase enabler and the B-phase enabler enable the motor. If we do not adjust the speed, we directly connect the high level and the next pin on L298N. The speed is determined by the voltage of the motor. If we need to adjust the speed, the two pins need to be connected to the single-chip pin, and the PWM output is done through the program design.

51 Code settings, how do we define how to connect.

//Enabler, speed control using PWM wave
sbit ENA = P1^4;
sbit ENB = P1^5;
sbit IN1 = P1^0; //Define right control pin
sbit IN2 = P1^1;
sbit IN3 = P1^2; //Define left control pin
sbit IN4 = P1^3;

How to control the motor rotation?
Above we have set the pin, you can make the enabled pin connect to the high level first, or make the enabled pin equal to the high level.
If you want the motor on the right to turn, you can IN1 = 1, IN2 = 0, the motor will turn, if IN1 = 0, IN2 = 1, the motor will reverse. If IN1 = 1, IN2 = 1; IN1 = 0, IN2 = 0, the motor will stop.

How to adjust the speed of the motor?
Motor speed control involves PWM output, and timer, duty cycle, is involved in 51.
So let's start with the timer configuration, which mainly includes initialization and interruption functions.

Timer Base Register

  • There is no basis to look at registers which are more demanding, and I don't delve into it here. Just ask what I need, skip what I don't want to know, just look at the application.

Interrupt System Diagram

TMOD Register

TCON Timer Control Register

TR0:TR0=1 means that T0 starts to run. (T1 pin in single-chip computer needs high and low level driver)
TR1:TR1=1 indicates that T1 starts to run. (T0 pin in single-chip computer needs high and low level driver)

Interrupt Source Priority and Interrupt Number

I'll list what I need here. As for register specifics, I can look them up by myself. I don't want the article to be too cumbersome.

Timer Initialization Process

  • 1. Select the mode of timer and set TMOD, for example, we set TMOD=0X01;As you can see from the figure above, M1 = 0, M0 = 1; Choose Mode 1. Remember that the last four bits are Timer 0 and the first four bits are Timer 1. Choose Mode is the number of registers that determine the timing and count.
  • 2. Given the initial value of the timer, determine the time for each register overflow
    How to feed in initial values:
from TMOD Mode selection, mode 1 is a 16-bit timer/Counter
16 Bit register capacity is 65535
 Once the timer starts, the register is added to the original value by 1, each time adding 1 is a machine cycle
 A machine cycle equals 12 clock cycles, which are related to the frequency of the crystal oscillation
 If the crystal frequency is 12 HZ,Then the time of a clock cycle is 1/12us
 So a machine cycle is 1 us

This means that each count of registers requires 1 us Time
10000us == 10ms
 If we set the initial value of the register to 65535 - 10000 = 55535
 So starting at 55535, when you reach 65535, you need to count 10,000 times, which is 10 ms
 We can control the number of register overflows to get the exact time
 If we set 10 for each overflow ms,So 100 times is 1 s

How to set the initial value of the register?
If we want to set the initial value to 55535
1,For 55535 / 256 = 216; 216 The corresponding hexadecimal number is 1101,000 = 0xd8
 finish writing sth. TH0=0Xd8; 
2,For 55535 more % 256 = 239; 239 Corresponding hexadecimal 110 1111 = 0xef
 finish writing sth. TL0=0Xf0;
  • 3. Open interrupt permission, ET0, EA
	ET0=1;//Turn on timer 0 interrupt allow
	EA=1;//Open Total Interrupt
  • 4. Start time TR0=1;

Sharing logic based on interrupt system diagrams is clearer, and the following video tutorials are mainly summarized.

From the analysis above, we can write
Initialization function for timer 0

//Timer 0 Initialization Function
void Timer0Config()
	TMOD &= 0xF0; //Clear mode of timer 0
	TMOD |= 0x01; //Set timer 0 mode
	TH0 = 0xFF; //Input Initial Value (65536 - 130) / 256 65536 - 65406
	TL0 = 0x7E; //(65536 - 130) % 256
	EA = 1; //Open Total Interrupt
	ET0 = 1; //Turn on timer 0 interrupt allow
	TR0 = 1; //Timer 0 Allow Control Bits

Timer 0 interrupt function

//Timer 0 interrupt function interrupt number is 1
void InterruptTimer0() interrupt 1
	//The initial value needs to be reset after each overflow
	TH0 = 0xFF; //Given an initial timer value, timer 130us
	TL0 = 0x7E;
	cnt++; //Add 1 cnt per overflow and 1 130us per overflow
	if(cnt >= 100) //Clear 0 when cnt is greater than or equal to 100
		cnt = 0;
	//Here is to define a period of 130 * 100 = 13000us, 13ms

Timer initialization function and interrupt function are both written, how to control the motor?
Not yet, because we still have to write PWM functions.
We analyze it with a piece of code

	IN3 = 1;
	if(cnt <= DutyCycle) //DutyCycle is a duty cycle
		IN4 = 0;
		IN4 = 1;

Because of the timer interrupt function, the cnt variable loops between 0 and 100, overflowing 100 cycles; analyzing the code above, when DutyCycle = 60, we execute the program above 100 times, cnt increments. You will find that IN3 100 times are 1, IN4 60 times are 0, 40 times are 1, the speed is%60 at full speed; when DutyCycle = 60At 100, IN3 is all 1, IN4 is all 0 and the speed is full. So we can adjust the speed by modifying the duty cycle.

The above analysis may be vague, because there is no subjective understanding, you can use single-chip computer and motor drive to test, to modify the duty cycle, to see the speed changes, I will also demonstrate in the video tutorial.

We encapsulate the function that adjusts the duty cycle.

Parameter Definition: 
	ReverOrCoro Pass Forward and Reverse, 1 Forward and 0 Reverse
	DutyCycle Duty Cycle Parameter
void Motor_Right(bit ReverOrCoro, unsigned char DutyCycle) 
	if(ReverOrCoro == 1)
		IN3 = 1;
		if(cnt <= DutyCycle)
			IN4 = 0;
			IN4 = 1;
		IN4 = 1;
		if(cnt <= DutyCycle)
			IN3 = 0;
			IN3 = 1;

How do we call it in the program?

Motor_Right(0, 0); //Duty ratio 0, stop
Motor_Right(0, 50); //Duty cycle 50, medium speed
Motor_Right(0, 100); //Duty cycle 100, full speed

The above is the function to control the right motor, and the same is true for the left motor, but it is modified to IN1, IN2.

Through timer initialization, interrupt function, PWM motor speed control function. We can already control the motor's turn and rotation speed. If we want to achieve remote control car, it is to receive data from the remote control and make judgments. You can see the writing in the program, the program will be analyzed below.

	if(receiveTable[9]==0x31) //When character 1 is entered, go forward
		Motor_Left(1, number), Motor_Right(0, number);

	if(receiveTable[9]==0x32) //Backward when character 2 is entered
		Motor_Left(0, number), Motor_Right(1, number);

	if(receiveTable[9]==0x33) //Turn left when entering character 3
		Motor_Left(1, number), Motor_Right(0, 0);		

That's all for the motor-driven part here. To review what we need to know.

  • 1. The footer meaning of L298N motor driver chip, it is necessary to distinguish the control motors, control the motor turn, power supply and enable each part.
  • 2. Timer-related registers, TMON, TCON, and interrupt system diagrams.
  • 3. Steps of timer 0 initialization, setting mode, feeding initial value and turning on timer.
  • 4. Timer interrupt function, we can control the time of each overflow, what we need to consider each overflow.
  • 5. PWM output function, through the configuration of timer 0, we need to know how to set the duty cycle and adjust the speed.


There are two WiFi modules above, the first one is ESP8266 -01s, and the next one is Esp8266(NodeMCU). We are just using it for data transmission and the effect is the same.

Principle of ESP8266

ESP8266 mode:

AP Mode Server
STA Mode Client
AP + STA Pattern

Test ESP8266
Serial assistant can be used for AT instruction testing.

Communication Structure Diagram
51 and STM32 work the same way.

Configuration ideas

  • If single-chip computer acts as a server, ESP8266 is AP mode, open hot spot, has IP address and port number. When other TCP clients want to connect to the server, they need to connect hot spot first, then bind IP address and port number to connect.
  • If it's STA mode, you need to connect to the server's hotspot, bind the IP address to the port number, and connect

Connection Range

  • Because it uses WIFI local communication, but only works within the local network, to achieve wide area network communication, you can connect to the cloud server, you need to use WIFI or traffic configuration

ESP8266 Configured as Server (Instruction)

ESP8266 Configure as a server ( PC Or single chip sends instructions:
(1)  test AT Directives: AT

(2)  Change Module Baud Rate: 
AT+CIOBAUD=9600 (Set other baud rates after successful baud rate settings)

(3)  Reset the restart module: AT+RST

(4)  Set to AP Pattern: AT+CWMODE=2

(5)  Set up name password,Encryption method:

(6)  View Host Side ip Address:
AT+CIFSR(Here's the IP Address is the module itself IP,No ST Assigned when a router is added to a mode IP)

(7)  Set module transfer mode to TCP Pattern: AT+CIPMODE=0

(8)  Set to multi-connection mode, start module: AT+CIPMUX=1

(9)  Setup port for server:
AT+CIPSERVER=1,8090  (TCP client Connect server Keep port numbers consistent)

Instruction Test

Set up AP mode, account password, and then you can search for the WIFI module.

TCP client data transfer test.

The TCP client written by himself communicated successfully.

Through the serial assistant we can test the instructions, I tested them once above, set the AP mode, then set the account password, and then use the TCP client to connect for data transfer test.

The above is to test ESP8266 on the serial assistant, and we want to use ESP8266 on the single chip computer. Through the AT instruction test, we also found that on the serial assistant, we also send related instructions to the serial assistant, and then send them to the ESP8266 through the serial port.
Below, we also need to use the serial port of single-chip computer to send instructions to ESP8266 for configuration.

So here we describe the configuration and use of the 51 Serial Port.

Serial Port Initialization Function

//Serial Port Initialization Function
void UartInit(void)		//Serial Port Initialization Function
	TMOD &= 0x0F; //Clear configuration of timer 1
	TMOD |= 0x20;	//Timer works in 2,8-bit auto overload (0010 0000)
	TL1 = 0xfd;	 //Load Initial Value
	TH1 = 0xfd;	//Load Initial Value	
    IP = 0; //Interrupt priority is the same
	TR1 = 1;	//Start timer 1
	REN=1;    //Allow serial port to receive data
	SM0=0;    //Working mode 1,10-bit asynchronous transceiver
	EA = 1;   //Turn on global interrupt control
	ES=1;     //Open Serial Port Interrupt

Serial port send data (single byte)

//Serial Send Data Single Byte
void Sent_ZF(u8 dat)  //Send a Byte
	ES = 0; //Do not allow serial port to accept or send interrupts
	TI=0; //Loop waiting for end of send, when end of send, TI=1
	SBUF = dat; //Save dat data in SBUF as one byte
	while(!TI); //When the sending is complete, TI = 1, then!TI false, end cycle
    TI = 0; //TI Reset
    ES = 1; //Allow Serial Port to Accept and Send Interrupts

Serial port send data (string)

//Serial port send data, string
void AT_Send_String(u8 *string)  //Send String
  while(*string) //'\0'ends the loop when it reaches the end of the character
     Sent_ZF(*string++);//Call Send Single Byte Function

Serial interrupt function

//Serial interrupt function receives data
void uart() interrupt 4  
	if(RI == 1) //Indicates receipt of data
	    RI = 0; //Clear the serial receive flag bits, only if cleared, can receive data next time
	    receiveTable[i] = SBUF; //Store data in an array
	 	if(receiveTable[0] == '+') 
	 //Determines whether the data is invalid because the WiFi module automatically adds a string starting with "+PID."
		//Valid data is tenth
		//If the external data is sent 5 to 51 via ESP8266
		//Then 51 serial port receives "+PID...5" 5 is the tenth
		//So receiveTable[9] is our real data
		  i = 0;
		if(i == 10)
		  i = 0;

ESP8266 Initialization Function

//ESP8266 Initialization Function
void ESP8266_Init()   //esp8266 9600 baud rate
    // = 2 is AP mode, = 1 is client mode
  	//Create WiFi Hotspots
    AT_Send_String("AT+RST\r\n"); //Restart Module
	//Set to multi-connection mode, start module
	 //Setup Port for Server

ESP8266 Configuration Client

Configure server instructions ( STA Mode)
1,AT+CWMODE=1  To configure STA Pattern
2,AT+RST  Restart takes effect
3,AT+CWJAP="wifi Name","WiFi Password"    Connect WIFI
4,AT+CIPSTART="TCP","",8090   Connect to Server
5,AT+CIPSEND=4     Send instructions
6,AT+CIPMODE=1    Turn on transfer mode
7,AT+CIPSEND    Start Transmitting

Code Link
Links: Code Link
Extraction Code: 1314

Tags: Programming Embedded system Single-Chip Microcomputer stm32 wifi

Posted on Tue, 12 Oct 2021 12:19:51 -0400 by danesc