langster1980

I'm an electronics engineer and uber geek. I mostly spend my time working on electronics projects. I do a lot of development using microcontrollers - particularly using the arduino and mbed....

langster1980 wrote 32 posts

Numato Mimas V2 Tutorial

Just in time for Christmas I got a present from Numato Labs!  They have sent me a Mimas V2 FPGA development board!  *Really Huge Grin*

I thought the first thing I should do would be to write up a tutorial on how to get started using it. Here is a short video of me unboxing it!

For those who are not aware the Mimas V2 is an FPGA development board.  It’s basically a simple to use tool for people who would like to learn how to use an FPGA (Field Programmable Gate Array) device to complete complex engineering and programming tasks.  FPGA devices are quite complex and the learning curve can be quite steep.  A simple to use and program development board takes some of the load off.

Here are the specifications of the Mimas V2:

  • FPGA: Spartan XC6SLX9 in CSG324 package
  • DDR: 166MHz 512Mb LPDDR (MT46H32M16LF/W949D6CBHX6E)
  • 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 purposes
  • VGA Connector
  • Stereo Jack
  • Micro SD Card Adapter
  • Three Digit Seven Segment Display.
  • 32 IOs for user defined purposes
  • Four 6×2 Expansion Connectors
  • On-board voltage regulators for single power rail operation

The key points to note from the above list is that we don’t need an expensive external programmer or complicated power supply, the board has lots of memory and plenty of ways to interface with the FPGA device!


In order to use the development board we will need to download a few bits and pieces from the Numato Website:
We will also need to download Xilinx Webpack ISE 14.7 and a licence file….and in order to that you will need to register with the Xilinx Website and then download the files as required.  It isn’t difficult but it might be confusing:

Once the software has downloaded you will need to install it.  Extract it to a suitable folder on your hard disk and then navigate to the install file xsetup.exe.  You will need to execute the setup and then let the software install.  The installation program will prompt you to respond to where you would like to install the software and which features you require.  Choose the default features (Webpack ISE) and continue.  At the end of the installation you will be prompted to obtain a licence file – make sure that you enter a suitable email address to receive the licence file.  You can’t program the Mimas V2 without it!
Once the software is installed run the Xilinx ISE 14.7 project Navigator (choose 32 bit or 64 bit as appropriate to your operating system)
Once the Xilinx project navigator software has loaded we need to start a new project – Exciting times! 
After that a new window will appear prompting you to select where on your hard disk you wish to store the project files and what you would like to name the project.  Choose somewhere suitable to store the files and call the project something appropriate.  Make sure you select HDL as the top level source – this means we will be typing in code to program the project, not drawing a schematic. Click ‘Next’ when ready:
The next screen prompts you to enter the specifications of the FPGA – Make sure your select the same settings as shown below, if you don’t your project may not compile and may not work!
Click ‘Next’ to continue onto the project summary screen.  Its a text file which confirms all of the information we just selected.  Click ‘Finish’ to close the window and return to the main Xilinx project screen:
Don’t be put off by all the menu items and toolbars. You will learn how to use them in time!  What we need to do now is create a new source file.  Right click on the box with the text ‘Empty view’ and add new source:
A new window will appear – select VHDL module and provide an appropriate file name:

Click ‘Next’ when you are ready to continue.  For this tutorial we are going to keep things simple!  Lets turn an LED on when we push an associated button.  I’ve chosen to have two inputs and two outputs and given them appropriate names:


Click ‘Next’ when you are ready to continue.  A summary screen giving the details we just selected will be provided.


Click ‘Finish’ and the source code template will be displayed in the main project window:


Any line which is in green and preceded by ‘–‘ is a comment.  Any word in dark blue is a ‘keyword’ and any text in purple relates to a library or method.  The Xilinx software has added a few comments relating to the source file.  I tend to delete them as they aren’t strictly necessary.  Cut out the comments (optional) and paste in the code below:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- Alex's Mimas V2 VHDL Tutorial
-- (c) 21-12-2014
-- A simple demonstration of a development board

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Mimas_V2_VHDL_Tutorial is
Port ( DIP1 : in STD_LOGIC;
DIP2 : in STD_LOGIC;
LED1 : out STD_LOGIC;
LED2 : out STD_LOGIC);
end Mimas_V2_VHDL_Tutorial;

architecture Behavioral of Mimas_V2_VHDL_Tutorial is

begin

LED1 <= DIP1;
LED2 <= DIP2;

end Behavioral;

The first three lines are comments about what the source code does.  Lines 5 and 6 tell the Xilinx compiler to use the standard library and notation.  Lines 8 to 13 tell the Xilinx compiler what inputs and outputs we want to use – two dip switches and two onboard LEDS.  The actual function (behaviour) the dip switches and LEDS perform is set by lines 19 and and 20.  LED1 is equal to the state that DIP switch 1 is at and the same for LED 2 and switch 2.

Now we need to tell the Xilinx compiler which pins are connected to what.  To do that we need to create an implementation constraints file.  Right click on the ‘Hierachy box’ and add a new source file.

Select ‘Implementation Constraints File’ and give it a suitable file name.

Click ‘Next’ when you are ready to continue and a summary window will be displayed:

Click ‘Finish’ to return to the main project window where the ICF file will be open and blank!  What we need to do is fill it.  To that we need to know how the Mimas V2 board is connected up – How are the DIP switches and LEDS and for that matter any peripheral devices connected to the FPGA?  The way to find out is to consult the manual and the schematic diagram.  The schematic diagram of interest is on page 29 of the manual.  The diagram is quite complex but if we look carefully we can see the bus connections of the DIP switches and LEDS:

We can choose to use any LED or any DIP switch we like.  I’m going to use LED1 and LED8 for the outputs and DIP switch 1 and DIP switch 2 for the inputs just to be different!  LED1 is connected to pin ‘P15′ and LED 8 is connected to pin ‘T17′.  The DIP switches are on pins ‘C17′ and ‘C18′.  From this information we can write the implementation constraints file.  Numato labs have helpfully provided a sample one.  All we need to do is modify it to suit our purposes.  Here is the sample file:

# This file is a .ucf for Mimas V2                                                                    #
# To use it in your project : #
# * Remove or comment the lines corresponding to unused pins in the project #
# * Rename the used signals according to the your project #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

#********************************************************************************************************************#
# UCF for Waxwing Spartan 6 Development Board #
#********************************************************************************************************************#

CONFIG VCCAUX = "3.3" ;

NET "CLK" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz;

NET "RST_n" IOSTANDARD = LVCMOS33 | PULLUP;


######################################################################################################################
# DIP Switches #
######################################################################################################################
NET "DPSwitch[0]" LOC = C17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[1]" LOC = C18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[2]" LOC = D17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[3]" LOC = D18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[4]" LOC = E18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[5]" LOC = E16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[6]" LOC = F18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "DPSwitch[7]" LOC = F17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

######################################################################################################################
# Push Buttons Switches #
######################################################################################################################

NET "Switch[0]" LOC = M18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET
"Switch[1]" LOC = L18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET
"Switch[2]" LOC = M16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET
"Switch[3]" LOC = L17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET
"Switch[4]" LOC = K17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET
"Switch[5]" LOC = K18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

######################################################################################################################
# LEDs #
######################################################################################################################

NET "LED[0]" LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[1]" LOC = P16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[2]" LOC = N15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[3]" LOC = N16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[4]" LOC = U17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[5]" LOC = U18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[6]" LOC = T17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"LED[7]" LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# Seven Segment Display #
######################################################################################################################

NET "SevenSegment[0]" LOC = A5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"SevenSegment[1]" LOC = C6 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"SevenSegment[2]" LOC = D6 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"SevenSegment[3]" LOC = C5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"SevenSegment[4]" LOC = C4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"SevenSegment[5]" LOC = A4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
    NET "SevenSegment[6]"     LOC = B4  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "SevenSegment[7]" LOC = A3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
# Enables for Seven Segment
  
NET "SevenSegmentEnable[2]" LOC = B3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "SevenSegmentEnable[1]" LOC = A2 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "SevenSegmentEnable[0]" LOC = B2 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# Audio #
######################################################################################################################
NET "Audio1" LOC = B16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Audio2" LOC = A16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# VGA #
######################################################################################################################

NET "HSync" LOC = B12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"VSync" LOC = A12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

NET
"Red[2]" LOC = C9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"Red[1]" LOC = B9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"Red[0]" LOC = A9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

NET
"Green[2]" LOC = C11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"Green[1]" LOC = A10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"Green[0]" LOC = C10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

NET
"Blue[2]" LOC = A11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"Blue[1]" LOC = B11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;


######################################################################################################################
# HEADER P6 #
######################################################################################################################

NET "IO_P6[0]" LOC = U7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[1]" LOC = V7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[2]" LOC = T4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[3]" LOC = V4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[4]" LOC = U5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[5]" LOC = V5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[6]" LOC = R3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P6[7]" LOC = T3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# HEADER P7 #
######################################################################################################################

NET "IO_P7[0]" LOC = U8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[1]" LOC = V8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[2]" LOC = R8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[3]" LOC = T8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[4]" LOC = R5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[5]" LOC = T5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[6]" LOC = T9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P7[7]" LOC = V9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# HEADER P8 #
######################################################################################################################

NET "IO_P8[0]" LOC = R11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[1]" LOC = T11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[2]" LOC = R10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[3]" LOC = T10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[4]" LOC = U13 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[5]" LOC = V13 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[6]" LOC = U11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P8[7]" LOC = V11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

######################################################################################################################
# HEADER P9 #
######################################################################################################################

NET "IO_P9[0]" LOC = H17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[1]" LOC = H18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[2]" LOC = J16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[3]" LOC = J18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[4]" LOC = K15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[5]" LOC = K16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[6]" LOC = L15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET
"IO_P9[7]" LOC = L16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

The above can be quite complicated to understand at first.  Lets take away all of the lines we don’t need and then explain what they mean:

#********************************************************************************************************************#
# Implementation Constraints file for Mimas V2 #
#********************************************************************************************************************#

######################################################################################################################
# DIP Switches #
######################################################################################################################

NET "DPSwitch[0]" LOC = C17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

NET "DPSwitch[1]" LOC = C18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

######################################################################################################################
# LEDs #
######################################################################################################################
NET "LED[0]"              LOC = P15  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

NET "LED[7]" LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

Anything preceded by a # is a comment in an implementation constraints file and is ignored by the Xilinx Compiler.

The line NET “DPSwitch[0]” LOC = C17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP; means there is a dipswitch connected between pin C17 and 3.3V, The pin uses a fast slew rate and the internal pullup resistor is enabled.  It’s the same thing for DPSwitch[1]

The line NET “LED[0]” LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; means there is an LED connected between pin P15 and 3.3V, the pin uses a fast slew rate.  It is the same for LED[7]

 What we need to do is change the ‘NET’ names to reflect the VHDL code we have already written.  Copy and paste the code below into the Xilinx ICF code editor:

#********************************************************************************************************************#
# Implementation Constraints file for Mimas V2 #
#********************************************************************************************************************#

######################################################################################################################
DIP Switches
######################################################################################################################
 
   NET "DIP1"         LOC = C17  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

NET "DIP2" LOC = C18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

###################################################################################################################### LEDs #
######################################################################################################################
NET "LED1" LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

NET "LED2" LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;


The Xilinx project screen should now look like this:

Once you are ready its time to save our work and to implement the top level – Click on the arrow on the left side of the screen:

If everything went as planned there should be green arrows present in the bottom left corner.  Now it is time to generate the bit stream file.  This is the binary file that is sent via the programming software to the FPGA to ‘program’ it.  Right click on the ‘Generate Programming File’ option in the bottom left part of the screen and then select ‘Process Properties':

A new window will appear.  ‘Check’ Create Binary Configuration File and then click ‘OK’

Now its time to actually generate the ‘bit stream file’….right click on the Generate Programming File’ option and select ‘Run’…

Once that is complete we can close down Xilinx 14.7 and load up the Mimas V2 programming software.  Navigate to where you downloaded the Mimas V2 files earlier – we are looking for the MimasV2Config.exe application.  For ease of use I made a shortcut and ‘pinned it’ to the start menu:

Next we need to connect the MimasV2 development board to a suitable USB port and install the USB driver.  I’ve done this already, if you haven’t when you plug in the development board you will be prompted by windows to locate the driver file.  It’s in the numatoCDC folder.  Once that’s sorted we need to find out the COM port for the Mimas V2 board.   Click on ‘Devices and printers’ from the start menu.  If the driver and board have been correctly loaded it should be present in the unspecified section:

Double click on the ICON highlighted and a window will appear showing the COM Port number:

Make a note of the COM port number as we will need it to program the development board.  Load up the MimasV2Config software and select the COM port:

Now click on the ‘Open File’ button and navigate to the project folder which contains the bit stream file we just created.  It should have a .BIN extension:

Click the ‘Open’ button and then click the ‘Program’ button – Exciting times!

Once programming has completed (it took a good 30 seconds) all of the LEDS should be OFF except LED1 and LED8.  When you change the state of DIP switches 1 and 2, LED1 and LED8 should go ‘OFF’!

And when we change DIP1 and DIP2….nothing happens!  I found that it was DIP7 and DIP 8 which cause the LEDS to go OFF.

This suggests there is something incorrect with the implementation constraints file and the schematic diagram!  I suspect the connections have been reversed and DIP1 and DIP2 are connected to pins F17 and F18.  I also noticed that the seven segment display is ‘Ghosting’ – it is slightly on when it should be….Lets fix that by modifying the VHDL code and lets modify the implementation constraints file to use the correct switches.  Lets also reverse the logic so that when the switches are ‘Off’ the LEDS are ‘Off’ and when the switches are ‘ON’ the LEDS are ‘ON’.

Here is the new VHDL code which needs pasting into the VHDL source file:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-- Alex's Mimas V2 VHDL Tutorial
-- (c) 21-12-2014
-- A simple demonstration of a development board

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Mimas_V2_VHDL_Tutorial is
Port (
DIP1 : in STD_LOGIC;
DIP2 : in STD_LOGIC;

LED1 : out STD_LOGIC;
LED2 : out STD_LOGIC;


-- Enable the control pins for the seven segment display
SevenSegmentEnable0 : out STD_LOGIC;
SevenSegmentEnable1 : out STD_LOGIC;
SevenSegmentEnable2 : out STD_LOGIC);

end Mimas_V2_VHDL_Tutorial;

architecture Behavioral of Mimas_V2_VHDL_Tutorial is

begin

LED1 <= NOT DIP1;
LED2 <= NOT DIP2;

-- set seven segment display to OFF

SevenSegmentEnable0 <= '1';
SevenSegmentEnable1 <= '1';
SevenSegmentEnable2 <= '1';

end Behavioral;
Next we need to modify the implementation constraints file with the following code:
#*****************************************************************************************## Implementation Constraints file for Mimas V2 ##*****************************************************************************************# ###########################################################################################
# DIP Switches ############################################################################################ NET “DIP1″ LOC = F18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP; NET “DIP2″ LOC = F17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP; ############################################################################################ LEDS #
###########################################################################################
NET “LED1″ LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET “LED2″ LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; ############################################################################################ Seven Segment Enable ############################################################################################  
NET “SevenSegmentEnable0″ LOC = B2 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET “SevenSegmentEnable1″ LOC = A2 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET “SevenSegmentEnable2″ LOC = B3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

Once that is done we then need to implement the top level again and generate a new bit-stream file 
and reprogram the device. I’m not going to post pictures….Here is a video instead!


Well….that is all for now. I’ll be writing more posts as I get more familiar with the development board
Thanks for reading and take care always – Langster!

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:
  Serial.begin(9600); 
}

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(sensorValue);      
  Serial.print(“t mapped output = “);      
  Serial.println(outputValue);   

  // wait 250 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(250);                     
}

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.

Cheers

Langster!