Tag Archives: PCB

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.

SMD PCB Stencils

Usually I build my printed circuit boards by hand. Once the boards are fabricated, I apply solder paste using the patented “Jon Toothpick Method”, then place the components by hand using tweezers. This works fine, as I usually only build 1 or 2 boards. But recently some of the projects I’ve been building have either lots of SMD devices (a recent board had 30+ 0603 resistors), or the devices I’m using are tin, with very small pitch legs (I use SSOP & TSSOP packages, which are very small).

So, I decided to try getting a solder stencil made to use during my next build. I use OSH Park for my PCBs and they recommended OSH Stencils. The stencils were very affordable. They cost about $10 each, and they are about 6.5 sq in. I think they are laser cut Kapton film which according to online review, is pretty durable.

The process of applying solder paste using a solder stencil is pretty simple:

  • Use a old PCB or a guide taped to a flat surface to stably locate the PCB
  • Place a PCB in the guide and line up the stencil with the pads on the PCB
  • Tape the stencil to the guide to locate it in place
  • squeeze a small bead of solder paste  across the film at one end and smear it across the film using an old credit card or squeegee.
  • The film shouldn’t have any left over solder paste on it after you make the pass across the board. The squeegee should wipe it off as it passes. Paste should only be in the holes in the film.
  • gently peel back the film off the board and the solder should be neatly applied to all your pads.
  • place components and reflow the solder in an oven.

Here are some pictures of the process.

AVC 2014 PCB

New PCB

PCB Stencil

PCB Stencil

PCB Stencil

Align stencil with PCB

PCB Stencil

Tape stencil in to position

PCB Stencil

Wipe solder paste across board

PCB Stencil - Solder paste

Solder paste applied on the pads

PCB Stencil - Solder paste

Solder paste applied on the pads

PCB Stencil - After soldering

After components and soldering

PCB Stencil - After soldering

After components and soldering

I’m very pleased with the results. There is almost no solder spilled on the PCB to clean off, you get consistently the right amount of solder paste on each pad  and the result looks very professional and neat.

The process was easy and quick. I think I’ll be using stencils with all my future PCB builds. I just need a pick and place robot now … 🙂

AVC – First test run

The mBed versions of the AVC PCBs arrived. I built the first version, with surface mount components in my oven at home. It works first time. It turns out I made one mistake on the PCB, using the wrong ratio SMD resistors with the battery divider in to the mBed, so I had to take them off and modify it with standard through hole resistors, as I couldn’t hand solder the 0602 surface mount resistors. I made the modification for the SPI connection for the IMU, and swapped a couple of sensor to different pins to give me SPI and Serial in the right places.

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

I mounted the circuit in a Tupperware box on the car to keep it water tight.

My first outside test of the complete system was very exciting, but a little disappointing. Not only did I manage to run my wife over with the car, giving her a nasty bruise, but also the car seemed to like to take the scenic route to the way point, rather than a more direct route. All down to magnetometer issues again. I was still getting erroneous and unstable readings. In fact this plagued me from start to finish on this project, and still hasn’t gone away.

The only solution I have found to improving the magnetometer readings is to re-run the magnetometer re-calibration process regularly (before each run). The numbers always come out slightly different?

The first end to end test of the system in my garden was one week before the competition. I still hadn’t written a lot of the other functions in the code. Sections of the code like; how to tell if I had reached a waypoint, loading way points from SD, obstacle avoidance using the sonar, and tuning the PID parameters. I also hadn’t actually mapped my waypoints for the route I was going to take through the course.

The PID tuning would have to wait. I was getting pretty good steering results just with the “P” terms. This would mean I was in danger of oscillations, but that was the least of my worries. I could hardly drive in a straight line at the moment …

I didn’t have time to write any sonar obstacle avoidance code. I had a plan to read the distance data from the sonar and if an object got within 2 metres, add an offset in to the steering calculation to veer slightly left or right to miss the object. However, I hadn’t quite worked out how to tell if I had “passed” it to remove the offset, as I only had a forward facing sonar. The other option was to just stop the bot if an object appeared less than 20cm in front of the bot, stop, turn a few degrees, go forwards, then continue under GPS control… I’ll get round to adding this later …

I arrived in the US for a conference about a week before the competition and spent the evenings in the hotel writing the missing code. I wrote a basic file reader to load way points and basic config data from file, plus as my xBee worked for about 2m at best, I wrote a simple logging function, which meant I had some debug data after each test run to investigate. My waypoint algorithm was relatively simple;

  1. Calculate the heading and distance to the next way point
  2. Use the PID control to steer on that heading.
  3. If the distance to the way point was less than 2m meters, we’re very close. At this point these it a danger the bot will drive in circles, as the turning radius is greater that the heading it needs to hit the way point exactly. So, once we get close, I no change the steering to steer to the waypoint, instead, continue on the heading I was on just before we got close. You can assume the heading I was on would hit the waypoint pretty close. So, if I stay on that heading, and monitor the GPS vector to the waypoint, as I pass the way point I should see the GPS vector increase to 90 degrees as I pass by the waypoint. i.e. the vector will go from straight ahead, to 10, 20, 30, 45, eventually 90 degrees. At this point I’m within 2m meters and its 45 degrees or 90 degrees to my left or right, so, that’s a pretty good assumption of hitting the way point, so I assume I’ve passed it, and move on to the next way point.
  4. Once the bot has visited all the way point it has loaded, it stops. Course complete.
Way Point Diagram

Way Point Diagram

I didn’t have time to write the obstacle avoidance code or tune the PID in time for the competition.

The day before the competition I spent the afternoon at the location planning the course and testing the code. I rewrote my magnetometer code again, this time using my own simple trigonometry rather than the library function. Plus I debugged the “hitting the way point” logic. By sunset, I’d navigated to a series of way points for the first time, but still careering off course occasionally. In addition I suddenly remembered that I hadn’t compensated for magnetic vs. true north, so added some Magnetic deviation code. This link has a great calculator for magnetic variance. It shows that Colorado has a deviation of about 8 degree, which would have been a big issue if I hadn’t remembered to compensate for it.

Other posts in this series :

AVC – Problems

The basic prototype worked on the bench, but as I built it on to the chassis, it started to have issues. The magnetometer would give very random and unreliable readings. I kind of assumed I’ve get some interference, but this was reading north sometimes 180 degree out. In addition, the reading changed when the motors ran and the servos moved. I assumed I was getting magnetic flux from the motors and servos, and this was interfering with the magnetometer. However, without the motors running, I was also getting bad drift from the magnetometer. For example, I would point the car north, take a magnetometer reading, then rotate the car 360 degrees, the reading wouldn’t give me a 360 change. When I get back to north I would read 280 odd degrees, in addition, if I did the same experiment in different places in the room, or at different times, I got different readings. The magnetometer be useless if I couldn’t reliably know where “north” was.

The xBee also had issues, and seemed to only work up to about 1-2m away … which wasn’t very useful. I only had 1mW series 1 devices, which on the data sheet said they’d get 600m, so I expected a bit better than 2m, but I assume this was also due to interference. This wasn’t a deal breaker, as most of the testing could be done with the car no actually driving. All the debugging was around the steering, so 2m was fine to just not have a cable in the way. But it was frustrating … I had to follow the car around carrying the laptop, instead of just sitting in the garden at a table and taking reading as it drove around.

I stuck with the xBee but I moved the magnetometer away from the main board and chassis, to try and reduce the interference. I assumed the interference was magnetic flux coming from the huge brushless motor and large powerful steering servo in the car. If I mounted the magnetometer away from these, perhaps I’d get a more reliable reading. And so was born “broom-handle-bot”

SparkFun AVC 2013 autonomous robot

SparkFun AVC 2013 autonomous robot

While working on the prototype I was also researching better GPS solutions. The basic GPS module I was using only had an accuracy of about 2-5m. This would be tricky to avoid a barrel or hit a jump 1m wide. I had stumbled across SBAS while research GPS issues and this potentially could give me accuracy down to 1-2m. Much better. You can read the wiki page for more details, but effectively (IIUIC) the SBAS system sends a separate signal from a different set of satellites that contains data to improve the accuracy of the main GPS signal. It compensates for atmospheric interface, and other transmission errors. There are different SBAS systems in different parts of the world, WAAS in North America and GLONASS in Europe. I would need a GPS receiver that supported both. Again, with some googling, I found NaviLock and the NL-622MP MD6 GPS Receiver. The data sheet confirmed it supported WAAS and GLONASS, it uses the latest u-Blox chipset, and came in a handy mountable self-contained puck. I ordered one and it arrived. The only downside was the output was RS232 (+/- 15v) not TTL, so I’d need a level shifter board to connect it to the mBed. If I had spent more time looking, they do do a TTL version, which would have been easier …

The very first test of the new GPS puck was transformational. The old GPS wouldn’t get a lock inside my house, which made testing a real pain. I would have to write the code, upload it, then disconnect the system, walk outside in to the garden, test it in the cold, then come back in and debug it, then repeat. This wouldn’t have been so bad, if this was on a Sunday afternoon, but due to my job and family commitments, nearly all my tinkering was done at night, between the hours of 10pm and 2am. It was also the back end of winter, and still snowy some weekend. Testing in the garden at midnight in the snow wasn’t fun.
The new GPS got a lock inside. Plus it got a lock really quickly, within seconds. The old GPS took minutes. It was clear from the first few outside tests that the accuracy was much better and the reading more stable. The GPS used the uBlox 6 chipset, with came with a very detailed and advance desktop config and debug utility.

The basic system was working. However I still had magnetometer issues. The reading would vary wildly if the magnetometer was close to the car. Even if it was some distance way, it wasn’t reliable. It would point north, then I would rotate it 180 and it wouldn’t point S, it would read 160 degrees, then I point it north again and it would read -30. If I rotated it 360 degrees sometimes it didn’t move, sometimes it rotated 250 degrees. I tried lots of different configurations. Even on the bench with no magnets or metal close it wasn’t reliable.
After some extensive Googling, it seemed I need to perform a calibration. This would calibrate out basic interference if the interference was constant, like a steel mounting screw that was always in the same relative position to the sensor. This link explains the process. You take lots of readings from every orientation, imaging mounting the sensor on gimbals and spinning it on all axis, so the tip of the sensor scribes the outline of a sphere. Ideally you want a data cloud of points in all orientations from all three sensors; x, y & z.
Once you have the data set you need to do three things;

  1. You need to remove “erroneous” readings, called outliners. There are clearly (statistically) incorrect. These are obvious to spot manually as the sit outside the circle/sphere of normal readings.
  2. You need to normalise the data in all three axis, so all the maximum readings from all the of the x, y & z sensors have the same magnitude
  3. You need to shift the data so to each set of readings is centred on zero.

Imagine a point cloud that is slightly oval shaped. The normalisation process shifts and scales the cloud so it’s a perfect circle, orgined around zero.These scaling and offset numbers are then used to scale the raw reading to give better accuracy.

Compass Calibration - Before

Compass Calibration – Before

Compass Calibration - After

Compass Calibration – After

This worked to an extent, and the magnetometer was noticeably more accurate and stable, but I still had problems. So I thought I’d tried a different approach. I had an IMU sensor from a previous project. This sensor has 9 DoF (gyro, accelerometer & magnetometer) plus a CPU and contains a kalman filter to process the data. It will give Euler angles, and all I was after was “yaw” – Phi. The issue was the device was not I2C, but serial or SPI. The serial interface had complex packet structure and I didn’t have time to write and debug a parser, so I opted for SPI. I modified the code to read SPI and got a basic Phi reading from the device.
This was more accurate. But it now had a different problem. The issue with yaw calculating with a 9 DoF board, is the yaw cannot use the accelerometer data, as it rotates around the accelerometer axis so it never changes. It can only merge the magnetometer and gyro data. And this is susceptible to gyro drift. This manifested itself in the yaw reading slowing rotating even when the unit was stationary. There was a function in the devices to zero the gyros when the unit was at a known stationary position, but after time the drift returned. That clearly wasn’t going to work.

The final option was to try the same basic magnetometer code, but with these IMU magnetometer readings. You can read all the raw gyro, accelerometer, magnetometer readings, plus the processed (filtered) version, plus the Euler angles from the device.
It turned out the process (filtered) raw magnetometer readings were pretty stable. So I had my final solution. However … about a week before the competition!

Other posts in this series :

Whats the old saying … Measure twice, cut once ?

You know how I show images of me laying out components on colour print outs of my PCBs to check they fit ?

I broke my own rule and it bit me !

The OpAmp footprints on the PCB are TSSOP14 but the devices I bought are SOIC14 😦