How to use a pressure sensor with a Microcontroller (MPS20N0040D-D)

A colleague of mine bought a pressure sensor from Amazon – they are all over the internet can be bought from Amazon, Hobby Components and Dealxtreme!  He wants to use it to measure pressure in a tank.  In order to do that we need to know how to connect it up and obtain the signal and read this signal with a micro controller so that we can display the result and act upon it…The sensor can be bought from the sites below:

MPS20N0040D-D-Pressure-Sensor (Amazon)

MPS20N0040D-d Pressure sensor (DealXtreme)

MPS20N0040D-D Pressure sensor (hobby Components)

The Sensor looks like this:

MPS20N0040D-D Pressure sensor

Here is a link to the datasheet for the sensor:

Pressure Sensor Datasheet

The datasheet isn’t the best I have read but it does provide most of the information required.  The pressure sensor has a measurement range of 0-5 8 psi (40kpa).  The unit psi is an imperial measurement which stands for pounds per square inch.  The scale was designed for use in measuring blood pressure in humans however the scale can be applied to any pressure – gas or liquid.

Wikipedia Entry on the psi unit

The unit psi can be converted to an SI unit Pascals and the datasheet for the pressure sensor refers to 40kpa as being the measurement range converted from psi to Pascals.

Wikpedia Entry on Pascals

1 Pascal (pa) = 1 kg / (metre * second)

Using mathematical formulae to define scales is technically correct but doesn’t really give a real world example of what 1pa actually feels like.  So a real world example of the pressure exuded by one pa would be the weight of a £5 note (or a dollar bill) on a table is roughly equivalent to 1pa. Popcorn kernels popping exudes roughly 10pa.  There are some more real world examples provided in the link below:

magnitudes of pressure

Converting psi to pascals is easy:

1 pound per square inch =

6 894.75729 pascals

So we have a sensor that is capable of measuring a range of pressures, can be driven by 5V and puts out a 0-25mV signal.

That’s enough theory for now…lets get on with using the sensor…The datasheet shows the device using a bridge connection that outputs a 0-25mV signal.  That is a very small signal, if we were to connect the output directly to a micro controller we wouldn’t measure much unless the pressure was full scale and that would be very low.  What needs to be done is to amplify the output of the pressure sensor in order to record the output properly.  That way we get more sensitivity and resolution – in short a better measurement device.

There are plenty of ways of amplifying electronic signals but in the case of instrumentation it is often necessary to amplifier signals quite a lot of times in order to get a usable signal.  To that end we are going to design a difference amplifier. This is an application of operational amplifiers set to provide gain but only measure the difference between the signals applied to the inputs.

Hyper-physics difference amplifier page

All about circuits – differential amplifiers

The datasheet for the Pressure sensor shows how to connect the sensor although not particularly clearly as a Wheatstone bridge.  If more information about Wheatstone bridges is required check out the link below.  It was conceived by a British Scientist and engineer – Samuel Hunter Christie in 1833 and improved by Sir Charles Wheatstone who made it popular.

Wheatstone Bridge

These measurement circuits are one of the foundations of analogue electronics and instrumentation. You can make almost any kind of sensor measurement using a Wheatstone bridge.  Here is the internal circuit diagram for the pressure sensor:

So which pins connect to what?

+ Input connects to +5V
- Input connects to 0V
+ Output connects to + In on the Operational Amplifier
- Output connects to – In on the Operational Amplifier

Next we need to calculate the gain required.  We need to change 0v – 25mV into something larger and we also need to account for the voltage offset present (around 2V).  So first of all lets design a differential amplifier.

How to design a difference amplifier

Rather than reinvent the wheel and go through all of the theory again I used an online calculator to generate values for me.  It’s a lot quicker and easier than pages of mathematical calculations.

Online Difference Amplifier Calculator

I have made several assumptions about the circuit….that the output from the sensor will be somewhere between 2V and 2.2V.   I set the supply voltage to the op-amp as +5V and 0V (single supply mode).  The amplifier then gives out between 57mV and 970mV.  Those values are quite small so we will need to amplify that further in order to give a reasonable output into the micro-controller ADC input.  We are looking for something between 0V and 5V.

Here is the first part of the circuit.  I’ve drawn the sensor as resistors in the ‘Wheatstone bridge’ configuration.  To check the sensor was working I measured the resistance between each sensor pin with an ohm meter and found there to be 5k Ohms present in each part of the sensor circuit.

Lets explain the circuit….

The blue square is a rough guess at how the sensor works…It may not be entirely accurate but I don’t have any more information to work from.  The amount the wheatstone bridge varies is again a guess at 1k – I’m hoping it works this well!!

The green square is a simple filter to prevent external noise (interference) from affecting the measurement.  We only want to measure signals from pressure sensor and nothing else.

The red square is the section designed with the calculator.  It’s a standard difference amplifier with a feedback capacitor and some supply de-coupling capacitors again to prevent external interference affecting the circuit.  The gain of the amplifier is 5.6.

The output of the amplifier is still a little low to drive the ADC so lets add a non inverting amplifier to the output section so that we then get a times 3 gain and therefore a 200mV to 3.5V swing.

Here is the full analogue input stage:

I simulated the circuit just to make sure it worked.  It appears to and here is the video of the circuit for those that are interested.

We can now design the full circuit and design an arduino shield.  I have added RS485 communications as that was one of the requirements of the circuit.  I haven’t discussed RS485 before but it is a fairly common serial communciations protocol.  Here is the full schematic diagram:

I have also designed an Eagle Shield for it but I have actually etched this yet….

Here is the top player – note that the Instrumentation amplifier is an SOIC surface mount package which is mounted on the underside of the board.

The rest of the circuit shows the connections to the arduino and I also added a 16×2 LCD display and the communications section.

So before I do anything I always prototype a circuit and this time is no different.  I got all of the required components and attached them with wires to my breadboard and arduino.  I didn’t bother with the RS485 Communications section.  That can come later  Here is how it looks:

I then wrote some very quick code to check it works:

Alex’s MPS20N0040D-D test Code

A simple piece of code to check the output from an
analogue pressure sensor connected via a difference
amplifier to the A0 input of the arduino

Based on the analogueInOut Serial Example


// These constants won’t change.  They’re used to give names
// to the pins used:
const int analogInPin = A0;  // Analog input pin that the OP-amp output is attached to

int sensorValue = 0;        // value read from the Sensor
int outputValue = 0;        // Mapped Value for the serial output

void setup() {
  // initialize serial communications at 9600 bps:

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 640, 1023, 0, 255); //The zero value of the sensor is around 640 
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);           

  // print the results to the serial monitor:
  Serial.print(“sensor = ” );                       
  Serial.print(“t mapped output = “);      

  // wait 250 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:

Once I had uploaded this to the arduino and opened a serial monitor I expected there to be a steady stream of values being output to the serial monitor – there was!  Excellent.  I then attached a small piece of tubing to the pressure sensor and blew down the tube (provided some pressure)….Nothing happened….I then checked all of my connections and swapped the LM358 OP-Amp for another one….just in case and nothing happened.  I then removed all of the connections and rebuilt the entire circuit and reconnected it to the arduino and repeated the test and nothing happened.  At this point I was beginning to think the sensor was faulty….And then I had a moment of clarity and sucked on the tube connected to the sensor instead of blowing down it – SUCCESS!!!  The reading from the serial monitor varied with the amount of suction provided….One slight hitch….We wanted to measure positive pressure and not vacuum….

So whilst this circuit does work for this sensor and does do everything required to get it working it isn’t what was originally required.  After the time spent designing and getting it working I’m writing it up as a learning exercise…It was a good piece of analogue electronics to get the amplifier designed….pity the sensor doesn’t work as intended….*wry grin*

I’m not going to etch the PCB for this project as there is no real point.  Everything is available to get it working if people are interested.



Elbert V2 FPGA Tutorial

I recently bought an FPGA development board from Numato Lab.  I have been wanting to get into FPGA technology for some time.  I haven’t really used them much since I was at university which was far too long ago!

Spartan 3A Development Board – Numato Lab

FPGA stands for Field Programmable Gate Array – basically an integrated circuit where the function can be decided by the designer.  Supposing a designer needed a circuit that would perform a specific boolean function continuously at very high speed.  How could this be implemented?  There are several options:

We could program a microcontroller to take perform the boolean function – possible but quite slow and time consuming…

We could create the boolean function in discrete logic – might take a very very long time and would be very difficult and expensive to implement…

We could write some VHDL or Verilog and program an FPGA – quite expensive and difficult to design but then this is not a simple problem…

A really good introduction to FPGA technology is here:

Embedded Micro – FPGA tutorials

I really want to get into FPGA technology because I can see it is useful…high speed instrumentation is difficult to achieve without being able to process data very quickly and something an FPGA can do very quickly (even faster than a microprocessor or controller) is process data!

There are other reasons for using an FPGA but my reasons are purely to learn the skill and to have some fun!

The development board I bought from India cost me £32 ($44) and I opted for it to be shipped by UPS and it arrived within three days!  I got charged a brokerage fee by UPS so ended up paying an extra £20 in fees but this is still cheaper than a lot of the other options available.

Here are the specifications of the development board taken from the Numato Lab website:

  • FPGA: Spartan XC3S50A in TQG144 package
  • Flash memory: 16 Mb SPI flash memory (M25P16)
  • USB 2.0 interface for On-board flash programming
  • FPGA configuration via JTAG and USB
  • 8 LEDs ,Six Push Buttons and 8 way DIP switch for user defined application
  • VGA output
  • Stereo audio out
  • Micro SD Card Adapter
  • Three Seven Segment Displays
  • 39 IOs for user defined purposes
  • On-board voltage regulators for single power rail operation

It’s a fairly standard development board and hopefully has everything I need to get started learning and using FPGA technology.  The key points to know are that this board has an onboard programmer so I don’t need to spend money getting an external one – they are expensive!  It has an onboard power supply – always useful and I can connect it directly to a VGA monitor; it has onboard sound output and can take a microSD card.

Exciting times! – I downloaded the USB driver, User constraints file and configuration downloaders from the Numato Lab website in preparation:

Download Elbert V2 files

I placed them in a Numator Labs folder on my Windows PC, and extracted the drivers and UCF file. Next I grabbed a USB A to Mini B cable and plugged it into the development board – The card powered up straight away and windows recognised a USB device had been attached.  It tried to locate a driver and when it couldn’t I navigated to the Numato Labs folder and pointed the driver installer to use the numatoCDC driver.  It installed straight away and is displayed as a COM port in the device manager.

I then began to follow the instructions from the Numato Lab Website and their tutorials.  The tutorials go through what an FPGA is and how it can be programmed and use a simple Not gate (inverter) example.  When it comes to programming the device the tutorial refers to some Xilinx software which is needed to compile the example and generate what is called a ‘Bit Stream’.

I went to the Xilinx website and tried to download the software suite known as ISE Webpack.  In order to get access to the downloads section I needed to register with the site, obtain a licence file and then select the software package required.  At first I downloaded the Vivado suite as this was the first and latest piece of software present in the downloads section of the Xilinx website download area.  It was 6.7Gb of data!  It took over an hour to fully download and turned out to not be what was required – the Spartan 3A device used on the Elbert V2 development board is not supported in the latest Xilinx design software – Very frustrating and confusing.  I then spent a great deal of time reading the Elbert V2 manual and looking for the correct software and finally found it here:

Download ISE Webpack softare

It was also 6.7Gb in size and took a long time to download….I then proceeded to install the software and that also seemed to take a very long time to install!  I then pointed the software to the location of the licence file and loaded up the software:

We are presented with the following user interface:

Get rid of the tip of the day box by clicking the OK button.

Next Click on the ‘New Project’ Button:

Choose a name for the project and choose to place the project in a suitable folder on your hard disk:

Click on the ‘Next’ button and fill in all the details as shown below – these are the parameters specific to the FPGA on the Elbert V2 Board – a Xilinx Spartan 3A – XC3S50A:

For this tutorial I will be using the Verilog style of programming for the FPGA.  Verilog is a type of hardware description language.  The other language often used is known as VHDL

Wikipedia Entry on Hardware Description Languages

Wikipedia Entry on Verilog

Anyway…as the original Elbert tutorial available discusses an inverter we are going to do the same thing.  The tutorials from the Numato Lab website are here:

Numato Guide Part 1

Numato Guide Part 2

Numato Guide Part 3

Numato Guide Part 4

I am referring to them to write this tutorial…The webshots were different and it wasn’t as straight forward for me as I think it could be…that’s why I am writing this one – it will hopefully redress the balance a little.  Click on the ‘Next’ button and you will be presented with the following window:

It confirms all of the details concerning the project – Click on the ‘Finish’ button to return to the main ISE Editor Screen:

Now we are going to create a text file which contains the Verilog code to model the function of an Inverter or NOT gate.  Right click on the ‘Hierachy’ window indicated:

A new window will appear – select verilog module and type a suitable module name in the dialog box:

Click the ‘Next’ button and another window will appear – Fill in the details as shown below:

This means we are creating a verilog module which has one input ( A ) and one output ( B ) just like an inverter.  This is confirmed in the summary window which is displayed when the ‘Next’ button is clicked on:

Click on the ‘Finish’ Button and you will return to the main ISE Webpack Screen.  The source code file we just generated will be displayed:

The screen to the right shows verilog module template with an input called ‘A’ and an output called ‘B’.  We now need to write the verilog code which models the behaviour of an Inverter or NOT gate:

On line 25 in the text editor (right side of the screen) type the following code:

input wire A;
output wire B;
assign B=!A;

Click on the Save button to save your work:

Here is what the code means:

module elbertNotGate(  // create a module called elbertNotGate
    A,                 // It has one input called A
    B                  // It has one output called B
input wire A;          // The input A is a physical wired input
output wire B;         // The input B is a physical wired output

assign B=!A;           // Assign output B the inverse of input A

endmodule              // End the module

Next lets check this code works properly by simulating it.  This is an awesome feature of FPGA programming.  Anything we type can be simulated to check it works properly!  Right click on the Hierachy window again and ‘add new source':

This time we are going to select ‘Verilog Test Feature’ and give it a suitable name:

Click on the ‘Next’ button and a new windows will be displayed:

Click on the ‘Next’ button to continue and a summary window will be displayed confirming the information we have provided for the test bench file:

Click on the finish button to continue and return the main ISE webpack screen.  Now we need to enter some code which tells the simulator how to test the NOT gate module.  Enter the following code after deleting the automatically generated code:

module elbert_testBox; // create a module called elbert_testBox 

   wire out;         // create an output called wire
   reg clock;         // create a register called clock

   always begin   // Start the clock oscillating
   #1 clock =!clock;

   initial begin        // Initialize clock at zero
   clock = 0;
   #10;         // Wait 10 ns to end simulation

   elbertNotGate NotGate(clock, out); // Set the outputs

Save the file and you should have the following on screen, also click on the simulate radio button above the hierachy box:

Now click on the newly created testbox module in the hierachy box, then select ‘Simulate Behaviour Model’ – right click on it and select ‘Run’

After a few moments (the software is processing the simulation) The following screen will be displayed from the simulation software module ‘Isim':

Click on the Default.wcfg tab to display the results of the simulation:

Click on the ‘Zoom to Full View’ Icon on the top tool bar to display the waveform clearly:

It shows the operation of the Inverter.  With a 1 nano-second clock input applied to the A pin the output is the inverted – Cool huh!

So….we have written a module in verilog that models the behaviour of an Inverter or NOT gate and we have simulated it.  Now lets make it work for real <really big grin>

What we need to do is tell the Xilinx ISE Project Navigator software about the Elbert V2 development board – which pins are IO pins, which pins are connected to buttons, LEDS, audio output, microSD card and VGA connector etc.  This performed using a text file called the user constraints file.  We place the appropriate user constraints file in the project folder, tell ISE where it is and then when we come to compile the verilog code we can create a bit stream file which we then use to program the development board – a little involved but we will get there!

First off we need to know which pins are connected to what and in order to do that we need the schematic diagram for the Elbert V2 development board:

Elbert V2 Development board schematic

If you scroll through the pages eventually you will see the FPGA connections:

It’s also a good idea to have a look at the Elbert V2 Manual:

Elbert V2 User Manual

On Page six it tells us how the LEDS and push button switches are connected:

So the push button switch 1 is connected to pin 80 on the FPGA and LED 8 is connected to pin 46. We can now use this information to generate a user constraints file:

 # User Constraint File for NOT gate implementation on Elbert V2

 # Push button switch 1 is connected to pin 80
 #NET “Switch[1]” LOC = P80  | IOSTANDARD = LVTTL | DRIVE = 12 | SLEW = FAST | PULLUP ;

 #  LED 8 is connected to pin 46

We can change this information in the above text file to point to the variable names we used in our module – ‘A’ and ‘B’

 # User Constraint File for NOT gate implementation on Elbert V2

 # Push button switch 1 is connected to pin 80
 NET “A” LOC = P80;  

 # Push Button Switches.
 # Internal pull-ups need to be enabled since 
 # there is no pull-up resistor available on board

 # LED 8 is connected to pin 46
 NET “B” LOC = P46;

All I have done is change the NET names to reflect the variable names we used in the module.  I have also enabled the internal pullup resistor on pin 80 as without this the switch will not work – there are no external resistors connected to the switch.

So now all we have to do is create this file in the project and add it – right click on the Hierachy window again and add an ‘implementation constraints file':

Select the implementation constraints file:

Click ‘Next’ and the summary screen will be displayed:

Click on the ‘Finish’ button to return to the main screen next Click on the ‘Files’ tab in the bottom left corner of the screen:

Now double click on the notGate.ucf file to open it and then enter the UCF text for our project from above:

 Click on the ‘Design’ tab in the bottom left corner and then select the implementation radio button:

If all goes well you will be presented with the following screen:

Now we need to generate a bitstream file to upload to the FPGA development board….right click on ‘Generate Programming File’ and select ‘Run’

Once that is is complete and successful we need to load up the external programming software from Numato Labs called ElbertV2config – Elbert FPGA Configuration tool V1.0 and then select the COM port associated with the development board – mine was on COM 5.  We then need to navigate to the project folder on the hard disk and select the binary file we just generated – elbertNotgate.bin

Click on the programming button when ready and then the bitstream file will be used to ‘flash’ the FPGA:

Once complete – advance to the FPGA development board and you should see that none of the LEDS are ‘ON’ and then when you press momentary button SW1….LED 8 comes on!  Cool Huh!  Well maybe not but its a start!

Here is a picture of the board and a short video showing the board working…take care people – Langster!

Ethernet, RS485 and power down a single cat 5 cable

For my boat automation system I plan to use RJ45 sockets and cat 5 cable for interconnecting the master and the nodes. Some nodes will have their own 12 V supply for larger loads, but ones that are just for switches and other transducers (sensors) will need to have 12 V delivered to them. According […]