Arduino Projects Breadboard Projects Circuits Electronics Projects Learn Electronics Multimeters Robotics Projects
Dustin Hodges  

How to Make an OwlBot: The Bird Intimidator – Part 5: Mechanical Movement

This post may contain affiliate links which means we may receive a commission for purchases made through links. Learn more on our Privacy Policy and Terms and Conditions pages.

Reading Time: 31 minutes
Project Name:OwlBot
Project Description:Part 5 build of the OwlBot, where we provide mechanical movement to our OwlBot prototype.
Project Difficulty:Easy
Project Note:For this fifth part of the project, we’ll focus on the OwlBot’s mechanical movements. We’ll update the code for when motion is detected by the PIR sensor we added in Part 1, to start moving a couple of solenoids and a DC motor, as well as flash the red LEDs we added in Part 3, and play owl sounds from the MP3 player we added in Part 2 of the build.

Introduction

In this part of the project we’re going to be performing the fifth step of what will eventually be the OwlBot. The OwlBot will be a device that can be used as a bird intimidation tool to scare away pesky birds in the yard, around the house or barn, at restaurants, or in trees, bushes, and gardens. Hence, the phrase, “The Bird Intimidator”.

The OwlBot (a.k.a. “The Bird Intimidator”) we’ll be making will be done in several parts. The OwlBot is an ambitious project. When complete, the OwlBot will sense motion. When motion is detected, the OwlBot should make owl sounds, perform varying movements, and flash its red eyes to intimidate and scare away pests. To put together all these tasks in one page would be too long and cumbersome, so we’ve decided to split each process we want the OwlBot to do into easy to accomplish chunks or parts as we continue on our goal to complete the OwlBot.

This is Part 5

This is part five. This fifth part of the OwlBot project will involve setting up its ability to perform mechanical movements. We will be using a pair of solenoids to move wings we’ll design and make later in the build process, and a DC motor that will have a propeller attached to its shaft, which we’ll use as an extra form of movement on our rigid plastic owl that we’re using for the body of the OwlBot.

Goal of Part 5 of the OwlBot Project

Our goal at the end of this part of the project will be to have the Arduino Uno control the solenoids to activate on and off continuously, and to have the motor spin the propeller when motion is detected by the PIR sensor we added in Part 1 of the build. So, if everything works out, by the end of this part of the build, our OwlBot prototype should sense motion, which will communicate to the Arduino to perform the following actions:

  • Play the MP3 file with owl sounds on it to the dual speakers we added to our prototype in Part 2 of the build.
  • Flash both red LEDs that we’re using as the OwlBot’s flashing red eyes that we added to our prototype in Part 3 of the build.
  • Activate the two solenoids and have the DC motor spin its propeller that we are adding to our prototype in this part of the build.

Solenoids

The type of solenoid that I’ll be using for this project is a 6V push-pull (linear) solenoid that, according to its technical specifications, has an electromagnetic push-pull force of 50g (1.76 ounces = 0.11 pounds). We’ll need two of them to control both faux wings of the OwlBot we’ll design later on in the project.

Mini DC 3V – 12V Push-Pull Solenoid

Solenoid Test

As previously stated, the technical specs of the solenoids I’m using have a push-pull force of 50g — which is equivalent to 1.76 ounces, or 0.11 lbs. This doesn’t sound like much force! Although, I did perform some very rough preliminary tests on how much force these particular solenoids of mine can pull, and I was pleased with their performance, based on what I’m using them for. I’ve provided a short video showing those tests below:

In the solenoid test video, I was able to get the solenoid to lift — without any assistance — a 9V battery with its snap connector, which is a combined weight of approximately 1.2 ounces, according to my measurements. I think that with what I have in mind on how we’ll make the wings and from what material we’ll be using, that this will work, but we’ll see what happens when we get to that part of the build at a later part in the OwlBot series.

DC Motor w/ Propeller

To add a little more motion than jumpy wings that the solenoids will probably provide, we’re going to add a small DC motor and propeller to the OwlBot. This may seem silly and even sound odd to put a propeller on our owl figure later in the build, but we’re pretty limited on how we can provide movement to our OwlBot. Having a motor with spinning propeller will help add motion to frighten critters away. Remember, that is the purpose of the OwlBot.

The DC motor I’m using is one that I had managed to scrap off some other device in the past, of which I do not remember what from, but any small DC motor with a shaft will do. Just make sure that you get a motor with a shaft long enough to hold a propeller. You can purchase hobby motor kits that come with several motors, propellers, and even motor mounts for pretty cheap. I’ve provided a link to one I’ve purchased in the past in the parts list below.

6V – 12V DC Motor

Let’s Be Methodical

I like to be very methodical about things, so we’ll go step-by-step — in detail — on the entire build of this project: the parts we’ll need, why we’re using them, how to connect them, how they work, and more! First, we’ll start with the following parts list:

Parts List

(This parts list is a continuation of the previous parts lists of the OwlBot project.)

ItemQuantityDescription
DC 6V Push Pull Solenoid2These solenoids will operate to act upon the OwlBot’s wings we’ll design and make later in the project.
DC Motor w/ Propeller1 eachWe’ll use the motor with propeller to add some extra eye-catching movement to help scare away pesky pests around the house.
Test Hook Clips to Breadboard Male Jumper WiresVariety of ColorsWe’ll use these types of jumper wires to easily make connections from the wires of the solenoids and motor, to the breadboard/Arduino.
Jumper WiresVarious Colors and SizesWe use these to make solderless connections to our
components on the breadboard.
RFP30N06 Logic Level N-Channel MOSFET2Used to control the solenoids using the Arduino Uno.
IRF840 Power MOSFET1Used to control the DC motor using the Arduino Uno.
10kΩ Resistor3Used as a pull-down resistor for the gate of each MOSFET being used in the circuit.
1N4001 Diode2Used as a flyback diode across each solenoid being used in the circuit.
0.1µF Capacitor1Used as a shunt capacitor across the DC motor in the circuit.

Tools Used in Project

ItemDescription
The Ultimate DIY 3220-Point Breadboard (Optional)If you haven’t built your own, go to our page here to do so! Otherwise, you can use another type of 3220-point breadboard or 830-point breadboard.
Digital MultimeterWe use a multimeter to take measurements of components and other devices used in this project.

Prototyping the Circuit

Previously, for Part 3 of the OwlBot prototype we successfully made all the connections needed for the red LEDs we added to our circuit, and then created the code to have those LEDs flash when motion was detected by the PIR sensor. Now we need to add to this prototype a pair of solenoids and a DC motor that will provide mechanical movement for the OwlBot. We also need to update the code and add to it the functionality we need to get the solenoids to activate and motor to spin when motion is detected by the PIR sensor.

In Part 4 of the build, we upgraded — we actually modified — the power supply for our OwlBot prototype circuitry. To power the new power hungry devices we’re adding in this part of the build, we added another 9V battery supply made up of six AA batteries to our prototype. We’ll use this upgrade to power both the solenoids and the DC motor. Our original 9V battery supply we’re still using to power the Arduino and the devices we’ve connected to it, thus far in the build.

As mentioned in the previous parts of this build, I will be using The Ultimate DIY 3220-Point Breadboard that was made from a separate project. I may refer to The Ultimate DIY 3220-Point Breadboard as “TUDIY” throughout this project to save me from having to say it every time.

DON’T WORRY! Even though I’ll be discussing how to make connections on TUDIY throughout the following prototyping steps, I’ll provide images of how to hook up items on a generic breadboard, so you can still follow along!

The Ultimate DIY 3220-Point Breadboard (TUDIY)

Arduino Uno’s ATmega328P Absolute Max Ratings

Before we get started with anything for this part of the build, we first need to go over the Arduino Uno’s ATmega328P microcontroller, and its absolute maximum ratings to gain an understanding of what we need to do to hook up our components properly to prevent damage to the Arduino Uno and its microcontroller.

If we take a look at the table below, we see that the values within it are the absolute maximum ratings for the I/O (Input/Output) pins of the Arduino Uno’s ATmega328P microcontroller:

Source from the ATmega328P datasheet, pg. 308

Looking at the values above, we can determine what we’re limited to, based on the microcontroller’s ratings. What we want to focus on are the following:

  • DC Current per I/O Pin: 40mA
  • DC Current VCC and GND Pins: 200mA

The datasheet is telling us that the DC current from each of the I/O pins, both analog and digital of the Arduino, is limited to 40mA. The DC current of the VCC and ground (GND) pins are limited to 200mA. The datasheet also states that stresses beyond these listed ratings may cause permanent damage to the device.

Using a USB to Power an Arduino Uno

There’s more to know though, about the power from an Arduino Uno. One thing to know is that the 5V pin of the Arduino is not connected through the microcontroller, so in theory, it could supply more power, however when powering the Arduino from the USB, this limits total power consumption to 500mA, which is shared among devices on the Arduino. This sharing means that available power will be less. As a safe bet, it’s best to keep the total power consumption to around 400mA, when powering the Arduino with a USB.

Using an External Power Supply to Power an Arduino Uno

In our case, we’re using an external power supply from a 9V battery. This 9V battery power supply is connected via a DC barrel jack to the Arduino board. This 9 volts is then lowered to 5V by the 5V regulator in the circuitry of the Arduino board. This regulated 5 volts is rated up to 1A, but is thermally limited, so when drawing power the regulator will heat up and shuts down temporarily when overheated. As a safe bet, it’s best to keep the total power consumption to around 900mA, when powering the Arduino with the 9V battery power supply.

Just to complete this analysis of the ratings of the Arduino and its microcontroller, the 9V battery power supply would also be lowered to 3.3V by the 3.3V regulator in the circuitry of the Arduino, making this supply available to the 3.3V pin. The 3.3V output is able to supply a maximum of 150mA, limited by the regulator onboard the Arduino.

Caveat for 3.3V Output of Arduino Uno

There is a caveat though for the 3.3V output, in that any power drawn from the 3.3V power rail also has to go through the 5V power rail. So, you must keep in mind that whatever current is being drawn from a device on the 3.3V output, you also need to consider it against the current being drawn from the 5V output. For example, say you have a device on the 3.3V output drawing 80mA, then you may want to limit any device on the 5V output to be around 300mA or so if powering the Arduino Uno with a USB, or around 800mA or so if powering the Arduino Uno with an external power supply.

Summary of Max Ratings for Arduino Uno

The following is a summary of the absolute maximum ratings for the Arduino Uno’s ATmega328P microcontroller and the Arduino Uno board mentioned above:

  • Absolute Maximum Rating for DC Current per I/O Pin: 40mA
  • Absolute Maximum Rating for Total Current From All I/O Pins: 200mA
  • Maximum Current Rating From the 5V Output Pin:
    • When Using a USB to Power the Arduino: 400mA
    • When Using an External Power Supply to Power the Arduino: 900mA
  • Maximum Current Rating From the 3.3V Output Pin: 150mA

Now that we know the absolute maximum ratings for the ATmega328P microcontroller on the Arduino Uno, we can now figure how we should connect the solenoids and DC motor properly to the Arduino itself.

Adding the Solenoids

Now that we have some of the preliminary stuff out of the way, let’s get to connecting the solenoids to our prototype circuit on the breadboard and to the Arduino. Each of the solenoids that I am using have two wires coming from the solenoid’s coil. To make the temporary connections from the solenoids to the breadboard, I chose to use test hook clips that are spring loaded to make secure connections to the wire ends of the solenoids. The opposite ends of the test hook clips have a male DuPont connector pin that allows me to easily place them into the points (holes) of the breadboard, as can be seen in the image below:

10pcs Test Hook Clips

How to Control Solenoids with an Arduino

When using devices, like solenoids, on low power devices, like an Arduino, we can’t just hook up the wires of the solenoids directly to the pins of the Arduino and expect everything to work. Solenoids require higher voltages and currents than a microcontroller alone can provide.

The solenoids that I’m using for this OwlBot project are a generic brand that was ordered from the rainforest store online. There was not a lot of info about the solenoids, except for the supposed push-pull force that they had (see Solenoids above) and their voltage requirements. Here’s what I care to know about them at this point:

  • 6V Push-Pull Solonoids (x2)
  • A pull force of approximately 1.4 ounces, as was tested previously under the Solenoids heading, above.

In order to find out how much resistance the solenoids have across their terminals, I took my multimeter and made a reading across each solenoid’s wire terminals using the 200Ω setting on my multimeter. We’ll need this information later to measure about how much current draw the solenoids will have. The following are the readings I obtained from each solenoid:

  • Solenoid #1: 6.3Ω
  • Solenoid #2: 6.2Ω

So, with this information, how do we control the solenoids with an Arduino Uno? We need a way to control the on/off switching of the solenoids, and we want to control this with the use of the Arduino we’re using for our project, but we can’t just connect the solenoids to the pins of the Arduino because solenoids require higher voltages and currents than a microcontroller alone can provide.

To control the solenoids using the Arduino, we need to incorporate some extra components to our circuitry to allow us to perform the tasks we ask the Arduino to do, like switching on and off the two solenoids we’re using for the OwlBot project. But what do we need to do to make all this work?

This looks like a job for… MOSFETs!

Using MOSFETs to Control Solenoids

To give the Arduino the capability to control the solenoids with its I/O pins, we will use the help of the RFP30N06 MOSFET. The RFP30N06 is a logic-level, N-channel, power MOSFET, designed for low voltage and low current applications. The great thing about logic-level MOSFETs is that their gate can be fully turned on with lower gate voltages of around 5V or less, which is perfect for us since we’re using the Arduino’s I/O pins to send pulsed DC signals to turn the solenoids on and off.

RFP30N06 Logic-Level N-Channel Power MOSFET

The schematic and details shown below explains how we’re going to make our connections to the Arduino Uno and solenoids using the RFP30N06 logic-level, N-channel, enhancement mode power MOSFET:

The schematic above shows both solenoids used for this OwlBot project — Solenoid 1 (X1), and Solenoid 2 (X2). Each solenoid is connected across a diode (D1 and D2) that acts as a flyback diode, and each of those diodes are placed in reverse-bias through from the +9V battery supply to the drain (D) pin of the RFP30N06 MOSFETs (Q1 and Q2). The flyback diodes are essential for protecting the circuit from voltage spikes generated when the solenoids are turned off.

For the source (S) terminal of the RFP30N06 MOSFET, we’re just going to tie it straight to the negative supply or common ground of the circuit.

The gates (G) of Q1 and Q2 are tied to the digital pins of the Arduino Uno — pin 7 and pin 8, respectively. Digital pins 7 and 8 of the Arduino will provide the voltage we need to turn the gate of each MOSFET on. When motion is detected by the PIR sensor we added in Part 1 of the OwlBot project, we’ll tell the Arduino in code later to activate the solenoids, pulsing them on and off continuously for an amount of time.

Resistors R1 and R2 are both valued at 10KΩ — both are tied from the gate to ground, and both act as pull-down resistors to discharge the gate of each MOSFET when no voltage is applied to the gate. The gate of a MOSFET acts as a capacitor. If we don’t have a path to ground to discharge the gates, then the MOSFETs (Q1 and Q2) may not turn off completely, so having a pull-down resistor at the gate of the MOSFET ensures that the MOSFETs (Q1 and Q2) turn off. You can learn more about how MOSFETs work and their applications here.

pull-down resistor: a resistor connected between a digital input pin and ground (0V) in an electronic circuit. Its primary function is to ensure that the input pin reads a definite low voltage (logic low) when no active signal is present.

Calculating Solenoid Current Draw

Earlier, I mentioned that I took some resistance readings across the terminals of each solenoid that I’m using for this OwlBot project. I also took a voltage reading of the 9V battery pack made up of six AA batteries we added to our prototype circuit in Part 4 of the build series — using the multimeter — and obtained a reading of 9.48V. The readings I obtained from my multimeter for each solenoid and the 9V battery pack made up of six AA batteries were:

  • Solenoid #1: 6.3Ω
  • Solenoid #2: 6.2Ω
  • 9V AA Battery Pack: 9.48V

6x AA Battery Pack w/ Snap Connector Terminals

I’ll take the average of the two resistance readings earlier from the solenoids to make a general calculation, which is:

\begin{equation}
\frac{(6.3Ω + 6.2Ω)}{2} = 6.25Ω
\end{equation}

So, with this information, we have a resistance reading and a voltage reading we’ll use for both solenoids:

  • Solenoid Resistance: 6.25Ω
  • Voltage Across Solenoid: 9.48V

Each solenoid is powered by the 9V battery pack made up of six AA batteries we added in Part 4 of the build series, yet controlled by the Arduino and an RFP30N06 MOSFET for each solenoid. With this information, we can use Ohm’s Law to calculate the current we should be seeing through the solenoids and through the drain and source of the MOSFETs.

\begin{equation}
V = IR
\end{equation}

\begin{equation}
I = \frac{V}{R}
\end{equation}

\begin{equation}
I = \frac{9.48V}{6.25Ω}
\end{equation}

\begin{equation}
\boxed{I = 1.5A}
\end{equation}

With a current this large, there’s no way we could have controlled the solenoids by just hooking them up directly to the Arduino. We must use the MOSFETs!

Adding the DC Motor w/ Propeller

The reason why I am including a DC motor with a propeller on its shaft to the OwlBot project is solely to add more movement to the finished product. Once we have everything in place on the OwlBot body — the plastic great-horned owl figure — the only thing that moves other than the propeller on the motor shaft is the owl’s wings via the solenoids.

The large owl figure, the owl sounds, the flashing red LED eyes, and moving wings are great and all, but I really want to make sure I’m scaring off critters, like the mockingbird, so I’m adding the propeller too. If you don’t want to include the DC motor with propeller on your OwlBot, then by-all-means, don’t feel like you have to. Just omit this part of the project if you’d like. Otherwise, let’s continue with how to control a DC motor with an Ardunio.

How to Control a DC Motor with an Arduino

Like the solenoids we’re using in our OwlBot prototype circuit, to add a motor to the circuit and connect it to the Arduino we’re going to have to incorporate some extra components to our circuitry to allow us to perform the tasks we ask the Arduino to do, like switching on and off the DC motor.

Again, this looks like a job for another MOSFET!

Using a MOSFET to Control the DC Motor

When using a device, like a DC motor, on a low power device, like an Arduino, we can’t just hook up the wires of the DC motor directly to the pins of the Arduino and expect it to work. DC motors require higher voltages and currents than a microcontroller alone can provide.

The DC motor that I’m using for the OwlBot project was hacked off some other device, that I don’t recall off what anymore, years ago. The only thing that I know about my DC motor is that it is a Mabuchi Motor and that it’s made in China. I’m guessing that it’s a 12V motor. Running it off the 9V AA battery pack supply for seconds at a time is totally doable though, for this project.

The schematic and details shown below explains how we’re going to make our connections to the Arduino Uno and DC motor using the IRF840 N-channel, enhancement mode MOSFET:

The schematic above shows the DC motor (M1) used for this OwlBot project. One terminal of the DC motor is tied to the positive 9V AA battery pack supply, and the other terminal of the DC motor is tied to the drain (D) terminal of the IRF840 MOSFET (Q3).

The DC motor being used for this OwlBot project is a brushed DC motor, so I’ve placed a 100 nano-farad (0.1µF) shunt capacitor (C1) across the terminals of the DC motor for a few important reasons:

  1. To improve the overall power factor of the system. The power factor is a measure of how effectively electrical power is being converted into useful work output.
  2. To stabilize the voltage across the DC motor terminals. This can lead to smoother operation.
  3. To filter out certain harmonic frequencies that may be present in the system, which leads to cleaner power and improved efficiency.

Adding a capacitor across the terminals of a brushed DC motor is good practice!

shunt capacitor: a capacitor that is connected in parallel (or “shunt”) with a load or supply point in an electrical system. Its primary purpose is to improve the power factor of the system, especially when dealing with inductive loads like motors and transformers.

For the source (S) terminal of the IRF840 MOSFET, we’re just going to tie it straight to the negative supply or common ground of the circuit.

The gate of Q3 is tied to pin 9 of the Arduino Uno. Digital pin 9 of the Arduino will provide the voltage we need to turn the gate of the MOSFET on. When motion is detected by the PIR sensor we added in Part 1 of the OwlBot project, we’ll tell the Arduino in code later to activate the DC motor, pulsing it on and off continuously — and simultaneously with the solenoids — for an amount of time.

Resistor R3, is valued at 10KΩ, and is tied from the gate to ground. This resistor acts as a pull-down resistor to discharge the gate of the MOSFET when no voltage is applied to the gate. The gate of a MOSFET acts as a capacitor. If we don’t have a path to ground to discharge the gate, then the MOSFET (Q3) may not turn off completely, so having a pull-down resistor at the gate of the MOSFET ensures that it turns off. You can learn more about how MOSFETs work and their applications here.

Solenoids and DC Motor Connections

Programming the Arduino to Activate the Solenoids and Spin the Motor

Now that we’ve properly made our connections for the solenoids and DC motor on the breadboard, we can now update our code from Part 3 to get the Arduino Uno to activate them when motion is detected by the PIR sensor.

In keeping full transparency, I will be using the help of some fantastic people who have offered their knowledge of Arduino and of the other components used for this project freely on the internet, and will be referencing those sources as we continue with this project. As the program has evolved, any sources used has been added into the Arduino code comments. It is encouraged that you go check out any person mentioned for yourself.

Solenoid Reference

Solenoid Reference: Matt Inglot (YouTube): “Control a Solenoid with an Arduino (Tutorial)

DC Motor Reference

DC Motor Reference: Science Buddies (YouTube): “Control a DC Motor with Arduino (Lesson #16)

Multitasking Reference

Arduino “Multitasking” Reference: Amrit Aryal (YouTube): “How to do multiple tasks in Arduino | Beginners | millis() function

The following is the code written for the Arduino Uno to accomplish the tasks needed for our OwlBot prototype, so far:

/* ------------------------------------------------------------------------------
 * Project: OwlBot: The Bird Intimidator - Part 5: Mechanical Movement
 * Written by: Dustin Hodges (Motbots)
 * Date Created: 10/11/2024
 * Date Last Modified: 03/22/2025
 * Description: This is part five of the OwlBot project and its prototype process. Here, we
 * are adding to our code from Part 3 of the build the ability to activate two solenoids
 * simultaneously and to spin a propeller on a DC motor when motion is detected by a PIR
 * sensor that was added to the prototype in Part 1 of the build process.
 *
 * Microcontroller Board: Arduino Uno R3
 * IDE Version: Arduino IDE 2.3.4
 * Modules Used: HC-SR501 PIR sensor, DFRobot DFPlayer Pro Mini MP3 Player
 * Components Used: 2x Flat Top Clear Lens Red LEDs, 2x RFP30N06 MOSFETs, 1x IRF840 MOSFET,
 *                  2X 6V linear solenoids, 1x DC motor
 *
 * ------------------------------- REFERENCES -----------------------------------
 *
 * Solenoid Reference: Matt Inglot (YouTube): "Control a Solenoid with an Arduino (Tutorial)"
 * URL: https://www.youtube.com/watch?v=nwVRMU9grSI
 *
 * DC Motor Reference: Science Buddies (YouTube): "Control a DC Motor with Arduino (Lesson #16)"
 * URL: https://www.youtube.com/watch?v=XrJ_zLWFGFw
 *
 * Arduino "Multitasking" Reference: Amrit Aryal (YouTube): "How to do multiple tasks in Arduino |
 * Beginners | millis() function"
 * URL: https://www.youtube.com/watch?v=Ol6x5mjeu4w
 *
 * DFPlayer Pro Reference 1: Toms Trains and Things (YouTube): “How I Setup & Program DFPlayer
 * Pro With Arduino Uno”
 * URL: https://www.youtube.com/watch?v=Ct8sVkWTptU
 *
 * DFPlayer Pro Reference 2: ModelSceneryTutorials (YouTube): “DFPlayer Pro Voice Prompt Removal:
 * A Comprehensive Tutorial To Unlocking the Full Potential”
 * URL: https://www.youtube.com/watch?v=dMyJDyrESxQ
 *
 * DFPlayer Mini Reference 1: Rachel De Barros (YouTube): "Motion-activated Sound Effects with
 * Arduino, PIR Sensor & MP3 Player"
 * URL: https://www.youtube.com/watch?v=mL0epDFNHqY
 *
 * DFPlayer Mini Reference 2: The Last Outpost Workshop (YouTube): “Sound problems with the
 * MP3-TF-16p DFPlayer Mini?”
 * URL: https://www.youtube.com/shorts/0lyhvAHV20k
 *
 * ------------------------------------------------------------------------------
 */

#include <DFRobot_DF1201S.h> // The DFRobot_DF1201S library for the DFPlayer Pro Mini MP3 Player
#include <SoftwareSerial.h>  // The SoftwareSerial library allows serial communication on
                             // other digital pins of an Arduino board.

/* The follwing is the initial setup of variables for the HC-SR051 PIR sensor. */
const int PIR = 12;          // Signal pin from PIR sensor to pin 12 on Arduino
const int RX = 3;            // This is what we'll designate as the RX pin on the Arduino (not the DF0768's RX pin)
const int TX = 2;            // This is what we'll designate as the TX pin on the Arduino (not the DF0768's TX pin)
int motionStatus = LOW;      // Current motion status or signal pin reading (0 = LOW, 1 = HIGH). Initially set to 0 or LOW.
int pirState = LOW;          // The state of the PIR signal pin (HIGH/LOW). Initially set to LOW.

SoftwareSerial soundFxSerial(RX, TX);   // Creating an object for our sound effects serial, saying which pins to use
                                        // for receiving (RX) and transmission (TX).
                                        // The SoftwareSerial is used to communicate with the DFPlayer Pro module.
DFRobot_DF1201S soundFxPlayer;          // We'll use this object when referring to the sound effects player (MP3 player).

/* The following is the initial setup of the variables for the OwlBot's blinking LED eyes. */
const int LEFT_EYE = 4;    // Red LED pin 4, for the owl's left eye (arbitrary).
const int RIGHT_EYE = 5;   // Red LED pin 5, for the owl's right eye (arbitrary).

/* The following is the initial setup of the variables for the owl's solenoid wings. */
const int LEFT_WING = 7;   // Will be an output pin from Arduino to control the owl's left wing (arbitrary) using a solenoid.
const int RIGHT_WING = 8;  // Will be an output pin from Arduino to control the owl's right wing (arbitrary) using a solenoid.
unsigned long prevTime_1, prevTime_2 = millis(); // Both variables will be used as a previous time mark used in code later for multitasking.
const long TIME_INTERVAL_1 = 250;                // Variable for a time interval initiallized to 250 (later for 250 milliseconds)
const long TIME_INTERVAL_2 = 750;                // Variable for a time interval initiallized to 750 (later for 750 milliseconds)

/* The following is the initial setup of the variable for the owl's propeller. */
const int PROPELLER = 9;

/* The setup function does all the initial setting up of everything we need. When code is
 compiled and ran, the setup function is only entered into during processing once. */                                    
void setup() {
    // Pin modes
    pinMode(PIR, INPUT);            // Pin 12 on Arduino (signal line from PIR) is set as an input pin.
    pinMode(RX, INPUT);             // Our receiving pin for the Arduino needs to be an input.
    pinMode(TX, OUTPUT);            // Our transmission pin for the Arduino needs to be an output.
    pinMode(LEFT_EYE, OUTPUT);      // Make pin for left eye of owl (red LED pin 4) an output.
    pinMode(RIGHT_EYE, OUTPUT);     // Make pin for right eye of owl (red LED pin 5) an output.
    pinMode(LEFT_WING, OUTPUT);     // Make pin for left wing of owl an ouput.
    pinMode(RIGHT_WING, OUTPUT);    // Make pin for right wing of owl an ouput.
    pinMode(PROPELLER, OUTPUT);     // Make pin for propeller of owl an output.

    // Initially turn off both eyes, both wings, and propeller of the owl.
    digitalWrite(LEFT_EYE, LOW);
    digitalWrite(RIGHT_EYE, LOW);
    digitalWrite(LEFT_WING, LOW);
    digitalWrite(RIGHT_WING, LOW);
    digitalWrite(PROPELLER, LOW);
    
    // Serial setup
    Serial.begin(115200);               // Want to be able to use Serial Monitor for debugging purposes.
    soundFxSerial.begin(115200);        // Setting up the serial for the sound effects serial.
    soundFxPlayer.begin(soundFxSerial); // Telling the sound effects player to use the sound effects serial.

    // Player setup
    soundFxPlayer.setVol(30);                           // Set volume for the sound effects player.
    soundFxPlayer.switchFunction(soundFxPlayer.MUSIC);  // Enter music mode.
    soundFxPlayer.setPrompt(false);                     // Silence voice prompt at start.
    delay(2000);                                        // Delay for two seconds to allow everything to calibrate before proceeding.
    soundFxPlayer.setPlayMode(soundFxPlayer.ALLCYCLE);  // Set playback mode to "repeat all"
}

/* The loop function is an infinite loop, meaning once the code is compiled and ran, the
 processes of the code will continually run what's within the loop, until the processes are
 stopped, either within the code, or by the user, or by some other act of God. */
void loop() {
    motionStatus = digitalRead(PIR);  // Get the motion status from pin 12 (Is the signal HIGH or LOW?)
    
    /* If there's motion detected by the PIR sensor, do what's inside the loop. */
    if(motionStatus == HIGH) {
        // If the pirState is LOW (it's initially set to LOW)
        if(pirState == LOW) {
            Serial.println("Motion has been detected!");  // Print message to serial monitor.
            /* Going to need to change the pirState to HIGH, since motion has been detected. */
            pirState = HIGH;

            if(!soundFxPlayer.isPlaying()) {  // If the owl FX not playing...
              playOwl();                      // Play the owl MP3 audio.
            }
        }
    }
    /* Else, if no motion has been detected by the PIR sensor, do what's inside here: */
    else {
        // If the pirState is HIGH
        if(pirState == HIGH) {
            Serial.println("No motion detected.");  // Print message to serial monitor.
            /* Going to need to change the pirState to LOW, since no motion has been detected. */
            pirState = LOW;

            if(soundFxPlayer.isPlaying()) { // If the owl FX is still playing...
              pauseOwl();                   // Make absolute sure we pause the owl.
            }
        }
    }
}

/* The playOwl() function is called when we want to play the owl MP3 file to make owl sounds. */
void playOwl() {
  uint16_t fileNum = soundFxPlayer.getCurFileNumber();  // Getting the current file number in our MP3
                                                        // player and setting it to the variable 'fileNum'.
  soundFxPlayer.playFileNum(1);   // Play file #1, the numbers are arranged according to the sequence
                                  // of the files copied into the U-disk.
  soundFxPlayer.setPlayTime(0);   // Starts the file 0 seconds in (or at the very beginning).
  soundFxPlayer.start();          // Start playing sound FX.
  blinkEyes();                    // Blink the owl's spooky eyes.
  delay(250);                     // Wait 250 milliseconds (1/4 second)
  pauseOwl();                     // Pause the owl's FX as soon as we're done playing the FX.
}

/* The pauseOwl() function is called when we need to pause the audio playing from the MP3 file. */
void pauseOwl() {
  soundFxPlayer.pause();          // Pause the sound FX player.
}

/* The blinkEyes() function blinks the OwlBot's red LED eyes at a rapid pace for approximately 10 seconds or so. */
void blinkEyes() {
  delay(250); // Wait 250 milliseconds (1/4 second)

  for(int i = 0; i < 5; i++) {    // Do this loop ten times.
    for(int j = 4; j > 0; j--) {  // Do this loop four times.
      unsigned long currentTime = millis();

      digitalWrite(LEFT_EYE, HIGH);   // Turn left eye on.
      digitalWrite(RIGHT_EYE, HIGH);  // Turn right eye on.
      delay(125);                     // Wait 125 milliseconds (1/8 second)

      if(currentTime - prevTime_2 > TIME_INTERVAL_2) {
          spinPropeller();
          prevTime_2 = currentTime;
      }

      if(currentTime - prevTime_1 > TIME_INTERVAL_1) {
        flapWings();
        prevTime_1 = currentTime;
      }

      digitalWrite(LEFT_EYE, LOW);  // Turn left eye off.
      digitalWrite(RIGHT_EYE, LOW); // Turn right eye off.
      delay(125);                   // Wait 125 milliseconds (1/8 second)
    }
  }
}

/* The flapWings() function activates the two solenoids used for the OwlBots wings. The solenoids create the mechanical
movement needed to move the OwlBot's faux wings, creating a "life-like" action for the OwlBot. */
void flapWings() {
  digitalWrite(LEFT_WING, HIGH);    // Flap left wing.
  digitalWrite(RIGHT_WING, HIGH);   // Flap right wing.
  delay(150);

  digitalWrite(LEFT_WING, LOW);     // Stop flapping left wing.
  digitalWrite(RIGHT_WING, LOW);    // Stop flapping right wing.
  delay(150);
}

/* The spinPropeller() function activates the DC motor to create an extra form of movement for the OwlBot by spinning
a propeller mounted on the motor's shaft. */
void spinPropeller() {
  digitalWrite(PROPELLER, HIGH);
  delay(250);
  digitalWrite(PROPELLER, LOW);
  delay(250);
}

The Code Explained

For this part, I will only go over the code we’ve added here for Part 5 of the OwlBot prototype build. If you need an explanation of the other parts of the code, please visit our project series page The OwlBot Project Series, to find the code explained for each part of this series, thus far.

Referring to the code above, let’s walk through some key lines to understand what’s going on:

Creating and Initializing the Variables

const int LEFT_WING = 7;   // Will be an output pin from Arduino to control the owl's left wing (arbitrary) using a solenoid.
const int RIGHT_WING = 8;  // Will be an output pin from Arduino to control the owl's right wing (arbitrary) using a solenoid.

The first bit of code that we want to look at that’s been added new to the OwlBot code are the two variables LEFT_WING and RIGHT_WING. We’ve set the variables to be connected to digital pins 7 and 8 on the Arduino, respectively. These two variables arbitrarily represent the left and right wings of the OwlBot, or the two solenoids used to control the wing movement. There are no political innuendos here, they’re literally used for the owl’s wing orientation. Just chill!

Keanu Reeves Just Chill meme – Origin: Wholesome Memes, Source: Reddit
unsigned long prevTime_1, prevTime_2 = millis(); // Both variables will be used as a previous time mark used in code later for multitasking.
const long TIME_INTERVAL_1 = 250;                // Variable for a time interval initiallized to 250 (later for 250 milliseconds)
const long TIME_INTERVAL_2 = 750;                // Variable for a time interval initiallized to 750 (later for 750 milliseconds)

The prevTime_1 and prevTime_2 variables will be used in code later to mark two separate previous times that we’ll need for multitasking later. We need multitasking in our code to be able to run multiple devices or components on our prototype circuit simultaneously, such as when the PIR sensor detects motion, the MP3 player plays owl sounds, the two red LEDs flash, the two solenoids activate and the DC motor activates all simultaneously.

We’ve initialized two time intervals, TIME_INTERVAL_1 and TIME_INTERVAL_2, to use in our code later. We want to use these for their specific predetermined times that we created as time intervals for how long the solenoids will activate on and off, for example. These values can be adjusted and changed to your preference.

/* The following is the initial setup of the variable for the owl's propeller. */
const int PROPELLER = 9;

The PROPELLER variable represents the digital pin 9 on the Arduino that we’ve hooked one of the leads of the DC motor to. We’ll use this variable in code later to control when to turn the DC motor on and off.

Pin Modes

In the setup, we’ll initialize the pin modes for each of the pins we’re using on the Arduino Uno for both of the solenoids and for the DC motor:

pinMode(LEFT_WING, OUTPUT);     // Make pin for left wing of owl an ouput.
pinMode(RIGHT_WING, OUTPUT);    // Make pin for right wing of owl an ouput.
pinMode(PROPELLER, OUTPUT);     // Make pin for propeller of owl an output.

Both the LEFT_WING and RIGHT_WING variables that represent the solenoids will be receiving output signals from the Arduino to activate or to turn on when needed, at pins 7 and 8. The PROPELLER variable that represents the DC motor’s propeller on its shaft will also be receiving output signals from the Arduino to turn on when needed at pin 9.

Digital Write

digitalWrite(LEFT_WING, LOW);
digitalWrite(RIGHT_WING, LOW);
digitalWrite(PROPELLER, LOW);

We use the digitalWrite() function for both the LEFT_WING and RIGHT_WING variables to initially set them to LOW, or to initially have them turned off when the circuit is initially powered on. We also set the PROPELLER variable to be LOW using the digitalWrite() function to turn it off when the whole prototype circuit is initially turned on. We don’t want the solenoids and motor to start becoming activated immediately after turning the whole circuit on.

Inside the playOwl Function

The playOwl() function is a function that we created ourselves back in Part 2 of the OwlBot project, and is called into from the main loop() function when motion is detected by the PIR sensor we installed on our prototype circuit back in Part 1 of the OwlBot project.

/* The playOwl() function is called when we want to play the owl MP3 file to make owl sounds. */
void playOwl() {
  uint16_t fileNum = soundFxPlayer.getCurFileNumber();  // Getting the current file number in our MP3
                                                        // player and setting it to the variable 'fileNum'.
  soundFxPlayer.playFileNum(1);   // Play file #1, the numbers are arranged according to the sequence
                                  // of the files copied into the U-disk.
  soundFxPlayer.setPlayTime(0);   // Starts the file 0 seconds in (or at the very beginning).
  soundFxPlayer.start();          // Start playing sound FX.
  blinkEyes();                    // Blink the owl's spooky eyes.
  delay(250);                     // Wait 250 milliseconds (1/4 second)
  pauseOwl();                     // Pause the owl's FX as soon as we're done playing the FX.
}

Looking inside the playOwl() function we can see the call to the blinkEyes() function is made. We created this function ourselves back in Part 3 of the OwlBot project in order to get the two red LEDs we installed on our prototype circuit to blink when motion is detected by the PIR sensor. Let’s now look inside the blinkEyes() function next.

The blinkEyes() Function

The blinkEyes() function is a function we create ourselves to control the process of blinking or flashing the red LEDs we added to our prototype circuit in Part 3 of the OwlBot project. We’ve since modified this function and it now looks as follows:

/* The blinkEyes() function blinks the OwlBot's red LED eyes at a rapid pace for approximately 10 seconds or so. */
void blinkEyes() {
  delay(250); // Wait 250 milliseconds (1/4 second)

  for(int i = 0; i < 5; i++) {    // Do this loop ten times.
    for(int j = 4; j > 0; j--) {  // Do this loop four times.
      unsigned long currentTime = millis();

      digitalWrite(LEFT_EYE, HIGH);   // Turn left eye on.
      digitalWrite(RIGHT_EYE, HIGH);  // Turn right eye on.
      delay(125);                     // Wait 125 milliseconds (1/8 second)

      if(currentTime - prevTime_2 > TIME_INTERVAL_2) {
          spinPropeller();
          prevTime_2 = currentTime;
      }

      if(currentTime - prevTime_1 > TIME_INTERVAL_1) {
        flapWings();
        prevTime_1 = currentTime;
      }

      digitalWrite(LEFT_EYE, LOW);  // Turn left eye off.
      digitalWrite(RIGHT_EYE, LOW); // Turn right eye off.
      delay(125);                   // Wait 125 milliseconds (1/8 second)
    }
  }
}

This function contains a pair of for loops, one inside another, that allows us to create the illusion of the OwlBot having red blinking eyes. We can see that we’ve modified the second for loop and that it now has a local variable called currentTime initialized within the for loop. We use this to return the number of milliseconds passed since the Arduino board began running the current program.

local variables: in Python are defined within a function and are exclusive to that function. They cannot be accessed from outside the function.

Next, we use the digitalWrite() function to turn both the left and right eye (the two red LEDs) of the OwlBot, then wait (delay) for an eighth of a second.

Next, we see that two if statements follow. The first if statement looks to see if the difference of the currentTime and prevTime_2 is greater than TIME_INTERVAL_2, and if it is, then it’s to call the spinPropeller() function, which we’ll see later is a function created to tell the Arduino to turn the DC motor on to spin the propeller on the shaft of the DC motor. We then set the prevTime_2 equal to the currentTime to use again later when the blinkEyes() function is called again.

The second if statement looks to see if the difference of the currentTime and prevTime_1 is greater than TIME_INTERVAL_1, and if it is, then it’s to call the flapWings() function, which we’ll see later is a function created to tell the Arduino to turn the solenoids on that will act as our mechanical motion to flap the faux wings we’ll create for the plastic owl figure we’re using in a later part of the OwlBot project series. We then set the prevTime_1 equal to the currentTime to use again later when the blinkEyes() function is called again.

Lastly, in the blinkEyes() function, we call the digitalWrite() function for each eye (LED) of the OwlBot to turn off (LOW), then wait (delay) for another eighth of a second before the program leaves the second for loop.

The spinPropeller() Function

The spinPropeller() function is called from within the blinkEyes() function. When called, its only job is to turn the DC motor on (HIGH), followed by a ¼ second delay, then to turn the DC motor off (LOW), followed by another ¼ second delay.

/* The spinPropeller() function activates the DC motor to create an extra form of movement for the OwlBot by spinning
a propeller mounted on the motor's shaft. */
void spinPropeller() {
  digitalWrite(PROPELLER, HIGH);
  delay(250);
  digitalWrite(PROPELLER, LOW);
  delay(250);
}

The flapWings() Function

The flapWings() function is called from within the blinkEyes() function. When called, its only job is to turn each solenoid on (HIGH), followed by a 150 millisecond delay, then to turn each solenoid off (LOW), followed by another 150 millisecond delay.

/* The flapWings() function activates the two solenoids used for the OwlBots wings. The solenoids create the mechanical
movement needed to move the OwlBot's faux wings, creating a "life-like" action for the OwlBot. */
void flapWings() {
  digitalWrite(LEFT_WING, HIGH);    // Flap left wing.
  digitalWrite(RIGHT_WING, HIGH);   // Flap right wing.
  delay(150);

  digitalWrite(LEFT_WING, LOW);     // Stop flapping left wing.
  digitalWrite(RIGHT_WING, LOW);    // Stop flapping right wing.
  delay(150);
}

Compiling and Uploading the Code to Arduino

Now that we’ve gone over the program we’re going to use to get the Arduino to activate the solenoids and spin the motor, you can either tediously write the code yourself, or just copy-and-paste it into your file on the Arduino IDE. I’ve named my file owlbot_part-5.ino. You can name yours whatever you want.

If you need or want to see the process of copying and pasting the code into the Arduino IDE, connecting the Arduino to a computer, choosing the board and port under tools in the IDE, verifying code, and fixing code errors, then check out Part 1 of this OwlBot project here, because these processes are similar for Part 5.

Testing What We’ve Done

At this point, you have your prototype for step four of this project complete and you have completed writing your code for this step of the prototyping process. You’ve also copied the code, verified it, and fixed what errors you may have had after doing so. You’ve then compiled and uploaded the code to the Arduino Uno to see if what you’ve done so far even works! Here are the steps again, to test what you’ve done up to this point in the project:

  1. Add the solenoids to the prototype of the OwlBot project.
  2. Add the DC motor w/ propeller to the prototype of the OwlBot project.
  3. Create the code you’ll use for the Arduino Uno in the Arduino IDE.
  4. Verify the code and fix any errors.
  5. Compile and Upload the code to the Arduino Uno using the provided USB cable that came with your Arduino.
  6. Disconnect the Arduino from your computer once you’re done compiling and uploading the code to the Arduino. Connect the two 9V power sources to the Arduino and to the breadboard. Onced everything is powered on, start waving your hand in front of the PIR sensor. Once motion is detected, the MP3 player should start playing the owl sounds to the speakers, the red LEDs should start flashing, the solenoids should be activated, and the motor should be spinning the propeller.

Once you’ve compiled and uploaded your code to the Arduino, and have started waving your hand in front of the PIR sensor, you should start hearing the owl sounds playing from the MP3 player to the speakers, seeing the two red LEDs flashing, and seeing the two solenoids and DC motor moving.

If everything is working as it should, then congratulations! You’ve successfully completed the fifth step of the OwlBot prototype. Check out the video below to see the full prototyping process, as well as to see this part of the project working!

In step 6 of the OwlBot project, we’re going to be adding switches to our power supplies to be able to control turning everything on and off, for when we start going from prototype to permanent circuitry to place into our owl figure for the finished OwlBot product. We’ll need these switches so that our OwlBot isn’t constantly on with no way to turn it off without removing the batteries. After that, we’ll be on our way to begin affixing everything we’ve done in the prototype phase of the project on a more permanent board than the breadboard. So, stick around for more!

Video Build of the OwlBot: Part 5 – Mechanical Movement

What’s Next

So far, we have implemented motion sensing, sound, flashing LEDs, and now mechanical motion with the use of a couple solenoids and a DC motor. Now we need to have a way to control turning everything on and off – a master switch, if you will, for the entire circuit. So, next we’ll need to add a switch for each power supply being used for our circuit to be able to control the power to our circuitry. All this will be in Part 6 of the OwlBot project!

“How to Make an OwlBot: The Bird Intimidator – Part 6: Adding Switches” will be the next step of this project. This part of the project is currently being developed. You may check back to this page here, to see when it’s complete and ready for you to continue, or you may signup for our newsletter to receive updates on this project and others!

Part 6 COMING SOON!

Thank you for participating in this project. We hope that you have enjoyed the build thus far. Let us know by giving a comment in the comments section below. Share the link to your friends and family. Let them know how much you’ve enjoyed the process of prototyping the OwlBot!


Leave A Comment

Motbots