[Comprehensive Practice of electronic system] - intelligent car for question F of 2021 electric competition


primary coverage
   design and manufacture intelligent drug delivery trolley to simulate the delivery and collection of drugs in hospital pharmacy and sick room. The structure of the hospital area is shown in Figure 1. The walls on both sides of the hospital corridor are represented by black solid lines. The corridor floor is painted with a solid red line in the middle, and the black digital movable paper identifying the ward number is placed. Pharmacy and proximal ward numbers (No. 1 and No. 2) are as shown in Figure 1. The positions are fixed, and the central ward and distal ward numbers (No. 3-8) are set randomly during the test.

1. Task requirements

  • (1) A single trolley transports drugs to the designated proximal ward and returns to the pharmacy. If the delivery and return time are required to be less than 40s, 1 point (40 points) will be deducted for every 1 second overtime
  • (2) A single trolley transports drugs to the designated central ward and returns to the pharmacy. If the delivery and return time are required to be less than 40s, 1 point (10 points) will be deducted for every 1 second overtime
  • (3) A single trolley transports drugs to the designated remote ward and returns to the pharmacy. If the delivery and return time are required to be less than 40s, 1 point (10 points) will be deducted for every 1 second overtime
  • (4) Complete the defense link (20 points)
  • (5) Complete the writing of curriculum design report as required (20 points).

2. Scheme

2.1 hardware design


   as shown in the above figure, (1) regulated power supply module: it is used to convert the 7.4~8.4V input voltage of the double lithium battery 18650 into the 5V working voltage available for the other four modules. During commissioning, it is found that the output power of the first LM7805 regulated circuit is insufficient to supply power to the whole trolley, Therefore, a DC-DC voltage stabilizing module built by the voltage stabilizing chip LM2596 is added to supply power to the 51 minimum system module and the detection red line gray sensor module, while the first LM7805 voltage stabilizing circuit only supplies power to the motor PWM drive module. (2) Keys and nixie tube module: there are two keys (key_s2 and key_s3) and a common cathode nixie tube. The nixie tube displays the ward number to be delivered. The two keys are used for ward number + 1 and determining whether to deliver to the ward with this number. (3) Gray sensor module for detecting red line: the sensor is a 5-channel photosensitive gray sensor, in which the light is on to detect the ground (white), the corresponding pin output is 1, and the light is off to detect the red line or black line, and the corresponding pin output is 0. (4) Motor PWM drive module: L293D drive chip is used to drive the rotation of DC reduction motor. (5) 51 minimum system module: it is used to detect the level change of the five pins of the gray sensor and control the DC reduction motor through the level change of the five pins of the gray sensor.

2.2 software design


   as shown in the above figure, in the program design, (1) tracking program design: modularize each trolley motion model through modularization idea, which is divided into straight-line function, left turn function, right turn function, straight-line retreat function, rotation function and stop function. The specific signs contained in the route of each ward can be mapped to the pin level of a specific five-way gray sensor, and then we can control the motion state of the motor by detecting the change of the specific level state of the five-way sensor in real time through the program, so as to realize the tracking of the car to the specific ward. In short, it is to control the car tracking through the specific signs of the specific ward line. (2) Trolley speed program design idea: the trolley speed is to control the motor duty cycle through the timer of single chip microcomputer, so as to control the trolley speed. (3) Confirm ward programming: key_s2 each time you press, the MCU will detect the low level and define the variable room_ Num will + 1 (Room_num will cycle 0 ~ 9 + 1), and the nixie tube will display room in real time_ Num, and press key_s3 is the OK key, only when the key_ After S3 is pressed, the MCU will continue to execute the tracking ward program. In short, it is the key_s2 let the number of wards + 1, press key_s3 to determine whether to follow the ward, the nixie tube displays the ward number in real time. The above is the idea of designing the tracking of each ward.

3. Physical map

4. Source program

The background color is set according to the hexadecimal color value: #7FFFD4
#ifndef __CAR_H__
#define _CAR_H__

/*Motor drive IO definition*/
sbit IN1 = P1^2; //Left motor reverse rotation for 1
sbit IN2 = P1^3; //Left motor forward rotation
sbit IN3 = P1^6; //1 right motor forward rotation
sbit IN4 = P1^7; //1 right motor reverse
sbit EN1 = P1^4; //Enable left motor for 1
sbit EN2 = P1^5; //Enable the right motor for 1

/*Tracking trolley IO port definition*/
sbit R_led2 = P3^6;// The right tracking lamp 2 is 0 and the red line is not recognized, while the red line is 1
sbit R_led1 = P3^5;//The red line is not recognized when the right tracking lamp 1 is 0, and the red line is recognized when it is 1
sbit M_led0 = P3^4;//The middle tracking lamp 0 is 0, no red line is recognized, and the red line is 1
sbit L_led1 = P3^3;//Left tracking lamp 1 is 0, no red line is recognized, and 1 is red line recognized
sbit L_led2 = P3^2;//Left tracking light 2 is 0, no red line is recognized, and 1 is red line recognized


/*Key definition*/
sbit key_s2 = P3^0;//+1
sbit key_s3 = P3^1;//OK key
sbit beep = P2^3;//Buzzer
sbit LE1 = P2^7;//Nixie tube position selection
sbit LE2 = P2^6;//Nixie tube segment selection

#define left_motor_en 		 EN1 = 1 	// Left motor enable
#define right_motor_en 		 EN2 = 1 	// Right motor enable
#define left_motor_dis 		 EN1 = 0 	// Left motor not enabled
#define right_motor_dis 		 EN2 = 0 	// Right motor not enabled



#define left_motor_stops 	 IN1 = 0, IN2 = 0 / / left motor stop
#define right_motor_stops 	 IN3 = 0, IN4 = 0 / / right motor stop
#define left_motor_go 		 IN1 = 0, IN2 = 1 / / left motor forward transmission
#define left_motor_back 		 IN1 = 1, IN2 = 0 / / left motor reverse
#define right_motor_go 		 IN3 = 1, IN4 = 0 / / right motor forward transmission
#define right_motor_back 	 IN3 = 0, IN4 = 1 / / right motor reverse

typedef unsigned char  uchar;
typedef unsigned int  uint;

#endif
motor.c Documents
#include<reg52.h>
#include<car.h>	 

/*Millisecond delay*/
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}	


/*Trolley forward*/
void forward()
{
	left_motor_go; //Left motor forward
	right_motor_go; //Right motor forward
}

/*Trolley left turn*/
void left_run()
{
	left_motor_stops; //Left motor stop
	right_motor_go; //Right motor forward	
}
/*Trolley turn right*/
void right_run()
{
	right_motor_stops;//Right motor stop
	left_motor_go;    //Left motor forward
}

/*Trolley back*/
void backward()
{
	left_motor_back; //Left motor backward
	right_motor_back; //Right motor reverse	
}

/*Trolley stop*/
void stop()
{
	right_motor_stops;
	left_motor_stops;
}

/*to turn to*/
void turn_roud()
{
	left_motor_go;
	right_motor_back;
}

/*Go straight*/
void go_straight()
{

  if(L_led1==0  && M_led0 ==1 &&  R_led1==0 )//Identify red line straight ahead
	{  
	   forward();
	  
	  
	
	}
	  else
		{
			
			
			if(L_led1 == 1 &&  R_led1 == 0)//Trolley right outgoing line, left turn correction 1 is red, 0 is white
			{
				left_run();//Turn left
			}
			
			if(L_led1 == 0 &&  R_led1 == 1)//Trolley left outgoing line, right turn correction
			{
				right_run();//Turn right
			}	
			
			if(L_led2 == 1 && L_led1 == 0 &&  R_led2 ==0) //Trolley right outgoing line, left turn correction
			{
				left_run();//Turn left
			}
			if(L_led1 == 0 &&  R_led1 == 0 &&  R_led2==1)//Trolley left outgoing line, right turn correction
			{
				right_run();//Turn right
			
			}	
		
		}	

}

void chesi()
{
	stop();
	while(1);
}
main.c Documents
/* explain:
 (Light on white 0) (light off red 1)
 */
#include<reg52.h>
#include<car.h>	 

extern void delay(uint z);
extern void forward();
extern void left_run();
extern void right_run();
extern void backward();
extern void stop();
extern void turn_roud();
extern void go_straight();
extern void chesi();
void key_exa();
void congif_T0();
uchar PWM_T = 0; //cycle
uchar PWM_left_val = 110;//Value range of duty ratio of left motor 95
uchar PWM_right_val = 110;//Duty ratio range of right motor 95

//Common cathode nixie tube (off, 1 ~ 9) meter
uchar code leddata[]={0x00, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uchar T1_H = 0xB8;
uchar T1_L = 0x00;
uchar Room_num = 0;
uchar EN_room = 0;

uchar flag_go = 0;
uchar flag_back = 0;



void congif_T0()
{
	EA = 1;
	TMOD = 0x02;
	TH0 = 183;
	TL0 = 183; //Motor T = T1*256 = 20ms;
	TR0 = 1; 
	ET0 = 1;
	P0 = leddata[Room_num];
		
}


void key_exa()
{
	while(1)
	{
	   if(key_s2 == 0)
		{
			delay(20);
			if(key_s2 == 0)
			{
				Room_num++;
				if(Room_num > 9)
				{
					Room_num = 1;
				}
				 while(key_s2 == 0);
			}
		}
	   if(key_s3 == 0)
		{
			delay(20);
			if(key_s3 == 0)
			{
				EN_room++;	
				while(key_s3 == 0);
				break;
			}
		}
	}
}


void main()
{										 
	LE1 = 1;
	P0 = 0xfe;
	LE1 = 0;
	LE2 = 1;
	
	congif_T0();
	
	key_exa();
	
	while(1)
	{	 
		

		if( Room_num == 1 && EN_room == 1)
		{			
//			PWM_left_val = 108;
//			PWM_right_val = 108;
			go_straight();																		  
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				backward();
				delay(50);
				left_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					left_run();
				}
				while(1)
				{
					
					go_straight();
					if((L_led1 == 1 && M_led0 == 0 && R_led1 == 1)||(L_led1 == 1 && M_led0 == 0 && R_led1 == 1 && R_led2 == 1))
					{
						
						stop();
						delay(1000);
						backward();
						delay(200);
						while((uchar)R_led2 != 1)
						{
							turn_roud();
						}
						
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)R_led2 >= 2)
							{
								backward();
								delay(50);
//								chesi();
								right_run();
								delay(300);
								while((uchar)L_led1 != 1)
								{
									right_run();
								}
								while(1)
								{
									go_straight();

									if((uchar)L_led1 + (uchar)R_led1 >= 2 )
									{
										stop();
										delay(1000);	
										while(1);
									}	
								}
							}
						}
					}
				}	
			}
		}
		
		//Room 2
		if( Room_num == 2 && EN_room == 1)
		{			
//			PWM_left_val = 105;
//			PWM_right_val = 105;
			go_straight();																		  
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				backward();
				delay(50);
				right_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					right_run();
				}
				while(1)
				{
					
					go_straight();
					if((L_led1 == 1 && M_led0 == 0 && R_led1 == 1)||(L_led1 == 1 && M_led0 == 0 && R_led1 == 1 && R_led2 == 1))
					{
						
						stop();
						delay(1000);
						backward();
						delay(200);
						while((uchar)R_led2 != 1)
						{
							turn_roud();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)R_led2 >= 2)
							{
								backward();
								delay(50);
//								chesi();
								left_run();
								delay(300);
								while((uchar)L_led1 != 1)
								{
									left_run();
								}
								while(1)
								{
									go_straight();

									if((uchar)L_led1 + (uchar)R_led1 >= 2 )
									{
										stop();
										delay(1000);	
										while(1);
									}	
								}
							}
						}
					}
				}	
			}
		}
		
		
			
		//Room 3
		if( Room_num == 3 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 2)
			{
				backward();
				delay(50);
				left_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					left_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						
						stop();
						delay(1000);
						backward();
						delay(200);
						while((uchar)R_led2 != 1)
						{
							turn_roud();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)R_led2 >= 2)
							{
								backward();
								delay(40);
								right_run();
								delay(300);
								while((uchar)L_led1 != 1)
								{
									right_run();
								}
								while(1)
								{
									go_straight();

									if((uchar)L_led1 + (uchar)R_led1 >= 2 )
									{
										
										flag_back++;
										stop();
										delay(500);	
										
									}
									if(flag_back==2)
									{
										stop();
										while(1);
										
									}
									
								}
							}
						}
					}
				}	
			}
		}
		
		//Room 4
		if( Room_num == 4 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 2)
			{
				backward();
				delay(50);
				right_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					right_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						
						stop();
						delay(1000);
						backward();
						delay(200);
						while((uchar)R_led2 != 1)
						{
							turn_roud();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)R_led2 >= 2)
							{
								backward();
								delay(50);
								left_run();
								delay(300);
								while((uchar)L_led1 != 1)
								{
									left_run();
								}
								while(1)
								{
									go_straight();

									if((uchar)L_led1 + (uchar)R_led1 >= 2 )
									{
										
										flag_back++;
										stop();
										delay(500);	
										
									}
									if(flag_back==2)
									{
										stop();
										while(1);
										
									}
									
								}
							}
						}
					}
				}	
			}
		}
		
		
		
		//Room 5
		if( Room_num == 5 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 3)
			{
				backward();
				delay(50);
				left_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					left_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						backward();
						delay(40);
						stop();
						delay(500);
						while((uchar)R_led1 != 1)
						{
							left_run();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
							{
								stop();
								delay(500);
								backward();
								delay(200);
								while((uchar)R_led2 != 1)
								{
									turn_roud();
								}
								while(1)
								{
									go_straight();

									if( (uchar)R_led1 + (uchar)R_led2 >= 2 )
									{
										backward();
										delay(50);
										right_run();
										delay(300);
										while((uchar)L_led1 != 1)
										{
											right_run();
										}
										while(1)
										{
											go_straight();
											if( (uchar)R_led1 + (uchar)R_led2 >= 2 )
											{
												backward();
												delay(50);
												right_run();
												delay(300);
												while((uchar)L_led1 != 1)
												{
													right_run();
												}
												while(1)
												{
													go_straight();
													if((uchar)L_led1 + (uchar)R_led1 >= 2)
													{
														flag_back++;
														stop();
														delay(500);
														
													}	
													if(flag_back == 3)
													{
														stop();
														while(1);
													}
												}
											}
										}
									}
									
									
								}
							}
						}
					}
				}	
			}
		}
		
		
		//Room 6
		if( Room_num == 6 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 3)
			{
				backward();
				delay(50);
				right_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					right_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						backward();
						delay(40);
						stop();
						delay(500);
						while((uchar)R_led1 != 1)
						{
							right_run();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
							{
								stop();
								delay(500);
								backward();
								delay(200);
								while((uchar)R_led2 != 1)
								{
									turn_roud();
								}
								while(1)
								{
									go_straight();

									if( (uchar)L_led1 + (uchar)L_led2 >= 2 )
									{
										backward();
										delay(40);
										left_run();
										delay(300);
										while((uchar)L_led1 != 1)
										{
											left_run();
										}
										while(1)
										{
											go_straight();
											if( (uchar)L_led1 + (uchar)L_led2 >= 2 )
											{
												backward();
												delay(50);
												left_run();
												delay(300);
												while((uchar)L_led1 != 1)
												{
													left_run();
												}
												while(1)
												{
													go_straight();
													if((uchar)L_led1 + (uchar)R_led1 >= 2)
													{
														flag_back++;
														stop();
														delay(500);
														
													}	
													if(flag_back == 3)
													{
														stop();
														while(1);
													}
												}
											}
										}
									}
									
									
								}
							}
						}
					}
				}	
			}
		}
		
		
		//Room 7
		if( Room_num == 7 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 3)
			{
				backward();
				delay(50);
				left_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					left_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						backward();
						delay(40);
						stop();
						delay(500);
						while((uchar)R_led1 != 1)
						{
							right_run();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
							{
								stop();
								delay(500);
								backward();
								delay(200);
								while((uchar)R_led2 != 1)
								{
									turn_roud();
								}
								while(1)
								{
									go_straight();

									if( (uchar)L_led1 + (uchar)L_led2 >= 2 )
									{
										backward();
										delay(50);
										left_run();
										delay(300);
										while((uchar)L_led1 != 1)
										{
											left_run();
										}
										while(1)
										{
											go_straight();
											if( (uchar)R_led1 + (uchar)R_led2 >= 2 )
											{
												backward();
												delay(50);
												right_run();
												delay(300);
												while((uchar)L_led1 != 1)
												{
													right_run();
												}
												while(1)
												{
													go_straight();
													if((uchar)L_led1 + (uchar)R_led1 >= 2)
													{
														flag_back++;
														stop();
														delay(500);
														
													}	
													if(flag_back == 3)
													{
														stop();
														while(1);
													}
												}
											}
										}
									}
									
									
								}
							}
						}
					}
				}	
			}
		}
		
		
		
		//Room 8
		if( Room_num == 8 && EN_room == 1)
		{			
			
			go_straight();
			if((uchar)L_led2 + (uchar)R_led2 >= 2)
			{
				flag_go++;
				backward();
				delay(50);
				stop();
				delay(500);
				
			}	
			if(flag_go == 3)
			{
				backward();
				delay(50);
				right_run();
				delay(300);
				while((uchar)L_led1 != 1)
				{
					right_run();
				}
				while(1)
				{
					
					go_straight();
					if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
					{
						backward();
						delay(40);
						stop();
						delay(500);
						while((uchar)R_led1 != 1)
						{
							left_run();
						}
						while(1)
						{
							go_straight();																		  
							if((uchar)L_led2 + (uchar)L_led1+ (uchar)R_led1 + (uchar)R_led2 >= 2)
							{
								stop();
								delay(500);
								backward();
								delay(200);
								while((uchar)R_led2 != 1)
								{
									turn_roud();
								}
								while(1)
								{
									go_straight();

									if( (uchar)R_led1 + (uchar)R_led2 >= 2 )
									{
										backward();
										delay(40);
										right_run();
										delay(300);
										while((uchar)L_led1 != 1)
										{
											right_run();
										}
										while(1)
										{
											go_straight();
											if( (uchar)L_led1 + (uchar)L_led2 >= 2 )
											{
												backward();
												delay(50);
												left_run();
												delay(300);
												while((uchar)L_led1 != 1)
												{
													left_run();
												}
												while(1)
												{
													go_straight();
													if((uchar)L_led1 + (uchar)R_led1 >= 2)
													{
														flag_back++;
														stop();
														delay(500);
														
													}	
													if(flag_back == 3)
													{
														stop();
														while(1);
													}
												}
											}
										}
									}
									
									
								}
							}
						}
					}
				}	
			}
		}
		
		
		
		
	}
}

void intter0() interrupt 1
{
	PWM_T++;
	if(PWM_T <= PWM_left_val)
	{
		left_motor_en;	
	}else{left_motor_dis;}

	if(PWM_T <= PWM_right_val)
	{
		right_motor_en;	
	}else{ right_motor_dis;}
	P0 = leddata[Room_num];
		
}


5. Harvest

    in this comprehensive electronic practice, I was busy for almost half a month, and it took about five or six days. Because I wanted to brush up the grade point, the car was not designed by myself, and I was not ready to use 32 (mainly 32 was not very skilled). I hurried to use Qingxiang's 51 car. I didn't think there was much harvest, so I thought it was fun to make this car.
   there are not many difficulties encountered, that is, the power supply of the car bottom plate is insufficient. At the beginning, I always thought there was something wrong with my code logic, resulting in adjusting the code for about two days. Finally, I found the problem through the guidance of my classmates, and then solved the problem by adding a power supply voltage stabilizing module.
  finally, hang up a famous saying I like, "don't be ashamed of the last. Even if it is slow, it will lag behind and fail, but it will reach the place it yearns for." --- brother Xun

Keywords: Single-Chip Microcomputer

Added by Webspeeder on Wed, 12 Jan 2022 13:54:03 +0200