Feed on
Posts
Comments

Recently I was involved in a project that requires reading data from a personal weather station (PWS) installed at a friend’s backyard. If you search for “personal weather station” you will find plenty of off-the-shelf products manufactured by various companies. Almost all of them use 433MHz Radio Frequency (RF) signal to transmit data from the outdoor sensors to the indoor receiver (with integrated LCD display). A few years ago I wrote a series of blog posts about how I reverse engineered some of the individual wireless sensors, like temperature, humidity, rain, and soil sensors, so that I could decode and use them in my own project. The basic technique is to use a RF sniffing circuit to capture the signals, then patiently take many RF readings and compare them with the reference readings displayed on the received unit. By correlating the binary values of each RF signal with its corresponding reference value, I was able to figure out the encoding pattern. That was a lot of fun, but honestly very painful and tedious, as I had to simulate the changes of weather conditions many times to create variations in readings, and figuring out how they are correlated with the raw signals is not always trivial.

This time I am dealing with a even more sophisticated PWS which combines several different sensors, so the RF signals contain a lot more values that will be very difficult to reverse engineer. I was definitely not looking forward to repeat the same tedious experiments I’ve done a few years ago. However, technology has changed rapidly the past few years. What’s interesting now is that this particular PWS has a receiver unit that is WiFi-capable, and it can even send data to Weather Underground. I was reading its user manual and came across this part: open a browser and type in IP address 192.168.4.1. That immediately caught my attention as that’s the default IP address in AP mode for ESP8266. Ah ha, I bet it has an ESP8266 inside. So I took it apart and there you go, a ESP-WROOM-2 chip laid right in front of my eyes.

Next to the ESP chip are three pins clearly marked TXD, RXD, GND. I wasn’t actually hopeful that the TX pin will send any useful data, but I decided to hook up a USB serial adapter to check it anyways. I soldered three wires to connect the receiver’s 5V, GND, and TXD pins to the serial adapter’s 5V, GND and RX pins.

Hooking up a USB serial adapter

I took a few guesses about baud rate, and found that 115200 is the correct one. Well, I didn’t think it was going to be that easy, but right there on the serial monitor screen, the chip is sending out sensor values in plain text, presumably for debugging purpose. Can’t be easier than this 🙂

Serial output from the receiver unit

You can see that it occasionally print out {{6}}, which probably indicates the current status. Then it’s a sequence of numbers separated by commas. Some of the values are easily recognizable if you look at the LCD screen. For example, 2992 must be the barometric sensor value, 81 and 55 are the temperature and humidity values respectively. But the other values are more obscure, like what is that 1575 value?

Then I remembered this PWS can connect to Weather Underground. Maybe the serial print out will change once it’s set to send data to Wunderground? So I followed the user manual to configure the WiFi settings and typed in a random WU station name (aaa) and a fake key (bbb). You can actually go to Wunderground.com and apply for a proper PWS station name and key, I didn’t do that because I was merely experimenting with the unit so I didn’t want my unit to contaminate the Wunderground data in my area. In any case, once it’s configured, the serial output started showing the HTTP GET command that it’s using to send data to Wunderground. Below is an example:

/weatherstation/updateweatherstation.phpID=aaa&PASSWORD=bbb&dateutc=now&winddir=157.5
&windspeedmph=0&windgustmph=0&tempf=81&dailyrainin=0.00&baromin=29.92&dewptf=63
&humidity=55&weather=0&clouds=0&softwaretype=vws%20version00&action=updateraw&realtime=1&rtfreq=2

So now the numbers all make sense: that 1575 value is the wind direction (157.5 degrees), and all values have clear meanings marked by their variable names. At this point, I can easily write a script that parses the serial output and use the data for my own project.

Summary: this PWS turns out to be the easiest wireless sensor I’ve worked with, as it involves practically no reverse engineering effort. I am glad to see that ESP8266 has made into so many WiFi products on the market today. To be fair, this is a lucky example as it prints out all the useful data through serial, so no painful RF decoding effort is necessary. I am not sure so other weather stations would be as easy.

Can’t believe I have been silent on this blog for more than a year now. I would really like to get back to blogging more regularly, and hopefully this post serves as a good starting point. As the first order of business, I would like to showcase a number of student projects from a new class I taught at UMass in the Spring 2018 semester. It’s a brand-new class called Make — A Hands-on Introduction to Physical Computing. It covers basic electronics, circuits, Arduino programming, sensors, actuators, ESP8266, Processing, and rapid prototyping techniques. It’s a rather exciting adventure for me, as it’s the first time this course has ever been offered in my college, and it fulfills the college’s lab science credit. I have both the freedom to choose whatever topics I am passionate about teaching the students, and the burden of designing the complete set of lectures, weekly lab, homework, and exam.

The class ended with a final project where students work in two-person teams for 6 weeks to complete a project of their choice. The basic requirement is that it must be a physical computing project that involves both constructing hardware and developing software. The outcome was really satisfying as many of the projects are truly impressive and/or innovative. It’s particularly so as for many students this was the first time they have ever learned about electronics and Arduino. Below I briefly describe some of my favorite projects. I took videos of some projects, which you can find in this shared Google Photos album. The complete list of 27 project can be found in this folder of Google sites (I asked every team to create a Google site to document their project).

The most ambitious and visually marvelous project is the 8x8x8 Neopixel Cube project by Alex and Chris (warning, the site is loaded with pictures and videos so loads rather slowly). Though there is an abundance of LED cube projects you can find online, this one is based on Neopixels, so it’s a full-color LED cube and it’s slightly easier to solder than standard color LEDs. They’ve done a fantastic job constructing the cube, and solved a number engineering challenges such as power stability issues, and data transfer speed issues by splitting the cube into sections and providing data entry point for each section separately using the FastLED library. I have a video clip showing the project in action. I wish I had taken a longer video because there were a few really cool animations (e.g. visualizing 3D surfaces, video streaming, 3D snake game) that show off just how amazing a Neopixel cube is.

Then there is a smart mirror project, ironically called Dumb Mirror, by Sam. It’s constructed using a two-way mirror, with a Raspberry Pi driving a scavenged LCD display and a Neopixel ring. A Python program grabs time, news, and weather information and displays them to the LCD screen. There are also some buttons on the side for user interaction. I’ve two short video clips (video1 and video2) showing the project in action. It’s aesthetically beautiful and quite functional as well, makes me want to own one myself.

Next in line is the Mint Drawing Tin project by Paul. This is a really cute project constructed using an Arduino nano, 128×64 OLED display, buttons, Lithium battery, and a 3D printed front panel, snugly fit inside a Altoids tin. It’s like a mini version of Etch a Sketch, but much cooler as it can store image frames and play them back as an animation. I have a thing for mint-tin project, as my own journey of Making began many years ago with a mint-tin sprinkler controller.

Some students made custom PCBs for their projects. One of them is the PixelLight project by Julian. It’s constructed by many Neopixel tiles daisy-chained to make a larger display. Each tile is a custom PCB of 10cmx10cm in size containing 4 Neopixels. The original goal was that the user can connect the tiles in an arbitrary manner and the system can automatically identify the topology of the connections. That proved to be a bit of a challenge so in the end he settled with a pre-determined topology. Still, it’s a quite elegant and visually pleasing project, and the display patterns can be changed in dynamically in real-time by using a ESP8266-based microcontroller and the Blynk app.

Another custom PCB project is the Radio Fireflies by Nick and Emily. It simulates how fireflies in nature synchronize their flashing patterns. Each node is a custom-made circuit consisting of an ATtiny85 mcu, color LED, 433MHz RF transmitter and receiver, and buzzer. RF is used to simulate how individual fireflies communicate with each other, eventually leading to synchronized flashing pattern. It’s a cool and ambitious project, though the real-time demo didn’t work very well as the presentation room was full of RF interferences.

A really fun and entertaining project is the Voice-Controlled Pong by Mike and Garret. It’s made of an Arduino, a 16×16 Neopixel matrix, and two microphone sensors. Each of the two players uses their voice to control the movement of the bat, i.e. the louder the sound the higher the bat moves. At first, it looks somewhat silly that the two players just keep yelling ‘Ahhhh’ repeatedly towards the microphone sensors, but when you try it out yourself, you will find it’s absolutely a joyful and entertaining game to play.

And of course there has to be a pet-centered project. The Bone Appétit is a lovely project by Mary and Nick, perfect for pet owners — it’s made of a Raspberry Pi, camera, servo, load cell (for measuring food weight), tucked inside a lovely wooden box. Using a Blynk app, they can monitor the pet, release food up to a pre-defined weight, and snap a picture. The best part of their demonstration is that they brought an actual puppy, who must have had a great time drawing so much attention from the audience.

There are a number of other amazing projects, like color candy sorter, pocket synthesizer, smart curtain, mail checker, pellet stove monitor, secret knock door lock etc. It’s truly delightful and rewarding to see such a range of creative student projects. I am teaching the Make course a second time this semester and will update the post when this semester’s final presentation ends.

When designing electronic circuits, often it’s necessary to have a proper enclosure for the project, to protect the circuit board and components, and for aesthetic reasons. There are several options to choose from. For example, if this is a one-off project, you can pick an off-the-shelf enclosure, make custom cutouts to fit the PCB and its buttons, connectors etc. But you will be limited by the enclosures available on the market, and you have to design the PCB size and screw hole locations according to the enclosure, so it’s not very flexible. You can also use 3D printing to make a custom case that fits the PCB nicely, but 3D printing is generally slow, and cheap 3D printers have poor precision. If you are making a commercial product and need volume production, you can order an injection mold, and the injection-molded enclosure fits the circuit perfectly. But you have to spend costs thousands or tens of thousands of dollars to order the mold, and this upfront cost is too much for small-scale projects.

Since last year I’ve been experimenting a lot with laser-cut acrylic enclosures. Compared to the other options, laser-cut enclosures are very easy to customize for the particular PCBs I have designed; they are relatively cheap and fast to make, you can add text engravings to them, and there is no upfront cost. So I have been using laser-cut enclosures a lot for a variety of electronics projects. Generally speaking, the enclosure consists of six pieces of laser-cut acrylic panels, with teeth and holes on the side to lock them together and form a box. You can use plastic or copper screws and pillars to secure the PCB inside the box. As a side benefit of this type of enclosure — if you happen to make a mistake on one panel (which I did a few times), you can just re-order that particular panel so it’s very easy to re-design and correct the mistake.

When I started, I found some tutorials and design tools online, to help create the six panels. But they are not really convenient or easy to work with. Because I routinely use EagleCAD to create my circuit boards, it would be really nice to have a enclosure design tool inside EagleCAD, so that I can compare the enclosure with the PCB precisely, making sure that all the cutouts are in the correct locations and have correct sizes. So a little while back, I wrote an EagleCAD script to help me create laser-cut enclosure panels, and used it to create a variety of project enclosures, as shown in the picture below.

Below I will briefly walk through the details of the script, what the various parameters mean, and I made a video to demonstrate how to use this script. To begin with:


Video Tutorial


Explanation of Parameters

The way this script works is that it follows the dimensions of your PCB outline to create the six panels. It assumes the PCB is rectangular shaped, but if needed you can modify it to support non-rectangular shaped PCBs. There are a number of parameters you need to set, which I will briefly walk through below. Most of them are best explained by the annotated images below. All parameters of lengths are of unit millimeter (mm).

  • PCB-enc margin: the margin from PCB border to enclosure interior border.
  • Slot-edge margin: the margin from the slot boundary to enclosure edge.
  • Acrylic thickness: the common acrylic material I’ve used are either 2mm thick or 3mm thick. You may have to adjust this slightly according to your supplier’s acrylic material thickness. You may want to make this slightly larger (like 2.1mm and 3.1mm respectively) to account for error and variations in the actual material.
  • PCB thickness: standard PCB thickness is 1.6mm, but there are other choices too, like 1mm, 1.2mm, 2.0mm etc.
  • Height above/below PCB: this defines how much space there is above and below the PCB (NOT including acrylic). The ‘above’ height depends on the tallest component on your PCB. The ones I commonly use are 11mm and 13mm. The ‘below’ height is typically 3mm, to provide spacing underneath the PCB for through-hole components.
  • Top/Bot X/Y slots: define the number of slots on the top/bottom panel and in the x/y directions. The number of slots depend on the length in x or y: longer edges probably need more slots. Also I generally make the number of slots on the top and bottom panels different, to make it easy to identify the orientation of the side panels.
  • Slot rounding: this will round the slot size to the nearest (ceiling) multiple of the slot rounding number. The slot size is automatically computed based on the number of slots. If you want the slot size to be rounded to the nearest multiple of 10, for example, you can set slot rounding to 10.
  • Mount wing/hole size: if you need the back panel to be wall-mountable (which is generally the case for my boards),
    you can define the width of the wing and mount hole size (diameter).
  • Round corner r: radius of the rounded corners.
  • Slot-plug margin: this will shrink the plug size slightly to make it easy to insert into the slot. The default is 0.1mm but I suspect leaving it 0 is fine (because laser cut holes generally have negative error, meaning they are larger than design).
  • TB hole size: top-bottom hole size. This is set according to the size of screws/pillars you need. For example, if you plan to use M3 screws, set this to be slightly larger than 3.0; if you plan to use M4 screws, make it slightly larger than 4.0 and so on.
  • Eagle layer: defines which Eagle layer it uses to draw the enclosure. By default it uses layer 104.

Running the Script: upon running the script, it will hide all layers except the Acrylic layer (104 by default). This allows you to see the overall enclosure design. You can go back and un-hide the other layers. If you re-run the script, it will remove the existing content on the Acrylic layer, and re-create the outlines. So be careful re-running the script — if there is anything you want to preserve (such as custom cutouts as explained below), you want to put them in a different layers so that they don’t get wiped out.

Annotated figures are more intuitive for explaining the parameters:

Creating Custom Cutouts and Text Engravings

The script doesn’t automatically create cutouts for connectors, and that part you have to do it yourself. Still, having the enclosure outline embedded with the PCB design makes it easy to align the cutouts with the connectors. As shown in the last image above: the custom cutouts (colored in red) are embedded in the PCB design, so you can precisely align each cutout with its designated connector. I generally create the custom cutouts in a different layer, so that in case the Acrylic layer gets wiped out, the cutout layer is still preserved. You can also add text engravings — where I order acrylic pieces, they can add laser engravings for only a small amount of additional cost. So if I need any labels for the connectors, I can easily add them to the custom cutout layer and get them ordered as engravings.

Order Laser-cut Acrylic Pieces

Once the design is finalized, I place an order from a vendor on Taobao.com — the Chinese equivalent of eBay. To prepare the design for ordering, I export the Acrylic layer and Custom Cutout layer together into a DXF file in EagleCAD, then convert it to Adobe Illustrator (.ai) file, and send it to the vendor. I then specify the acrylic thickness, color (the most common is transparent, but there are a variety of other colors to choose from). Make sure the scale of the design is appropriate — Chinese vendors work with millimeter (Americans should too!), so make sure the design is scaled to the correct millimeter scale, which you can do easily in Illustrator.

Assemble the Enclosure

Assembling the enclosure is fairly straightforward: it involves a set of screws on the top panel and bottom panel, and separation pillars below the PCB and above the PCB. I generally like plastic screws and pillars as they are much lighter than iron or copper screws and pillars. The acrylic pieces come with a brown protective sticky paper cover. You can peel the sticky paper cover. If the acrylic material is transparent, you can see through the enclosure to the circuit board, which looks pretty cool. I generally only peel the top panel and keep the protective cover on the other panels, because peeling a lot of paper is tedious, and the brown paper cover gives a wooden appearance, which is not bad. So I keep them as much as possible. To peel the cover, it’s best to use another acrylic piece, or a stiff card of some sort to lift the cover from one corner, then carefully peel and remove the entire cover. Don’t use your nail as it can easily damage your nail. Acrylic is reasonably scratch-resistant, so using another acrylic to help peel it is totally safe.

The GIF below shows the assembly process:

Limitations and Todo for the Future

Perhaps the biggest limitation of laser-cut enclosure is the assembly time — putting all those screws and pillars together cost time and labor. But given that there is no upfront cost, it’s pretty suitable for small-scale projects, or serving as a temporary enclosure until you have a more permanent solution like an injection mold. In addition, for DIY-style projects, you can give the enclosure pieces to the customers and let them assemble the enclosure. It’s actually quite fun, kind of like the philosophy of Ikea furniture — its value is not only in the low cost but getting yourself involved in assembling the product provides a more engaging experience.

There are a couple of improvements I want to make to the script and I will try to work them out in the future. One is the ability to create a local file to store the parameters. At the moment if you want to re-design the enclosure for the same circuit, you have to manually remember what parameters you have used before — the script doesn’t remember the previous parameters because every time you run it, it will load the default parameters. It would be nice for it to store previous parameters for a particular circuit board to a local file, making it easy to modify in the future. Another improvement is providing visual aid to indicate where the PCB is located on the side panels, to make it easier to design cutouts for connectors etc. Right now to create cutouts I still have to do a lot of hand calculations, which can be automated in the future.

That’s it. Feel free to try it out and let me know what you think. If you make modifications to the script and improve its features, please be generous to share your contributions!

Update: the technique described in this article is possibly no longer necessary for the current version of OSBee, as it now supports setting a different opening vs. closing voltage.


Recently when helping a customer, I came across an interesting case of how to control Gardena 1251 latching solenoid valve using OpenSprinkler Bee. This valve is mostly sold in the European market and isn’t very popular in the US market. On spec, it’s operated using a single 9V battery, and to use this valve you need to buy a Gardena 1250 controller unit. The whole assembly including the valve and controller unit are quite pricy (close to 100 bucks), so it’s not a very cost-effective solution compared to other brands. Nonetheless, it’s an interesting case that helped me understand how these latching solenoids work.


Measure the Control Voltages

The initial request to look into this valve was due to the fact that OSBee can’t seem to operate this valve correctly: it can open the valve but never manages to close the valve. This was reported by a German customer, and it caught my curiosity. To figure out the issue, the first thing I did was to check how the control unit (1250) is sending out control voltages to the valve. It’s pretty common that when operating latching solenoid valves, the control circuit sends an impulse voltage to open the valve, and another impulse voltage in the reverse polarity to close the valve. On most solenoid valves I’ve seen, the two impulse voltage (of opposite polarity) are roughly the same, and that’s also how the OSBee circuit works.

Upon connecting the control unit to an oscilloscope, I noticed something strange: no matter how I press the on/off button, it’s only sending a very short (a few milliseconds) pulse, which cannot possibly operate the valve. Then it became clear to me that the controller is in fact actively sensing the existence of the valve, and would not send control voltages if the valve is not detected. I measured the resistance of the solenoid valve, which is about 35 ohm. So I connected a 33 ohm resistor to the controller as a dummy load, and there you go, now we can observe the control voltages and pulse lengths.

It’s pretty easy to notice the asymmetry here: while opening the valve requires a pulse of 250 ms and -7.84 voltage (this is roughly the battery voltage since my 9V battery isn’t fully charged), closing the valve only requires a very short pulse of 62 ms and very low voltage — 2.5V. This is quite strange to me: how come closing the valve only requires such a short pulse and such low voltage?


How Does This Latching Valve Work?

In order to figure out what’s going on here, I un-tightened a bunch of screws and opened up the valve.

At the bottom of the valve is a pressure chamber with a spring. This is very similar to other valves I’ve seen.

The top section contains, supposedly, a coil and magnet inside, and a small cone-shaped metal piece that can be attracted to the magnet or released. It’s quite easy to observe that when opening the valve, the metal piece gets attracted (left picture above), this supposedly releases the pressure in the bottom chamber, thus allowing the water to flow through the valve. Conversely, when closing the valve, the metal piece is released and dropped to block the hole at the bottom, this supposedly allows water pressure to build up in the bottom chamber, thus stopping the water flow.

The key in making this latching is that an impulse voltage can permanently magnetize the core, thus permanently attracting the metal piece. This makes it possible for the valve to remain in the ‘open’ status without contiguously drawing current from the power source (which is unlike non-latching valves like 24VAC valves).

Observing this mechanism, it became clear to me that ‘closing’ the valve basically requires de-magnetizing the core, and that requires just a short pulse of low voltage in the opposite polarity. If you apply the same voltage and strength as before, it will start magnetizing the core the other way, thus the magnetic pole changes direction but the metal piece will still be permanently attracted!

Anyways, this is very interesting to me because previously I had no idea how latching solenoid valves work internally. Now at least I know understand this particular valve works, and this understanding will help me figure out how to get OpenSprinkler Bee to control this valve.


Use OSBee to Control the Gardena 1251 Valve

There are several issues that make OSBee incompatible with the Gardena 1251 valve, but it turns out they can all be solved without too much difficulties. The first is that OSBee by default boost the input voltage (which is 5V from USB) up to 22VDC, which is significantly higher than 9V required by the valve. This is reasonably easy to solve — by fine tuning the boosting time, I can find the sweet spot where the boosted voltage is just around 9V. This boosting time turns out to be around 80 to 100ms.

Second, OSBee by default uses 100ms pulse in both directions (i.e. both opening and closing the valve). This is very easy to change to 250ms and 62ms respectively to match the Gardena controller.

The last issue deserves more thinking, that is, opening the valve requires 9V, but closing the valve requires only 2.5V. Because the input voltage is from USB and it’s 5V, there is no obvious way to step that down to 2.5V since the boost converter can only bump up the voltage and never reduce the voltage. How do we create this asymmetric voltage in opposite polarities? Turns out that you can do so by making use of a diode connected in parallel with a 100 ohm resistor. Why? The diode is a one-way gate: when positively biased, it turns on almost fully (except the 0.7V voltage drop across it, which can be ignored here); but when reversely biased, it turns off, thus current has to flow through the resistor (connected in parallel to the diode), and that resistor will divide the voltage, ensuring that only about 2.5V falls on the valve.

I’ve attached here a diagram showing the connection. The diode can be almost any general-purpose rectifier, like 1N4148, 1N4001 and so on. I’ve also included two photos showing the actual components connected to OSBee and the valve. With this modification, OSBee can now both open and close the Gardena 1251 valve successfully. Mission accomplished!

Today I am very excited to introduce OpenSprinkler Bee (OSBee) 2.0: it’s an open-source, WiFi-enabled, universal sprinkler controller. It is suitable for garden and lawn watering, plant and flower irrigation, hydroponics, and other types of watering project. This is the first OpenSprinkler product built upon the popular ESP8266 WiFi chip. It’s designed primarily for latching solenoid valves, but can also switch non-latching solenoid valves (such as standard 24VAC valves), low-voltage fish tank pumps (which can be used to feed water to flower pots and indoor plants), and other types of low-voltage DC valves and pumps. All of them can be powered from a single USB port. This is made possible by using a unique circuit design that leverages a boost regulator and a new solenoid driver circuit. Hence I call it a Universal sprinkler controller. Among the software features, it introduces the concept of Program Tasks, which provides maximal flexibility in programming the zones. In contrast to the first version of OSBee, which was in the form of an Arduino shield and relies on an additional Arduino, OSBee 2.0 is a standalone controller with built-in WiFi, OLED display, laser cut acrylic enclosure, and can switch up to 3 zones independently.

Here is not-so-short video introduction to OSBee 2.0:

Here are two photos of the OSBee 2.0 circuit board:

osbeewifi_1osbeewifi_2

Screenshots of the web interface and Blynk app:
osbee_screenshots

In summary, in terms of Hardware Design, it has the following features:

  • A single ESP8266 chip serves as the microcontroller and handles WiFi connectivity.
  • On-board 128×64 OLED display, real-time clock with backup battery, USB-serial chip. Can switch up to 3 zones independently.
  • Boost converter and a new H-bridge design that allows the same controller to switch both lathing and non-latching solenoid valves, all powered from a single 5V USB port.
  • An easy-to-assemble laser cut acrylic enclosure.

In terms of Software Features:

  • It has a built-in web interface that allows you to easily change settings, perform manual control, and create automatic sprinkler programs. It also provides logging and program preview features.
  • It introduces Program Tasks to allow maximal flexibility in programming zones. For example, you can define arbitrary ordering of zones, have multiple zones run at the same time, and insert delays between tasks. Zone water time is programmed at precision of seconds.
  • It allows remote control through the Blynk app and Blynk cloud server.
  • Firmware update can be performed either wirelessly using the web interface (OTA), or through the on-board USB port with a USB cable.

It improves upon the current OpenSprinkler 2.3 by adding built-in WiFi capability, and using a unified solenoid driver that can handle both latching and non-latching solenoid valves. On the other hand, it can only switch up to 3 zones, and the number cannot be expanded. It’s also missing a few advanced features at the moment, such as weather-based water time, virtual stations (e.g. HTTP and RF stations), and support for sensors. Some of these features are purely software, and can be easily added in the future.

OpenSprinkler Bee 2.0 is now available for purchase at our online store:

The package includes a fully assembled OSBee 2.0 circuit board, laser cut acrylic enclosure, instructions, USB cable, and optionally an USB adapter.


Resources and Technical Details

OSBee 2.0 is an open-source project. Its hardware schematic, firmware source code, user manual, and API document are all available at the OpenSprinkler Github repository (look for the prefix OSBee in the repository).

Below I will briefly go over the technical details of the boost converter and the solenoid driver, as I think it’s an interesting design that’s potentially applicable elsewhere. The boost converter is borrowed directly from the OpenSprinkler DC circuit. It’s a simple MC34063-based boost regulator that bumps the input 5V up to 24V DC, and stores the charge into a 2200uF capacitor.

osbee_circuit_1

The Booster is controlled by two MOSFET-based high-side switches. The first one controls the input power: the microcontroller uses it to feed the input 5V to the booster, which quickly raises the voltage to 24V. After a couple of seconds, high-side switch 1 is turned off and the microcontroller prepares the states of the half H-bridges (COM, Z1, Z2, Z3). Let me first explain how the states are set for Latching solenoids. The solenoids for the three zone are connected between COM-Z1, COM-Z2, and COM-Z3 respectively. Normally all four half bridges are in ‘High’ state, so the net voltage across every solenoid is 0. To activate a solenoid (say Z1), the corresponding half-bridge will be pulled down to ground (i.e. ‘Low’ state). The microcontroller then turns on high-side switch 2 momentarily to dump the charge from the 2200uF capacitor to the solenoid. This turns on the valve. To deactivate the solenoid, the microcontroller pulls all half-bridges to Low, except the zone that is to be deactivated which remains in High state. It then turns on high-side switch 2 momentarily, again dumping the capacitor charge to the solenoid, but now in reverse polarity, thus closing the valve. This is basically how it operates latching solenoids.

So how does the same circuit work for Non-Latching Solenoids, such as 24VAC valve commonly used in residential sprinkler system? It turns out that just like latching solenoids, non-latching ones also require a pretty high impulse current (called inrush current) to get activated. The difference, however, is that to keep it on, it needs to draw current continuously from the power source. When the power cuts off, the solenoid is deactivated. This is called the holding current and is considerably lower than the inrush current. So to operate non-latching solenoids, all I need is an additional diode that provides a path from the input 5V to the solenoids to provide the holding current. This diode could be software switched by the microcontroller, but because ESP8266 has very few number of GPIO pins, (and I want to avoid having to use an IO expander), I opted to enable this diode path using a solder jumper. To operate non-latching valves, this jumper needs to be soldered on.

osbee_circuit_2

On the Software side, the firmware uses an option to allow the user to choose the valve type (unfortunately the controller can’t automatically detect the valve type yet). For non-latching valves, the half-bridge states are actually easier to manage than the latching case: now COM is always in ‘High’ state, and Z1, Z2 or Z3 are kept ‘Low’ for as long as needed to keep the valves on. That’s it.

You may be wondering how does this even work for valves rated at 24VAC? How can we drive them using DC, and just 5V? The short answer is that this is due to the way such solenoids behave under AC. Specifically, when you first connect the solenoid to 24VAC, it immediately draws a high inrush current, which reliably energizes the solenoid and opens the valve. Once energized, the solenoid presents a large inductance and high reactance to AC, thus limiting the effective current flowing through it. This results in lower holding current, which is enough to keep it on and saves the coil’s lifespan. We can exploit this behavior and achieve the same effect using a DC-based circuit: the booster produces a high voltage initially to provide the inrush current needed to energize the solenoid, and then lowers the voltage to the input level to provide the holding current. Exactly how much holding current is needed is not clearly defined, but for all 24VAC solenoids I’ve tested, once energized, they can remain on at just 5V input voltage.

Now we are left with the last part of the technical details: the Half H-Bridge Design. From the circuit diagram above, it seems we can easily implement the half bridges using relays. While this is totally true, relays are bulky, expensive, slow to switch, and difficult to replace. For these reasons, modern electronics prefer to use semi-conductors as much as possible in place of relays. So I decided to use a MOSFET-based H-Bridge design, and it’s a more interesting design than just throwing relays everywhere.

Typically when you want to switch between GND and a voltage considerably higher than the microcontroller’s output, you can use a half H-bridge design as show in the left image below. It uses a low-power N-MOSFET to drive the high-power P-MOS on the bridge, making it possible to use a GPIO pin to switch a high voltage. However, this generally requires 2 GPIO pins (i.e. A and B) per half bridge. Because ESP8266 has a small number of GPIO pins, the challenge is how to use just 1 GPIO pin per half bridge.

osbee_hbridge_1osbee_hbridge_2

So I came up with a slightly modified half bridge design, as shown in the right image above. It leverages two low-power N-MOSFETs to drive the high-power P-MOS and N-MOS on the bridge. This allows using just 1 GPIO pin (A) to switch the bridge. When A is Low, both input N-MOSFETs turn off, and the gates of the P-MOS and N-MOS are both pulled high, so the P-MOS turns off and N-MOS conducts, pulling the OUTPUT to Low. When A is High, the reverse happens, and the OUTPUT is also High.

Using two input N-MOSFETs also makes it easy to prevent shoot-through problem, which is often an issue with H-bridge. Shoot-through happens when the control signal A transitions from Low to High (or conversely from High to Low), and at some point the P-MOS and N-MOS may both be in conducting state, causing a shorting. To avoid this, I chose to use two different types of input N-MOSFETs: one with lower gate threshold voltage (such as BSS138) and one with higher gate threshold voltage (such as 2N7002). This way, as the control signal A swings between Low and High, the two input N-MOSFETs will turn on and off at different times, ensuring that the P-MOS and N-MOS will not both conduct at the same time. As for the choices of the P-MOS and N-MOS, I opted to use the common AO3401 and AO3400, which provide ample room for continuous current as well as impulse current.

Sorry about going through these nitty-gritty details, but I think these are interesting design notes worth documenting and sharing. Feel free to chime in with your comments and suggestions. Thanks!

« Newer Posts - Older Posts »