Two small glowing eyes in a dark corner, under a hedge, behind the porch rail. They blink now and then, the way a real animal does. Every so often one winks, or both vanish and come back a moment later. When someone walks up they snap open and stare. That is this sketch: a classic ESP32, two 5 mm pixel LEDs and one data wire, flashed from this page in about a minute and run from your phone.
It is also the first sketch in this library that measures nothing and sends nothing. The board raises its own small Wi-Fi network, your phone joins it, and the control page opens by itself. No app, no account, no internet, nothing to set up at home. Out of October it has a second job: Garden Guard turns the same board into a red predator-eye light that flashes at night to give deer and raccoons a reason to think twice.
What it does.
A pixel LED is an ordinary LED package with a tiny controller inside. One data wire carries a color for every pixel on the chain, so two eyes, or eight, need one pin. This sketch draws each eye a hundred times a second from a handful of layers multiplied together: whether the eye is present, how far its lid is open, the character's mood, a flare, and how long someone has been standing there. That is what makes it read as alive and not as a decoration.
- Blinks and winks at uneven gaps, with the odd double blink. The lids close fast and open slower, like a real eye.
- Moods: a slow breath, a ghostly flicker, a demon's flare.
- Vanishing: a pair fades out, stays gone for a few seconds, and fades back. In a dark corner this is the one that gets people.
- Up to four pairs on the same wire, each blinking and vanishing on its own schedule. A row of eyes along a path, or a pack in the bushes.
- Motion and dusk: an optional motion sensor keeps the eyes dark until someone comes, and an optional light sensor wakes them at dusk.
- A visitor count: how many came tonight, and when, in your phone's own clock.
What you need.
The two eyes and the board are the whole build. The two sensors are optional, and the eyes work without either.
Wire it up.
The eyes form a chain. Data goes into the left eye, out of it into the right eye, and on to the next pair if you have one. Every eye shares 5 V and ground. Power off while you wire:
| Part | Connects to | On the ESP32 | Note |
|---|---|---|---|
| Left eye DIN | through 470 Ω | GPIO 23 | The one data pin for every eye. |
| Left eye DOUT | right eye DIN | – | Then right DOUT to the next pair's left DIN. |
| Every eye VDD | 5 V | 5V (VIN) | The USB supply. Not 3V3. |
| Every eye GND | ground | GND | Either GND pin. |
| Motion sensor OUT | – | GPIO 32 | Optional. Its VCC and GND to 3V3 (AM312) or 5V (HC-SR501). |
| Light divider | photoresistor + 10 kΩ | GPIO 34 | Optional. Analog pins 32 to 39 only. |
Finding the legs on a 5 mm pixel
- Four legs: data in, power, ground, data out.
- The order differs by maker. Check the seller's drawing, which keys the legs to the flat edge of the lens.
- Data has a direction. DIN takes from the board; DOUT feeds the next eye.
Why those pins
- 23 drives the eyes: a plain output with no boot-time job.
- 34 reads light: Wi-Fi takes over the other analog block, so only 32 to 39 can read while the eyes' network is on.
- The setup page refuses a pin that cannot work, and says why.
Color order. Pixels disagree about which byte is red. The PL9823, the most common 5 mm pixel, takes red, green, blue; the WS2812D 5 mm and every WS2812B strip take green, red, blue. The firmware starts on rgb, and the control page has a Color check button that lights every eye pure red for three seconds. Green instead? Set color order to grb on the setup page.
If an eye flickers or ignores you. A PL9823 is designed to see about 3.5 V as a data "high", and the ESP32 sends 3.3 V. It nearly always works anyway. When it doesn't, put an ordinary 1N4001 diode in the eyes' 5 V line: the pixels then run at about 4.3 V, and their threshold drops to about 3.0 V. Long wires make this worse, so keep the run from the board to the first eye short and put the length between the eyes instead.
Flash it.
Plug the board in and press the button. The installer reads the chip on the wire and refuses to write if it isn't the board this image is for, so there is nothing to get wrong.
If the board won't take the flash, or it restarts over and over
Hold the BOOT button down while you plug the USB cable in. Let go once it is plugged in, then press the install button above. That is the whole fix, and it is worth trying first any time a board is being stubborn.
Here is what is going on. A board with no working firmware on it restarts several times a second, forever, because it looks for a program to run and finds nothing. The installer needs the board to hold still long enough to write a megabyte and a half, and it cannot get hold of one that keeps restarting. Holding BOOT as the power arrives puts the chip into the loading mode it was built with, where no program runs at all, so there is nothing to restart and the installer gets a still target.
If you have a serial monitor open, you will know it worked because the scrolling stops. Quiet is what you want.
You may also see invalid header: 0xffffffff repeating in the monitor. That reads like damage and it is not: it is what an empty chip looks like, which is exactly where a board lands if a write was interrupted. The board is fine. Flash it again with BOOT held and it will come back.
If it flashes and runs fine on its own but fails the moment the sensor is connected, suspect whatever sits between them before you suspect either one. A screw-terminal carrier, an adapter board or a breakout is a component too, and a bridged or cracked terminal on one will stop the board booting while the sensor and the ESP32 are both perfectly good. Detaching the sensor is the quickest test: if the board comes back to life, neither it nor the sensor is at fault, and the thing in the middle is where to look. That exact fault cost us most of a night.
Two other things are worth checking before you decide a board is bad. Use a data USB cable, since a charge-only cable carries power but no signal and gives you the same symptoms. And plug straight into the computer rather than through a hub, because a write that browns out part way through leaves the board empty in just this way.
You'll need a data USB cable (not charge-only) and Chrome or Edge on a computer. A classic ESP32 talks to your computer through a separate USB chip, so the first time you plug one in you may need to install its driver once: look for CP2102 or CH340 printed near the USB socket, then fetch that driver. After that the computer is done; everything else happens on your phone.
Set it up.
- Power the board from any USB charger.
- On your phone, join the Wi-Fi network
OAT-Eyes-XXXXXXwith the passwordoatsetup. The control page opens by itself; if not, visithttp://192.168.4.1. - Press Color check. Both eyes glow red for three seconds. Green? Open Setup at the bottom of the page and set color order to
grb. - Pick a character, set the brightness, and choose When and Motion. Everything saves itself.
- On Setup, change the Wi-Fi password, so the neighbor's kids can't take over your eyes.
Auto, On, Off. The three buttons at the top of the control page decide who is in charge. Auto follows your When and Motion choices. On ignores them, which is how you test the eyes in daylight, when a dusk schedule would keep them dark. Off is off. The line above the buttons always says, in words, what the eyes are doing and why: Waiting for dark, light 64%, or Asleep until someone comes.
Scare now. Six buttons for working the eyes by hand from across the yard: Blink, Wink, Vanish, Flare, Pretend motion, and Color check. Pretend motion does exactly what a passer-by would, so you can try the motion behavior without walking past your own porch.
Everything on the page is also on the USB console, if you like a keyboard: blink, wink, vanish, flare, motion, mode on, char Ghost, and status. Type help for the list.
Who’s watching.
A character is a color, a mood and a way of blinking. Pick one on the page and every pair of eyes takes it on at once.
| Character | Looks like | Behavior |
|---|---|---|
| Wolf | amber | Steady, slow breath, blinks every few seconds, now and then twice. |
| Demon | red | Flares to a hot glow on its own every half minute or so. |
| Cat | yellow-green | The slow cat blink: lids down, a long pause, lids up. |
| Ghost | pale blue | Flickers and drops out, rarely blinks. |
| Owl | wide amber | Often closes one eye, then the other. |
| Toxic | green | Quick breath, twitchy blinks, lots of doubles. |
| Garden Guard | red | Short flashes at uneven gaps, a volley on motion. More below. |
| Custom | any color | Your color, your mood, and a blink-rate slider from never to constantly. |
Leave Vanish now and then ticked and each pair also fades out every minute or so, stays gone for a few seconds, and fades back. With two or more pairs they vanish separately, so the eyes in the dark seem to move.
Dusk, motion, visitors.
When. Three choices: Always, Dusk to dawn, and From dusk for a few hours, with a slider from one to twelve. Dusk comes from the light sensor, not a clock, so there is nothing to set and nothing to drift. The page shows the light level live, and a link, It's dusk now, use this light, sets the threshold to the light you are standing in. The light has to stay past the line for thirty seconds before the eyes believe it, so a flashlight or a car's headlights never wake them or put them to sleep. Keep the light sensor out of the eyes' own glow and away from porch lights.
Motion. Three choices again. Ignore the motion sensor. Count visitors only, where the eyes keep to When and the sensor just counts. And Stay dark until someone comes: the eyes stay closed until the sensor fires, then snap open and stay open for as long as you set, from five seconds to five minutes after the last movement. Tick Stare harder the longer they stay and the eyes open at half brightness and climb to full over about eight seconds while the visitor stands there.
Visitors. Each new arrival is counted: motion after thirty quiet seconds is a new visitor, and one person shuffling on the step for a minute is one. The page shows how many tonight, since dusk, and how many since you last reset, with the time of each in your phone's clock. On Halloween that is a trick-or-treat count. In the garden it tells you whether anything is actually coming at night.
Garden Guard.
The cheapest commercial animal deterrents on the market are not much more than this: a red LED or two in a weatherproof box that flashes all night. Many nocturnal animals, deer, raccoons and foxes among them, are wary of a pair of eyes that seems to be watching them. Garden Guard is that light, with the parts that matter done properly.
- Uneven flashes. Short red flashes at gaps from under a second to nearly three, with the occasional double. A fixed rhythm is exactly what an animal learns to ignore.
- Dusk to dawn. Pair it with the light sensor so it runs all night and rests all day.
- A volley on motion. With the motion sensor fitted, an animal that comes close sets off a rapid burst from every pair.
- Pairs that move. Several pairs on one wire flash independently, so the eyes appear in different places.
- A count. The visitor count tells you how often something came near, which is the only way to know if any of it is working.
For the garden, put the board and a USB power bank or outdoor USB supply in a sealed box, bring the eyes out through a grommet at animal eye height, and point the motion sensor along the path the animals use rather than out across open ground.
What it does not do.
It does not join your home Wi-Fi, and it sends nothing anywhere. There is no cloud, no account and no app. The only network it uses is its own, and the only device that talks to it is the phone you join to it. That is deliberate: a Halloween prop that has to reach the internet is a prop that fails in the front yard.
It keeps no clock. Visitor times are worked out on your phone from "this many seconds ago", so they are right without the board ever knowing the time. The visitor count lives in memory and starts again if the power goes off. Your settings, the character, brightness, schedule and motion choices, are saved on the board a few seconds after the last change and come back after a power cut.
A fresh firmware flash erases everything, the Wi-Fi password included, which is how you hand a board on to someone else with nothing of yours left on it.
For makers & trainers.
Frequently asked questions.
How do I make glowing eyes for Halloween with an ESP32?
Wire two pixel LEDs, such as 5 mm PL9823 or WS2812D, in a chain: the ESP32's GPIO 23 through a 470 ohm resistor to the first eye's data in, the first eye's data out to the second eye's data in, and both eyes to 5 V and ground. Flash the Night Eyes firmware from the Open Agriculture Technology sketch page, join the board's own Wi-Fi network from a phone, and pick a character. The eyes blink, wink and vanish on their own, and an optional motion sensor keeps them dark until someone walks by.
Do I need a capacitor and a resistor with WS2812 or PL9823 pixels?
The resistor, yes: a 300 to 500 ohm resistor in series with the data line, near the controller, protects the first pixel's input from ringing. The large capacitor across the power supply that strip guides recommend is for long strips that draw amps when they switch on; two or a handful of pixels on a USB supply do not need it. A 0.1 microfarad capacitor across each pixel's power legs is cheap insurance when the pixels sit at the end of a long wire.
Can an ESP32 drive 5 V pixel LEDs from its 3.3 V pin?
Usually, yes. Pixels powered from 5 V expect a data high of about 70 percent of their supply, roughly 3.5 V, and the ESP32 outputs 3.3 V, which most pixels accept anyway, especially on a short wire. If a pixel flickers or ignores commands, run the pixels from about 4.3 V by putting a 1N4001 diode in their 5 V supply, which lowers their threshold to about 3.0 V, or add a 74AHCT125 level shifter on the data line.
Do flashing red lights keep deer and raccoons out of a garden?
Sometimes, and usually for a while. Flashing lights that look like a predator's eyes are a common nonlethal deterrent, and the evidence is mixed: they work best at first and lose effect as animals learn the light is harmless. Random timing, a motion-triggered burst of flashes, and moving the light every few days slow that habituation. They work best as one layer alongside fencing or netting, and counting night visits is the way to tell whether they are helping.
How can I control an ESP32 from my phone without the internet?
Have the ESP32 run its own Wi-Fi access point and serve a web page. The phone joins the board's network, and a captive portal opens the control page automatically, usually at 192.168.4.1. Nothing passes through the internet or a home router, and no app is needed. Night Eyes works this way, with a WPA2 password on the board's network that the owner can change.
Which PIR motion sensor works with an ESP32?
Both common ones. The small AM312 runs from 3.3 V and its output goes straight to an ESP32 pin. The larger HC-SR501 needs 5 V for power but its output is 3.3 V, so it is also safe on an ESP32 input; set its time dial to the minimum so the firmware controls how long the response lasts. Either sensor needs up to a minute to settle after power-on, during which it can trigger falsely.