I originally wrote code for the MS5541C pressure sensor using bit banging, and described the result of my investigation in the previous log entry. At the end I mentioned that the sensor’s weird digital interface is kind of like SPI, and looks SPI-compatible, with several differences that could be worked around. The most notable difference was that reading and writing data happen out of phase with respect to the serial clock edge. It wound up being a little squirrellier than that, but it worked out. Below is some code for accessing the MS5541C with SPI. It runs on a Seeeduino Mega (which is compatible with the Arduino Mega and uses the ATmega1280 microcontroller), but I’ve eschewed the Arduino libraries for the sake of more control (and, for the ol’ bit-banging, better timing resolution). Some of the code, particularly the SPI stuff, could be replaced with Arduino library calls. Continue reading →
The MS5541C is kind of an oddball sensor, BUUUUUUUT it’s small, it can be used underwater (with appropriate waterproofing), it’s cheapish (~$30), and Digikey sells it. It’s a pain to get running though, because of its hardware interface (50 mil pitch, surface mount (and not the good kind of surface mount either)) and its data interface (which doesn’t implement any particular standard protocol).
I tried carving out an interface board using some copper-clad PCB and a rotary tool, but I didn’t do a good job and it was really hard to get the 50 mil pads to line up with the messily-carved copper traces. I used a heat gun to solder the sensor onto the PCB, and it almost worked—but two of the pins were shorted. And of course a copper pad got torn off of the sensor when I tried to remove it from the PCB. I bought another one and connected it to a 100 mil header via some ribbon cable. That’s the wrong thing to do. The datasheet specifies that the sensor should be securely fastened to a circuit board to prevent it from flexing, although it hints that might be just to prevent stress on the solder pads (which are, as previously noted, not incredibly strong) and not necessary to improve sensor performance. The spec also says that a 47 μF tantalum decoupling capacitor should be placed as closely as possible to the sensor. That is a noise reduction requirement, but whatever, there’s one on the Arduino that I have the sensor hooked up to and that’s good enough for now. In any case, eucatastrophically, it works.
The data interface is a little easier to work out. Like I said before, it doesn’t use a standard protocol, presumably to keep the internal circuitry as uncomplicated (and small and low-power) as possible. The thankfully decent datasheet defines the protocol using electrical timing diagrams, and fortunately it’s simple enough once you work through it:
It’s pretty hard to get a watertight object out of our Makerbot Thing-O-Matic. The walls of printed objects are pretty solid, but unexpectedly porous; even a thick block printed with 100% infill will allow water to penetrate it due to errors around the edges and imperfectly fused strands of plastic. If you want to make a hollow object waterproof you’re going to have to do some post-processing.
It gets worse when the object is a curved surface, as is my AUV hull. I’ve read that objects can be made watertight by adding outer shells. That may be true for some objects, but on objects that curve along the z-axis the number of shells exposed to the surface grows as the tangent plane gets closer to parallel to the printer’s build platform—and big holes start to form.
My hull doesn’t actually have to be watertight, it’s a wet hull. But it has to be airtight in order to hold the bubble of gas that controls the robot’s buoyancy. Here’s what the airtight hull looks like:
I tried a solenoid I scavenged from underwater valves on my 3D printed valve system and it didn’t work (duh). It was just too weak. The original valve spreads the force from the high-pressure side across a larger area, so I guess the spring return can be comparatively weak. My design didn’t do that. I also didn’t cut my compression spring down very much, but I qualitatively determined that the solenoid wasn’t generating a useful amount of force by holding it on the magnetic core while turning the power on and off a bunch of times. I am a terrible engineer.
So I went back to square 2 and decided to remake the original brass valve body in lighter ABS plastic using our Makerbot 3D printer. The beta version looked like this: Continue reading →
I’m having trouble with the upper valve that will allow air to be released from the hull (thus decreasing buoyancy and giving some downward thrust). I mean, I’m having trouble with everything, but that’s why I’m doing this, right? Anyway, I decided to order a couple underwater solenoid valves in the hope that I could stick one in the robot and have it work (hahahahaha). I found several suppliers in China listed on this site alibaba.com, and settled on Nuoling Pneumatic. Most of the other options either weren’t waterproof, were too big, didn’t support a 12 V power supply, or had a large minimum order size. The two I bought were $12.35 each, which is less than I was expecting (although the shipping was $55 for two units).
Underwater solenoid valve from Nuoling Pneumatic
The valves were a lot bigger and heavier than I expected. You can see it’s basically a big chunk of brass connected to the waterproof electrical components. Fortunately it’s easy to take apart:
It turned out doing software UART was a terrible idea. The processor is way too slow to support a reasonable baud rate. I did figure out how to use a comparator though: the key phrase I was missing was “rail-to-rail.” That means that inputs can be in the full voltage range from ground to Vcc. Another handy phrase is “push-pull,” which means that the comparator can output 0 and 1; in contrast, an “open collector” comparator can only output 0, and needs an external resistor to pull the output to 1.
I bought a rail-to-rail push-pull comparator, the MCP6541, and tried it with the receiver circuit, and sure enough it increased the maximum range significantly. Unfortunately it also increased the minimum range significantly.
The range on the infrared channel, which I discussed in the last entry, is probably enough; but I’d like to increase it a bit. With more range I can space modules farther apart if needed, and hopefully be able to have a wider angle between the transmitter and receiver.
Fortunately the signal output by the Darlington transistor pair on the receiver is a pretty clean digital signal. At full power it ranges from (a little above) 0 V to (a little below) 3.3 V. As the transmitter gets farther away the digital signal remains but the low voltage increases beyond the UART receiver’s ability to read a 0. For example, at a large distance the UART signal might range from 2.5 V (logical 0) to 3.3 V (logical 1).
The hull is done for now. As I mentioned before, I have some improvements in mind (mainly to get rid of the outer bolts), but it took about 34 hours to print all eight pieces and I’m not eager to do it again. If I ever get around to putting motors on this thing then I will have to re-print at least four of the semidemihemispheres, as the current ones don’t have any mounting points for motor attachments.
I printed four copies of the semidemihemisphere and refined it a bit as I went. Here’s the whole thing, including the hull that I covered in my last log entry. The only difference in the hull is I removed the top hole, as only two of the semidemihemispheres need it (as valve mounting holes).
Tweaked version of the AUV model.
I made a few interesting changes to the cutaway portion though: