Regardless of what industry you're in, every startup hits that dangerous phase where you're nearing the end of your runway but you still haven't gotten to the point where you can actually make money with your product. The cash crunch starts, and what happens next can often make or break the company.
Nathan was working for a biotech company that had hit that phase. They had a product, but they couldn't produce enough of it, cheaply enough, to actually make a profit. What they needed was some automation, and laboratory robots were the solution. But laboratory robots were expensive, and for a company facing a cash crunch, "expensive" was too risky. They needed a cheaper solution.
So they found Roy. Roy was an engineer and software developer, and Roy could build them a custom robot for much cheaper. After all, what was a lab robot but an arm with a few stepper motors and some control software? Roy turned around and shipped them a 2-axis robotic gripper arm ahead of schedule and under budget.
When Nathan joined the team, the arm wasn't working. Or, well, it kinda worked. Like a lot of such systems, the gripper had a "home" position. Between tasks, the gripper needed to return to that home position, and the way it was supposed to know that it was there was by checking a limit switch- a physical "button" that the arm would touch, telling the motor-control board that it should stop moving the arm.
For some reason, during the homing operation, the arm would stutter its way over, constantly stopping at random intervals, jerking and making godawful noises along the way. Nathan got Roy on the phone to talk through the symptoms and what was going on.
"So, when I was testing these," Roy said, "I found a fault in the motor-control boards. I think it's the whole batch of them, because every one I tried had the exact same behavior."
Nathan asked Roy to repeat that. "You think the entire lot of motor controllers you ordered from the vendor have QA failures?"
"It's the only explanation," Roy said. "It's certainly not anything in my software or any of my custom parts."
Nathan was almost certain that wasn't true.
Nathan examined the hardware while Roy continued his explanation. "So, anyway, what I was seeing was that the motor controller will report the home switch is hit, even when absolutely nothing is touching the home switch. So I added a work around; when the motor controller tells my software the switch is hit, I stop the motor, but then check to see if the switch is actually hit- and if it isn't, I keep moving."
"So, wait, when you stop the motor, the incorrect data goes away?"
"That's what I found in testing, yeah."
Nathan examined the wiring that connected the motor controller to the rest of the hardware- specifically the stepper motors and the limit switch. Roy had obviously wanted to keep his design "neat and clean", because he used a single, multi-conductor cable. From there, it wasn't hard for Nathan to figure out what was going on.
Some of the wires in that connector were just power and ground. One was for the limit switch- it'd read "high" if the switch were hit, and "low" otherwise. And the others were for the stepper motors. All of these wires were crammed together, with only a thin layer of insulation between them. The problem with that design was that stepper motors are controlled by sending PWM signals down the wire. Time-varying electrical fields have this seemingly magical power to induce current in other fields, which is a fancy way of saying "putting PWM signals on one wire can induce current in a nearby wire", and also is one of the basic principles which anyone doing electrical design should know.
When the homing operation told the steppers to move, the signal to the steppers created interference in the home switch wire, causing the motor controller to think the home switch had been hit. By stopping the steppers, Roy stopped the interference, so the interference stopped, and now the system could continue.
The fix was also simple: Nathan replaced the single multi-conductor cable with two shielded cables, isolating the home switch wire from interference.
As a bonus example of what you get when you hire Roy, Nathan also supplied some of the sample code in Roy's custom robot scripting language. This sample promises to show you how to weigh every vial in a rack of vials:
For Vial = 1 to 96
Rack.MoveToCell(XY, Vial)
Gripper.PickUpVial()
Balance.Tare()
Balance.MoveToCell(XY, 1)
MyWeight = Balance.Weight()
PutVialBack(Vial)
Next
Roy calls this code "easy to understand and modify", but I'll let Nathan explain why this isn't true:
Why do the Rack and the Balance each have the ability to move the Gripper? Why is "PickUpVial()" a function on the gripper, but "PutBackVial()" is not part of a class? What's the logic and abstraction here? Much like the robot itself, this is code that looks easy to understand but in practice is hard to operate.
As for what happened to the startup that was so focused on cutting costs they were buying equipment from Roy? Well, Nathan doesn't say, but whether they survived or failed, it's still not really a happy ending either way, is it?