Category Archives: Electronics

Design, Fabrication and Testing of a MOSFET Shield for a Wemos D1 mini ESP8266 Microcontroller

Design

I needed a MOSFET Shield for a Wemos D1 mini to drive solenoids and relays. I could not find anything suitable online, so I decided to design and build my own. The board size of a Wemos D1 mini is quite small (1″ x 1.3″) and part of that is the PCB antenna, so a shield should avoid covering the area over the antenna with copper or lots of components.

Wemos D1 Mini ESP8266 Development Board

Wemos D1 Mini ESP8266 Development Board

I wanted the shield to be the same size as the Wemos D1 mini. I need to be able to switch about 12v at about 2A. Most use cases I had were small relays and solenoids.

I found a very small dual channel MOSFET in a 2mm x 2mm package (FDMA1024NZ – Dual N-Channel MOSFET 20V / 5.0A). This MOSFET is so small I could fit two on the shield, giving a total of four channels.

Wemos D1 Mini MOSFET Shield 4ch v1.3 Schematic

Wemos D1 Mini MOSFET Shield 4ch v1.3 Schematic

Wemos D1 Mini MOSFET Shield 4ch v1.1 Board

Wemos D1 Mini MOSFET Shield 4ch v1.1 Board

Fabrication

I created the board design and ordered the PCBs and a solder stencil for the first prototype. The 2mm x 2mm package is very difficult, if not impossible, to hand solder, so the stencil would allow me to stencil the solder paste and hand place the components, before reflowing it in an oven.

MOSFET Shield for Wemos D1 mini before solder stencilling

Before solder stencilling

MOSFET Shield for Wemos D1 mini during solder stencilling

During solder stencilling

MOSFET Shield for Wemos D1 mini after solder stencilling

After solder stencilling

MOSFET Shield for Wemos D1 mini close up of solder stencilling and component placement

Close up of solder stencilling and component placement

MOSFET Shield for Wemos D1 mini v1.1

First prototype completed

The first version worked perfectly, but the 2mm x 2mm MOSFET was a little obscure and difficult to hand solder. In addition, JLC PCB had launched a pick and place PCB fabrication service which was very economical. I thought I’d try it for my MOSFET board, but the MOSFETs I was using were not supported. So I replaced the two obscure dual MOSFETs with four discrete MOSFETs which JLC support as a basic components.

Wemos D1 Mini MOSFET Shield 4ch v1.3 Board

Wemos D1 Mini MOSFET Shield 4ch v1.3 Board

The JLC PCB fabrication service built a batch which again all worked perfectly.

MOSFET Shields for Wemos D1 Mini v1.2

MOSFET Shields for Wemos D1 Mini v1.2

Testing

I needed to test the board design to ensure it could handle the current rating. The MOSFETs are rated at a maximum of 5A each. So, each individual channel should switch 5A. In addition all four channels can be connected together which would switch about 20A in total. I wanted to make sure the tiny PCB would handle this load. I designed the power traces on the PCB to be as wide as the physical dimensions of the board would allow.

I bought a 180W battery tester from BangGood to use as a variable load which could test up to 20A and 180W. This device has lots of useful features. You can configure it as a constant current load in 10mA increments. It measures voltage, current, power and even temperature using a plug in thermocouple, and displays all the readings in real time on a colour LCD. Its a very functional device for a very economical price.

To source 20A, I decided to use a lead acid battery. I don’t have a bench power supply that can easily provide 20A. I used thick 12AWG wire to connect the battery to the variable load and the shield under test.

MOSFET Shield for Wemos D1 mini Power Testing Setup

MOSFET Shield for Wemos D1 mini Power Testing Setup

The test setup consisted of;

  • A 12v lead acid battery
  • The variable load
  • The shield under test – with the MOSFET outputs shorted together
Power Testing Setup

Power Testing Setup

I planned to test each individual channel at 1A, 2A, 3A, 4A & 5A, while monitoring the temperature of the MOSFET, PCB traces and connectors. In addition, I want to connect all four channels together and test up to 20A.

The first few tests went well. Each channel can handle up to 5A. The MOSFETs get a little warm at 5A. If the board is used at maximum capacity for long periods, it would benefit from either forced air cooling or a small heat sink on the MOSFETs.

MOSFET Shield for Wemos D1 mini Power Testing Temperature

MOSFET Shield for Wemos D1 mini Power Testing Temperature

I struggled to test all channels to a total of 20A. The battery tester I had can only handle 180W, and the only convenient 20A source I had was a 12v lead acid battery. 12v @ 20A is 240W which is more than 180W, and the tester cuts out when it hits 180W.

I managed to test up to 16A with the lead acid battery setup, which was right on the limit of the 180W limit.

MOSFET Shield for Wemos D1 mini Power Testing 16A

MOSFET Shield for Wemos D1 mini Power Testing 16A

I had a small 2S LiPo at 7.2v and managed to complete a final test of 20A using this LiPo, but at 20A is the battery discharged very quickly and the voltage would drop to 6v very quickly and the tester cuts out at 6v to protect the battery from over discharge.

MOSFET Shield for Wemos D1 mini Power Testing 18A

MOSFET Shield for Wemos D1 mini Power Testing 18A

I’m confident the boards will operate to 5A per channel, to a maximum combined current of 18A as I managed to successfully test to both these levels. At higher currents the individual MOSFETs get hot and the Dupont header does. I think the header pins are only rated to 5A, so for 20A the board would need a redesign with more power pins to distribute the load. 4A per channel is way more than most of my projects need, so I’m happy with the design. If you really need to switch 20A for short periods of time, use a heatsink and solder the wires directly to the board rather than use pin headers and a Dupont connector.

Batch production

The shields were used in three of my home automation projects:

  • Automatic Garden Watering to control four water solenoids connected to garden hoses.
  • Immersion Heater Controller to control 2 high current relays to switch two 3kW hot water immersion heaters.
  • Automatic plant Pot Watering to control a small peristaltic pump to water pot plants based on moisture reading from a capacitive moisture sensor. This was the project that I added the analogue in header on the shield for. This allowed me to connect the moisture sensor and the peristaltic pump to the same shield.

Once the shields had been running in projects for a couple of months, without any issues, I decided to build a small batch to sell online. If I couldn’t find something similar online, then maybe others would like to buy these to use in their robotics or home automation projects.

MOSFET Shield for Wemos D1 mini v1.3 Panel for Fabrication

MOSFET Shield for Wemos D1 mini v1.3 Panel for Fabrication

The four channel MOSFET shield can be purchased here on Tindie.

I sell on Tindie

Final Specification

  • Dimensions : 1″ x 1.3″ x 0.063″ (25.4mm x 33.0 x 1.6mm)
  • Four MOSFETs : AO3400A – 30V N-Channel
    • Maximum Drain-Source Voltage : 30v
    • Continuous Drain Current : 5A
  • GPIO pins used : D5 (GPIO14), D6 (GPIO12), D7 (GPIO13) & D8 (GPIO15)
  • ADC pin A0 available on 0.1″ header with power pins (selectable 3.3v or 5v)

Future revisions

I have already starting thinking about additional features that could be useful.

Using four digital GPIO pins to control the MOSFETs is sometimes a pain as the GPIO pins are shared with other features on the microcontroller. The D5, D6, D7 & D8 pins used on the shield are also the SPI port, so when the MOSFET shield is connected you cannot use SPI at the same time.

An improvement would be to use a I2C device to control the four MOSFETs rather than discrete GPIO pins. Multiple I2C devices can be connected in parallel to the same pins, so if I switched the shield to use I2C you could stack other shields in parallel and all of them would work.

There is a 4-bit I2C I/O expander IC (PCA9536) which could facilitate this. The board layout would be very tight to fit this additional chip on the same top layer. I could try and place it on the bottom layer, but a dual sided board is more expensive and complex to produce.

Or I could also try and add solder jumpers on the bottom layer to allow different GPIO pins to be user selectable.

I’m interested in any feedback on the board or any additional feature requests you would like to see. Leave your feedback in the comments section below.

Hot water tank monitoring

I have electrically heated hot water in my house, and it takes ages to heat a whole tank. It heats up overnight on low cost electricity and we use it during the day. One constant frustration I have is there is no way of knowing how much hot water is left in the tank. I have to canvas my family and interrogate them on who’s had a shower or bath and how much washing up has been done. It would be so much better if I had a web page that showed the remaining hot water level in the tank !?

So, I attached temperature sensors up the side of the hot water tank and monitored them with a Raspberry Pi, of course ! 🙂

I have always wanted to use 1-wire devices in a project, and this was the perfect project. 1-wire devices make the cabling of many sensors easy as they all sit on a shared bus. You can get away with just 2 wires, a signal and a ground, as the devices can consume parasitic power from the signal line before communicating. However, to avoid any power issues and as I didn’t have a problem running more wires, I opted for three wires, power, signal and ground.

I am using the MAX31820 1-wire temperature sensors. They have a simple 3 pin transistor style package (TO-92) and there are lots of existing libraries and support for them. They’re also cheap. I decided to connect them using a ribbon cable, so I made little PCBs for them with a 4 pin header, to make the ribbon cable connection easy. I ended up using 6 way ribbon cable with 6 pin sockets, as it turns out 4 pin IDC sockets are a very difficult to find, where as 6 pin sockets are cheap as chips.

MAX31820 1-wire temperature sensor mounting PCB

MAX31820 1-wire temperature sensor mounting PCB

MAX31820 1-wire temperature sensors on small PCBs

MAX31820 1-wire temperature sensors on small PCBs

Example MAX31820 1-wire temperature sensors on small PCB attached to a ribbon cable

Example MAX31820 1-wire temperature sensors on small PCB attached to a ribbon cable

I already had a USB Adapter for 1-wire, which conveniently is supported by most of the 1-wire Raspberry Pi libraries. However, there are lots of ways of connecting 1-wire devices to a Raspberry Pi. The USB adapter is DS9490R. It takes an RJ11 plug to connect to the 1-wire bus, which also conveniently attaches to my ribbon cable. So, the solution is surprisingly neat.

The tank is pretty standard. Its covered in a insulated foam. I arbitrarily decided that 10 sensors was probably enough resolution. I marked the tank and made 10 equally spaced holes in the insulation with a pencil, then cleaned out the foam with the eraser end of the pencil, until I could see the shiny copper. I dabbed a blob of thermal paste in each hole, to assist with heat transfer from the copper tank to the temperature sensor, as I wouldn’t get direct mechanical contact. The boards and sensors just friction fitted in to the holes, and are kept in by the resistance of the foam on the boards. They are pretty snug and don’t fall out.

The cabling is simple, just attaching IDC connectors at the same regular intervals and then connecting the string of sensors to the Raspberry Pi.

Hot water tank

Hot water tank

Hot water tank with holes for temperature sensors marked

Hot water tank with holes for temperature sensors marked

Hole in the foam insulation showing the shiny copper tank

Hole in the foam insulation showing the shiny copper tank

Temperature sensor on mounting board inserted in the foam insulation

Temperature sensor on mounting board inserted in the foam insulation

Temperature sensors wired together with ribbon cable

Temperature sensors wired together with ribbon cable

Raspberry Pi connected via USB 1-wire adapter to string of sensors

Raspberry Pi connected via USB 1-wire adapter to string of sensors

Raspberry Pi connected via USB 1-wire adapter to string of sensors

Raspberry Pi connected via USB 1-wire adapter to string of sensors

Once the sensors were mounted and connected I installed OWFS (One Wire Filing System) on the Raspberry Pi which is a really easy way to read 1-wire sensors. It maps all the sensors found on the bus to a file system, so by reading the files you can read all the data and configure of all the connected sensors. Again there are loads of ways to access 1-wire devices. Using OWFS just made it easy for me. You could use Python or C, or any other myriad of languages, which all have 1-wire libraries.

Here are some instructions to install OWFS on a Raspberry Pi.

The OWFS maps the devices to a mount point. If you list the contents you get something like this :

root@raspberrypi:# cd /mnt/1wire/
root@raspberrypi:/mnt/1wire# ls -la
total 4
drwxr-xr-x 1 root root 4096 Nov  4 16:17 .
drwxr-xr-x 3 root root 4096 Mar  3  2015 ..
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.0BA759050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.168F59050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.229659050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.33A559050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.49B159050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.849459050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.AAB059050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.BBA459050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.C8AA59050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 28.E6B059050000
drwxrwxrwx 1 root root 4096 Mar 20 19:46 81.E1E324000000
drwxr-xr-x 1 root root 4096 Nov  4 16:17 alarm
drwxr-xr-x 1 root root 4096 Nov  4 16:17 bus.0
drwxr-xr-x 1 root root 4096 Nov  4 16:17 settings
drwxrwxrwx 1 root root 4096 Mar 20 19:46 simultaneous
drwxr-xr-x 1 root root 4096 Nov  4 16:17 statistics
drwxr-xr-x 1 root root 4096 Nov  4 16:17 structure
drwxr-xr-x 1 root root 4096 Nov  4 16:17 system
drwxr-xr-x 1 root root 4096 Nov  4 16:17 uncached

In each directory you can read either the cached or uncached version of the data, plus other details about the device.

root@raspberrypi:/mnt/1wire/28.0BA759050000# ls -la
total 0
drwxrwxrwx 1 root root 4096 Mar 20 19:46 .
drwxr-xr-x 1 root root 4096 Nov  4 16:17 ..
-r--r--r-- 1 root root   16 Nov  4 16:17 address
-rw-rw-rw- 1 root root  256 Nov  4 16:17 alias
-r--r--r-- 1 root root    2 Nov  4 16:17 crc8
drwxrwxrwx 1 root root 4096 Mar 20 19:46 errata
-r--r--r-- 1 root root    2 Nov  4 16:17 family
-r--r--r-- 1 root root   12 Nov  4 16:17 fasttemp
-r--r--r-- 1 root root   12 Nov  4 16:17 id
-r--r--r-- 1 root root   16 Nov  4 16:17 locator
-r--r--r-- 1 root root    1 Mar 20 19:46 power
-r--r--r-- 1 root root   16 Nov  4 16:17 r_address
-r--r--r-- 1 root root   12 Nov  4 16:17 r_id
-r--r--r-- 1 root root   16 Nov  4 16:17 r_locator
-r--r--r-- 1 root root    9 Mar 20 19:46 scratchpad
-r--r--r-- 1 root root   12 Nov  4 16:17 temperature
-r--r--r-- 1 root root   12 Nov  4 16:17 temperature10
-r--r--r-- 1 root root   12 Nov  4 16:17 temperature11
-r--r--r-- 1 root root   12 Nov  4 16:17 temperature12
-r--r--r-- 1 root root   12 Nov  4 16:17 temperature9
-rw-rw-rw- 1 root root   12 Mar 20 19:46 temphigh
-rw-rw-rw- 1 root root   12 Mar 20 19:46 templow
-r--r--r-- 1 root root   32 Nov  4 16:17 type

root@raspberrypi:/mnt/1wire/28.0BA759050000# cat address 
280BA759050000FA

root@raspberrypi:/mnt/1wire/28.0BA759050000# cat family 
28

root@raspberrypi:/mnt/1wire/28.0BA759050000# cat temperature
51.375

root@raspberrypi:/mnt/1wire/28.0BA759050000#

I run a shell script every 5 minutes to read the latest data from all the sensors and store it in a text file.

> cat /root/scripts/logtemp.sh 

#!/bin/sh
date | tr -d '\n' >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.E6B059050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.0BA759050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.49B159050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.168F59050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.C8AA59050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.33A559050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.849459050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.BBA459050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.229659050000/temperature >> /home/pi/templog.txt
echo -n ',' >> /home/pi/templog.txt
cat /mnt/1wire/28.AAB059050000/temperature >> /home/pi/templog.txt
echo ',END' >> /home/pi/templog.txt

I then use this data from a simple web page written in Python to display the latest temperatures in the tank. I decided 35 degrees Celsius is “cold”. If the water is below this I show it as blue (Cold), if its above this I show it as red (Hot). This is open to future expansion where I can fade the colour from red to blue depending on the temperature, more red for hot, more blue for cold, rather than a single colour, but that’s for another day.

> cat hotwater.py 

#!/usr/bin/env python
import cgi
import cgitb
cgitb.enable()

form = cgi.FieldStorage()

print 'Content-type: text/html\n\n'
print '<html><head></head><body>'

fn = '/home/pi/templog-latest.txt'
f = open(fn, 'r')
t = f.readline()
f.close()

temps = t.split(',')

o = ''

if form.getvalue("up","true") == 'true':
        up = True
else:
        up = False

for temp in temps:
        if len(temp) > 8:
                d = temp +"<br>"
        elif len(temp) < 2:
                if up:
                        o = o +'<tr><td bgcolor="#00FF00" align="center"></td></tr>'
                else:
                        o = '<tr><td bgcolor="#00FF00" align="center"></td></tr>'+ o
        elif temp.strip('\n') == 'END':
                z = 1
        else :
                n = int(float(temp))
                if n > 35:
                        if up:
                                o = o +'<tr><td bgcolor="#FF0000" align="center">'+ str(n) +'</td></tr>'
                        else:
                                o = '<tr><td bgcolor="#FF0000" align="center">'+ str(n) +'</td></tr>'+ o
                else:
                        if up:
                                o = o +'<tr><td bgcolor="#0000FF" align="center">'+ str(n) +'</td></tr>'
                        else:
                                o = '<tr><td bgcolor="#0000FF" align="center">'+ str(n) +'</td></tr>'+ o

print d +'<table width=150>'+ o +'</table>'
print '</body></html>'

I can access the web page from anywhere in my house, on my mobile phone, and it instantly shows the quantity of hot water left in the tank, plus each of the 10 individual temperature readings from the sensors. The query string parameter in the web page script reverses the order of the sensor readings in the tank. “up=false” or with no query string, is the default setting, where the temperatures are shown in the correct order, with the hottest water “floating” at the top of the tank. The alternate view, is for users who don’t want a view based on physics, and would rather the visualise a tank full of hot water emptying from the bottom. In this view the hot water is seen at the bottom, slowly draining away to empty. Not scientifically correct, but easier to explain to my 8 year old. Either way the bookmark is saved with the appropriate query string parameter, and everyone in my house can now tell how much hot water is left, before they get in the shower. No more showers suddenly going cold half way through.

Hot water monitoring web page. This shows the tank about half full of hot water. The top of the tank at 45 degrees. The bottom of the tank at 16.

Hot water monitoring web page. This shows the tank about half full of hot water. The top of the tank at 45 degrees. The bottom of the tank at 16.

 

Star Wars Death Star Christmas Bauble

A slightly unplanned project. We needed to test a 3D printer in the office, and seeing as it was Christmas, we printed a Death Star Christmas tree bauble. We already had a Star Wars themed Christmas tree, so it fitted nicely.

The Death Star model came from Thingiverse. The print took about 5 hours and as it was only our second 3D print, it was a pretty good quality.

3D printed Death Star

3D printed Death Star

3D printed Death Star

3D printed Death Star

It had a void in the middle, which fitted an Arduino Mini, so I installed some LEDs to make it flash …

I used a 24 RGB LED NeoPixel ring from Adafruit and an Arduino Pro Mini from SparkFun and a high brightness green LED.

Death Star bauble innards

Death Star bauble innards

With the help of some hot glue, I installed the flashing innards. the two halves are held together with bits magnets from an old hard drive. Its powered by a USB power adapter, and the bauble hangs from the cable.

Star Wars Themed Christmas Tree

Star Wars Themed Christmas Tree

I’m pretty pleased with the result.