Building Simon with Angular-IoT Part 2
One of the exciting things about Angular 2 is the push to make Angular code more than just the web. I thought it would be fun to explore the limits of this, and see if I could make the same control/logic code for both a web application and a physical, “Internet of Things (IoT)” device.
In Part 1, I talked about how you can use angular-iot to extend your Angular code beyond the web browser to hardware, and showed how to use this platform to code a “Simon” game using angular-iot. In part 2, we get to the fun part: building and deploying the physical game!
Hardware and Enclosure
In order to make the game feel really “real,” I thought it would be fun to make a big, off-the-shelf version of the game using big, colorful buttons, a speaker, a 7-segment display, and an enclosure built with a laser cutter and 3D printer. Here’s the full list of hardware:
- Raspberry PI 3 — older models can also work if you don’t need connectivity (or you can use an external USB WiFi stick).
- 4 Leds, 4 Buttons — Red, Green, Blue, Yellow.
We used big arcade game buttons from SparkFun, and 3D printed legs for the buttons with black PLA (here’s a link to the model file).
- Speaker — USB or 3.5mm jack speaker connected to the Raspberry Pi.
We used Jabra Speak 510, though any kind of USB or 3.5mm jack speaker will do well. Here’s a much cheaper alternative, or another.
- 7 Segment Display — We used a SparkFun 20mm 7-segment display, painted the edges black, and used an Arduino nano as controller.
Initially, we had a breadboard with wires going directly from Arduino pins into the 7-segment display, along with resistors for some of the pins. Now there is a PCB that makes it much easier. See below for details.
An easier way to do it would be to use a SparkFun 7-Segment Serial Display, which speaks I2C directly, though it offers a smaller display size.
- Enclosure — The top and bottom panels were laser cut from 3mm black gloss plexiglass, with 10 black-painted wooden craft sticks holding it together (diameter 12mm, height 58.8mm).
You can also 3d-print the dowels (model file here — dowel.stl).
The enclosure laser-cut (DXF) file is available here: https://github.com/urish/ng2-simon/tree/master/enclosure
The enclosure was designed by my talented sister Noa Shaked.
Hardware and Enclosure (Economy Version)
While we had a lot of fun designing and building the full-on game, I realize not everyone may want to sink so much time and money into the project. Here’s a version you can easily build using only off the shelf components (no soldering required!):
- Raspberry Pi 2 or 3 — as the controller (same as in the “Real” Simon game above). You can also use an Arduino, though how to do that is not covered here.
- LEDs — I used 10mm LEDs: Get a pack here or individually buy Red, Green, Yellow and Blue.
- Buttons — I used this pack (you get each color twice).
- Resistors — Any value between 100Ω and 400Ω will do. This pack would do the trick.
- Breadboard — Needed for assembly. Either a half-size or full-size will do.
- Jumper Wires — Connect everything, no soldering required. You will need at least 10 Female to Male wires to connect the LEDs and Buttons, and you can get a pack here. You will also need some Male-to-Male wires, you can get a pack here or buy a hook-up wire spool and cut it.
- Serial 7 Segment Display to display to game score, requires soldering 4 wires.
- Speaker — any USB or 3.5jack speaker will do, see above for some options.
I showed off a working “economy version” of ng2-simon during my angular-iot talk. You can check out the video here.
Connecting the Buttons to the Raspberry Pi
Here’s a diagram showing how to wire up the buttons and LEDs:
Connecting the 7-Segment Display
In addition to the above diagram, you can optionally connect the 7 Segment display to the I2C bus of the Raspberry PI. First, make sure that I2C is enabled in raspi-config. Then, connect the SDA and SCL pins of the 7 Segment display (these are pins A4, A5 on Arduino Nano) to pins 3 and 5 on the Raspberry Pi (they are also named GPIO-0 and GPIO-1). Also, install i2c-tools for command line access:
$ sudo apt-get install i2c-tools
You can run the following linux command on your Raspberry Pi terminal to make sure that the 7-Segment display is connected properly:
sudo i2cdetect -y 1
If everything is connected properly, you should see the number 71 appear in the output:
This number represents the address of the 7-Segment display in the I2C bus (0x71). You can use the following command to write values to your display:
sudo i2cset -y 1 0x71 1 2 3 4 i
This will write ‘1234’ on the display.
Connecting the Dome Push Buttons
You need to solder four pins:
- Button Positive — goes to Raspberry GPIO, according to diagram
- LED Positive — goes to Raspberry GPIO, according to diagram
- Button Negative — goes to GND, solder a black wire to follow convention
- LED Negative — same — goes to GND, solder a black wire
Note: Depending on your LEDs, the LED polarity could be different. You can either check it before soldering, or rotate the LED 180 degrees inside the button assembly if the polarity is wrong.
The buttons come with an internal resistor that works best for 12V system. For instance, in my yellow button, I measured 466Ω. While this will work, the LEDs will be faint. You can work around this by replacing the internal resistor with a 100Ω resistor. In my case, I also installed bigger, 10mm LEDs inside the buttons.
Deploying the Angular-IoT Code on the Raspberry Pi
Log into your raspberry pi and open a terminal (or connect via ssh), then install git, curl, sox and mpg123:
$ sudo apt-get update
$ sudo apt-get install git curl alsa-utils sox mpg123
(alsa-utils, sox and mpg123 are required for the sound output)
Install nvm as explained here, then log out and log-in again to complete the installation.
Install node.js 6.9.1 (or newer):
$ nvm install 6.9.1
$ nvm alias default 6.9.1
$ nvm use 6.9.1
Clone the project and build it:
$ git clone — depth 1 https://github.com/urish/ng2-simon
$ cd ng2-simon
$ npm install
$ npm run build:iot
Start the project:
$ sudo `which npm` run iot
The project must be run as root to gain access to the GPIO pins. This is a requirement of the wiringPi library. Thus the use of ‘sudo’ above.
Note: The — depth 1 option to git clone speeds up the cloning process, by skipping all the commit history and cloning just the latest revision.
Configuring Audio Output
You can test the audio output by running the following command:
$ play -n -c1 synth 5 sin 500
It should play a steady, 500hz beep tone. If you get no sound output, try running this command to force the audio throught the 3.5mm jack:
$ amixer cset numid=3 0
You can also run the command line mixer and make sure that sound is not muted:
Use the arrow keys (keyboard) to affect the sound output level.
Configuring USB Audio (Optional)
By default, the sound will come out of the raspberry’s 3.5mm audio jack (or HDMI port when connected to a display). If you want to connect a USB audio device, you can override the default sound device by copying this file over /etc/asound.conf and then rebooting your Raspberry Pi:
$ sudo cp raspi/asound.conf /etc/asound.conf
Assembling the 20mm 7-Segment Display
The 20mm 7-Segment display is controlled by an Arduino Nano, which runs a modified version of Sparkfun’s Serial 7 Segment Display Firmware. The Arduino Nano board is connected to the Raspberry Pi through the I2C bus, as outlined above.
We created a small PCB that helps to put everything together. You can get it printed at Oshpark.com for 13.40$ (3 pieces, including shipping).
Alternatively, you can simply run wires between the Arduino Nano and the 20mm 7-Segment display. Pin mappings are as follows:
You can find the modified firmware for the Arduino Nano on my github:
Putting it All Together
Then, after it’s all put together, it’s time to play!
Working on angular-iot and ng2-simon was real fun. It gave me the opportunity to connect my two passions: Web Development and “Making”. I hope that this will inspire the web developer community to explore new ideas and to further experiment with building physical interfaces and games.
Where else can we take it? What else can we build with angular?
Please write a comment below with your ideas :-)