Smart Windshield Wiper Design Based on Arduino Microcontroller

1. Main Functions

This project uses Proteus8 to simulate the Arduino microcontroller, utilizing an LCD1602 display module, button module, raindrop sensor, ADC, LED module, etc.

Main Functions:

After the system is running, the LCD1602 displays the current mode, rainfall, gear, and status of the windshield wiper.

It defaults to manual mode, corresponding to the manual mode indicator light being on. The K3 button can control the wiper’s start and stop, and the K4 button can adjust the wiper’s speed gear. When the K2 button is pressed, it switches to automatic mode, at which point the automatic mode indicator light is on. If the detected raindrop value is within the threshold range, it matches the corresponding value to run at the speed gear. If it exceeds the maximum value, it runs at the highest speed; if it is below the minimum value, the wiper is turned off. The threshold range can be set using the K1 button, and K2 and K3 buttons can be used for adjustments. The entire process will display the corresponding speed gear, wiper status, rainfall value, and manual/automatic mode on the LCD1602.

Main Functions:

Button control: Automatic/manual switching, setting rainfall threshold, speed, etc.;

Display control: LCD1602 displays rainfall, gear, threshold, wiper status, etc.;

Driver circuit: Uses ULN2003 to control the stepper motor simulating wiper rotation;

Detection circuit: Uses a sensor to detect the current rainfall through ADC conversion;

Speed control: Controls the wiper’s rotation speed based on rainfall;

Automatic mode: Automatically controls based on rainfall;

Manual mode: Controls the wiper’s start/stop and speed through buttons.

2. Hardware Resources

1. Arduino microcontroller core module

2. LCD1602 display module

3. Raindrop sensor, ADC module

4. Button, LED module

5. Stepper motor driver module

3. Software Design

// Parameter initialization
void sys_parm_init(void){
	sys_ctrl.dir=0;
	sys_ctrl.gear=3;
	sys_ctrl.run=0;
	sys_ctrl.ad_valh=50;
	sys_ctrl.ad_vall=20;
	sys_ctrl.mode=0;
	sys_ctrl.setflag=0;
	sys_ctrl.zeroflag=1;
}

// System initial interface display
void sys_open_show(void){
	lcd1602_clear();
	lcd1602_show_string(0,0,"RN:   %");
	lcd1602_show_string(8,0,"SD");
	lcd1602_show_string(11,0," ");
	lcd1602_show_string(13,0,"OFF");
	lcd1602_show_string(0,1,"MAX:  %");
	lcd1602_show_string(9,1,"MIN:  %");
	// Initial manual mode
	SD_LED=0;
	ZD_LED=1;
}

// System parameter acquisition
void sys_parm_get(void){
	while(1)
	{
		// Read rainfall AD value
		sys_ctrl.ad_val=pcf8591_read_adcvalue(0);
		// Map the range 0-255 to 0-100
		sys_ctrl.ad_val=cal_map(sys_ctrl.ad_val,0,255,0,100);
		break;
	}
}

// System parameter setting
void sys_parm_set(void){
	u8 key=0;
	key=key_scan(0);
	// Threshold setting
	if(key==KEY1_PRESS)
	{
		sys_ctrl.setflag++;
		if(sys_ctrl.setflag>=3)sys_ctrl.setflag=0;
		sys_ctrl.run=0;
		if(sys_ctrl.run)lcd1602_show_string(13,0,"ON ");
		else lcd1602_show_string(13,0,"OFF");
	}
	// Upper limit setting
	if(sys_ctrl.setflag==1)
	{
		if(key==KEY2_PRESS)// Increase
		{
			sys_ctrl.ad_valh++;
			if(sys_ctrl.ad_valh>=100)sys_ctrl.ad_valh=0;
		}
		else if(key==KEY3_PRESS)// Decrease
		{
			sys_ctrl.ad_valh--;
			if(sys_ctrl.ad_valh<=0)sys_ctrl.ad_valh=99;
		}
		lcd1602_show_string(4,1,"  ");
	}
	// Lower limit setting
	if(sys_ctrl.setflag==2)
	{
		if(key==KEY2_PRESS)// Increase
		{
			sys_ctrl.ad_vall++;
			if(sys_ctrl.ad_vall>=100)sys_ctrl.ad_vall=0;
		}
		else if(key==KEY3_PRESS)// Decrease
		{
			sys_ctrl.ad_vall--;
			if(sys_ctrl.ad_vall<=0)sys_ctrl.ad_vall=99;
		}
		lcd1602_show_string(13,1,"  ");
	}
	// If no threshold is set
	if(sys_ctrl.setflag==0)
	{
		// Wiper on/off
		if(key==KEY3_PRESS)
		{
			sys_ctrl.run=!sys_ctrl.run;
			if(sys_ctrl.run)lcd1602_show_string(13,0,"ON ");
			else lcd1602_show_string(13,0,"OFF");
		}
		// Switch between automatic/manual mode
		else if(key==KEY2_PRESS)
		{
			sys_ctrl.mode=!sys_ctrl.mode;
			if(sys_ctrl.mode){SD_LED=1;ZD_LED=0;}
			else {SD_LED=0;ZD_LED=1;}
			sys_ctrl.run=0;
			if(sys_ctrl.run)lcd1602_show_string(13,0,"ON ");
			else lcd1602_show_string(13,0,"OFF");
		}
		// In manual mode, gear adjustment
		if(sys_ctrl.mode==0)
		{
			if(key==KEY4_PRESS)
			{
				sys_ctrl.gear++;
				if(sys_ctrl.gear>=6)sys_ctrl.gear=1;
			}
		}
	}
}

// System parameter display
void sys_parm_show(void){
	while(1)
	{
		// Display rainfall value
		lcd1602_show_nums(3,0,sys_ctrl.ad_val,3,0);
		// Display rainfall threshold
		lcd1602_show_nums(4,1,sys_ctrl.ad_valh,2,0);
		lcd1602_show_nums(13,1,sys_ctrl.ad_vall,2,0);
		// Display gear
		lcd1602_show_nums(11,0,sys_ctrl.gear,1,0);
		break;
	}
}

// System parameter control
void sys_parm_ctrl(void){
	static u16 i=0;
	u16 len=0;
	// Manual mode
	if(sys_ctrl.mode==0)
	{
		// Wiper starts running at initial gear
		if(sys_ctrl.run)
		{
			i++;
			if(i==1)
			{
				step_motor_28BYJ48_send_pulse(4,0,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
				sys_ctrl.zeroflag=0;
			}
			if(i==3)
			{
				i=0;
				step_motor_28BYJ48_send_pulse(4,1,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
				sys_ctrl.zeroflag=1;
			}
		}
		// Wiper off
		else
		{
			step_motor_28BYJ48_send_pulse(4,1,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
		}
	}
	// Automatic mode
	else
	{
		if(sys_ctrl.run)lcd1602_show_string(13,0,"ON ");
		else lcd1602_show_string(13,0,"OFF");
		// If collected rainfall is greater than upper limit, run wiper at highest gear
		if(sys_ctrl.ad_val>=sys_ctrl.ad_valh)
		{
			sys_ctrl.gear=5;// Highest gear
			sys_ctrl.run=1;
			i++;
			if(i==1)
				step_motor_28BYJ48_send_pulse(4,0,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
			if(i==3)
			{
				i=0;
				step_motor_28BYJ48_send_pulse(4,1,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
			}
		}
		// If collected rainfall is less than lower limit, stop wiper
		else if(sys_ctrl.ad_val<=sys_ctrl.ad_vall)
		{
			sys_ctrl.run=0;
			step_motor_28BYJ48_send_pulse(4,1,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
		}
		// Within threshold range, automatically adjust speed based on rainfall
		else
		{
			sys_ctrl.run=1;
			len=(sys_ctrl.ad_valh-sys_ctrl.ad_vall)/3;
			if(sys_ctrl.ad_val>sys_ctrl.ad_vall && sys_ctrl.ad_val<=sys_ctrl.ad_vall+len)
			{
				sys_ctrl.gear=1;
			}
			else if(sys_ctrl.ad_val>sys_ctrl.ad_vall+len && sys_ctrl.ad_val<=sys_ctrl.ad_vall+2*len)
			{
				sys_ctrl.gear=2;
			}
			else if(sys_ctrl.ad_val>sys_ctrl.ad_vall+2*len && sys_ctrl.ad_val<=sys_ctrl.ad_vall+3*len)
			{
				sys_ctrl.gear=3;
			}
			else if(sys_ctrl.ad_val>sys_ctrl.ad_vall+3*len && sys_ctrl.ad_val<=sys_ctrl.ad_vall+4*len)
			{
				sys_ctrl.gear=4;
			}
			i++;
			if(i==1)
				step_motor_28BYJ48_send_pulse(4,0,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
			if(i==3)
			{
				i=0;
				step_motor_28BYJ48_send_pulse(4,1,gspeed[sys_ctrl.gear-1],1,sys_ctrl.run);
			}
		}
	}
}

// Application control system
void appdemo_show(void){
	sys_parm_init();// System parameter initialization
	lcd1602_init();// LCD1602 initialization
	sys_open_show();// System initial interface display
	while(1)
	{
		sys_parm_set();
		sys_parm_get();
		sys_parm_show();
		sys_parm_ctrl();
	}
}
C
Smart Windshield Wiper Design Based on Arduino Microcontroller

Leave a Comment