Thrift stores, particularly the electronic-recycler variety are a great source of inexpensive project material. I try to stop by weekly and see what’s new. You’re never quite sure what you’re going to find, I’ve picked up everything from vintage shortwave radios to plotters, to perfectly good, albeit dated test equipment like scopes and analyzers. Often, what you find is at best “working status unknown” and at the worst, “very obviously broken.” But the price is almost always right.
Entré ! The Barco CLM-HD8
On a recent visit, I noticed a legit-looking and surprisingly modern (for a thrift store projector) Barco HD8.
I’ve worked in the event industry before, enough to know the price tag typically assigned to road-friendly gear. The presence of HD-SDI ports, DMX, Artnet, and the “HD” moniker stamped on the top also quickly got my attention.
It was priced at $70, with a “working status unknown” sticker. There wasn’t a power cord present, and it features a plug that’s a bit beefier than your standard IEC, a good sign they weren’t able to test it at all. I shelled out the $70 and brought it home, with the cashier acknowledging that I probably struck a reasonable deal.
I figured in the least I could sell off the lens, and get some pretty nice parts out of the thing. Best though would be if I could refurb it. The things still go for a couple-few thousand dollars on the ol’ Electronic Bay in good working condition.
Examining the spoils
After returning home, I checked the specs quick to see what I’d need to power it up. There, I found:
- It’s a full 1080p HD DLP projector
- 8k Lumen, designed for “mid-venue” projection
- It’s runs on 4 arc-source lamps
- It’ll take about any input voltage, but scales lamp power back if you run in the 120v zone.
Coolio, I’ve got some 20amp plugs in the wall, so I made up a cable, and plugged it in.
On power-up, the display came to life, and it ran through its boot diagnostics. It finished with no obvious error messages, but no light either. I explored the lamp menus trying to see if they needed to be struck manually, but no dice. Eventually, while standing back scratching my head, I noticed the second power button marked “standby.”
With a push, the fans roared to life, and I could hear the decidedly expensive sound of a very high-speed color wheel spinning up. There was a flurry of messages on the screen, and I started to notice a blue glow in the room getting brighter. And brighter. Finally it settled on ridiculously bright. ‘Well, OK then,’ I thought, this day is starting to look up.
Not so fast there, Rockefeller
While I was rotating through the built-in test patterns, an error plunked up on the LCD screen, informing me that “lamp 4 did not strike.” Well, there go my plans of a quick and easy buck.
I dug into the lamp status, and found that in reality, only 2 lamps were on. Lamp 4 had not struck for reasons unknown, and lamp 3 was off because I was using a 120v source. Presumably they try to keep the overall current draw in a zone in which people are less likely to do dumb things. Fair enough. Still, I was impressed at the brightness coming out of the thing, given it was operating at half capacity.
I popped the cover and had a look at the lamps, verifying that they were all well-seated. I swapped lamp 4 for lamp, 1 and the problem followed the lamp. Good to know it wasn’t a ballast problem.
You, light up my lightguide
The lamps are arranged all facing into a light guide / prism / bit of optical duct-work. High voltage comes in at the bottom of the lamp, and there’s a conspicuous looking RJ-12 cable plugged into the top. LEDs blinked away indicating some sort of clock.
Checking the lamp statistics, lamp 4 had only run for about 80 hours while the other three had been pushing 800+. It seems lamp 4 hadn’t been operational for a while.
At 800 hours, the other lamps were reaching their end of life too, and according to their manual would soon start displaying a nasty-gram, and eventually refuse to light at all. Well, I can’t really sell the thing in that condition. So I jumped on the intertubes to see what the cost would be for a new set of lamps.
I was hoping to get maybe 2 – 3k for the thing reselling it, a 2400$ lamp investment really wasn’t going to work. Sadly, there were no “compatible” lamps either, just the mother-ship sanctioned exceptionally expensive pieces of aluminum with a cheap arc bulb along for the ride doing all the work.
On closer examination, the logic board wasn’t even attached to the high-voltage side of the lamp at all. It was just effectively a piece of vendor-lock-in stapled to the lamp, and required for it to function.
So how much are the actual bulbs?
So how complicated can those little logic boards be anyway? There must be some way to spoof what it’s telling the projector.
RS-485, 486, whatever it takes
On closer inspection, I saw there really wasn’t much there. Basically:
- Some power conditioning
- A 40mhz oscillator
- A programmable microprocessor
- A TI 65176b (RS-485 interface IC.)
Well, hello there.
It makes plenty of sense that the projector would use RS485 to communicate with these things. It can be bussed together (there’s 4 lamps) it’s cheap, it’s reliable, and the data payloads are tiny.
My first thought was to see what the projector and the module are chatting about, and see if I could make a little circuit on my own that emulates the response, but allows me to reset the utilized hours.
But alas, I don’t have a logic analyzer, or even a RS485 to USB interface. So I went on over to Amazon and ordered one. 4 days until delivery. But, I’m kind of bored now. I mean, it wouldn’t hurt to see what other methods I might be able to use.
ISP – not just for internet anymore
So I started to look at the microcontroller. It’s a Philips P89LPC938. Looking at the data sheet, it’s inexpensive magic in a tiny form factor. A bunch of IO, flash memory, RAM, a data area, counters, timers, PWM driver. All for something that costs a couple bucks on digikey. Apparently I’m either easily impressed, or don’t play with microcontrollers very often. Probably both.
So I started to read the manual to try to find a way to dump the code running on the thing. Handily, they included and populated an ISP (In-system programming) header on the board. So with the right programmer, I could probably dump this thing, modify it, and re-flash the chip. That has the nice benefit that I don’t have to add hardware to the projector, I could likely just reset the lamp minute count.
The downside is, I have no experience with microcontrollers, so I have none of the equipment. In addition, there seemed a fairly high risk that I would brick at LEAST one of these things in the process of figuring out how to dump and program it. Too risky for my bargain basement endeavor.
Try the front door
So I had the RS485 interface on the way, and felt pretty confident I could come to a solution with that. But then I started to think about what’s running the projector. I had recently had a bunch of luck getting into the linux OS running an expensive plotter, and it gave pretty much total access to the hardware. Maybe there was a similar situation here?
So I ran a port scan against the IP assigned to the projector. Not a lot open, but of note, were:
- 23 (telnet)
On connecting to port 1000 it seemed to be a debugger connection. Certainly possibly useful, but telnet sounded likely more friendly.
Sadly, unlike the HP plotter I was just working with, the root password was not blank. I tried throwing a dictionary at it, but no luck there either.
So I turned my attention to firmware. How do updates get on this thing? Well, the answer it turns out, is: ridiculously.
The main application is in ELF format. The updater is a bunch of binary files that get put onto the device and plunked into the main executable. By way of, well, some shell scripts.
My gut told me there probably wasn’t even a checksum involved with this process, so it might be as easy as modifying do-upgrade.sh to set an account password.
But how do these files get onto the projector in the first place? Well you load them into a piece of software called the projector toolset, and it performs the update. But there were only two ports obviously open, telnet and the mysterious debugging port. The update must be going over one or the other.
Baby (wire) Shark
Well, let’s break out wire shark, and see who is saying what to whom.
So basically, the update program is connecting by telnet, and running shell commands to get information. In clear text. And sending a root password.
Well, alright then.
After poking around, I was able to find the main binary for the projector and run it. There’s a watchdog that also runs, so if you want to kill the process to get exclusive access to the hardware, kill the watchdog first, or it’ll reboot on you.
You can run the binary again though, and most things will function fine along side the already-running process.
Handily, there’s a lot of nice convenience functions built into the binary:
There are also a slew of command line options if you start the binary with a
/? most of which appeared to crank up the logging level. One titled
NO-LIM seemed like it would at least stop the lamp timers from running by its description, but when I modified the startup script to start with it, the lamps would not strike at all, despite appearing as if they had. Certainly a useful command if you’re working on projector R&D but not so much for me.
While I could certainly use the RS485 device enumeration on the linux side to see what was going on between the projector and the lamps, I started to think there’s probably a way to get to the lamp hours through the application stack.
I had little to reference in terms of hardware addresses, etc. So I turned to analyzing the projector toolkit to see if I could find some clues.
More than a toolkit
The projector toolkit has a lot of useful functionality in it. You can control the projector from the software, lamp it up or down, tweak the color space, etc.
Wondering though how this thing was built, I went to look at the application, and low and behold, it’s java:
As I looked around, it appeared that there was a whole lot more to this toolkit than originally appeared. It seems their own service folk use this same software to perform various service-related tasks on the projector, and that one of those tasks is to “refurbish” a lamp.
Functionally, refurbishing a lamp simply set the runtime and number of strikes to zero, and incremented a counter for the number of refurbishments. If the lamp is refurbished too many times, it can no longer be reset. So it appeared they built a facility to allow themselves to do exactly what I wanted to do, and exactly what makes common sense: to replace the bulb, and reset the counter on the housing, which itself has no obvious lifetime limitation.
Digging into the functionality that performed the reset, I quickly found I wasn’t going to easily make the same call. There are some pretty involved services that setup the communication with the projector, perform checksums on the communication, and while it could be rebuilt externally, it seemed much easier to do it in the software that was designed to do it in the first place, (but was quietly hiding its advanced abilities.)
So I poked around some more.
A very specific set of skills
It was obvious that the software needed to have some way to know it was in use by a “service” person. I wondered if maybe there was a configuration flag, or some kind of context check for a specific piece of infrastructure.
It seemed that the utility actually supports more than just ‘service’ related utilities, in fact with the proper usb stick, you can perform all kinds of actions on different models of projectors. I’m surprised they released all this in a publicly available utility.
But alas, I am sadly lacking in the dongle department. Looking at the logic that handled the access check, it seemed a simple modification to look past the check, but I’ve never worked in Java, and it seemed challenging to try to get the toolchain up to be able to recompile the whole thing. What to do, what to do.
I’ve never worked with Java, but was superficially familiar with the concept of bytecode. Basically, (much like CIL in .NET) it’s a sort of intermediate set of instructions that is relatively portable across multiple platforms. It reduces the program to a sort of assembly-like stack with simple operations using relatively primitive types. Not much fun to attempt to analyze, but could also be modified in simple ways, without having to get the whole thing to recompile. In this case, all I was trying to do was skip a check and return an access level to the caller, which seemed a task reasonably possible to achieve in bytecode.
It took a bit to grasp what was actually happening in the listing.
Basically, there’s a stack, you can push values or references onto it. Flow control happens by labels and “goto” calls. I knew my days with the TRS-80 would come in handy!
In my case I was able to remove a couple existing calls, replace their place in the stack with a constant and a float value (representing the access level returned by a function call) and then add a goto to send the runner to the end of the listing.
And to my surprise, the first attempt worked:
I started the projector up, hit reset on each lamp, and it set all fields to zero and incremented the refurb count by 1. Huzzah!
Oddly, when performing the reset it warned about “possible warranty consequences.” I’m not sure in what situation this utility is intended to be used.
But luckily, I could now replace the bulbs on the lamp housings with brand new ones, and have a zero-hour lamp counter to match. Mission accomplished. OR IS IT?
But what about that refurb count?
I mean, my intent is to resell the projector to someone who can hopefully get a good life out of it. I can’t imagine a situation where I’d need to refurb the lamps more than once. But I did begin to become curious whether the refurb count could also be reset.
Enter the ‘Direct Communication’ utility
Usefully, the service utilities offer an ability to directly communicate with the projector. This involves opening a socket connection and sending hex codes that represent commands along with a data payload. Doing this on your own would be a pain, as you have to calculate checksum, split large messages, etc., but the utility handles all that.
Looking at the code that runs the lamp reset, I was able to find the message used to increment the refurb count. It’s more complicated than I expected, sending some 8 hex values of payload, only two of which represented the lamp number and the new value. It’s possible the intent was obfuscation. But it turned out simply replaying the logic applied to determine the other values worked just fine.
RefurbNbr = 0
There were many possible ways to go about resetting or spoofing the lamp value, most of which showed great promise. However, one of my motivating factors in this was to ‘flip’ the projector, get it in good working order and resell it. Time is money, as they say, and if I were to spend days getting to the bottom of it, while personally fulfilling, I certainly wouldn’t be making much money doing it. So an added challenge in this case was to identify the likely time investment of each approach and attempt to get to the one that took the least.
As someone often driven by the desire to “figure it out” it’s not in my nature to give up quickly on a given approach and look for a better one, though there’s great benefit to stepping back every so often and saying: “let’s back up, is there an easier or better way to go about this?”
It’s the old “printer for free, charge like crazy for the ink” model. I can’t tell you the number of perfectly good ‘premium’ devices I see get thrown away because the consumables cost isn’t reasonable for someone not looking specifically for a premium product.
This particular projector is considered “end of life” by the manufacturer. At that point, why not release some tools that allow enterprising folks in the second hand market to find good homes for these things? I can’t imagine it’s going to eat into new sales that much, premium users are quick to upgrade. Let’s keep these giant hunks out of the trash heap and get them to good homes.
I think the printer industry is on to this. Competing by the propriety of your consumables is a losing proposition.
I’m not an expert in any of the stuff covered here, I just enjoy hacking away at things. If I’ve misrepresented anything in particular, or you have further knowledge to impart, I really do appreciate feedback.