Wednesday 27 July 2022

DIY repair nightmare

After returning from a long holiday over winter our Bosch dishwasher worked once and then failed during its second use. It came up with this error at the start of the drying cycle and the dishes were cold and not as clean or dry as usual.
I am normally able to diagnose and fix our electronic or electrical appliances, so I set about trying to fix it myself rather than following the advice on the display to contact customer service, perhaps a mistake! I did turn it off and on a few times but it then came up with a communication error.

The model number is SMS88TW01G/01 and we bought it in 2015 for £749 delivered. It was expensive at the time but it normally does a good job washing and drying, is very quiet and energy efficient, so I didn't feel like replacing it. 

It turned out to be the longest and hardest repair I have ever done and even involved plenty of 3D printing, so I thought I would document it here in case it helps somebody else. Obviously only attempt something like this yourself if you understand the dangers and do so at your own risk.

I could find lots of YouTube videos for repairing Bosch dishwashers but none for models like this that have the Zeolite drying system. Either they are not very common or don't often break, or are too new to have broken yet.

Googling fault code E02 gives this unhelpful hit on the official Bosch website.

Unofficial repair guides indicate this error is a problem with the heating element, wiring, thermostat or the control board, in particular "the relay". This matched the symptoms as the machine ran cold but the communication error was still a mystery, so I decided to investigate the heating system. I removed the top and side panels simply by unclipping them.

The main electronic control unit is easily accessible at the bottom back right corner of the machine after removing its clip on cover.

The heater connections are the thick red wires and can be probed by removing the connector and inserting 6.4mm spades into the female connector slots. The other connectors are edge connectors directly onto pads on the PCB. They can be probed by putting them over a piece of veroboard as they have the same 0.1" pitch as the tracks.

Research with Google informed me that there are two generations of heating system in Bosch dishwashers. The original heater was like a kettle element that the water flows around.

The thermostat was a separate unit that contained a thermistor and a thermal cutout:

The control unit had a single relay and the thermal cutout was wired in series with the element to prevent the water getting too hot in the event of a failure. Simple and straightforward and each component could be replaced separately. However, later models like mine are far more complicated!

The heater is a metal cylinder that the water flows through and has a thick film element printed around the outside. There is no thermal cutout, so for safety it has two thermistors printed or maybe surface mounted onto the cylinder.  You can't get just a replacement heater from Bosch, you have to get the whole assembly, which includes the wash pump.

The two thermistors are identical but they have different pullup resistor values at the control unit inputs that feed two analogue inputs on the MCU with two different voltages for the same temperature. So it can detect a faulty thermistor or wiring by working out the temperature two ways and checking they agree. 

Instead of a single relay it has two relays, one in live and one in neutral and these are driven by three transistors, one on the +12V to both relays and one in each ground of the relays, so everything is redundant. A single failure will not cause the heater to be permanently on. Seems like a lot of complication just to remove the need for a thermal cutout and if the MCU or its firmware failed it could get too hot. Presumably it has a watchdog as well.

Zeolite models like ours are even more complicated because they have a second heater and a blower fan that draws air from half way up the inside of the wash tub, blows it through a heater, through the zeolite granules and back into the bottom of the wash tub. During the first water heating of an eco cycle the hot air heater is used to both dry the zeolite and heat the water indirectly. The main heater then takes over to get the water to its desired temperature. During the final rinse the main heater gets the water to a high temperature so that the dishes are steaming hot. After the water is drained the blower sucks the moist air from the tub and blows it through the zeolite. The Zeolite absorbs the water vapour and gets very hot due to an exothermic chemical reaction, aiding in the drying.

So there is a third relay and a fourth transistor to switch the neutral to the second heater, sharing the switched live with the main heater. This heater does have a tiny axial thermal cutout in series with it. I don't think there is any other temperature control for it other than the two thermistors attached to the main heater see the water temperature rise when the hot air heater is on. Note the air heater isn't used in the drying cycle, just the blower and the zeolite. It claims to be energy efficient because the heat put into the zeolite while it was heating the water is released when it absorbs the moisture, so you get the water absorption aspect of the drying for free. The vapour will be released again during the heating cycle of the next wash when the dishes are wet anyway and presumably condenses. Some other dishwashers open their door at the end to get rid of the water vapour but that would make your house damp.

Another energy saving mechanism I noticed when I opened the machine is there is large thin water tank over most of the left side of the machine that is filled with clean water at the end of the cycle. So the water for the next cycle is already at room temperature at the start, so needs less heating than cold water straight from the main would.

I tested both heaters and found they had the correct resistance and no apparent leakage to ground or to the thermistors. The thermistors both measured about 13K, which seemed reasonable for a 10K thermistor at room temperature and they had no leakage to ground. I added a cup of warm water to the sump and they both reduced in value by the same amount. I could find no fault with the electrical side, so I decided to turn my attention to the control unit.


On opening, it immediately became apparent that there are two separate control units, the other is the button and display controller in the door of the machine and they are linked by an optically coupled serial bus via the little PCB on the left and this serial comms is presumably what the communication error refers to.

The main controller is not isolated from the mains. The mains gets half wave rectified by a single diode, producing a 340V DC rail relative to mains neutral. This powers two three phase brushless DC motor controllers. One drives the main wash pump motor and the second one is multiplexed between the drain pump and zeolite blower motors by the white relay top centre. This makes the motors quiet and reliable and means the controller can vary the speed.

The four SOT223 packages top left are triacs. One drives a small AC synchronous gear motor that rotates a disk with holes in it to route the water from the circulation pump between the upper and lower spray arms. It has an index switch so it knows where it is. I think the rest drive various solenoid valves.

The three SOT223 packages top right of centre are transistors for driving high voltage DC solenoids. One drives the soap dispenser solenoid.

The TNY268PN seven pin DIP package near the centre of the PCB is a switch mode regulator that steps down the 340V to about 12V referenced to the 0V rail of the board, i.e. mains neutral, and that is further regulated down to 3.3V for the ST ARM MCU by the tiny 6 pin chip at the bottom. Having the main board referenced to neutral makes sense because it means the motor controllers and the triac drives, etc, can be easily driven by the MCU without any isolation and also means the switch mode regulator doesn't need an opto in its feedback loop.

I presume for safety reasons, the touch sensitive button controller in the door is isolated from the mains, hence the optocouplers for the comms. It also has a separate 12V supply coming from an isolated second secondary winding on the switch mode transformer. This is the leftmost brown electrolytic, small diode and the white two pin connector going to the opto board. These are the only parts of the main board that need an isolation gap from the rest of it. So instead of the usual isolation gap that splits the circuit in two there is just a small isolated island in the middle and an isolation gap across the middle of the opto board.


Curious to know why there are four optos and what could be wrong with the serial comms I reverse engineered the circuit. Here is a my very scruffy schematic:


Two of the SFH6156 optos together with four transistors and two diodes implement the transmit and receive coupling, which is complicated because there is a single half duplex bidirectional comms line. The transistors and diodes are needed to decide which side is pulling the line low and activate the opposing opto to pull the other side low without forming a latch by turning both optos on. There are also three zeners to clamp the comms to 5V despite the supply to the opto board being 12V. Odd it is 5V when all the MCUs run at 3.3V, so they have more transistors in their interfaces to the comms line.

A third opto controls the supply to the other two, so that they get powered off by the main controller to save power when the machine is in standby. The fourth opto is needed because when the comms optos are powered down the button controller can no longer send messages. So when you touch the power on button this fourth opto is turned on to wake up the main controller, which then powers up the other three optos to allow serial communication.

Since I had two faults to deal with I wondered if there was something systemic wrong with the board, such as the power supply. I powered it up on my bench using my 3D printed isolated variac supply that I use mainly for repairing switch mode PSUs, safely.


The power rails seemed fine. The isolated supply was about 12V, the non-isolated supply of the main board was 13.4V. I don't know if that was correct but most things are run from the regulated 3.3V supply derived from it and that was spot on. 

I also couldn't find anything wrong with the opto board. All the optos seemed to be working and their data sheet advertises "Low CTR Degradation". I didn't know that was a thing but apparently the LEDs in optos slowly wear out and that is bad when they are used in the feedback loop of power supplies.

My attention moved to the relays. They looked fine and the soldering to the PCB was solid. It wasn't easy to test them on the bench because the board doesn't do anything without its button controller and all its I/O. I didn't want to put power on the relay coils to test them as it risked damaging the board, so I made a little 3D printed box with seven LEDs to display the state of the four transistors driving the relays and the three relay contacts.



 I soldered it to the PCB using a ribbon cable that fed through a gap in the plastic case, so I could run the machine relatively safely.

I put the controller back in the machine, took out the lower basket and spray arm and put a thermocouple in the sump. I ran the quick wash cycle that only takes 45 minutes and heats to 45°C for its wash cycle. The thermocouple said it heated to 43C, which is close enough for me, and it ran the complete cycle with no errors. The LEDs worked as expected.

Thinking it might have just been a loose connector I filled the machine with dishes and ran the normal eco cycle that takes 3.5 hours. This time it ran the cycle cold and stopped with the EO2 error again, so back to square one.

I managed to find out how to get into a self test routine by holding the Pre-Rinse and Info buttons while powering it on. That displayed two recent errors which were the E02 and an aqua sensor calibration error. The aqua sensor measures how dirty the water is and you can select programs that vary the wash cycle accordingly. I don't think it is used by the quick wash or the eco programs we use.

After doing several steps the self test got stuck due to a comms error. I tried running it again but that caused a flood because it seemed to fill the machine that was already left full by the previous test not finishing. The water level overflowed the door hinge, went into a gutter which has a down pipe into the base of the machine. The water collected there and triggered a float switch that is a disk of expanded polystyrene under a microswitch. When the flood sensor is triggered all the machine will do is run its drain pump. Since that can't empty the base the only way to fix it is to bail out the base or wait for it to evaporate. I did the latter and decided to study the controller while I waited.

I noticed that an SOT transistor near to the thermistor inputs was a bit crooked, so I poked it with my fingernail and to my surprise it moved. It is the left most transistor here.


I desoldered one leg and it fell off in pieces. It had a hole through the middle like it had been blown up but tracing the circuit I found it was just switching a 150Ω resistor to ground. It looked like it was an LED driver for one of the optical sensors. I found a wiring diagram for a similar machine and it seems to be where the aqua sensor connects, so it must be an optical sensor and the LED is switched off to save power and sensor life. So that explained the aqua sensor error.

The SMT marking code seemed to indicate it was a Nexperia PDTC143ZT NPN "Digital" transistor, which has a pair of internal resistors connected to the base. I confirmed this by measuring the base resistance of another device on the board with the same markings. I had to order 50 from RS at about 25p each. It was tempting just to stick a MOSFET with the same footprint on as it would have worked but might have needed a pulldown resistor between source and gate. I can probably use the rest in other projects where I would normally use a MOSFET to avoid the need for two resistors.

The thermistor inputs just connect to two pullup resistors and then the MCU inputs. One is 8.2K and it measured spot on my UNI-T UT61E 22000 count DMM. The other is 4.7K and it measured nearly 1% low. The resistors looked special because they were green and bigger than others. I think they might be high stability / close tolerance so, as I was putting an order into RS anyway, I ordered a 0.1% 25PPM high stability resistor as well but had to buy 20 at 42p each. I didn't think it needed to be that accurate though because thermistors are usually only accurate to one percent at most. I have no idea how close the firmware expects the readings to track before it gives an error but I assumed it would allow a reasonable tolerance before giving an error, so I didn't expect it to fix the E02 errors.

As I wasn't really making any progress in diagnosing the two original errors I decided to bring in the big guns. I have a Mooshimeter Bluetooth enabled multimeter that can can log to an internal SDcard, so I thought that was ideal to log the thermistor voltages over a full wash cycle. 


The only problem is it has only one auto ranging voltage channel. The resistance input can be used to measure voltages but only up to 1.2V, so I needed an external attenuator. I decided to 3D print one that would maintain the cat III safety rating. I was, after all, connecting to a controller that is not isolated from the mains.
























I used the pins from a couple of 4mm banana jacks and 3D printed threads in the base to accept them at the standard 3/4" pitch used for multimeter input terminals. The input impedance is 10MΩ and there is a 10 turn pot to fine tune the ratio to 10:1. Strangly the Mooshimeter seems to have an unmeasurably high imput impedance on the Ohm socket when used as a voltmeter, so I didn't need to take that into account.

One problem I did have was bit-rot because I bought the meter in 2016, so of course it doesn't work properly with my latest Android phone. It wont stay connected long via Bluetooth BLE. I had to dig out my previous phone and that did work except emailing the log files from the app no longer works due to some permission problem. I had to find the uploaded file in the Files app and email it from there. It is crazy buying hardware that needs an app to function because it wont stay working for long unless it is actively maintained. Especially true for obscure test equipment because I only use each item occasionally. My home made IOT devices serve up a web page over Wifi, so they should stay working a lot longer because they work on any phone, tablet or computer without an app, and can be scripted with Python and curl.

My UT61E multimeter has an optically coupled serial interface, so I can connect it to my laptop to log readings from live equipment. I decided to use it to measure the 3.3V supply to see if that ever goes flaky. Again that has bit rotted because I bought it in 2015 and this is the first time I needed the serial link. The serial connection now needs a USB to serial converter because even my old laptop hasn't got real serial ports and I couldn't get the software to run on it. Not sure why, but it was pretty crap as far as I can remember. I managed to find a Python script on Github that I could hack to do what I needed. 

I couldn't get the serial interface to work until I took it apart and realized it needs RTS to be negated because it uses it for a negative supply rail. I rewired it to use RXD as that isn't used by the interface, so is always driven negative by TXD from the host.

To investigate the comms errors I eventually used three more instruments. I attached my Saleae 8 channel logic analyser to the optically isolated end of the serial bus. It connects to my laptop with a USB cable, so isn't isolated, but that is OK for the isolated end of the bus. 


I also eventually added my Analog Discovery USB scope to the isolated serial bus as well. Both of these devices still worked well, without bit rot.


On the non isolated end of the serial bus I added my OpenScope WiFi oscilloscope, powered by a USB power bank to keep it isolated. Here it is in its 3D printed case:



I backed this on Kickstarter and it shipped in June 2017, so this was actually the newest piece of equipment but it has bit rotted the most and took me ages to get working. I think it was sold until 2020 and then suddenly retired and no longer supported. Although the software is open source it hasn't been updated and the Android app seems to have disappeared from the Google Play Store, so only works on my old phone again. Worse than that, the web based interface served from Digilent's servers no longer works because modern browsers don't allow cross origin browsing. 

When you open the web page served by the scope it redirects to waveformslive.com and that tries to access the scope on your home network and that is now blocked by the browser. I tried a Chrome plugin that is supposed to get rid of CORS errors but I couldn't get it to work. You are supposed to be able to host the website from the OpenScope itself by putting it on its SDcard, but I couldn't get that to work either.

In the end I had to host it on my laptop using the Digilent Agent as a server and that did work. There is however a bug in the scope that causes it to regularly lose its WiFi connection and need to be reset when it is being rapidly triggered, but it will stay connected waiting for a trigger, so I did manage to use it.

So by the time I received the RS order, installed the new parts and got all this equipment attached and working by curing the bit rot and designing and printing the attenuator, the machine's flooded base had long dried out. 


This is what it looked like before I had attached the Analog discovery. I soldered wire wrap wires to the PCBs and brought them out of the case to pin headers to allow probes to be connected. I also have a power monitor connected to the mains input so that I can see how much power the machine is using. It is only about 160mW when in standby mode, which is impressive. It takes about 4W when it is active but doing nothing. I.e. with the display active before the program is started. When the various motors are running it takes between 20 and 40W. The zeolite heater takes around 1.5kW and the water heater takes about 2.4kW.

So armed with all this equipment I ran a quick wash and it worked perfectly. I then ran an eco wash and it failed at the drying cycle with a comms error. Since I changed the thermistor pullup resistor and the transistor I have never seen the E02 error. I can't imagine the small error in value caused the problem because when I graph the resistances calculated from the voltages they only stick within 3% of the same value and when cold water is filling the sump, or the heaters are being switched on or off they can drift about 10% apart. This seems reasonable because heat travels relatively slowly through metals due to the heat capacity relative to the thermal conductivity. So even if the thermistors are mounted close together thermal transients may hit them at slightly different times.
This shows a quick wash with the voltages logged every 10 seconds and then used to calculate the resistances of the two thermistors. The program starts at the first dip on the left, which is where the water that has been standing in the tank on the side of the machine is released into the tub for the cold prewash. There is a small temperature increase at that point, so it must have been warmer than the sump water. Around the 100 mark the water starts to be heated to 45°C for the wash cycle by the main heater. I think the two peaks are where more cold water is added. The final slope on the right is where it heats the water to 85°C for the final rinse. It then finishes and the machine slowly cools down on the right.

The log of the 3.3V supply voltage every 100ms showed it was pretty stable:


So replacing the resistor somehow or other seemed to fix the EO2, and replacing the transistor fixed the aqua sensor error, but I consistently got the comms error during the drying cycle of the eco wash, when the machine is at it hottest. Thinking it might be temperature affecting the electronics, I ran the machine with the door controller and the main controller hanging out of it and it still failed in just the same way, so I then started to reverse engineer the serial protocol.

This is a typical packet captured by the logic analyser and decoded:


The data is sent at 9600 baud with a start bit, 8 data bits and one stop bit. The first byte (0x08 in this case) is the length of the packet's payload. The first nibble of the second byte is the destination device address. I came to realise it is a multi-master protocol and there are actually three devices. Address 1 is the main controller in the bottom of the machine, address 2 is the button controller in the top of the door that also controls a small LCD. Address 5 is a controller for the larger LCD on the front of the door. The bottom nibble of the second byte appears to be a packet type. Then comes the payload data, 8 bytes in this case, then a 2 byte CRC16 checksum. The 0x2A on the end is an acknowledgement sent from the receiving device. The top nibble is its address and the A seems to mean a positive acknowledge. 

It wasn't obvious the last byte wasn't part of the packet at first. I thought it was an end of packet marker until I looked at the data on the OpenScope:


Here you can see the last byte's logic zeros go a bit lower than the preceding bytes. This is because the processor on the local side of the bus can drive it to zero but the device on the other side of the opto can only pull it low through a diode, so is a little higher. It was also a small differences in logic levels that made me realise there was a third processor in the door. This is actually a Microchip PIC24FJ256 that features a built in display controller and graphics accelerator.

The button controller sends packets to the main controller when you press buttons. The main controller seems to send regular status packets to the button controller and that forwards the status information to the display controller to update the big display. For example I could see a value in the payload that corresponded to minutes remaining in binary and that is shown on the main display during a wash cycle.

I don't think the main controller ever talks to the display controller directly. I am not sure how bus arbitration is done because I never saw a collision, but it seems possible if you hit a button just as a status message is due both the button controller and the main controller could start a packet simultaneously.  They can both see their own data on the bus, so if there was a clash they could detect it and retry like Ethernet. Or maybe the button controller records when it got the last status message and knows when the next one is due.

Using the logic analyser and the two scopes plus a multimeter looking at the supply to the optos I couldn't find anything wrong with the serial comms. Even when it was displaying comms error all three devices were still talking to each other and being acknowledged. The packets were well formed at the transport layer and had the correct CRCs. There was no obvious way to know what all the packets mean at the application layer but after doing all this reverse engineering and monitoring I decided the communication error was probably a red herring and I needed to look elsewhere. My theory is the main controller goes into an error state and starts sending messages that the button controller doesn't understand, so it reports a communication error.

The communication error now always happened at the same point in the eco cycle, 40 minutes from the end where it had just done the hot rinse and drained the water. It waits a few minutes doing nothing and then turns the blower on. That is the point it fails. I knew there wasn't a problem with the blower motor because that is used earlier in the cycle to dry the zeolite with the heater on. At this failure point it blows hot steamy water over the heating element while it is switched off. When the machine cools down a bit the comms error clears. So if I had run it overnight, like I normally do, the only noticeable effect hours afterwards would be the dishes would not be quite as dry as normal.
 
When I was looking at the board near the faulty transistor the nearest chip is a SEN013, which is described as a "Zero loss high voltage sense signal disconnect IC".  Note that ,although the 3 channel version of the chip is fitted, only two channels are used, so the SEN012 could have been fitted.

I had also noted that the LED that was monitoring the output of the live relay glows dimly even when the relay is off, so I decided to investigate the relay mains circuitry. This is what I found:


The SEN13 is used to monitor the state of the heaters. When all the relays are off  then live is fed to the heaters via 220K and monitored by an analogue input of the MCU and the neutrals coming back from the heaters are summed and then monitored by the second channel of the SEN13. So the MCU can detect relays being open or shorted, heaters being open or leaking to ground. The SEN13 avoids wasting any power when the machine is in standby by disconnecting the sense lines. There is also a special chip that disconnects the X2 cap discharge resistor when the mains is on, so every measure is taken to reduce the power consumption.

So now I finally had an idea of what was going wrong. I monitored the sense inputs to the MCU with my isolated meters and found that the voltages dropped as the machine got hot and steamy. Suspecting the zeolite heater was leaking I measured its resistance to earth with a multimeter and still got an open circuit but when I reversed the probes my meter freaked out on the Ohms range. The heater was acting like a battery generating a few hundred mV. Lesson learned, always check for earth leakage in both directions! I still might not have not found the fault at the beginning because it was only leaky enough to cause a fault detection at the start of the drying cycle when it was hot and damp.

To test that my theory was correct I replaced the heater with a small incandescent bulb to fool the control unit it had a non-leaky heater. I placed a bridge rectifier and a relay in series with the bulb and used the relay contacts to drive the real heater directly from the mains via a second wall socket. The bulb had a small Edison screw base that I didn't have a socket for, so I had to 3D print one. Here is my lashup:


And here it is connected to the machine while it was heating the zeolite:


The machine was able to complete the eco cycle without a communication error, so I had proved my diagnosis correct after about 3 months of testing, reverse engineering and head scratching. It was driving me mad. My wife and friends said I should scrap it and buy a new one but after I had invested so much effort I felt I had to press on. It was only 2 days before we went on holiday again for a few weeks, so it as good to solve it before we went after the mandatory 90 days at home.

On return it was tempting to just minaturise the bodge and make it permanent because the zeolite heater is very difficult to access. When you blow steam into a bare heating element connected to mains live I don't think it is a surprise that you might get some leakage and I don't think it really causes a problem when the heater is enclosed in a steel tube that is grounded and the heater is already dissipating 1.5kW and sinks about 6A.

Eventually I plucked up the courage to attempt to remove the heater and see if it could be fixed by cleaning it.

The heater should look like this:


It just presses into the inlet tube of the zeolite tank and is sealed by the top o-ring. The peg on the side ensures the correct orientation.

But then it is held in place by the blower fan, which seals to the lower o-ring and has three barbed prongs that lock into slots in the metal flange of the tank.


The blower needs to descend to separate from the ventilation duct, so I figured I would need to remove the base of the machine. How to do that was not at all apparent. Older machines just have four screws to undo but all I could see were two bent tabs at the back of the machine. I couldn't see how the front was fixed. Fortunately I found this video that showed how to remove the base of the same generation machine. It wasn't one with a zeolite heater but the basic construction was the same. 

I would never have worked it out myself because there are three hidden plastic tabs that need to be released. To get to two of them you have to remove two covers over the door counterbalance spring cords, remove the cords and then remove the guides for the cords, the tabs are underneath those. Who would have guessed that?

You also need to turn the machine upside down, so you need to empty the sump. I first tried to use a small water pump I bought to make a laser cutter but it wasn't self priming, so that was a fail. Next I decided to use my vacuum pump but I needed to separate the dirty water from the air to stop it entering the pump.

I found this air assist pop bottle pressure filter on Thingiverse that screws onto a standard bottle thread and connects two pipes and allows a third one inside, so the water goes to the bottom while air is drawn from the top. 

I found a PET pop bottle was no use for vacuum, and neither was a thicker HDPE bottle used for acetone, as they just collapse. So I ended up with a glass vinegar bottle and that worked well to empty the sump. I think I will do that each time we go on holiday from now on.


So that was the final bit of 3D printing for this project.

I managed to remove the base to get to the pump and with great difficulty remove the three barbed prongs that requires three hands and three pairs of pliers. When I removed the heater it left its glass tube behind because the inside of the tank was thick with rust that jammed it solid. I broke the glass removing it and then I had to Dremel out the rust in order to make room for a replacement heater.

The replacement was £129.40 including next day delivery from Bosch. Here is the new one next the old naked one:


The corroded electrode encased in the white ceramic tube in the foreground sits at the bottom of the glass tube when it is horizontal and is there to detect water. It connects to the control unit via a brown wire that has a mystery inline component encased in resin and tape. It measures as a 1nF capacitor and must detect AC leakage from the element if it gets submerged. 

After breaking the glass it was hard to determine what was causing the leakage but there was a lot of black charcoaled strips of material amongst the elements that I think was the remains of the silicone glue that joins the glass to the base. Here are some small bits of it:


Perhaps it became detached and the fan blew it into the elements and somehow bridged to the rust.

This is a view into the tank after I had Dremeled most of the rust out of the inlet tube. Notice how corroded the bottom of the tank is (at the top of this view):


It was a total mess of corrosion and I think that it is a design fault to use galvanised steel for something that has hot water vapour passing through it regularly. My understanding is hot water and steam are far more corrosive than cold water and galvanised steel doesn't even last long outside. I don't know why they didn't use stainless like the rest of the tub.

A replacement zeolite tank is £159.41 so I didn't feel like replacing it, but I don't know how long it will be before it rusts all the way through, especially as there is now bare steel where I Dremeled it. If it did leak it would only be water vapour that would escape, it shouldn't flood as the inlet and outlet are above the high water line.

Putting the base back on the machine is difficult because it is obviously designed to be assembled the other way up at the factory, but that would need a hoist. I tried to improvise one with two stepladders, a plank, four luggage straps and a ratchet strap but that was a fail. 

The difficulty putting the base on upside down is that there is a big weight at the back to stop the machine tipping forward that isn't fastened to anything, it just sits in the base. On the zeolite machine there is also a metal heat shield under the zeolite tank that just sits in the base as well. It falls out when the base is removed upside down. So again you need lots of hands to hold them in place while the base is clipped back on. They are then trapped in place.

Then I had to find all the parts spread around the house for four months and remember where they all went. Amazingly there was nothing left over, not even the usual screw, but there aren't that many in this machine. Lots of plastic parts just clip together. Obviously designed for cheap and easy assembly, not easy repair.

I ran the self test and it went through something like 75 steps in an hour and a half and seemed to pass them all. I wish I had put crockery in because it was twice as long as a quick wash!

So the machine is up and running again but having three different, unrelated faults occur at the same time is weird. The broken transistor seems to have been a manufacturing fault. Assuming it worked when new, it must have been soldered on crooked, in a way that left it under great stress, and then it later cracked. 

The earth leakage problem was misreported as a comms error and that wasted so much of my time. And the E02 error fixed by changing a resistor value by a fraction of a percent makes no sense, so perhaps it will come back to bite me. Or perhaps it was another manifestation of the earth leakage problem because the first heating in the eco cycle uses the zeolite heater. That would explain why the quick wash cycle tended to work because that doesn't use the zeolite heater at all. Better error codes and available  schematics and wiring diagrams would have made the job so much easier.

Saturday 7 August 2021

ESP32 auto program fix

Out of the box my ESP32 dev board required me to hold down the BOOT button at the start of programming to get it to program from the Arduino IDE. The board has a pair of transistors to connect the DTR and RTS lines to EN and GPIO0. This is intended to enter programming mode automatically but seems to have timing problems. If I don't hold the button I get:

Fatal Error Occurred: “Failed to connect to ESP32: Timed out waiting for packet header”

Looking around the internet I found a recommendation to add a 10uF electrolytic capacitor between EN and ground. While this did work for programming it seemed to inhibit the board reset at the end of programming. I found 1uF worked better, which let me use a small ceramic SMT cap, which is a lot neater.


The nearest ground is the top right pin of the module and I could have angled it to reach that but I found it easier to just link it to the metal can.

Investigating why it doesn't work I found the setup and hold times for the strapping pins in the ESP32 datasheet:

To enter programming mode GPIO0 needs to be low as EN transitions to high and stay low for 1ms after that.

This is the two transistor circuit on my board which is labelled ESP32 DEV KIT V1, which implements the truth table shown.

The truth table shows that EN and IO0 can't go low at the same time, so the zero setup time cannot be achieved unless both lines change together. Here is what it looks like on a scope after I added the capacitor.


During reset RTS is low and DTR is high, which makes EN low and IO0 high. At the end of reset DTR goes low and then about 1ms later RTS goes high. This would work without the transistors but with them EN starts to go high 1ms before IO0 goes low, so it violates both the setup and hold time. Adding the capacitor delays EN long enough for IO0 to be low as the chip comes out of reset.

My best guess is the transistor circuit is there to ensure random serial monitors don't put the board into programming mode if they assert both DTR and RTS. To work without a capacitor RTS and DTR would need to change state simultaneously. There is a long discussion about it here: https://github.com/espressif/esptool/issues/136.

Friday 16 July 2021

Third Hand

A problem I often face hand soldering surface mount components is keeping them in the correct position while soldering the first end. The surface tension of the solder invariably moves the component.  When using paste and an oven the surface tension is the same on both ends and pulls the component into position. Solder paste and hot air works similarly but it is easy to blow the component away.

One solution is to tin the pad and the end of the component first and then use tweezers to hold the component on the pad while applying the soldering iron to the tinned end. However that requires a steady hand and today, after having two strong cups of coffee, my hands are far from steady!

Some time ago I bought a PCBite probing kit from Elektor. This consists of a steel base, four magnetic clamping posts to hold a PCB and four sharp tip probes with magnetic bases and flexible swan necks intended for making measurements. It works well for its intended purpose although I think the flexible necks would be better if they were stiffer.



I found they make an excellent third hand for holding SMT components in place while soldering.


Here it is holding an 0805 resistor, they are the smallest parts I am comfortable soldering by hand.







Saturday 12 December 2020

Sinkholes

Continuing my series of adventures in 3D printing holes the correct size, I turned my attention to countersink holes. 

I don't normally use countersunk screws in 3D printed parts because they create lateral stress, whereas other forms of screw exert a purely compressive force, which can be spread by a washer. However, I am currently designing a part that needs flush screws in its base that is only 4mm thick, so there is no room for a counter-bore to bury a flat head.

First I had to improve my countersunk screw model because I previously just used a 45° cone with a sharp edge. In practice the edge has a nominal thickness of 1/10th of the screw diameter. That means if you countersink the hole with a normal conical countersink drill bit it has to be oversized to sink the head flush, and then leaves a gap around the circumference.



So the ideal shape for a 3D printed hole is an improvement because it can have a straight section at the top.

The complications are that, like horizontal holes, we have to take into account the rounded staircase produced by the filament layers and also, like vertical holes, we need to use polyholes to get the correct diameter when printed.

The cone makes contact with the rounded filament edge above, rather than the centre of the extrusion, where the slicer samples the model, as shown below:

In order for the extrusion to not overlap the cone it has to be offset outwards by a distance $x$, which is simply $(\sqrt2-1) r$ where $r$ is half the layer height. Applying that to the line equation of the cone and limiting the result to be in the range between the screw clearance radius and the screw head radius gives the correct placement for the rings of filament that just touch the cone without overlapping.


To make each of the rings print the correct size I make a stack of polyholes to subtract from the model.


These are double sided so they can be subtracted from the either the top or the bottom of a hole. As the slope is 45° they should be printable either way up.

This is what it looks like subtracted from a part:



I have added an OpenSCAD module called screw_polysink() to NopSCADlib to make printed countersinks. I haven't tried printing it yet but it should certainly work on a top surface. It might get a bit scrappy printed as an overhang without support.

Thursday 23 July 2020

Over cooked it

When I was printing 24/7 for about 5 years I never had a problem with filament absorbing moisture because the heat from the machines kept the rooms they were in hot and dry and the filament was stored in the same rooms as the printers. In fact in winter it was so dry I had to buy a long conductive ESD mat that runs the length of my workshop and wear ESD ankle straps to prevent getting sparks off everything I touched.

Since I retired I print more sporadically and tend to go away in winter and leave the heating at only 12°C. I still didn't have a problem with the white ABS that I got from Germany for kit production. It was unusual in that its natural colour was white instead of cream and it didn't smell much while printing. I used to find that I might get one or two bubbles in the skirt round the object but after that the rest of the print was fine. It appeared that filament sitting in the extruder from the last print would absorb some moisture over time but the rest on the spool that hadn't been melted did not, no matter how long it was left.

I also got some black ABS from the same German company and that is totally different. It bubbles very badly and needs to be dried. It also smells like ABS when it is printed. I never got good results from printing it, so I put off using it for years until I ran out of white. I then decided to tackle the moisture problem. Inspired by RichRap's heated dry box, I designed a parametric heated dry box that I could tailor to fit any size spool.

When I made the Dibond version of Mendel90 I noticed the dummy load resistors for the ATX PSU ran a lot cooler than they did on the MDF version. I came to realise that Dibond makes quite a good heat spreader even though the aluminium layers are only 0.3mm thick.


I also had lots of 47 Ω 50W TO220 resistors from various heated bed iterations that didn't go too well. Since this doesn't need to get very hot or need much power I thought it would be a good way to use them up.

I have a parametric box in NopSCADlib that is made from Dibond panels and printed brackets that can be scaled to any size that fits my CNC mill, so it was easy to wrap that around my large 2.4kg spools and add 12 resistors along three sides. The spool runs on 608 ball bearings between penny washers, there is a thermistor to monitor the temperature and a small fan to stir the air around.


I ran the resistors in series from half rectified mains to give a total wattage of 51W. I earthed all the panels and covered all the connections with heat shrink sleeving but it wouldn't pass any safety standards as the wiring isn't double insulated. Safe enough for me though as I don't need to put my hands inside it but I wouldn't recommend it. 

For my smaller 1kg spools I use 9 resistors and wire them in parallel for 12V operation. That gives 28W, which is enough for the reduced surface area and much safer.


To reduce the energy consumption I obviously needed to insulate the outside of the box, so I suspended it inside another slightly larger box and filled the gap with cotton wool. It is a lot nicer to work with than fiberglass or rockwool and quite cheap in the quantities needed. It is also just the right thickness to fill the gap, which is dictated by the corner fixing blocks. Even without the cotton wool the air gap gave quite good insulation. The only connection between the inner and outer cases is a few printed standoffs and the wires and filament exit guide.


It is completed by a hinged double door made of acrylic sheets with a hygrometer and thermometer module in the inner door. An arduino Leonardo with an LCD, some buttons and a couple of MOSFETs controls the temperature and the fan and keeps a record of the heater duty cycle. Again parts I had to use up.

So basically I created a 3D printed fan oven! 

The base of the outer box is extended, so it bridges the frame stays of my Mendel90s after removing the spool holders. Four fixing blocks stop it sliding off but are only screwed to the base, not the printer., so it can be lifted off and they then act as feet.


The mains version is controlled by a stand alone Arduino thermostat I had previously built to control a beer fridge. Another reason the first version was mains operated.


I have parts to make a third one the same as the second, after that I will probably make it headless with an ESP8266 and an I2C temperature and humidity sensor.

To dry the ABS filament I set the temperature to 80°C for a few hours and then left it at 50°C, even when the printer is not in use. The relative humidity in the box drops to about 19%. In the room it is about 60%. When I was printing 24/7 it used to be well below 50%.

As well as stopping bubbles it improves surface finish making it more glossy, makes bridges pull tighter, completely stops nozzle ooze at the end of a print and even reduces the ABS smell while printing to almost nothing.

At the end of a print I retract an extra 1mm and turn off the heater before moving Z back to the top. Without the dryer I used to get 10 to 20mm ooze out of the nozzle as the extruder cooled down. I had always assumed this was due to gravity but it is in fact due to moisture turning to steam pushing the filament out. When it is dry the surface tension must be sufficient to stop any flow due to gravity.

I was used to snapping off the ooze before I start a build, it had become an unconscious action, but now there is nothing to remove. It will be a big advantage when I make a multi material machine as there should be no ooze from the idle extruders while another is being used.

The reduction in smell was a complete surprise. Before I dried the black ABS it seemed to smoke as it came out of the nozzle. I now realise that was water vapour and it must carry off some volatile products. It now hardly smells at all when printing but if I stick my nose in the dryer it does smell of hot plastic, even though it is only at 50°C.  I guess the moisture it has driven off carries some VOCs with it.

About a year ago I got some wood coloured ABS in the UK which was even more affected by moisture than the black, so that is when I built the second smaller dry box, around October. After drying it printed very well. I made this replacement handle for a curtain puller with it.


After switching the dry boxes off when we went away for the winter I turned them on again in March and they have been on ever since. I last printed with the brown plastic at the end of May and it was fine but when I tried to use it yesterday it has gone super brittle. The coil has a very strong heat set, something I don't like about 3mm filament on 1kg spools, and bending it straight now causes it to snap.

I was trying to use it on my original MDF Mendel90 that is now encased in a box with a chamber heater. The filament feeds from the top of the box rather than through a PTFE tube that runs all the way to the extruder. The part that was outside of the dry box for about seven weeks was still ductile but had moisture in it. When I pulled the dry part from the box through it just snaped, so I can no longer print it on that machine. 


It does still seem to work on my Dibond machines that do have the PTFE tube all the way to the extruder. That keeps some of the coil's curve and doesn't require it to be fully straightened. 


And the printed objects don't seem to be brittle at all. I haven't done any proper strength tests but a quick test bending a small 100% filled block with pliers it bent and got white bruises like ABS normally does.





So keeping brown ABS at 50°C for a few months seems to completely denature it but a melt cycle seems to restore it. I have heard of PLA going brittle on the spool but nobody seems to know for sure what causes it. PLA is also somewhat brittle but ABS isn't at all. Presumably the long polymer chains must get shorter somehow and then reform when melted. I am not sure if the temperature is the problem or if it is too dry. I have read there is an optimum moisture level for processing plastic at, rather than as dry as possible, not sure why.

The black ABS hasn't gone brittle yet and it has been in its heated box for longer.

My prototype MDF Mendel90 runs with a chamber temperature of 45C and I have noticed that the printed parts it is made of seem to become brittle over time. The extruder runs a lot hotter of course and the Wade's block tends to crumble after a few years and needs to be replaced regularly. They last a lot longer on my unboxed machines. 

I also think ABS shrinks over time, even at room temperature. I made a test print with some holes in it a four years ago when I was having an interesting discussion about Polyholes with Giles Bathgate. I tested it with plug gauges but as I didn't have a case for them I left them standing in it on a shelf near a north facing window. When I went to use them for my Horiholes test I found they were stuck in it much tighter than I remembered and the plastic has yellowed slightly.


I made a case for them with a screw top using my thread utility in NopSCADlib, printed in the black ABS.


So now I have dropped the temperature of my dry boxes to 30°C as surely that won't degrade the plastic much more than in a hot room without sunlight. That vastly reduces the power consumption of course. 50°C needed about 50% duty cycle but 30°C is only 4%, only a shade over one Watt. The hygrometers are still reading 19% after a day at the lower temperature. I find that odd because, for a given air water content, reported relative humidity should increase as temperature falls.

So I think I will try initially drying new plastic at 80°C overnight and then reducing to 30°C for long term storage from now on and see how that goes. A good measure of whether it is dry enough is the complete lack of ooze at the end of the build.

Monday 20 July 2020

Horiholes 2

As whosawhatsis pointed out in a comment on my last post, the edges of the filament staircase are actually semicircular and that makes a big difference as to where they should be to meet the circle tangentially. Not sure why I missed that as I have done several posts about extruded filament shape, I must be losing it!

This is what my previous shape actually produces.


The circle only touches at four points. The correct shape is obtained by calculating where the semicircles meet the circle.

The centres of the ends of the filament lie on a circle with a radius of the hole plus half the filament height. The end of the filament is then offset inwards horizontally by half the filament height. I.e. the slicer samples the layer at the central tip but the filament touches the circle on a tangent.


To make the shape geometrically I make a teardrop with a radius of the hole plus half the filament width, split it in half and shift the two halves together by half the filament width. As can be seen here that goes through all the filament tips, i.e., where the slicer samples.


This is what it looks like relative to the target hole.


Interestingly it is the same as my previous attempt at the top, bottom and sides, i.e. the only four points it touched before.

I made a test with the new formula.


The plug gauges all fit, but more snugly than before, so this is definitely a better solution for supporting a bearing in a pocket. At every layer it should have a tangential support from the rounded edge of an extrusion.


Here is a close up of the 6mm hole that is aligned on a layer boundary and the 1mm hole above it.



I have updated NopSCADlib on Github to use this method.

Saturday 18 July 2020

Horiholes

Back in 2011 I came up with polyholes to get around the problem of 3D printed vertical holes coming out too small. Horizontally printed holes also come out too small but for a different reason: the slicer creates a staircase approximation of the hole, but because it samples the model at the middle of the layer, the top or bottom corners intrude into the circle.

 This shows a 6mm truncated teardrop sliced with 0.25mm layers, with red highlighting the overlap.


A long time ago I mitigated this by adding 1/4 of the layer height to the radius, for reasons I can't remember now, but it isn't very accurate. There is some slight interference vertically and gaps at the sides.


I am currently designing a gearbox with ball bearings in 3D printed pockets, which I want positioned accurately, so I decided to revisit the problem.

The correct solution is simple: the compensated shape for the teardrop is simply the hull of itself shifted up half a layer and shifted down half a layer. That compensates the top half so that the bottom of the layer ends up on the circle and the bottom half so that the top of the layer ends up on the circle.


So now all the tips of the stairs sit exactly on the circle, except near the top where the 45 degree overhang would be exceeded.

This is what the hole looks like before it is sliced.


It does of course make the model specific to being sliced at a certain layer height, but my models tend to be designed that way anyway,

I printed this test piece with 6mm holes at different offsets from the layer boundary as well as holes from 1mm to 5mm and I tested it with plug gauges.


The gauges fit all the holes easily. Some are snug and some have a little play vertically depending on how the top edge aligns with the layer boundaries.


The bridge layers over the top come out a bit low because the filament forms a cylinder from a volume that would normally almost fill a rectangle, making it a slight interference fit when the top  lines up exactly with the layers. In other cases there is a bit of vertical play due to the 45 degree limit at the top of the teardrop. This won't be an issue with my gearbox because it will be split into top and bottom halves and the top half will be printed upside down.

I have updated teardrop_plus() in NopSCADlib to use this method and also added a plus option to all the other variants like tearslot(). See https://github.com/nophead/NopSCADlib#Teardrops and https://github.com/nophead/NopSCADlib#Horiholes where you can find the code to make the test STL. 

It should work universally as long as all slicers slice in the centre of the layer. Obviously it makes less difference with smaller layer heights.

Thursday 13 June 2019

NopSCADlib

When I used OpenSCAD to design Mendel90 I modelled complete assembly views with all the vitamins in place and a significant part of the code was actually the vitamins. Vitamins being the RepRap term for non-printed parts of a 3D printer, fasteners, motors, etc. I also automated the generation of the bill of materials, STL files, DXF files and PNG assembly views, but making the build manual was still a lot of manual work, pardon the pun.

After Mendel90 production ended I started designing other projects and found myself needing to use its vitamin library, but because it wasn't designed to be stand alone, that quickly got messy. Eventually I made a new stand alone library and a more general Python framework that would work for any project.

Over the last few years I have refactored it many times, making it much faster to preview, more general and more automated. In particular it can now catalogue all the vitamins and automatically make build manuals for any project using Markdown embedded in OpenSCAD comments. There is a simple example here. I also added reusable printed parts, such as feet, hinges and handles and some reusable enclosures.


It will never be complete because each significant project I make with it usually needs a few more types of vitamin, but it is hopefully structured so that it can grow sustainably without bringing OpenSCAD to its knees. To do that I had to fix some issues in OpenSCAD itself because it used to slow down exponentially with the number of files used. The picture above has an instance of every part in the library. The latest release of OpenSCAD can draw it in about one minute on my desktop PC. This is remarkable because at one time it took 12 minutes.

Here is an example of a typical assembly views it creates: -


I have published it open source on GitHub to enable me to publish projects that use it in the future. I use it for every project I make now, so I don't have any stand alone scad files that can be put on Thingiverse, for example. Feel free to use it in your own projects.


Wednesday 6 June 2018

Beware fake multi-meter leads

I bought these multi-meter leads on eBay for £2.99. They are advertised as "16PCS/Set Multimeter Probe Pin Test Leads Cable Multifunction Digital Clip Kit". I was attracted to them by the large number of accessories including pin type plugs that fit old analogue multi-meters.


When they arrived I discovered that the wires are steel and have a resistance of about 1 Ohm each, which makes them about as useful as a chocolate teapot. Any resistance measurement gets 2 Ohms added . Current measurements on the amps range drop large voltages, the wires get hot and would burn if left on for more that a few seconds.

Voltage measurements would be accurate enough but where the attachments screw on there is exposed metal, so not suitable for high voltages.

I got a full refund and get a set of these instead for £2.97.


They claim to be CE cat III rated for 1000V and 20A. Their resistance is only 64 milliohms. Not bad but my UNI-T UT61E came with 600V 10A rated ones that measure 44 milliohms and my EEVblog BM235 wins with 24 milliohms for 1000V 10A probes.

I got them to replace these old ones that belong to a multi-meter I inherited from my Dad. They have numerous burns from touching a soldering iron.


I dug out this old meter when I realised all my modern digital meters only go up to 1000V at most. This one goes up to 6KV!


I think it was purchased sometime in the early 1970s. It is branded Honor Model TE-12, made in Japan. I have seen identical ones on the web branded Lafayette. I don't think you would get away with connectors like that for 6KV nowadays!


Saturday 2 June 2018

Avoiding annoying Blogger cookie warnings

Being warned by every web site that it uses cookies is very annoying. I don't see how it is useful because virtually every site uses cookies.

When looking at a Blog hosted by Blogger it is even more annoying because it warns for every new page of a blog visited. Looking at the cookie it uses to decide whether to warn about using cookies I noticed it stores the path of the page relative to the blog. That is why it warns for each page of someones blog. However it looks like it won't warn for sub paths of the path in the cookie. So if you visit the root of the blog and dismiss the warning there it gets rid of the warnings for every other page in the same blog. This is a lot more reasonable and probably the way it should work by default.


It is also annoying that this will expire in a year. If every website I visit repeats the warning every year it will continue to be a constant stream of warnings forever.