[<< | Prev | Index | Next | >>] Monday, July 06, 2020
$33 Homebrew Dishwasher Controller
Don't try this at home. Electrocution or fire are likely outcomes. That said, here's my story:
Our Maytag Quiet Series 300 dishwasher died in a way that seemed to be the control board so I ordered a used one on ebay for $30. Turned out it wasn't that--it was the control panel, which is hard to find for less than $150. Having already taken the thing apart a few times, my instincts kicked in and next thing I know I'm building a new controller for it from scratch. (Partly because I wanted something better than I can buy, and partly as a didactic exercise to get me up to speed on hardware hacking since I haven't done any in over thirty years.)
Total elapsed time from it breaking to working again was about a month, but in terms of 8-hour days actually working on it, it took about two days total to design and build the hardware and software (mostly the latter because the entire hardware assembly was accomplished by sliding jumper wires onto pins), two days to mount the hardware in the original controller box and build the wires to connect the thing to the dishwasher (which I managed to do with no modifications to the dishwasher itself--my controller is a plug-in replacement for the original), and three days worth of reading reviews on Amazon and elsewhere just trying to find usable parts and tools from a vast sea of utter crap. (I dream of an Amazon-like site but with standards.)
I chucked the control panel and didn't replace it. The new user interface works like this: You close the door, and it washes the dishes.
Oh and my phone tells me what stage of washing it's in, the time remaining, and what temperature the water currently is. Plus from my phone I can abort the current cycle (which jumps straight to draining) or put it into a test mode (which briefly exercises each of the hardware functions in a reasonable order). These are all accomplished via a pre-existing chat thread with my house via Telegram so I hardly had to do anything for this.
Initially I was going to use a Raspberry Pi Zero W, and even ordered one for it, but before that arrived a friend of mine clued me into the NodeMCUs, which are arduino-ish boards which include WiFi and cost about four bucks. The rPi suffers from a long boot time and does not like being powered down abruptly, both of which were sub-optimal here. The NodeMCU is up and running in a second or so and you can pull the plug on it all day long and it doesn't care.
I was worried it would take me days to get up to speed on programming and flashing the NodeMCU. In fact it was about fifteen minutes from dumping the parts out onto my desk until I had it running my code and controlling a relay. Color me shocked. Everything else about it proved just as easy, including getting it connected to WiFi and sending and receiving UDP packets (TCP is even easier but I thought UDP was a better fit here). I basically wasted no time futzing or debugging--everything just worked. Even most of the jumpers I connected it to the relay board with in those first few minutes ended up staying on and are now installed in my dishwasher.
So, yeah, go get one and play with it--pretty fun. (Links below.)
I did end up wasting a lot of time on two things, though: One, I spent way too many hours looking for connectors to match the ones in the dishwasher. Turns out they are strictly cable-to-board, and there simply aren't any compatible cable-to-cable connectors. My solution to this was to just terminate my wires with spades and ferrules and plug those into the connectors one by one. Seems to have worked, but it's a bit awkward.
The other time waster is that most of the NodeMCU's I/O pins flitter about during the brief booting process, and with those hooked up to relays, and those relays controlling big motors and things, bad things were going to happen every time the power came on. So I sketched a circuit to gate the 5v power to the relays, then realized I needed a MOSFET to avoid too much voltage loss, then realized this circuit exists in a pre-made chip for about twenty cents under the name "high-side load switch"... but only in surface-mount form and that's a whole world of yuck away from just plugging jumpers onto pins. At which point I decided elegance be damned, I'll just add another relay to power the other relays. (And the trick here is to use GPIO pin 4 or 5 for this because those are stable during boot. So, yeah, a few quirks to learn and deal with...) Works like a charm--now the relay board just remains powered down until the NodeMCU is up and running, and then my code enables the board, runs the cycle, and when it's done it powers the whole relay board back down again which adds another level of safety and efficiency.
Here's the parts inventory with extrapolated costs at the moment:
120AC to 5v Power Supply - $12.50
NodeMCU board - $4.33 (3 for $13)
5v 8 Channel Relay board - $8.80
Single 5v Relay - $1.63 (8 for $13)
Jumper Wires - ~$1.00 (120 for $6.60)
High Voltage 18 AWG Wire - ~$0.20 (78' for $15)
High Voltage 14 AWG Wire - ~$0.60 (100' for $29.50)
Spade Connectors - ~$0.60 (260 for $22)
Ferrules - ~$0.10 (1200 plus tool for $24)
Wire Labels - $0.18 (600 for $9)
Mounting Hardware - $2.55 (10 boards worth for $8.50)
Total parts: $32.50Here's the code I'm using.
Here it is installed:
There's a small hardware bug there which I fixed after taking the photo: I connected the resistor to the wrong ground (120AC instead of 5v - yikes). Fortunately it just resulted in spuriously high temperature readings (that's the reference resistor for measuring the dishwasher's thermistor) and did not fry anything or burst into flames. (It's a 5k resistor so not a lot of current even at 120AC, and it was neutral not line.)
There's a usb port in the side which can be used to reprogram the thing if desired.
I only needed 6 relays but had 8 so I doubled up the relays feeding the main motor and the heating coil, which gives a lot more headroom on the amperage. The other four devices are relatively low amperage by comparison so not a concern.
I strictly used the switched power (both line and neutral switched by the door latch) so when the dishwasher door is not fully closed there is no power to the board at all. I'm not super confident in the relay board or especially the connectors they used which barely accepted a short segment of AWG 14 wire, so this at least limits the time it might burst into flame to when the dishwasher is actually running. (Specifically by discouraging us from latching the dishwasher normally, since the power through the relays would be switched in any event.) It also simplifies the UI because I don't have to worry about a start button if it just starts when the door latch powers it up.
So far I've only used it once since finishing it, but it worked great. We'll see how it holds up over time. The main improvements I made to the cycle is that it pre-heats the water (by running the inlet and drain at the same time to flush the cold water from the hot-water line--something the instructions with the original dishwasher tell you to do manually but we often forget), holds the soap back until it hits 130F, brings it all the way up to 152F during the wash cycle, and finally does 2 short pre-rinses before the final hot rinse. This will actually save us water on net because, like most, this dishwasher used to leave enough soap on our dishes that they would make soap bubbles when you filled a "clean" glass, so we got in the habit of hand-rinsing dishes before using them. I'm happy to report the dishes that just came out of my first test run were both sparkling clean and passed the soap bubble test, so no more hand-re-rinsing. Yay.
And it will be handy to be able to glance at my phone to see how long before it's done.
Small victories.
Update 2022-12-28: It's been working great so far, but after two and a half years of near daily use it started stuttering in various ways and occasionally restarting itself mid-stream. It seemed to be due to the push-on jumper cables either becoming too loose after years of jiggling or perhaps oxidizing and self-insulating a bit, so I simply carefully removed their plastic end-caps, slid a small bit of heat-shrink insulator over them, plugged them back in, soldered them in place, and slid the insulators down over them. (I didn't bother to shrink-on the insulators in case I ever want to unsolder anything. Though a couple got too close to the soldering iron and pre-shrunk which was annoying...)
While I had it on my workbench I also updated the firmware a bit with a standby mode and jump command, which between the two allow my home automation server to instruct the dishwasher to resume where it left off if it's been opened mid-cycle (say because I hear something clanking and want to reposition the dishes, or just want to add one more thing...). And it also opens up the option of having the dishwasher not run until you hit start (in our case on our phones, which are the wands we control everything in the house with), though for now I like that it just runs when you close it.
Did all of that yesterday, and plugged it back into the dishwasher today and it's running great again, now with resume.
Update 2023-03-28: Sadly some of the relays are getting sticky and are no longer reliably opening (so, a mechanical problem inside the relays themselves now, not just flaky wires), so I'm calling this controller dead after three years of daily service. Not terrible, but not great. I wonder if solid state relays would have been better? (It's odd because, if I recall correctly, a very similar relay was used on the original controller board. Maybe just bad luck, but I suspect something about the service cycle didn't sit well with these particular relays and the same problem would happen again.)
Update 2024-02-06: Didn't have the time to replace the dishwasher so jurry rigged it a bit longer, then eventually just ordered another $9 relay board and re-built the original jumper-cabled version in a couple hours (since I was able to reuse the main wiring harness) figuring it will buy me another two to three years... "Good as new" again. Heh.
[<< | Prev | Index | Next | >>]