How to Make Colors With Ruby and Bitwise Operations
Tags: raspberrypi, ruby, tutorial
Published: 2019-10-12 10:33:10

---
title: How to Make Colors With Ruby and Bitwise Operations
published: true
date: 2019-10-11 21:05:00 UTC
tags: RaspberryPi, ruby, tutorial
canonical_url: https://blog.codenamev.com/a-simple-ruby-guessing-game/
series: Sunfounder Superkit
---

 ![How to Make Colors With Ruby and Bitwise Operations](https://blog.codenamev.com/content/images/2019/10/raspberry-pi-color-guess-web.jpg)

In our last lesson, we utilized the badass (P)ulse (W)idth (M)odulation tech to breathe life into a simple LED.  Here, we're going to take this to new levels and apply it to _multiple channels_.

Unfortunately, the PWM hardware included with the Raspberry B+ is only capable of communicating over a _single channel_.  Since we have 3 channels we need to talk to (for each of our three colors), we'll have to go soft and crank this up with software: **softPwm**.

### First: How the RGB LED works

The RGB LED I'm working with has four pins.  Three of these pins take input that control the brightness level for (R)ed, (G)reen, and (B)lue.  This allows us to take advantage of the [additive color system](https://en.wikipedia.org/wiki/Additive_color) to create all kinds of colors by supplying different proportions of these three types of light (e.g. fully bright red and fully bright blue will appear purple).

Our Problem: How can we easily store color values in RGB format as a percentage of luminance?

### Hexadecimal To The Rescue!

I know what you're thinking:

![How to Make Colors With Ruby and Bitwise Operations](https://blog.codenamev.com/content/images/2019/10/eye-roll.gif)

Don't lose me just yet.  There's some hidden gold here!  The magic of bitwise operations.

The binary `11111111` is equal to `255`.  Luckily for us, this binary representation maps perfectly to Hexadecimal, as `FF == 255`!

`11111111 00000000 00000000`

   RED        GREEN      BLUE

What this means is that we can use [Hexadecimal literals in Ruby](https://docs.ruby-lang.org/en/2.6.0/syntax/literals_rdoc.html#label-Numbers), and as a result start to see some serious gains.  First off, Hexadecimal numbers make a lot of sense to us as colors already.  These are the Ruby equivalent of the CSS versions you might be familiar with:

| Color | Hexadecimal Representation in Ruby |
| --- | --- |
| Red | `0xFF0000` |
| Green | `0x00FF00` |
| Blue | `0x0000FF` |
| Purple | `0xFF00FF` |

The real value here comes with the calculations we can make.  Using hexadecimal literals makes some things easier.  We can extract each red, green, or blue value from any given hexadecimal color by AND'ing the bits of the maxed out version of our target.

Let's say we have the color `0xFF1133` .  This has a binary form of:

`11111111 00010001 00110011`

We can extract the value of just the blue color `0x0000FF` by using the bitwise AND (`&`) operator to cancel out all non-blue bits.  So:

`0xFF1133 & 0x0000FF == 0x000033`

This is because all the `0` bits in our pure blue color `0x0000FF` override any bits set in any of the other color positions, and any `0` bits in our `0xFF0033` color override any `1` bits in our pure blue.

```
  11111111 00010001 00110011
& 00000000 00000000 11111111
               ⇣
  00000000 00000000 00110011
```

This works great for our blue value, but for the others we have to take this one step further.  If we were to perform this same bitwise AND on the pure green color `0x00FF00` then we will get what we want, except with a lot of trailing zeros.

```
  11111111 00010001 00110011
& 00000000 11111111 00000000
               ⇣
  00000000 00010001 00000000
```

In order to target that middle section of the resulting bitwise operation, we need to shift the bits to the right to get rid of the extra zeros.  To do this, we can use the bitwise right shift operator `>>` and push them eight places to the right.

```
00000000 00010001 00000000 >> 8
             ⇣
00000000 00000000 00010001
```

**Bingo! Unity.**  With this in mind, we can translate it to Ruby and apply these lightning fast calculations to extract percentages of each RGB color value from a hexadecimal numeric:

```
# Given the folowing color
color = 0x6495ED
percentage_blue = (color & 0x0000FF) * 100 / 255 # => 92%
percentage_green = ((color & 0x00FF00) >> 8) * 100 / 255 # => 58%
percentage_red = ((color & 0xFF0000) >> 16) * 100 / 255 # => 39%
```

### All Together Now

Since the duty cycle value is essential the percentage that the signal will be ON, we can just extract the RGB color percentages from a hexadecimal color value and set these to the duty cycle of each RGB pin of the LED.

Ok, ok, all this binary mumbo jumbo and all we get is a bunch of flashing colors!?  Let's turn the dial all the way up to eleven and add a simple twist: _have a button trigger a random color_.

BOOM!  We have made a game!  Guess what color the LED will be when you press the button?

![How to Make Colors With Ruby and Bitwise Operations](https://blog.codenamev.com/content/images/2019/10/raspberry-pi-color-guess-vid.gif)

{% gist https://gist.github.com/codenamev/33248181037adfee938edf5ecd4f756e %}

* * *

Special thank you to [Calle Erlandsson's fantastic write-up on bitwise operations in Ruby](https://www.calleerlandsson.com/rubys-bitwise-operators/).