Like a moth to a flame
I was talking to a moth
The other evening
He was trying to break into
An electric light bulb
And fry himself on the wires
(From The Lesson of the Moth by Don Marquis)
There’s something almost haunting about the way moths behave at night. They’re drawn to light like it’s a promise. They gather around, fluttering and buzzing softly, their wings making that faint, whispery hum. But then, if you try to shoo them away, they would scatter wildly, fluttering in unpredictable, desperate patterns. For a moment, they’re chaotic, a swirl of wings and shadows. And yet the moment you leave them be, they return almost as if nothing happened, and back to the glow that mesmerizes them, back to that strange, almost tragic obsession. And when they’re startled—really disturbed—their movements become sharper, more frantic. You can see their confusion in the way they flit around, bumping into things, making those sudden, exaggerated flaps as if trying to escape some invisible threat. It’s like they know the light is dangerous, but they just can’t tear themselves away. They always come back.
There’s something intriguing about moths that makes me want them on my screen.
I’m simply going to create visual effects with the pressure sensor, light sensor as input readings and a servo motor as output. I was thinking:
- the canvas should be black at first
- I can create a swarm of moths using white short lines, and make them move randomly, just like how i used trigonometry to generate my ball movements in the Kaleidoscope project.
- But overall they should move in a messy spiral.
- Their initial position can be determined by a grid system.
- My light sensor will decide if they are scattered or gathered (the darker, the more they gather)
- The pressure sensor will make their movements more spread and messy, as if something is driving them crazy, but wouldn’t change if they are gathered or scattered.
- The servo will move more rapidly according to the light sensor, but the core function is to make a buzzing sound. maybe the speed can change proportionally?
>>> MOTHS
The final code for this section:
https://editor.p5js.org/mukirkland/sketches/msJfeICIC
> First attempt
The moths are positioned in a grid layout, which is determined by gridSpacing.
Each moth moves according to its own angle and speed, with small random changes applied to their angles to create a more natural movement.
The moths have a slight tendency to move towards the center (centerX, centerY), simulating a gathering effect.
When a moth moves off the screen, it wraps around to the opposite side, maintaining a continuous flow of movement.

> Motion
I wanted to make the lines point in the same direction as the moths’ movement, we can use the angle of movement to determine the line’s rotation. By rotating the line (or rectangle) in the direction of the moth’s current movement angle, it will visually align with their trajectory.
I tried to use targetAngle and calculate using atan2(directionY, directionX), which gives the angle between the moth’s position and the center of the canvas. It should gradually transition the moth’s current angle towards the target angle.


But its not coming out as I expected.
I gave up. I changed the lines into suqares & continue using our cheap tail effect.

> Inharmonious
I finally gained this by:
- Increasing the attraction force towards the center by adjusting directionX and directionY using a multiplier (* 0.02).
- Perlin noise offsets (noiseX and noiseY): see https://p5js.org/reference/p5/noise/
- btw do you know that Perlin noise is named after Ken Perlin? He was a computer science professor in NYU
- As moths get closer to the center, their speed decreases using a damping factor based on the distance to the center: moth.speed = map(distanceToCenter, 0, width / 2, 0.5, 5);. This makes them slow down and hover more consistently near the middle.
- The angle of each moth is based on noise and a small random value.

>>> FLAMES
From the Moths part, the most important parameters that can be used for playing with the light sensor is:
- Increase or decrease directionX and directionY multipliers to make the attraction toward the center stronger or weaker
The value of the light sensor (lightSensorValue) is read from the serial port using the serialEvent() function, then used to control the gathering strength of the moths.
gatheringStrength is mapped using map(lightSensorValue, 0, 500, 0.1, 0.001); so that when it’s dark (lightSensorValue is low), the gathering strength is high (0.1), and when it’s bright, the gathering strength is low (0.001).
The attraction force (directionX and directionY) is modified using the gatheringStrength value, making the moths either gather closely or scatter depending on the light level.
The serial object reads data from the Arduino’s serial port and stores it in inData, which is then parsed to update lightSensorValue.
It works as expected, but it’s making my computer super, super laggy. I already tried to reduce the moth number.
> Optimization
I tried 3 different ways of optimization:
- Limited the frame rate to 30 FPS using frameRate(30) for smoother performance.
- Reduced the number of moths to 200 for less processing and rendering.
- Updated the light sensor value once every 10 frames by using a frameCounter variable and only calling updateLightSensorValue() conditionally (if (frameCounter % 10 === 0)).
The third one is the most efficient. The number of moths also cannot exceed 500 (or it will be laggy again).
>>> WINDBEATS
For this part, I simply make the servo work with the light sensor. The more the moths collide with each other, the servo will oscillate more frequently to immitate the sound of the moth swarm.
(In real life, The moth (depending on species, age, size) will flap it’s wings at 10–25 times per second.)
For this part I used a loop for shaking from my stupid pet trick, where I tried to imitate my pet cat shaking tails, if you can remember. So it’s on my arduino side.
What I need to change are: Update the Arduino code to handle the servo’s oscillation frequency based on the value received from p5.js. If the light value is low, the servo should oscillate frequently (buzzing sound). If the light value is high, the servo should either stop oscillating or move very slowly.

I tested the value for like 10 times and finally gets a buzzing sound like moth swarms.
>>> LUNATIC
I want to add a little pressure and make the swarm go even crazier. Added pressureSensorValue to stores the pressure sensor values received from arduino.
chaosFactor = map(pressureSensorValue, 0, 1023, 0, 10);
This maps the pressure sensor value (0 to 1023) to a chaosFactor that ranges from 0 (no randomness) to 10 (high randomness), and is used to scale the Perlin noise values applied to the moths’ positions.
>>> FINAL EFFECT
> Video
> Code
https://editor.p5js.org/mukirkland/sketches/zgngnzd12
Full Screen: https://editor.p5js.org/mukirkland/full/zgngnzd12
I tried to make my post more condensed and easy-reading this week. Hope it will be better than previously (yapping too much).
Probably because of the shapes and monochrome, the whole thing looks unfinished and sketchy. I wanted to convey a befuddled and cranky mood and perhaps visually shaper than what it is now. Now everything is moving too smooth and circular. I doubt if it would really remind my audiences of crazy moths… anyways the result is still satisfying to watch 🙂
but at the same time i wish
there was something i wanted
as badly as he wanted to fry himself
*There’s something intriguing about moths. There’s something intriguing about you.*



