Arduino windshield wiper

Does somebody know how to make windshield wiper with servo motor?
I want make project with servo motor when I press 1 button servo motor start looping 0-180-0 degress one speed and when press 2nd buton it does same but faster.

Nope

Welcome to the forum

The video is unavailable

Here is a windshield wiper simulation. You make the second button to increase the speed.

Files for wokwi

sketch.ino
// https://forum.arduino.cc/t/arduino-windshield-wiper/1128524/4

#include <Servo.h>

Servo servo1;
Servo servo2;
byte servo1pin = 5;
byte servo2pin = 6;
int servo1home;
int servo2home;
int servoCount = 0, dir = 1, speedControl = 10;

#define ENC_CK 7 // encoder
#define ENC_DT 8
#define ENC_SW 2 // button

void setup() {
  Serial.begin(115200);
  pinMode(ENC_CK, INPUT);
  pinMode(ENC_DT, INPUT);
  pinMode(ENC_SW, INPUT_PULLUP);

  servo1.attach(servo1pin); // start the servos
  servo2.attach(servo2pin);
  servo1.write(servo1home);
  servo2.write(servo2home);

  attachInterrupt(digitalPinToInterrupt(ENC_CK), readEncoder, FALLING);

  while (digitalRead(ENC_SW)); // wait for switch press
}

void loop() {
  if (servoCount > 180 || servoCount < 0)
    dir = -dir;
  servo1.write(servoCount);
  servo2.write(servoCount);
  servoCount += dir;
  delay(speedControl);
}

void readEncoder() {
  Serial.print(1);
  int dtValue = digitalRead(ENC_DT);
  if (dtValue == HIGH) {
    speedControl++;
  }
  if (dtValue == LOW) {
    speedControl--;
  }
  if (speedControl > 10)
    speedControl = 10;
  if (speedControl < 1)
    speedControl = 1;
}
diagram.json
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": -4.8, "left": -0.5, "attrs": {} },
    {
      "type": "wokwi-servo",
      "id": "servo1",
      "top": -221.8,
      "left": 59.4,
      "rotate": 270,
      "attrs": { "hornColor": "white" }
    },
    {
      "type": "wokwi-servo",
      "id": "servo2",
      "top": -221.8,
      "left": -46.2,
      "rotate": 270,
      "attrs": { "hornColor": "white" }
    },
    {
      "type": "wokwi-text",
      "id": "text2",
      "top": -76.8,
      "left": -86.4,
      "attrs": { "text": "(START)" }
    },
    { "type": "wokwi-vcc", "id": "vcc1", "top": -104.84, "left": 76.8, "attrs": {} },
    { "type": "wokwi-ky-040", "id": "encoder1", "top": -55.9, "left": -96.8, "attrs": {} },
    {
      "type": "wokwi-text",
      "id": "text1",
      "top": 9.6,
      "left": -96,
      "attrs": { "text": "CONTROL" }
    }
  ],
  "connections": [
    [ "nano:GND.2", "servo1:GND", "black", [ "v-9.6", "h9.6" ] ],
    [ "nano:GND.2", "servo2:GND", "black", [ "v-9.6", "h-96" ] ],
    [ "vcc1:VCC", "servo1:V+", "red", [ "v9.6", "h57.5" ] ],
    [ "nano:GND.2", "encoder1:GND", "black", [ "v-9.6", "h-115.2" ] ],
    [ "nano:5", "servo1:PWM", "green", [ "v-57.6", "h67" ] ],
    [ "nano:6", "servo2:PWM", "green", [ "v-57.6", "h-29" ] ],
    [ "vcc1:VCC", "servo2:V+", "red", [ "v9.6", "h-48" ] ],
    [ "nano:7", "encoder1:CLK", "green", [ "v0" ] ],
    [ "nano:8", "encoder1:DT", "green", [ "v0" ] ],
    [ "nano:2", "encoder1:SW", "green", [ "v0" ] ],
    [ "nano:5V", "encoder1:VCC", "red", [ "v0" ] ]
  ],
  "dependencies": {}
}

tank you sir, this helped me a lot

Haha, also she should figure out how to stop the wipers.

Must be a teeny little car.

a7

It's in Portland.

@ivek12312 - hint: "servoHome()" and exit the loop.

1 Like

im still strugling with this code, looks like this is a little to hard for amateur so if u will be kind could u send finished code for this i would be realy thankfoul

Ask any questions. Copy the sim program (wokwi >> save as copy >> newfilename) and put your comments in the copy. You can make any changes you want.

Here is a "pseudo code" describing the major parts without the complete text.

#include - this is where you identify hardware and hardware drivers

void setup() { - this is where you configure the hardware
  servoHome(); - calls a local function to send the servos "home" (zero degrees)
  welcome(); - calls a local function to introduce the project

void loop() { - this is where you put code that repeats (without needing to write a loop function
  readButton(); - calls a local function to read the button

void readButton() - this is the local function that reads the button, turns "wipers" from off to on.
moveWiper(); - this is the local function that is called from readButton() to make the wipers move

  if (wiperOn) - in the beginning, wiperOn was 0 (off), but readButton made it 1 (on)
    moveWiper(); - if wiperOn is 1, then move the wipers

void moveWiper() { - this is the local function to move the wiper
  servoRED.write(180 - servoPosition); - this is a way to make RED do exactly the opposite of GREEN
  servoGRN.write(servoPosition); - GREEN will move to a position set by the servoPosition variable

  delay(servoInterval); - this lets the servos physically move to position before making it move again

void servoHome() {

void welcome() {

I take this is simulated windscreen wiper ?

Car wipers run a DC motor and a gear box linkage to give the sweep . There is micro switch that keeps the motor running until it’s in the park position. If the control switch is still on it does another sweep.
Newish cars have some very clever features about which I know nothing .

I did some job, could u check comments on the end of program for help?

Very good windscreen wiper simulation! (@hammy)

Two lines to correct:

  // myservo.attach; // need the servo pin which can be 9 or servoPin
  myservo.attach(servoPin);

  // button1 = digitalRead(buttonPin);  // you are using button1, so need 2 or button1Pin
  button1 = digitalRead(button1Pin); 

And to color the buttons, click your diagram.json tab and edit your first button color...

    {
      "type": "wokwi-pushbutton",
      "id": "btn2",
      "top": -138.48,
      "left": -22.35,
      "attrs": { "color": "green" }
    },

to this

    {
      "type": "wokwi-pushbutton",
      "id": "btn2",
      "top": -138.48,
      "left": -22.35,
      "attrs": { "color": "red" }
    },
``

This line has the error, which is a space between loop and 2...

void loop 2 () {

BUT... do not use a loop2()... just use the first loop() to read both buttons, like this...

void loop () {
    readbutton1();
    readbutton2();
}

To make the servo stop, you need to set a flag that tells the sketch to not write to the servo pin... something like this...

This part of the sketch sets wiperOn flag to tell the sketch to not print the word ON to the serial monitor by first checking the wiperOn flag

    if (!wiperOn) { // if the wiperOn flag is clear... if wiperOn == 0;...
      Serial.print("ON "); // print the word ON
      wiperOn = 1; // and set the wiperOn flag so ON will not get printed again making -- if (!wiperON) -- will fail
    }

Here is your sketch, with "ON" and "OFF" - you must hold the OFF button down to make it work (read on for why).

#include <Servo.h> //servo libary
Servo myservo;//object servo motor
const int servoPin = 9; //servo motor conected on pin 9
int servoPosition;
bool wiperOn = 0;
long servoInterval = 300; // 1st speed of wiper
long servoInterval2 = 500; // 2nd speed of wiper (faster)

const int button1Pin = 2; // the button 1 is connected to pin 2
bool button1 = 0;

const int button2Pin = 3; // button 2 is connected to pin 3
bool button2 = 0;

void setup() {
  Serial.begin(115200);  // not shure about this numbers (copied)
  pinMode(button1Pin, INPUT);

  myservo.attach(servoPin);
  servoHome();
  welcome();
  Serial.print("OFF ");
}

void loop () {
  readbutton1();
  readbutton2();
}

void readbutton1() {
  button1 = digitalRead(button1Pin);
  if (button1) {
    delay(50);
    if (!wiperOn) {
      Serial.print("ON ");
      wiperOn = 1;
    }
    moveWiper();
  }
  if (wiperOn)
    moveWiper();
}

void readbutton2() {
  button2 = digitalRead(button2Pin);
  if (button2) {
    delay(50);
    if (wiperOn) {
    Serial.print("OFF ");
    wiperOn = 0;
    }
  }
}

void moveWiper() {
  // this is a blocking routine... no buttons will be read while the servo is moving
  myservo.write(180 - servoPosition);
  servoPosition = 180 - servoPosition;
  delay(servoInterval);
}

void servoHome() {
  myservo.write(servoPosition);
}

void welcome() {
  Serial.println("Press the RED button to start.");
  Serial.println("Press the GREEN button to start.");
}

The original sketch (turn a servo on with a button) has transformed. In addition to "moving a servo" it now needs to read two buttons. The buttons are blocked from being read by the servo movement. At this point, the command delay(x); should not be used, and should be replaced with a time keeper that lets the servo move while also reading the buttons. Here is an event-based sketch that simply prints some numbers, but at different frequencies. Think of placing the sketch inside the button-reading routines.

So for now how i see when i press red button it starts servo and green button stops it.
Now i would like to add a option to press eather green button to start servo and its work faster
(or should i make 3rd button to do it). Now im kinda confused with eventTiming cuz im not so good at coding

This routine travels at the maximum speed from 0 to 180 or 180 to 0.

void moveWiper() {
  // this is a blocking routine... no buttons will be read while the servo is moving
  myservo.write(180 - servoPosition);
  servoPosition = 180 - servoPosition;
  delay(servoInterval);
}

To make the servo "step" through each degree in its full range (0 to 180 to 0), you would either make a loop:

// this is also "blocking" code - when the servo is moving, nothing else happens
for (int i = 0; i < 180; i++)
  myservo.write(i);
for (int i = 180; i > 0; i--)
  myservo.write(i);

or

Event timing.

A third button will only need the hardware, the function, and add the call to readButton3(); in loop()

After understanding how to add buttons, and how to use event timing (really, event timing is very important for every program that reads any device reliably), you could then try a much more difficult method of one-button control.

  • press button to start.
  • press button to increase speed
  • double-press button to decrease speed
  • long-press button to stop

Event timing with your servo will move the servo (forward or backward) at some known time (for example, every 200ms, like the wokwi example). It is okay if you do not understand the coding of event timing right now... but understanding what it does is simple... you wake up every day (event1) to an alarm because you set an alarm time, and when the alarm knows that it is time to wake up, it sounds. You eat lunch every day at mid-day (event2), and when your stomach says "it is lunch time" (exactly at mid-day) and you respond by doing something (eating). You go to sleep every night (event3) because you are tired exactly at midnight. Meanwhile, time is always counting. Your clock, stomach and eyes are programmed to do something at exact times. You are a living example of event timing. Now, translate that to code: Start a timer, compare the timer to an event, if it is an event time, do something... repeat. The rest is practice, trying, making mistakes, and then fixing them.

thanks for explaining, in meantime i did something so now when i start program it start working in green mode (slow one) when i press red button it shwitches to fast mode. But now i have 2 problems one is that when im in fast mode red button it does only half of movement (is that by defoult) and second one is that i have to press few time to porgram register that second button is pressed

  myservo.write(90 - servoPosition);
  servoPosition = 90 - servoPosition;

The full range is 0 to 180 degrees.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.