Music by RepRap

Seems, I’ve been a bit lax in keeping my blog up to date on my adventures of the last year. And what a year it’s been.

Much of my recent tinkering has revolved around a deep dive into 3D printing. Searching for a cheap 3D printer a few months back, I stumbled upon a lot of 13 Makerbot Replicator+ printers on Ebay. They were in various states of disrepair and I thought I’d get one or two pieced together while learning about their ins and outs in the process. As luck would have it, I was able to get all but one back into perfect working condition.

Ultibots D300VS+

While there were some things I really liked about the Makerbots, the closed source hardware and proprietary software really limited any upgrades and experimentation. So back on Ebay they went. With the profit burning a hole in my pocket I honed in on my next choice; the Ultibots D300VS Plus. First off, Deltabots just look cooler; much more like a robot than a kitchen appliance. Second, the kit was a proper challenge — wiring, soldering, crimping —  involving a measure of skill and frustration, but with that, a sense of pride on completion. It’s definitely not a kit for the plug and play novice.

I’m in the honeymoon phase right now. With the first test print out of the way, it’s on to calibration, tuning, and customization. A few of the things I miss about my Makerbots were the remote monitoring (phone app and camera) and end-of-filament sensor. These were very practical features that I used all the time. Oddly enough, I also found myself missing the little chimes it played at the start and end of prints. The absence of which was made more evident by how silent (and fast) the Ultibots is. Sitting in the next room, I wasn’t sure when a print had finished. While the hardware upgrades might take some time, I thought to tackle the sound via software.

The D300VS+ runs on the Duet Wifi Controller and uses the open source RepRap firmware. That means you can use gcode command M300 to play tones (example M300 S300 P1000). However, a simple tone didn’t really do it for me. The Makerbot used to play a satisfying little ‘TaDa’ song using a custom gcode (M72) which isn’t supported by my model. I found a nice post on 3D systems that describes how to transform simple tones into complex tunes and a bunch of samples. This online tool can play these samples before loading the gcode into your printers settings file.

After sorting through a bunch of junk from 2-pac to ZZtop, I finally settled on the truncated version of the Superman theme below.

M300 S1174 P150
M300 S1174 P150
M300 S1174 P150
M300 S1567 P225
M300 S0 P75
M300 S1567 P150
M300 S2349 P600
M300 S0 P150
M300 S2349 P150
M300 S2637 P150
M300 S2349 P150
M300 S2093 P150
M300 S2349 P1200
M300 S0 P150


Setting up Retropie on a Raspberry Pi 3

Loser pays, Winner stays

During weekends when I was a kid, I used to grab a bag of quarters, hop on the subway, and head to Times Square for the day. In those days, arcades weren’t like Dave and Busters filled with families. This was the seedy Koch/Dinkins era of Time-Square. It was awesome.

If I was having a good day, I could spend a few hours on Galaga or Pac-Man until my quarters ran out. I always spent my last dollar on Dragon’s Lair; I was such a sucker for those animated laser-disc graphics, but I never once made it past the first cut scene.

Playing Pac-Man at an arcade in Times Square, 1982. (Yvonne Hemsey/Getty Images)

After I got a Nintendo (NES) for Christmas, my energy went into marathon sessions of Mario Bros. and Double Dragon in the comfort of our cold basement.

Maybe it’s natural then that I associate those old video games with struggle, danger, and even little a whiff of the forbidden. Over the past few weeks,  I’ve been deciphering MAME versions, hacking at roms, and downloading files from legally-questionable sites, but when that Double Dragon theme starting playing I was all smiles.

Getting Started

First off you need the minimum hardware; Raspberry Pi 3 Model B, power adapter, MicroSD (at least 32GB), HDMI cable, and a controller. I didn’t like most of the RetroPie kits that I saw because most were made up of cheap components (microSD, power, controllers etc.). So, I sourced everything individually.

The Raspberry Pi Model 3 B is 1/8th the size of my NES.

You’re going to be writing and reading a lot from the MicroSD so don’t skimp. The Samsung 32GB MicroSD was recommended by a few forums. I may even go back and get a 64GB. Atari games are only a few kilobytes but Playstation ISO’s really add up.


A lot of people recommended the Buffalo Classic USB Gamepad as a low cost, yet quality retro controller. I didn’t get one for two reasons; I heard they take weeks to ship and I also wanted a all-around generalist controller more suited to all the platforms the Retropie can emulate. So, I bought the Logitech F310 for only a few dollars more.

Buffalo Classic

Logitech F310

The Logitech was a great choice. Once I got through the initial configuration upon first booting the Retropie, I didn’t have to do anything else to get it to work on all the games/platforms. Though according to the RetroPie wiki, the RetroPad ABXY pattern is the opposite of the ABXY pattern on the controller (A=B). When I set mine up, I followed A=A, so maybe I’ll go back and fix that. Really it doesn’t matter because I just hit buttons till I figure out what does what in each game anyway. That lack of instruction feels more like retro gaming in my opinion.

EDIT: I liked the Logitech so much I ended up also getting its wireless brother the F710. Which was just as easy to setup.

Logitech F710


You’ll definitely want to overclock the CPU to run any N64 and Playstation games. Even some of the newer FBA/MAME arcade games probably benefit. Once you overclock, you have to address cooling. I bought heatsinks and a stuck them on the processors. I also got a fan-cooled case.

Heatsinks are a must have for long gaming sessions.


A metal case is great protection against the inevitable “rage quit”


Power is Important

Get a good power adapter for your PI. Ideally it should output 5+ volts and 2+ amps. Initially, I was running the PI off a 5V 600mA phone charger that I had laying around. The Pi turned on and everything seemingly worked, but only later did I realize that the Lightning Bolt icon I kept seeing flash in the corner wasn’t normal. My pi wasn’t getting enough juice. This is especially critical if you overclock your Pi.

Check the specs on your power adapter. This one does 5V 2.5A .

Don’t get a cable that has a switch in it. The worse way to shut down the PI is by cutting the power. That’s a sure way to corrupt the SD card. Use the shutdown command from the UI or terminal instead. (I’m actually researching a way to add a button to the case and scripting a shutdown command.)

Loading RetroPie

This part is straight forward. Follow the instructions on Retropie’s site for your OS. Essentially you download and unzip Retropie, and use an app (like Pi Baker for Macs) to load the image file onto the SD card.

Then all you do is put the MicroSD into the Pi, connect the HDMI cable, controller, and power and you’re done. Once it boots up, you’ll be prompted with to configure your controller. Press the buttons it asks for and you’re done. For now.

Getting Games to Work

In 1988, my dad brought home a new IBM PS2 and immediately my brother and I went to work setting it up. Finally, we pushed the power button and the screen lit up with a cursor that blinked. And blinked. And blinked. It slowly dawned on us that the computer wasn’t going to do anything. It sat there just prompting us, beckoning us, practically daring us to take the next step. The RetroPie reminded me of that.

The RetroPie doesn’t come loaded with any games. Nothing. Even the first screen that shows ’13 games’ under the Retropie logo is misleading. It means 13 options are available.

There are a few ways to transfer ROMs (games) to your Pi; USB, FTP, or SMB. Personally I find the USB option awkward and complicated. Also, I didn’t have a thumb drive large enough. I didn’t feel like installing an SFTP app, so I just used SMB shares.

Setting up WIFI on the Retropie allows for hands free (although slower) transfers. The only caveat is that you will need a usb keyboard to enter the password. If you have an Ethernet cable and can connect the Pi directly to your router/hub, this is a bit faster and doesn’t require a keboard. From my Mac, I opened Finder, selected Go >> Connect to Server.. and entered smb://retropie as the server address. Login as Guest. Select roms as the directory and now you can drag and drop files as you would with any other folder.

Legally, you should only have roms for games you own. Google roms related to the platform you want (ex Atari 2600) for examples. Some search results might mention ‘bundles’ or ‘reference sets’ and will save you downloading individual examples. Some examples may list the origin county in the filename – [U] United States, [E] Europe, [J] Japan – or some combination of such. Examples that have [!] are usually the best working option.

Use the RetroPie supported systems wiki as a guide. It will tell you what directory to put roms in and what file types are expected by that platform. For example, Sega Genesis roms go in /roms/megadrive and will have an extension of smd, bin, md, iso, or zip. Copy the file to the proper directory, reboot the Pi (from the UI quit menu), and then try loading the game. It’s that easy. Sometimes.

Troubleshooting games

I spent a lot of time in the Reddit RetroPie sub and other sites trying to figure out how to get MAME and FBA games working. There are lots of posts and videos on this topic. Despite that, it’s surprisingly tricky to figure out. It’s even a bit hit or miss when you do.

First follow these preparations for the specific platforms. Then we’ll cover troubleshooting individual games.

FBA, Arcade, and NeoGeo

Save yourself a ton of frustration and go find a file called Ideally, it should contain;

  • 000-lo.lo
  • asia-s3.rom
  • japan-j3.bin
  • sfix.sfix
  • sm1.sm1
  • sp-1v1_3db8c.bin
  • sp-45.sp1
  • sp-e.sp1
  • sp-j2.sp1
  • sp-s.sp1
  • sp-s2.sp1
  • sp-u2.sp1
  • sp1.jipan.1024
  • uni-bios_1_0.rom
  • uni-bios_1_1.rom
  • uni-bios_1_2.rom
  • uni-bios_1_2o.rom
  • uni-bios_1_3.rom
  • uni-bios_2_0.rom
  • uni-bios_2_1.rom
  • uni-bios_2_2.rom
  • uni-bios_2_3.rom
  • uni-bios_2_3o.rom
  • uni-bios_3_0.rom
  • uni-bios_3_1.rom
  • vs-bios.rom
  • uni-bios_3_2.rom

Copy that zip into each of the three corresponding roms folders. Then go toRetropie > Retropie Setup  optional packages and install the FBA2012 emulator.


Go back to Retropie > Retropie Setup  and install the optional package mame2010.

Playstation (PSX)

You need to google and download the bios files for the Playstation – SCPH1001.bin (USA), SCPH1000.bin (Japan), and SCPH7003.bin (Europe) – and drop these in the directory /RetroPie/bios/.

General Troubleshooting

File Type – Assuming you’ve dropped the correct Rom file in the correct directory, your game should just load when you start it from the UI. If it doesn’t load or you get glitches during gameplay, the first thing to check is the file type. Some platforms like the Atari7800 will take .zip files. Others need you to unzip the file contents. Check the RetroPie wiki for the expected file type. That will let you know if you need to unpackage the downloaded file before you transfer it over to the rasperry pi.

Try different Emulators – Next,  you can try a different emulator for that specific game. If a game doesn’t load and goes back to the selection ui, you have other options. As it loads, you’ll see a message to hit any button for options. Do that, and you’ll see the following menu.


In this example, the default emulator for Sega Genesis roms put in the /roms/megadrive/ directory will use the lr-picodrive emulator. If for some reason, that emulator didn’t work you could select option 2 and try setting lr-genesis-plus-gx or DGen for that specific game to see if they work better.

This works really well for troubleshooting MAME, Final Burn Alpha (FBAlpha), and N64 games. The retropie wiki provides a chart of which MAME versions work with what emulators, but it’s really hard to know what version of a rom you might have. Rotating through the possible emulators is a trial and error method that should work. Note that your emulator choices are limited by the directory you place the rom in. The Arcade folder allows you to select all of the MAME and FBalpha related emulators, whereas the MAME and FBAlpha directories only offer those emulators specific to that directory.

For other troubleshooting, try the Retropie offical FAQ and Reddit Retropie FAQ.

It’s on like Donkey Kong

I hope you enjoy recapturing your youth as much as I have.


Profiling an Epson 9600 with an X-rite i1 Pro and ArgyllCMS

This is part 3 of my continuing experience with an old Epson 9600 i picked up on Craigslist. (See part 1 and Part 2)

Do you see what I see?

After spending as much on paper, ink, and parts as I did purchasing the printer, I decided to put another ($400) drop in the bucket to pick up a X-rite (formerly GregtagMacbeth) i1 Basic Pro spectrophotometer (a.k.a Eye-One Pro, EFI ES-1000) on Ebay. This tool handles profiling both my display and my printer. Display profiling confirms that the colors on the screen are actually what’s in the image file. Printer profiling confirms that the ink hitting the paper matches what the computer thinks it’s sending. Having both sides of the equation in place means what you see on the screen should match what you see on the page.

Calibrating my printer and looking good doing it.

Calibrating my printer and looking good doing it.

In my last few projects, I’ve been dealing with lack of supported software for older hardware. This effort is no exception. The i1 Basic Pro (Is that an oxymoron or what?) originally came with i1Match, ProfileMaker and MonacoPROFILER all of which won’t run on my Intel-based Macbook running OSX 10.8. X-Rite recommends upgrading to i1Profiler. You can download it from their site easily enough, but unless your device has a license key for it, it will run in evaluation only mode. There is an upgrade path you can buy, but that will run you $699. For that I could have bought a brand new i1 Basic Pro 2 at $1200. Though, more likely, I would have gotten the popular and less-expensive prosumer version, the ColorMunki Photo.

From previous experience, I was aware that the open-source software, ArgyllCMSsupported the i1 without purchasing the upgrade. It’s worth noting that with X-Rite and Spyder a lot of their offerings have the same device and it’s only the software included that limits or enables the device’s capabilities. So, using ArgyllCMS can allow you to get more for less (i.e. free).

ArgyllCMS to the Rescue

Installing Argyll is very straightforward. The website has some instructions for Mac installation which I needed to modify for my newer OS. Here is a revised version that should work on 10.8.5 and later.

Download the latest version and unzip it. I put the resulting folder in my Application directory. I also recommend removing the version number from the folder name so that when you upgrade, you can just drop the updated files in this directory without having to redo the next step.

On the Mac, you will need to add the ArgyllCMS to the path.

Step 1: Open Terminal

Step 2: Enter the follow commands:

    open ~/.bash_profile

Step 3: Add the following line to the end of the file adding whatever additional directory you want in your path in the format PATH=$PATH:$HOME/PATH_TO_DIRECTORY/Argyll/bin


Step 4: Save the .bash_profile file and Quit

Step 5: Force the .bash_profile to execute. This loads the values immediately without having to reboot. In your Terminal window, run the following command.

    source ~/.bash_profile

Step 6: You can confirm the new path by opening a new Terminal window and running:

    echo $PATH

So, once you’re done, you just need to open Terminal, navigate to the ArgyllCMS directory and run the commands that follow. I keep the commands saved in a text document so it’s a cut n’ paste operation. Easy peasy! See my earlier post for a handy utility that opens terminal directly from a Finder window.

Color Management for Doctorates 

The ArgyllCMS site has a page that gives a run down on the steps involved in creating a printer profile. It’s detailed. Very detailed. Very, very detailed. To quote;

“Most printers running through simple drivers will appear as if they are RGB devices. In fact there is no such thing as a real RGB printer, since printers use white media and the colorant must subtract from the light reflected on it to create color, but the printer itself turns the incoming RGB into the native print colorspace, so for this reason we will tell targen to use the “Print RGB” colorspace, so that it knows that it’s really a subtractive media. Other drivers will drive a printer more directly, and will expect a CMYK profile. [Currently Argyll is not capable of creating an ICC profile for devices with more colorants than CMYK. When this capability is introduced, it will by creating an additional separation profile which then allows the printer to be treated as a CMY or CMYK printer.] “

Hmm. Yup. Yup. Yeah. I recognize some of these words. Yup, definitely words.

Even if you know what Color Management is, the documentation can be a bit dense; detailed to the point of obscurity, some might say. If you don’t know what Color Management is, then you may want to start backing away very slowly. While I lack an advanced degree in color theory, I do have quite a bit experience with command-line programs. So, after a few days of trial, error, and Google, I have developed a simple workflow that should help other newbies get started.

image from

In summary, you’ll create a print target, one or many pages with rows of colored squares, and then read that target with your spectrophotometer. From that reading, ArgyllCMS generates a printer profile (.icc). There are five steps;

  1. targen – this command tells ArgyllCMS how many patches to put in the target
  2. printtarg – here you generate TIF file(s) of your target
  3. Print the TIF file(s) without Color Management
  4. chartread – captures the data coming from the spectrophotometer
  5. colprof – creates the printer profile from the chart scan

Technically, you only need to do the first two steps once, because once you have your TIF file generated, you can just reprint that for any subsequent re-profiling. (Though this may not be entirely correct, since the ArgyllCMS documentation differentiates between printer profiling and printer calibration with the latter being used to “allow day to day correction of device drift without resorting to a full re-profile”. Honestly, it’s outside the scope of my understanding thus far and maybe I’ll revisit it after I delve into it more.)

If you just want the ArgyllCMS commands I used without the details and colored commentary (pun intended), jump to the Summary at the end.

Step 1 – Targen

By default, targen with the minimum options for an RGB printer [-d2] will generate 836 patches, which when printed on US Letter, will span a little under 2 pages.


targen -v -d2 FileName

targen -v -d2 FileName

Now you may be asking yourself, “Do I have an RGB printer?” If in doubt, try answering the following questions;

  1. Name an aquatic animal that can see more than RGB?
  2. How the heck does the K in CMYK mean black?
  3. Is RIP something that only pertains to funerals?
  4. Did you buy your fine art printer at Costco?

Answers: 1) The Mantis Shrimp, 2) The K in CMYK stands for “Key Plate”. In CMYK, this is usually done with black ink. Plus, B already meant Blue. 3) No. See Raster Image Processor. 4) Seriously?

If you answered “What the what?” to most or all of these questions, you probably have a printer that uses an RGB driver regardless of how many ink colors are physically put into it. If you have a driver or RIP that is printing directly to CMYK, than you should probably be writing this article. I humbly await your comments.

But, I digress… Good paper’s not cheap. So, I wanted to maximize the patches per square inch. If you look at the chart at the bottom of the targen documentation, it lists the ideal patches/page for your device. For the Eye-One Pro, it’s 462 for 1 page, 924 for 2 pages, and in multiples of that so forth.

targen -v -d2 -G -e8 -g128 -f700 EyeOne1pg

targen -v -d2 -G -e8 -g128 -f700 EyeOne1pg

With some fiddling, I got 700 patches on a single letter sized sheet. Let’s break down how.

targen -v -d2 -G -e8 -g128 -f700 EyeOne1pg

  • [-v] – Shows progress on the screen so, you aren’t just left listening to the fan whirr and wondering what’s going on
  • [-d2] – Because you have an RGB printer from Costco
  • [-G] – “Generate good optimized points rather than Fast” because good is better than fast. That’s what she said.
  • [-e8] – White color test patches. Default is 4.
  • [-g128] – Prints 128 greyscale patches so you can do accurate B&W prints later. Probably want to multiply this if you do multiple pages.
  • [-f700] – Overall patch count.

Some threads I read suggested patch counts of 2000-3000 for accurate profiles on large format printers. That seems excessive to me. The profiles I produced with a single sheet looked great. Though if you wanted to, just scale the [-f] number accordingly; 1400 for 2 pages, 2100 for 3 pages, etc.

Step 2 – Printtarg

This is the part that I spent the most time tweaking. Setting the number of patches is easy. Getting it to fit properly on the page will kill a few trees. Here’s how I got the one pager above.

printtarg -v -ii1 -L -a0.87 -m8 -M8 -T360 -P -pLetter EyeOne1pg

  • [-v] – Because watching the text output makes me feel like Neo.
  • [-ii1] – Specifies the device; i1. For example, Colormonki would be [-iCM]
  • [-L] – Gets rid of the extra whitespace created for the clip on the scanning board. You don’t need it. It’s a over-engineered gimmick.
  • [-a0.87] – Scales down the patches. The i1 can read patches a minimum of 7mm2. Default is 10mm2.
  • [-m8 -M8] – Sets the top/bottom and left/right margins to 8mm.
  • [-T360] – Create a TIF (postscript is default) at 360 dpi
  • [-P] – Doesn’t limit the strip length.
  • [-pLetter] – set the page size to US Letter (8.5″ x 11″)
  • EyeOne1pg – name of the resulting TIF

If you want to print multiple pages and modified the patch count accordingly inTargen, you don’t need to change anything here.

Step 3 – Print the Target

Use the Adobe Color Printer Utility application to print your targets without color management applied. Don’t use Photoshop, since newer versions don’t let you print without color management. With Epson printers, you also want to be sure you’re not using the color controls built into the printer.

I’ve also heard you can also use Mac’s native ColorSync (Applications > Utilities), if you select “Print as Color Target” under ColorSync Utility on the print options. While I couldn’t see any difference between the outputs of the two methods, I went with the Abobe utility as it was recommended by more users.

In the Adobe Color Printer Utility, select the TIF created in the previous step. Go to File > Page Setup and select your printer and paper size, US Letter. Your paper size options may be named differently and you may have several options within US Letter. Just be sure to select the one that has the minimum borders or is borderless. Hover over the option to see the margin sizes.

Page setup

Adobe Color Printer Utility – Page Setup

Select the Letter option with the smallest margins.

Select the Letter option with the smallest margins.

Next, select File > Print. Under Printer Settings, select the correct media type. If you’re using a non-Epson brand paper, look on the manufacturer’s website for the media equivalent. For example, I’m using Canson Baryta Photographique 310gsm which according to their website is equivalent to Epson’s Premium Semi Gloss Photo Paper.

Print Options

Print Options

Set your print quality. Confirm ColorSettings is disabled and print away. Let the print dry for a few hours (or even overnight) before scanning.

Step 4 – Chartread

Go back to terminal and enter;

chartread -T0.4 EyeOne1pg

The program will run you through a set off prompts to complete the scan. First it will ask you to place the i1 on its calibraton plate. Next, it will ask you to start scanning starting a row A.

i1 on its calibration plate

i1 on its calibration plate

The i1 and target on the backing board

The i1, printed target, and scanning ruler on the backing board

Here are some tips on scanning;

  • The scan starts when you press the button on the side of the i1, but there is a delay. So, wait till you hear the “Bonk” sound on your computer before starting to move the device. The sound plays through the computer not the device and is very low, so make sure your volume is turned up.
  • You can scan in either direction; top to bottom or vice versa. Alternating each line makes the whole process go faster.
  • Center the row vertically in the ruler opening so there is whitespace on both ends.
  • Line the row up horizontally in the center in ruler opening so that the patches aren’t touching the edges.
  • If you have to retry a row of a few times, try re-positioning the ruler.
  • Because we eliminated the white space on the left you can’t clip the page and use the ruler on the first few rows. Once you’re past those rows you can move the paper and clip it if you want to. I find the weight of the ruler hold the paper in place even without the clip.
  • If you don’t have a backing board any flat surface will do but, be careful, because the color of that surface can show through the paper. Put another sheet of the same paper beneath it to prevent any color bleeding through.

Step 5 – Colprof

The last step is to generate the printer profile from the scan.

First, copy AdobeRBB1988.icc (located in HD > System > Library > Colorsync > Profiles) to the ArgyllCMS Directory.

Next, here’s the command I used and the breakdown.

colprof -v -A “Epson” -M “Stylus Pro 9600” -D “*Epson 9600 Canson Baryta Photographique CCpro” -qh -S AdobeRGB1998.icc -cmt -dpp -O  Epson9600BarytaPaperCCPro.icc EyeOne1pg

  • [-v] – You’ll definitely want progress shown. This process can take a while.
  • [-A] – Manufacturer (optional)
  • [-M] – Model (optional)
  • [-D] – Very important. This is what you’ll see as the profile name in Photoshop and Lightroom. I put a leading * in the name to bring it to the top of the list and clearly differentiate the custom from standard profiles (see image below). In this example, I use the printer model, paper name, and ink type (CCpro = ConeColor Pro K3).
  • [-qh] -Set quality to  ‘High”
  • [-S AdobeRGB1998.icc] – I used Adobe1998 as source profile for gamut mapping. I confess to doing this only because most of the threads I read suggested doing so. That’s all the color profile I use in Photoshop, so it made sense. Reading About ICC profiling and Gamut Mapping didn’t exactly clarify things. So, let’s take this one on faith.
  • [-cmt] – “Monitor in typical work environment” Taking this one on faith, too.
  • [-dpp] – “Monitor in typical work environment” And this one as well.
  • [-O Epson9600BarytaPaperCCpro.icc] – resulting filename

The last step is to copy the .icc file from the ArgyllCMS directory to Macintosh HD > Library > ColorSync > Profiles. You’ll have to enter your password to do so.

The new profile appears in the Photoshop print menu

The new profile appears in the Photoshop print menu


Open up Photoshop, go to print and now you’ll see your new profile available in the list of available Printer Profiles under Color Management. If you don’t see it listed, try restarting your computer.


In summary, the steps are;

  1. targen -v -d2 -G -e8 -g128 -f700 FileName
  2. printtarg -v -ii1 -L -a0.87 -m8 -M8 -T360 -P -pLetter FileName
  3. Print the TIF file
  4. chartread -T0.4 FileName
  5. colprof -v -A “Printer Brand” -M “Printer model” -D “Profile Name/Description” -qh -S AdobeRGB1998.icc -cmt -dpp -O  ProfileName.icc FileName

To test my results, I compared a test image I printed on my 2200 using third party inks and Epson’s standard profile with the same image printed with the same inks and my new custom profile; both on Epson Photo Glossy paper. (I’m using my Epson 2200 instead of my 9600 because there was a more noticeable improvement with that printer/ink combination.)


‘Before’ print on top. ‘After’ print on bottom.


Above, I put my ‘before’ print on top of my ‘after’ print and took an (admittedly poorly lit) photo of the two to illustrate the difference, which I found most pronounced in the skin tones on my test image. The bottom print made with my custom inks and profile had less of a color cast and much more natural colors in the faces.

I also compared the ‘after’ print to a test image I printed a few months ago on my 2200 using Epson’s inks and profile. Using the custom ink/profile combination gave results that looked much closer to output from Epson’s standard ink/profile combination.

In closing, ArgyllCMS is a very sophisticated application of which, like Photoshop, I feel I am only scratching the surface of. From the forums I’ve read, its level of sophistication is on par with X-rite’s i1Profiler and superior to the Colormunki’s software. As my understanding of color management practices increases I may revisit some of the options I used here and get even better results. That being said, I was able to get results I was very happy with with only a small learning curve. Some users may be turned off using a command line interface, but having gone through the steps once and saving the commands in a text document, I feel that the next go around would be painless.

On the hardware side, the i1 may be an advanced piece of kit, but in my opinion, it could use some better product design. You can tell it was engineered for one purpose and then retrofitted to serve others. The form factor is clearly designed for reading printed targets. Which is evident by all the awkward accessories needed to set it up to do display or projector calibrations. The Colormunki, with its single-body multi-purpose design, is superior in comparison even if it’s inner-workings are inferior. If I had to make the choice again, I might opt for the one that took up far less room in my small NYC apartment.

Hope this was helpful.



Futureproofing the Epson 9600

» This is part 2 of my continuing experience with an old Epson 9600 i picked up on Craigslist. Be sure to check out Part 1 and Part 3)

That’s so 20th Century

First, I wanted to update the firmware to the latest version.  The biggest challenge was that for the Mac, the installer was only available for Mac System 9. (I know, right?) So, being the techno-wizard I am, I dived head-first into looking at emulators to run the older Mac OS (like Sheepshaver and Basilisk II) but they couldn’t access printer drivers. Even using a DOS emulator like DosBox or a Virtual Machine like VirtualBox didn’t help. Eventually I tossed in the towel and went with the path of least resistance (or so I thought), dug up an old PC, some boot disks, and a copy of Windows XP (I know, right?) After several hours of being reminded why I made the switch to Mac, I finally was able to get XP running. I installed the printer driver, and then the Printer Service Utility v1.33 but the utility would not “see” the printer despite being able to print test pages. I uninstalled the utility, installed Status Monitor3 v3.1b to check the connection and that application worked fine. After rebooting and reinstalling, the utility finally recognized the printer and I was able to update to Firmware version BW1452_Q.UPG .

Hello Windows, my old friend...

Hello Windows, my old friend…

Gather ye Spare Parts while ye may…

The printer came to me in fairly good shape; no clogs or any of the major issues I saw commonly cited on Luminous Landscape and in the Epson Wide Format Yahoo group. So my concern with such an old printer was more on future-proofing; guarding against some of the planned obsolescense inherent in today’s hardware.

There are only a few parts distributors listed on Epson’s Support Page for user replaceable parts. Most of these sites are god-awful, user-unfriendly garbage.

  • CompassMicro – Surprisingly, this website was updated in 2013. I hope they didn’t pay a lot. Of the few parts listed for my model, most are marked as unavailable.
  • Encompass Parts – Looks like it has a lot of parts but once you drill into the details and check the Total Availability or Estimated Ship Date you’ll see there actually aren’t.
  • National Parts Depot
  • TSAWorld – Shows one part, but if you search by part number it has some listed under the 7600. Requires login to view pricing.
  • PC Parts Canada – no pricing/availability just quotes.

My foray into these virtual junkyards made me feel only more certain that I needed to stockpile some parts if and when I could find them. So the next stop, of course, was Ebay. I picked up an Automatic cutter (part # C12C815291) for $60, less than the $95 Epson charges.

I also bought three (at $6 each plus shipping) Head Cleaners aka Wipers (part #1230744 or #1113691 depending on where you look) from American Injet Systems because I didn’t trust the cheap knockoffs from China floating around on Ebay. Manual says they last about a year each and the status page I printed said mine was about 3/4th of the way through its useful life.

Epson 9600 cutter replacement and wipers

Epson 9600 cutter replacement and wipers

US invasion of Epson imminent

A 220ml cartridge of Epson Ink for the 9600 retails at $138. So while people go crazy when gas goes above $4/gallon, a gallon of printer ink will set you back over $2,300.

High-quality third-party ink like Ink2Image’s Cave Paint and InkJetMall’s ConeColor inks run about 50% less (a reasonable $1,150/gallon). That discount and the possibility that Epson may discontinue manufacturing cartridges for this model — as ConeColor just recently discontinued their K2 inks in favor of the K3 used by newer Epson models — led me to invest in refillable cartridges. ConeColor’s cartridges were highly recommended but, in my opinion, over-priced at $242. I ended up getting a full set of eight from for $153. The same set were cheaper at InkPro2Day and InkOwl but InkJetCarts had a better reputation for support on some of the forums. Which turned out to be true, since one cartridge was missing a stopper and chip. I contacted them and the next day received a replacement. Be sure to check the chips on you set aren’t loose and apply a bit of glue if they are (be care not to get glue on the contacts). If any one falls off inside the bay, you might have to dismantle the whole thing to retrieve it. (Edit: I’m now on my second set which I purchased from InkOwl . Looking at another vendor on Amazon they must come from from a common supplier because they look exactly the same, only less expensive.)

Refillable cartridges

Refillable cartridges

I wasn’t completely happy right off the bat. I found the cartridges wouldn’t stay in their slots like the OEM carts and constantly pop back out. Because of this, I couldn’t get the printer to recognize that all new the cartridges were installed. It ended up being a game of whack-a-mole. When I got one working, the red light on another turned on. What finally worked was turning off the chip counter that keeps track of ink levels. I had planned to do that anyway to reduce the wear and tear on the delicate gaskets and chips caused by taking the cartridges in and out.

Bump in the road

When I installed the cartridges, I hadn’t received my inks from ConeColor yet. I was too eager to play with my new toy and transferred the ink from my old OEM cartridges using a syringe. However, I was really low on Light Magenta and the amount in the cartridge wasn’t enough to keep air from getting into the line when I first ran the Int Fill procedure. My heart dropped when I saw bubbles in the line. I had to deal with the same issue for hours once with my 2200 and now I had the same problem on a printer 5 times as big and complex. Nearly all suggestions I read talked about taking out the dampers or running cleaner through the lines; actions that require lots of dismantling, replacing, and praying. My heart dropped with every word.

Air bubbles than can potentially kill your print head.

Air bubbles than can potentially kill your print head.

One forum suggested just running the Int Fill procedure again. This seemed the least invasive course of action. So when my ink arrived, I filled up the carts, primed each one again (just to make sure), and ran int fill. I watched it run, thinking there’s no way it’ll be this easy. Once it finished, however, a quick inspection showed the line was clear of bubbles. Nice! The printer gods must be smiling upon me. Next step was to print a nozzle check. “Error: Maintenance Tank Full”. Curse you, printer gods!

The maintenance tank gets filled up quickly with all the ink the printer wastes constantly cleaning the print head. So, you always needs a spare. Epson charges $40 for this plastic container filled with absorbent material. Luckily, the chip resetter that came with my ink cartridges (more on those) also also worked on the tank. So my plan was just to crack open the tank, replace the material, reset the counter, and feel better about not adding needless waste to our landfills. Edit

When I took out the tank, I could feel that it weighed about 5 pounds (in other words, a few hundred dollars worth of ink). Mind you, I had just installed this new tank less than a month ago. When you crack it open to get the used material out, you’re going to want to do this over the sink because a good amount of the ink will pour out. I rinsed out the whole thing being carefull not to get the chip on the side wet. (I was also able to rinse out the material — which comes in pre-cut slices — and save it for future reuse.) Then I stuffed the dried tank full with 2 packs of 2×2 Cotton Squares that I had bought for $5. Incidentally, I did look at using diapers but, damn!, they are expensive for something that just gets sh*t on. Paper towels are not a good choice since tend to disintegrate as they get wet. Cotton holds together better and, when placed on their side, I was able to pack the squares in much tighter than cotton balls. I used the chip resetter, popped the tank back in, and everything was good to go at 1/10th the cost.

Packing an emptied maintenance tank with cotton squares.

Packing an emptied maintenance tank with cotton squares.

Before and after

Before and after

Next Steps or The Long March to Diminishing Returns

Since I’m not using official Epson inks anymore and I’ve heard about the 9600 exhibiting color drift over time, I’m planning to color calibrate the printer. My recent effort with my Spyder 2 helped calibrate my display so, I know what I see on the screen is what’s getting sent to the printer’s driver. However, without measuring the final output, I still haven’t closed the color management loop. For that I’ll need a Spectrophotometer. Back to Ebay, I guess.

Getting the DataColor Spyder 2 to work with Mac OS X 10.8

Spyder2Given my recent foray into large format printing, I needed to dig into the old junk drawer and excavate my Spyder2 Color Calibrator to profile my monitor. It’s been a few years since I last used it, so off to DataColor’s website to download the latest and greatest software. But lo and behold, as has become a recent trend in my digital archeology, the Spyder2 software doesn’t have a version that runs on Mac 10.8.5.

Hopes rose anew when I read that I could use the slightly newer Spyder3Express software to run my older Spyder 2 device. Furthermore, DataColor asserted that it’s software (including Spyder3Express) should work with Mountain Lion (OS X 10.8). This has not been my experience.

Following their own instructions for Mac OSX, I installed the Spyder3Express software for use with my Spyder2 device. The installation was flawless. The software recognized my hardware and ran all the way through the calibration. When the calibration process said Measuring is Complete and I clicked Finish, I got the following error;


Sorry, there was a problem getting the Color directory name (GetColorDirectory)
CMSSupport.cpp 445
-48 (OxFFFFFFD0)

Clicking OK only brought up a second error message;


Sorry, there was a problem creating the profile. (1) >>>file://localhost/Applications/Datacolor/<<<
CMSSupport 355
-170 (0xFFFFFF56)

Clicking OK on the second message brought me to the preview screen. Flipping between the uncorrected and corrected profile options did change the display and the change remained after closing the application. But once the laptop rebooted, the default (old) profile was re-applied.

From some research on the Interwebs, I didn’t find any solutions but started to suspect it was a permissions issue. A response from DataColor support confirmed this suspicion. I had assumed that the applications was trying to write to /Library/ColorSync/Profiles, which is where I had put all the custom ICC profiles for my printer. Support told me that the app is actually trying to write to /Users/YOUR USERNAME/Library/ColorSync/Profiles/. Problem is that staring from 10.7 Lion, Apple has set the User Library to be hidden. So the solution, is to make that directory writable either temporarily or permanently.

I opened up Terminal (Applications > Utilities > Terminal for those who don’t have in in the dock) and cut and paste in the following command.

sudo chflags nohidden ~/Library


Verify the profile is created in Display preferences

You’ll be prompted for your password. Once that’s done, this will make the directory visible and writable. Next, I navigated to /Users/YOUR USERNAME/Library/ in Finder. There wasn’t a folder called Colorsync as I expected. However, there was a text file with that name. I moved the file to my desktop for safe keeping and then created the ColorSync folder and then the Profiles folder within in. (I’m fairly certain the names are case-sensitive.) Afterwards, I was able to run the Spyder3Express application and get all the way through without error. In System Preferences, I could see the new Spyder3Express profile listed.

If you want to hide the User Library again, you could go back to Terminal and run the command line;

sudo chflags hidden ~/Library

I didn’t do this, because I didn’t want to have to do this everytime I ran another calibration.


Postscript – dispCalGui

In my troubleshooting research I came accross an open source color calibration software that supports the Spyder2; dispCalGui – by Florian Höch

Here are the installation steps (lifted from the Quickstart guide)

  1. Download Spyder PRO_2.3.5_Setup.exe from–win (yes, I know its an EXE file)
  2. Download Argyll CMS –
  3. Open the Argyll CMZ archive file. Copy the newly created folder to Applications.
  4. Download DispCalGui –
  5. Install DispCalGui–  double click the DMG to extract the content. Create new folder called DispCalGui under Applications and copy contents over.
  6. Run the app dispcalGUI – It will first ask you for the location of the Argyllcms. It wants the bin folder in the directory you created.
  7. Go to Tools > Enable Sypder 2 Colorimeter. It will ask for the location of the Spyder PRO_2.3.5_Setup.exe  from step 1.
  8. I had to run the aforementioned sudo chflags nohidden ~/Library command in terminal before it would save the profiles. This seems to be a known bug and may be fixed in later releases.
  9. You’re ready to go.

The dispCalGUI is much more complex than the push-button Spyder app but, you have many more levels of control and options to choose from.

This youTube video gives a fairly good tutorial on running your first calibration using DispcalGUI – Display Calibration Tutorial – How to calibrate your monitor correctly


Just in Time Provisioning for Salesforce Portal Users

Just in Time (JIT) Provisioning allows you to create new standard and portal user records in Salesforce when a user first logs in via an IDP (Identity Provider). So, how is this useful for managing large portals? If you are running a high volume Customer Portal in Salesforce, you may not want to create all the user records for each of your customers right from the onset since each user counts towards your license total. JIT provisioning allows you to create those user records when the customer first logs in so, you're only giving a license to those customers that are actually active in your portal. 

There are three possible scenarios for which you could use JIT Provisioning for Portal Users;  

  1. Match existing contact and account, create new user record.
  2. Match existing account, create new contact and user records.
  3. Create new account, contact, and user records.

The Axiom SSO Tool hosted on Heroku is a very useful app for testing your SSO configuration in Salesforce. This tool allows you to test your Salesforce configuration and make sure things are working as expected, irrespective of your IDP settings. (I will not be covering setting up your IDP here.) 

So let's go thorugh the steps for configuring Single Sign-On in Salesforce and testing Just in Time Provisioning for those portal users. 

1. Create a Customer Portal - I'm going to assume you already have a portal set up. If not, follow the instructions from the Salesforce documentation – Setting Up your Customer Portal.

2. Get Your Customer Portal Id – Setup >> App Setup >> Customize >> Customer Portal >> Settings. Click on the portal name to see the detail page below. 

Portal id

Copy the portal id to a text document for use in future steps

3. Get the Organization id - Setup >> Administrative Setup >> Company Profile >> Company Information

Org id

4. Download the Identity Provider Certificate - Go to . (Use a different browser so that when testing the SSO login you won't  get logged out of your Salesforce session.) Click the link for SAML Identity Provider & Tester. Then, download the Identity Provider Certificate

5. Configure Single Sign-on in Salesforce – Go back to your Salesforce session and go to Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings

Configure sso

NOTE: Enabling user provisioning requires that the SAML User ID Type be "Assertion contains the Federation ID from the User Object"
  • SAML Enabled: True
  • SAML Version: Default is 1.1. If you know the version your IDP uses, use that. Otherwise, select 2.0.
  • User Provisioning Enabled: True
  • Issuer: Axiom
  • Identity Provider Certificate: Upload the Axiom certificate from the previous step
  • SAML User ID Type: Assertion contains the Federation Id from the User object
  • SAML User ID Location: User ID is in the NameIdentifier of the Subject Statement

NOTE: Later when you're ready to test your production IDP, you can change the Issuer name and upload a new certificate. 

SSO settings

Click Save and copy the Issuer name and Login Url to a text document for use in the next step

6. Generate a SAML Response - In your other bowser, go back to the Axiom SAML Identity Provider & Tester, and click the link for Generate a SAML Response. Fill in the fields as follows; 

Axiom settings

  • SAML Version: Needs to match version selected in Salesforce SSO settings.
  • Username OR Federated ID: This is a unique identifier for the portal user and used to locate an existing user. This value will be stored on the user record (User.FederationIdentifier) when a new user is provisioned. For testing creation of a new user, just enter whatever string value you want. 
  • User ID Location: Subject
  • Issuer: Needs to match issuer name specified in Salesforce SSO settings.
  • Recipient URL: This Login Url displayed when you save the SSO settings. 
  • Entity ID: (default value)
  • SSO Start Page (default value)
  • Start URL / Relay State
  • Logout URL:
  • User Type: Portal (default is Standard)
  • Organization Id: Org Id from Step 3
  • Portal Id: Portal Id from Step 2

7. Enter JIT Provisioning Attributes - Just-in-Time provisioning requires the creation of a SAML assertion. The attributes in this assertion are critical details in matching/creating the records.

Here's the process as I understand it;

  1. Salesforce attempts to match the Federated ID in the subject of the SAML assertion (e.g. 12345) to the FederationIdentifier field of a existing user record. 
  2. If a matching user record is found, JIT provisioning uses the attributes to Update the fields specified in the attributes. 
  3. If a user with a matching user record isn't found, then Salesforce searches the contacts under the specified Account Id for a match based on LastName and Email. 
  4. If a matching contact record is found, JIT provisioning uses the attributes to Update the contact fields specified in the attributes and then Inserts the new User record
  5. If a matching contact record isn't found, then Salesforce searches for the Accounts for a match based on Contact.Account or AccountNumber and Account Name.
  6. If a matching account record is found, JIT provision Inserts a new contact record and Inserts a new User record based on the attributes provided.
  7. If a matching account record isn't found,  JIT provision Inserts a new account record, Inserts a new contact record, and Inserts a new User record based on the attributes provided.

Got it? If this seems really confusing then lets look at some more examples and their results in different scenarios.

Example 1: 

User record exists: Contact fields (eg LastName, Email) and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email.New user record inserted.

User record and contact record do not exist: New contact and user records are inserted.


In the above example, we can create new portal users and contacts given a hardcoded Account id. So, what if you don't know the id for the Account? Then you can search for it using the Account's Name and Account Number.

Example 2:

User record exists: Account fields (eg Name, Owner), Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Name, Owner) are updated. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: New account, contact, and user records are inserted.

User.ProfileId=00eU0000000ZLQe; User.PortalRole=Worker;;;

Note that in the above example, an owner Id is required to create a new account record.

Now what if you don't want JIT provisioning to create new account records or you don't have Account details in your IDP. Then you can leave out the account attributes altogether.

Example 3:

User record exists: Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: Process does not insert any new records because an account is needed to create a contact and portal user record.



The examples above show only the minimum attributes required. However, you can include additional attributes which correspond to standard fields on the User, Contact, and Account records. You can even include custom fields though only if they are a text field. You can get a full list of standard user attributes here and contact/account attributes here.

Example 4:

User record exists: Contact fields (eg Phone, CustomField__c, etc), and User fields (eg Title, CustomField__c, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Description, CustomField__c, etc) are updated. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: New account, contact, and user records are inserted.

Account.Description=Created by JIT Provisioning;
Account.CustomField__c=String Value Here;
Contact.Phone=212 555-1212;
Contact.CustomField__c=Hello World;
User.ProfileId=00eU0000000ZLQe; User.PortalRole=Worker;;;
User.CustomField__c=All your user are belong to us;

8. Generate the SAML Assertion – Click the Request SAML Response button.

Generate response

9. Login – If everything has been configured correctly and login is successful, you should be directed to the Customer Portal's home page. If some error has occurred, you'll be redirected to the Custom Error URL you defined in the Salesforce SSO settings. Check the URL for error codes that might help you troubleshoot.

10. Confirm – Back in Salesforce verify the records have been created successfully.



Here are answers to a few common errors;

  • INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY – Translation: you probably used an invalid id for either the User.ProfileId, Contact.Account or some other id field.
  • CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY – Check the error description to see if this refers to the contact or the account. Check for validation rules that might be preventing record creation.

Another helpful tool is the SAML Assertion Validator (Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings). To use this tool, copy the Plain Text SAML Response from Step 8 and paste into the validation tool. It will run through the generated assertion and check for any errors.

Saml validator


Related Resources:

About Just-in-Time Provisioning for SAML

Just-in-Time Provisioning for Portals

Just-in-Time Provisioning Requirements

Just-in-Time Provisioning Error

Salesforce Workbench extension for Firefox and Chrome

WorkbenchToolsForGoogleChromeScreenshotA few months back, I converted from Firefox to Chrome because it was much faster loading javascript intensive sites like and Workbench. Plus, it supports a bunch of helpful extensions (like these) that make my job easier.

A colleague recently informed me that Workbench has released extensions for both Firefox and Chrome. In Chrome it puts a Workbench icon on the right side of the location bar when you’re logged into a Salesforce production or sandbox site. Clicking on the icon logs you into Workbench for that instance in one easy step. As a bonus, it uses your local ip address so that you can get around any issues you may encounter with restricted IP ranges on your profile (ie the error message; Invalid_grant: ip restricted or invalid login hours).

Installing the Chrome extension was a bit tricky because Chrome has changed to only allow extensions installed from the Web Store which doesn’t have this extension available (yet?). You can get around this by downloading the extension from the project site. Then in Chrome, go to Window >> Extensions and drag and drop the extension onto the page. This will allow you to install it manually. Reboot Chrome and you’re ready to go.