Monday 30 May 2016

Generating more square wave pulses using counters on the Mimas V2

In a previous post I wrote about how it is possible to generate a 1 Hz clock pulse using the 100 MHz source clock and a 27 bit counter.  This post continues on that theme but this time we are going to generate different clock pulses and more of them!

If people did not see the previous post it's available here:

A simple post on counters...

Load up the project from the previous post and lets modify it.  What we are going to do is add more LED outputs and then use code we wrote to flash them at faster and faster rates:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity LED_flasher is
    Port ( clock_in : in  STD_LOGIC;
           LED_1 : out  STD_LOGIC;
 LED_2 : out  STD_LOGIC;
 LED_3 : out  STD_LOGIC;
 LED_4 : out  STD_LOGIC;
 LED_5 : out  STD_LOGIC;
 LED_6 : out  STD_LOGIC;
 LED_7 : out  STD_LOGIC;
 LED_8 : out  STD_LOGIC);
 
end LED_flasher;

architecture Behavioral of LED_flasher is

signal counter : STD_LOGIC_VECTOR(27 downto 0):= (others=>'0');

begin

process (clock_in) is

begin

if rising_edge(clock_in) then
counter <= counter + 1;
end if;

end process;

LED_1 <= NOT counter(27);
LED_2 <= NOT counter(26);
LED_3 <= NOT counter(25);
LED_4 <= NOT counter(24);
LED_5 <= NOT counter(23);
LED_6 <= NOT counter(22);
LED_7 <= NOT counter(21);
LED_8 <= NOT counter(20);

end Behavioral;

The above code basically works in exactly the same way as the previous code did.  The only difference is that we have more outputs and we are displaying the results from the counting at different stages on the LEDS.  So in the previous code we calculated that a count of 27 bits divided a 100 MHz source clock to 1 Hz.  Therefore a count of 26 bits will flash an LED every half second, a count of 25 bits will flash an LED every 0.25 of a second and so on...

We will also need to update the user constraints file to account for the extra outputs:

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# 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                        #
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

CONFIG VCCAUX = "3.3" ;

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

###################################################################################
#                                LEDs                                             #
################################################################################### 
   
   NET "LED_1" LOC = P15  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_2" LOC = P16  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_3" LOC = N15  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_4" LOC = N16  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_5" LOC = U17  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_6" LOC = U18  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_7" LOC = T17  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
   NET "LED_8" LOC = T18  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

Save the project, build the updated bit file and then upload the code to the Mimas V2 board.  Here is a video of the board in action:


There are even more things that could be done with this.  We could use the external outputs to provide the other clock divisions present.  There are more than enough outputs available.  What this project clearly shows is that it is quite simple to generate multiple clock streams simultaneously using an FPGA.

Here is the source code in case it's needed:

Square Pulses Source Code

That's all for now - Langster!

Calibrating a MPS20N0040D-D Pressure Sensor

It has recently become apparent that readers of the pressure sensor posts on my blog need a way of calibrating the MPS20N0040D-D pressure sensors.

Here is the original post on pressure sensors:

http://langster1980.blogspot.co.uk/2014/11/how-to-use-pressure-sensor-with.html

This is not too difficult but you will need a few items:
  • An air pump - a bicycle pump will do.
  • An air pressure gauge - something with a human readable scale, preferably calibrated...
  • An MPS20N0040D-D pressure sensor and the difference amplifier set to the gain required for the circuit in mind - Hint I sell breakout boards here - Buy a pressure sensor breakout board
  • An arduino uno or other suitable microcontroller development board.
Once you have everything ready connect up the pressure sensor, analogue electronics to the arduino - I used the analogue zero pin, use whichever analogue pin required but make of note of it as the code needs to match the circuit.

Connection Diagram



Once you have everything connected as above upload the code below into the arduino:

/*
Pressure Sensor test Code
 */

const int analogInPin = A0;  // Sensor connected to A0

int sensorValue = 0;        // value read from the pressure sensor via the amplifier stage
float outputValue = 0;      // value output to the Serial port

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  
  // print the results to the serial monitor:
  Serial.print("sensor = " );                       
  Serial.print(sensorValue);  
  
  Serial.println();
       
  delay(1000);                     
}

Now open the serial monitor in the arduino IDE.  Observe the bit value received when no pressure is applied to the sensor.  This is the zero value.  Now introduce air pressure to the sensor using the pump.  When the external gauge reads 1 psi record the value of bits received.  Repeat this process until you have reached 32 psi or when 1023 bits has been recorded.  Create a table of results, mine looked like this:


Input pressure
ADC
ADC voltage
(PSI)
(Bits)
(volts)
0
61
0.283295132
1
82
0.4001820137
2
96
0.4740954967
3
116
0.5620723363
4
141
0.6742689746
5
163
0.7817888563
6
191
0.9386412512
7
242
1.183020528
8
269
1.329648094
9
329
1.632903226
10
420
2.052785924
11
450
2.19941349
12
470
2.2971652
13
510
2.492668622
14
540
2.639296188
15
570
2.785923754
16
605
2.956989247
17
630
3.079178886
18
660
3.225806452
19
690
3.372434018
20
720
3.519061584
21
740
3.616813294
22
765
3.739002933
23
800
3.910068426
24
850
4.154447703
25
900
4.398826979
26
920
4.49657869
27
950
4.643206256
28
969
4.736070381
29
980
4.789833822
30
995
4.863147605
31
1000
4.887585533
32
1006
4.916911046

Now that the results have been obtained we can plot a graph which shows how the number of bits received relate to the amount of pressure present.  We could work this out from the table but it's much easier to visualise this using a graph:


We can use the information from the graph and the table to display the pressure measured in psi. There are several methods to achieve this such as a lookup table which will interpolate the results.  I have decided to use a map function as the results obtained a quite linear (a straight line was achieved). 

Arduino Map Function

Enter the highest value obtained and the lowest value obtained and apply it to the scale needed (in this case PSI) and the function will do the rest for us:

outputValue = map(sensorValue, 60, 1006, 0, 32);  

Here is the full code in case people need it:

/*
Pressure Sensor test Code
 */

const int analogInPin = A0;  // Sensor connected to A0

int sensorValue = 0;        // value read from the pressure sensor via the amplifier stage
float outputValue = 0;      // value output to the Serial port

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  
  // print the results to the serial monitor:
  Serial.print("sensor = " );                       
  Serial.print(sensorValue); 
  
  outputValue = map(sensorValue, 60, 1006, 0, 32);  // convert the raw bit value 

  Serial.print("sensor = " );                       
  Serial.print(outputValue); 
  
  Serial.println();
       
  delay(1000);                     
}

Hope this helps people make more use of the MPS20N0040D-D pressure sensor.
 

That is all for now - take care people!