PIX-6T4 Kits ready for launch!
Exciting news! We’re just about ready to launch our PIX-6T4 kits and here’s what they look like assembled
Exciting news! We’re just about ready to launch our PIX-6T4 kits and here’s what they look like assembled
With the growing amount of information that we have to share with the community about the Netduino-powered PIX-6T4 Game Console / DevBoard, keeping it all in blog-format has been increasingly challenging. So, we have created a dedicated site @ http://www.pix6t4.net, where you can find it all easily. To start with, we’ve added schematics, part lists and in-depth tutorials on working with the Netduino Mini. We hope that you enjoy the site and have fun building and learning with your own console.
Cheers,
-Fabien & Bertrand.
I have been waiting for an excuse to use a Nyan Cat in a blog post and the ‘ST7565 Negative LCD Display’ released by Adafruit being equipped with RGB LED backlights was the perfect occasion. After all, RGB LEDs can create a ‘rainbow’, right? All that’s needed is a cat to go with it and Voila!
Since Nyan Cat needed some friends, Hello Kitty and a Space Invader joined in. Eventually, Darth Vader was called in to scare the Nyan Cat away. But I digress…
The breakout board supporting the LCD display won’t accommodate a standard 0.1″ header unfortunately, so I had to build my own adapter to use it on a breadboard. No big deal but it’s time consuming.
No, really, this is not a squid.
The back of the connector.
The ST7565 is hooked up to the Netduino, ready for development.
The length of the wires that I used for this test were a bit long and limited the communication on the SPI bus to 22 MHz. With shorter connections, this display is capable of supporting much higher speeds, even though the LCD refresh rate can’t keep up at such high speeds and creates ghosting effects between frames.
Here’s the pin mapping I chose from the LCD connector to the Netduino:
Using the Netduino’s PWM pins is not a requirement: the B-, G- and R- LCD pins can just be connected to the Netduino’s GND pin instead, which results in a bright white backlight.
As always, reading the datasheet for the LCD module is a must before starting on the driver details which is part of the netduino helpers library as usual.
According to the datasheet, the Display Memory Map is divided into 8 pages of 128 bytes each, laid out like this:
There are 2 implications of this memory organization on the Netduino:
As it turned out, the display frames still get refreshed quickly.
In practice, the Display Memory Map pages are not organized as the datasheet describes. Instead, this is how the pages are actually organized:
In order to manage the RGB backlight easily, a new RGBLed class was also added to the netduino helpers library. It can be configured to work with RGB LEDs that have a common anode or common cathode configuration as indicated in the constructor of the RGBLed class. To use it, simply call SetColor() with a hex RGB value and an optional delay expressed in milliseconds before the function returns. The class also defines 12 handy common color constants, which is particularly useful in ‘Nyan Cat Animation’ scenarios 😉
The Adafruit ST7565 is a beautiful, crisp, graphic display with pixels large enough to be seen without a magnifying glass (I’m looking at you, SSD1306…) and small enough to display images or multiple lines of text. The built-in RGB LED backlight makes for an effective method of communicating application status conditions at a glance and from a good distance, without having to read text. The screen appears to be made out of thin glass and is fragile, so be sure to handle the display with care: I inadvertently put a small dent in mine while soldering the connector and did not notice it until I turned the display on. My only wish is for the breakout board to support the common 0.1″ header pitch. Finally, because it only takes ~1.1KB to manage the display buffer, it is very usable for Netduino Plus applications without jumping through hoops.
So, you’ve decided to build your own PIX-6T4 game console and you’re excited about learning C#?
Awesome! Buckle up, you’re in for a wild ride 🙂
The first step of your journey starts with gathering a few parts, which you can find listed in this spreadsheet along with their current retail price and links to the suppliers. In a nutshell, you’ll need about $95 to get all the required parts.
In an effort to keep the number of suppliers down to a minimum for your convenience, most of the parts for the PIX-6T4 prototype come from Sparkfun Electronics.
However, there are many alternative suppliers out there and with some research in Octopart, you will be able to reduce the cost of building this prototype.
Next time, we’ll cover the first step of the build, laying out the IC sockets, the analog joysticks, and some headers on the prototyping board, just like this:
Cheers,
-Fabien.
Earlier this month, AdaFruit released a nice little TTL camera, perfect for security and remote monitoring applications. The camera supports three resolutions (640×480, 320×240 and 160×120), has a built-in motion detection circuit and can output an NTSC signal, all in a fairly compact form factor. The communication with the camera is done over a TTL UART @ up to 115200 bauds. In many respects, this device is very similar to the LinkSprite camera, which has been out there for some time now.
As I’m working on a security-related project involving the Netduino, it was the perfect opportunity to put this camera to the test, starting with writing a C# driver. While interfacing with the camera over the TTL UART of the Netduino is straight forward, the datasheet describing the protocol and commands required to control the camera functions is painfully sketchy and sometime inaccurate. In some instances, some camera functions such as OSD (text overlay) are not supported in the firmware even though the datasheet documents them or only behave properly if called in a particular sequence, which of course, is not documented…
Limor’s tutorial on how to interface the camera with the Arduino outlines the required steps rather well, so I won’t re-iterate them here. The only difference worth mentioning is that the voltage divider configuration shown in the adafruit tutorial is not necessary on the Netduino, since its GPIO pins are 5 volt tolerant. So, you can simply connect the TX pin of the camera to PIN 0 (RX) on the Netduino and the RX pin of the camera to PIN 1 (TX) on the Netduino. To make things a bit easier while testing the camera with a breadboard, I built a connector using a standard 0.1″ pitch right-angle header and a small section of prototyping board: unfortunately, the breakout board of the camera uses a different pitch. In addition, you’ll want to connect an SD card reader to your Netduino so that you can store snapshots. Please refer to my earlier post on how to connect an SD card reader to the Netduino if you aren’t familiar with the procedure. If you’re using a Netduino Plus, don’t worry about that part 🙂
The Netduino driver currently implements 4 major functions.
To put the camera to the test, I wrote a sample taking a set of 100 pictures using each of the resolutions supported by the camera. The sample also tests motion detection and the camera’s composite output. During the test, the camera was set outside on a tripod, pointed at a neighbor’s house about 200 feet away around 8PM on August 11th. The goal of the test was to gauge the overall video quality of the camera in lower light conditions as well as evaluating the error-rate when taking snapshots.
The composite video quality, shown here on a small CRT TV, is generally quite good and stable.
The snapshots, on the other hand, often show compression artifacts like this:
Out of 100 pictures taken at the higher resolution, only one did not have any artifacts. Please note that I did not tweak the color saturation of the camera before using it: colors can be greatly improved with some tuning with the tool coming with the camera. Limor covers this in her tutorial as well but I’ll post updated snapshots with tuned color saturation when I get the chance.
In the large and medium resolutions, 1 picture out of 100 is generally corrupt and cannot be viewed. There could be several root causes for these artifacts and data corruptions:
Over the past few months, my friend Bertrand and I have been working on a game console, the PIX-6T4, which is powered by a Netduino mini.
The console is designed as platform for learning digital electronics and C#: we’re in the process of writing a book covering all aspects of building the console, how its components work and how to write games for it with our framework.
Here’s a video of the prototype of the console below:
and here, as we presented it during the Ask An Engineer Show-And-Tell run by AdaFruit on Google+ last weekend: http://vimeo.com/26943990
As always, it’s entirely open source / open hardware and we hope that you’ll have as much fun building your own and making games as we did, which we will cover in a series of upcoming posts, often referring to past articles on this blog.
Cheers,
-Fabien.
Make Blog: http://blog.makezine.com/archive/2011/07/build-a-netduino-powered-game-console.html
MSDN Blog: http://blogs.msdn.com/b/netmfteam/archive/2011/08/10/netmf-student-and-hobbyist-projects.aspx
Recently, my friend Bertrand wrote an interesting article about how he came to realize that we have become a “Society of Many Tribes”. Go ahead and read the article. It will be worth your time The core concept of the article centers around “Thinking locally first and sharing your ideas with your tribes will eventually result in your impact becoming global”. This is a fascinating idea, begging to be experimented with. But how can one actually measure the breadth, depth and impact of one’s ideas as they travel and evolve through social networks?
Curiously, it turns out that the Klout team has come up with a set of metrics to do just that. If you have a Twitter, Facebook or LinkedIn account, you should try to link them to Klout to understand how this works: in a nutshell, Klout applies a set of algorithms, similar to Google’s page ranking algorithm, to your interactions and relationships within social networks and comes up with a synthetic score on a scale of 1 to 100, representing your overall influence a.k.a your “Klout Score”. A “Klout Score” is itself broken down into multiple data points, described in details here.
Klout’s metrics are interesting from a self-development standpoint because they can be used as a feedback loop: with them, you can evaluate within days or hours the effect of your communications, measuring what works vs. what doesn’t and learn to focus a message in the areas where it will resonate with a target audience. This is a valuable tool for individual bloggers and businesses alike.
Klout exposes a web service enabling developers to build mash-up applications around its metrics and all that is required to play is an API key which is easily obtained when registering an application. My application is the “Klout Klock” device and before getting into the details of building it, you can see it how it works in this video:
The clock is built using a Netduino Plus and an AdaFruit ST7735 TFT screen. I have described how to connect them together in a previous post here. In that post, I had indicated that managing such a TFT screen from a Netduino was sub-optimal due to the memory requirements involved. That statement is even more true with a Netduino Plus which has roughly 28KB of RAM available for an application. This means that allocating a 40KB buffer to manage the TFT display as I was doing it previously is out of the question. Also, this time I am using the Netduino Plus’ SD card reader instead of the one built into the AdaFruit ST7735 breakout board. In addition, the screen’s back light is hooked up to a PWN pin to achieve the fade-in / fade-out effect based on the iCuffLink breathing effect 🙂
So, what do you do when you need to fit 10 lbs of crap in a 5 lbs bag? You use a virtual bag, of course! 🙂
The Netduino Plus, in addition to its Ethernet connector, features a handy micro SD card reader for storage which I turned into virtual memory to get around the RAM constraints.
The virtual memory concept is straight forward: instead of reading and writing to/from a RAM buffer matching the size of the AdaFruit TFT display, all reading and writing operations happen against a file whose size matches the size of the display. In this case, that file is exactly 40960 bytes, the size required to hold a 128*160*16 bit/pixel image.
To actually refresh the screen with the image contained in virtual memory, the physical display is updated in ‘segments’, reading the data for each segment into a small RAM buffer, then blasting its content over SPI to the display. For each segment update, a display address window is positioned to cover the proper range of pixels.
The trade-off here is speed since file I/Os are orders of magnitude slower than operations in RAM but speed is not the main concern in this scenario. In addition, the more memory segments are used to chop up a virtual memory block, the slower it gets.
The following diagram shows how the process of updating the display from segmented virtual memory works:
I have added two classes to the Netduino Helpers library, respectively called “VirtualMemory.cs” and “VirtualFrame.cs” which make this process simple. I also refactored the driver that I had previously written for the AdaFruit ST7735 to make use of virtual memory if desired:
In this snippet, a virtual frame the size of the display is created and divided into 16 segments, ensuring that the I/O buffer used to read the image will only require 2560 bytes. The number of segments should be determined by a balance between performance and the overall memory constraints for the rest of the application. The reference to the newly minted VirtualFrame object is then passed to the instance of the display driver. Everything else about the driver works exactly as it did previously when actual RAM was being used.
This class is the workhorse driving the display and it’s worth explaining its core functions:
In many ways, the “Klout Klock” application really pushes the envelope of what is possible on a Netduino Plus. To put things into perspective, here are the application requirements that needed to fit in 28KB of RAM:
* NTP Server list: http://tf.nist.gov/tf-cgi/servers.cgi string:name=ntpServers;value=nist1-lv.ustiming.org,nist1.aol-ca.symmetricom.com,nist1.symmetricom.com,nist1-sj.ustiming.org,nist1-la.ustiming.org,utcnist.colorado.edu,utcnist2.colorado.edu,ntp-nist.ldsbc.edu * string:name=user;value=<KLOUT user name> string:name=key;value=<KLOUT API Key> string:name=host;value=api.klout.com string:name=port;value=80 string:name=timeZone;value=-8 string:name=dst;value=1
In a previous post, I described how to drive an LED matrix relying on persistence of vision. While beautifully minimalist, this method has drawbacks: it requires 11 digital pins on the netduino and takes constant CPU cycles to refresh the matrix. This can potentially put tough resource constraints on the rest of the application.
This is where a chip like the MAX7219/MAX7221 LED display driver comes in handy: all you need to do is to send it the data that you want to display over SPI and it will drive LEDs without further involvement from the micro controller.
The chip offers 2 display modes: ‘Decode Mode’ is intended to manage 7 segment displays (plus a dot) and another which displays raw bitmaps instead, perfect for controlling an 8×8 LED matrix.
Multiple MAX72xx chips can be daisy-chained together to form larger displays as well.
Being a popular chip, a great deal has been written about the Max7219 and after you familiarize yourself with the datasheet, you should check out this article on the Arduino Playground and come back here when you’re done.
Connecting the MAX72xx to the netduino
Here are the hardware components that you’ll need:
Note: The MAX72xx requires 3.5 volt logic levels minimum and because the netduino uses 3.3 volt logic level on its digital output pins, you may need to place a logic-level shifter between the netduino SPI interface and the Max72xx SPI interface. Check out this article if you’re not sure how this works.
While the Max72xx SPI clock can go up to 10 MHz based, I was unable to get stable communications above 2 MHz when using the MAX7219 with a logic-level shifter. Without the shifter, SPI @ 10 MHz works flawlessly but because this is out of the chip’s specifications, so your mileage may vary.
The following summarizes the connections. It doesn’t matter which pins you choose on the logic-level shifter provided that they’re matching low-level input/high-level output pins.
Note: the MAX72xx is extremely sensitive to EMI and power fluctuations. So, be sure to:
If EMI is an issue, reducing the speed for the SPI bus and/or using shorter hookup wires may help. If you still have EMI issues, the MAX7221 is likely the right alternative.
Connecting the Max72xx to the LED matrix
The LED matrix that I’m using is wired like this:
Connecting it to the MAX72xx is straight forward:
Using the netduino.helpers Max72xx C# driver
The C# driver attempts to stick to the Max72xx datasheet as closely as possible. It presents properties matching the various registers of the chip and a simple overloaded ‘Display’ method. Be sure to check out the unit tests in the /Samples for usage details.
Action shot
Happy hacking!
-Fabien.
Our home is equipped with a relatively old gas heater, built in 1996. It still works great, has been serviced regularly since it was installed and there is no good reason to replace it yet. However, it isn’t as energy efficient as more recent models.
The other aspect of this gas water heater is that it keeps the water hot 24/7, 365 days a year whether we need it or not. In my home, we generally only need hot water in the morning between 7 and 9 AM and in the evening, from 5 to 9 PM. On weekends, our schedule is a bit whacky and we need hot water from 8 AM to 9PM.
So, 30 hours for week days + 26 hours for weekends, that’s 56 hours / week where hot water is actually needed, as opposed to 168 hours / week when the heater is just left alone. In order words, in our house, we only really need a third of the water heater energy that we normally consume.
To make matters worse, the water heater was installed in the garage by the builder and it gets pretty cold during the winter time.
Considering that ~25% of our heating bill goes into heating water, I felt compelled to stop this senseless waste.
The idea that I came up with was to design a scheduler, configured to follow our weekly hot water usage pattern and capable of lowering the water heater temperature down to a minimum during off-hours.
I wanted it to be cheap to build with easy-to-find parts and very reliable as my wife does not appreciate cold showers: I decided to use a netduino-mini micro-controller, an AdaFruit DS1307 real-time clock and a servo to adjust the temperature of the water heater.
Here’s what the end result looks like in action:
Startup Sequence
Manual Override
The slow moving speed of the servo is intentional in the application in order to minimize wear and tear on the servo’s gears and the overall assembly.
The configuration of the clock and the schedule is done over a serial interface. Here’s a sample output:
[02/19/2011 19:29:40]
Water Heater Controller v1.0
[02/19/2011 19:29:40] Initializing...
[02/19/2011 19:29:40] Loading schedule
[02/19/2011 19:29:40] Centering servo
[02/19/2011 19:29:41] Setting heater on high heat by default
[02/19/2011 19:29:51] Running...
-------------------------------------------------------------
Time: Saturday, 19 February 2011 19:29:51
Heater Schedule Today: Sat [8-21] [0-0] [0-0] [0-0]
Heater Status: ON [scheduled]
Main Menu:
1 : Show Schedule
2 : Set Schedule
3 : Set Clock
4 : Swith Heater ON / Resume Schedule
X : Shutdown
[02/19/2011 19:29:52] Heater state change
[02/19/2011 19:29:52] Setting heater on high
1
-------------------------------------------------------------
Heater Weekly Schedule:
Sun [8-21] [0-0] [0-0] [0-0]
Mon [6-9] [17-21] [0-0] [0-0]
Tue [6-9] [17-21] [0-0] [0-0]
Wed [6-9] [17-21] [0-0] [0-0]
Thu [6-9] [17-21] [0-0] [0-0]
Fri [6-9] [17-21] [0-0] [0-0]
Sat [8-21] [0-0] [0-0] [0-0]
You can find the C# code for this project at http://netduinohelpers.codeplex.com.
Look for the “/Samples/WaterHeaterController (netduino)” folder.
The rest of this post documents the implementation details of the system you should be inclined to build your own.
Actuating the water temperature knob
Our gas water heater is equipped with a thermostat control like this one The knob has a large dial, with a fairly flat hand-grip surface.
I needed to figure out how much torque was required to turn the dial in order to buy an appropriate servo. The method I used was simple: mount a lever on the knob, attach a light container to the lever, pour water into the container until the knob turns, measure the amount of water poured and derive the appromixate amount of torque based on the length of the lever and the amount of water.
Using various Internet resources to calculate torque, I determined that I needed an absolute minimum of 12 oz-inch of torque to get the knob to turn. To be on the safe side, I selected a servo with nearly 6 times as much torque and purchased a HiTech HS-6635HB servo for about $30.
Why de-rate the servo requirements so much? A few reasons:
Mounting the servo on the water heater
I chose to anchor the servo to the gas pipe of the water heater, using the section of the pipe to the left of the gas valve. To do so, I cut a piece of wood from left-over hardwood flooring material to fit the lower left area of the pipe. I drilled holes on the top and left sides of the board so that it could be secured to the gas pipe using zip ties. I also drilled 4 holes to secure the servo to the board with long thin screws and locking nuts.
Connecting the servo to the control knob
The parts for this phase are easy to come by at hardware stores and craft stores:
Parts:
Instructions:
The final assembly should feel tight and strong while turning the knob.
To secure the other popsicle stick to the arm of the servo, drill a few holes into the stick, matching the holes in the servo’s arm. Then weave the thin metal wire through the holes, then wrap the metal wire tightly around the stick and the servo’s arm. The final assembly should also be tight and strong while turning the servo’s arm.
Connect the popsicle sticks together with the brass rod and secure it by bending it carefully around the ends of the sticks. It’s easier to do this while the servo’s arm is not attached to the servo.
Finally, re-attach the arm to the servo and test the assembly by moving the servo’s arm slowly.
The knob should turn in sync with the servo with ease.
Building the Water Heater Controller board
This controller board is built around a netduino-mini, a DS1307 real-time clock by AdaFruit Industries and a few other components:
Simple Wiring diagram
To further increase the life of the servo, I decided to control the power supply to the servo through a 2N2222A transistor. It works well because the servo doesn’t need to hold the water heater knob into place all the time: once positioned, the knob stays where it is and the servo no longer needs power to maintain its position.
The base of the transistor is connected to the ‘Servo Power Enable’ (pin 16 of the netduino mini) through a 300 Ohm resistor in series with a 1N4001 rectifier diode. The diode is there to eliminate 0.7 volts present on the pin even when it is turned off.
Here’s the thread on the netduino forums discussing the 0.7 volts issue which seems specific to the netduino mini.
To be on the safe side, I also added a 1N4001 rectifier diode on pin 23 (power ground) of the netduino mini to prevent any potential damage to the micro-controller if the power were connected backwards. I did not see such protection on the schematics of the mini.
Building the board:
The final board:
Operation
Connect a dumb-terminal to COM2 on the netduino mini (or to COM1 on the regular netduino).
Using the serial interface:
Set the clock’s date and time and define a schedule when the heater should turn ON.
The schedule tracks 7 days, with 4 timeslots for each day. Each timeslot has a begin time defining when the heater should turn itself ON and an end time, defining when the heater should turn itself OFF.
Setting a timeslot to 0 resets the timeslot and the heater stays OFF.
Keep in mind that the heater timeslots and the clock expect to work on a 24 hour schedule.
Heater Weekly Schedule:
Sun [8-21] [0-0] [0-0] [0-0]
Mon [6-9] [17-21] [0-0] [0-0]
Tue [6-9] [17-21] [0-0] [0-0]
Wed [6-9] [17-21] [0-0] [0-0]
Thu [6-9] [17-21] [0-0] [0-0]
Fri [6-9] [17-21] [0-0] [0-0]
Sat [8-21] [0-0] [0-0] [0-0]
The schedule data takes 56 bytes, which happens to fit perfectly into the 56 bytes of battery-backed user-memory in the DS1307 clock. Funny how this worked out 😉
The push button (High heat override) on the board forces the water heater into high heat, overriding the pre-defined schedule settings.
Meaning of the LEDs
Starting the water heater controller the first time
Before you apply power to the board, make sure that the arm of the servo is centered (vertical position). This will ensure that the startup sequence is smooth. From there, the controller will slowly set the water heater knob on high heat before tracking to the schedule.
I’ve been running the controller on the gas water heater for a few weeks now and I’m anxious to see what our next water heating bill will look like 🙂
Happy Hacking!
PS: a number of readers have mentioned the potential risk of Legionellae bacteria development in the water. While this bacteria is more of a concern with cooling systems, to be on the safe side make sure that you tune the system so that the water temperature reaches at least ~130 degrees Fahrenheit when the system is ON.