DEV Community

Valentino Stoll
Valentino Stoll

Posted on • Originally published at blog.codenamev.com on

1

The Great Breathing Ruby LED

This is part 4 in my Sunfounder Superkit series.

The Great Breathing Ruby LED

In our last experiment, you were probably bedazzled by the alluring display of LEDs. This time around, we'll go from bedazzling to mesmerizing and use sweet technological magic to make an LED breathe.

magic

Admittedly, not that kind of magic. Lucky for you, I'm taking big risks, breaking the Magician's Code and revealing the secret behind the trick: Pulse Width Modulation.

Pulse Width Modulation (PWM)

To get a good understanding of what the heck this bad girl is, let's sprint down history lane and attempt to reproduce our results analog style. Before the wonderful invention of PWM, most electrical signalswere handled continuously by analyzing voltage over time.

analog signal
via GIPHY

As you might imagine, this can lead to huge wastes in energy while constantly having to check for changes to the output voltage. Most electronic applications will likely not need this continuous stream of signal, and to take advantage of this, the GPIO pins on the Raspberry Pi rely on digital signals. Instead of treating the signal as a continuous stream, digital signals stream a sequence of discrete values.

digital signal
via GIPHY

Ok, so where the hell does Pulse Width Modulation come in!? PWM takes advantage of these digital signals by rapidly turning the voltage off and then turning them on again to a slightly higher or lower voltage. In our example, this choppy signal will simulate a smooth increase in voltage (LED getting brighter) or decrease in voltage (LED getting dimmer).

The Great Breathing Ruby LED
Credit: https://www.instructables.com/id/Fade-LED-Arduino-Analog-Output-Tinkercad/

PWM with Ruby!

Ok, enough with the circuits already, and on to the fun part: Ruby! Luckily for us, the rpi_gpio gem comes with PWM built-in. With a little elbow grease we can start the mesmerization process.

#!/usr/bin/env ruby
require "rpi_gpio"
# Set #18 as LED pin
LED_PIN = 18
puts "========================================"
puts "| Breath LED |"
puts "| ------------------------------ |"
puts "| LED connect to GPIO1 |"
puts "| |"
puts "| Make LED breath |"
puts "| |"
puts "| SunFounder|"
puts "========================================\n"
puts "Program is running..."
puts "Please press Ctrl+C to end the program..."
puts "Press Enter to begin\n"
raw_input = STDIN.gets
# Make all output on the same line
STDOUT.sync = true
# Set the GPIO modes to BCM Numbering
RPi::GPIO.set_numbering :bcm
# Set LED_PIN's mode to output, and initial level to low (0v)
RPi::GPIO.setup LED_PIN, as: :output, initialize: :low
# Set @pulsed_led as pwm output and frequece to 1KHz
@pulsed_led = RPi::GPIO::PWM.new(LED_PIN, 1000)
# Set @pulsed_led begin with value 0
@pulsed_led.start 0.0
# Set increase/decrease step
step = 2
# Set delay time.
delay = 0.05
at_exit do
# Stop @pulsed_led
@pulsed_led.stop
# Turn off LED
RPi::GPIO.set_high LED_PIN
# Release resource
RPi::GPIO.clean_up
STDOUT.write "\r"
end
begin
loop do
# Increase duty cycle from 0 to 100
(0..100).step(step).each do |dc|
# Change duty cycle to dc
@pulsed_led.duty_cycle = dc
STDOUT.write "\r++ Duty cycle: #{dc}"
sleep delay
end
STDOUT.write "\r PAUSE "
sleep 1
# decrease duty cycle from 100 to 0
(-100..0).step(step).each do |dc|
# Change duty cycle to dc
@pulsed_led.duty_cycle = dc.abs
STDOUT.write "\r-- Duty cycle: #{dc.abs} "
sleep delay
end
end
rescue Interrupt, SignalException
exit
end

Wrap Up

We're really starting to dive into the embedded systems waters here. PWM is a great way to finely control things we want to... modulate. I'm out of ideas for alternatives on this one, but next time we'll take LEDs to new colored dimensions and I'll invent the simplest of games :-)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series