## Tuesday, 1 August 2017

### Designing A USB Breakout Board!

I often need to intercept USB signals for decoding and measurement purposes.  I cut a cable apart last time I needed one but to be honest I much prefer doing things properly.  I also noticed that nobody seems to sell a similar product on Ebay, Aliexpress or Amazon!  I did find a vendor in the USA on tindie:

 Image Copyright - Misperry via Tindie

https://www.tindie.com/products/misperry/usb-inspector/?pt=full_prod_search

I also found this product on tindie which is similar but has a current monitoring circuit built in:

https://www.tindie.com/products/Kaktus/usbuddy-usb-development-tool/?pt=full_prod_search

A friend of mine and blog reader found this one:

https://friedcircuits.us/50?search=usb

Either of these products would work for my purposes but the first product's shipping costs from the USA seem a little extravagant and I only wanted one or two.

The second product uses pin headers to allow connection which are a bit close together for my liking. It's often the way of things.  When I cannot obtain what I want I make my own!

The circuit is very simple:

The PCB layout is a little more complicated.  I would like to keep the board as small as possible but maintain the recommended conductor impedance that a USB cable should have.  By maintaining the impedance it means that signals can be correctly measured and power is not needlessly wasted.  The USB specification document is possibly one of the hardest pieces of technical literature I have had to read.  I don't recommend it unless absolutely necessary:

http://www.usb.org/developers/docs/usb20_docs/#usb20spec

There is also a standard for USB cables which dilutes the information into a slightly more readable format (note - I am being overly sarcastic):

BS EN 62680-2-3:2015

The standard is not free to read however...but memberships to local and university libraries yields useful results.

A USB 2.0 cable must have many specifications but the two most critical that I am interested in are:

• Cable impedance - 76.5 Ω to 103.5 Ω
• Current carrying capability - 500 mA (standard) or 1.5 A from a dedicated charging port.

The information on the current carrying capability is confusing as there is mention of 5 amps on the wikipedia article:

https://en.wikipedia.org/wiki/USB#Power-use_topology

So based upon the above information we need to ensure the board layout has tracks capable of carrying 1.5 Amps of current at 5 Vdc and that the data pairs D+ and D- are routed as a differential pair with 90 ohms impedance.  I picked 90 ohms as a reasonable middle value and it was cited in this application note from Silicon Labs:

https://www.silabs.com/documents/public/application-notes/AN0046.pdf

Here is a useful article on layout guidelines for differential pairs:

http://www.eetimes.com/document.asp?doc_id=1144365

Basically I want to make sure my breakout board doesn't ruin the USB signals by interrupting them. USB cables are actually proper transmission lines and the cable should be screened and the internal cables twisted to maintain uniform impedance.  The D+ and D- tracks which are differential signals will need to be routed close together above a solid ground plane (Microstrip transmission line) ensuring that both tracks are exactly the same length.  Most PCB routing software like eagle have built in calculators and tools to assist with this.

Here is an excellent (and free) online trace width calculator:

http://www.4pcb.com/trace-width-calculator.html

I entered the following information into the calculator:

• Current: 1.5 Amps (I'm going with the lower value specified)
• Copper thickness: 35 µm (Standard 1 oz copper thickness for FR4 PCB material)
• Temperature Rise: 10 °C (Just a guess)
• Ambient Temperature: 25 °C (Just a guess)
• Trace Length: 35 mm (just a guess for now)

I'm only going to have a two layer PCB so I'm only interested in external traces.  Here is what the calculator came up with:

• Required Trace Width: 525.491 µm or 0.525491 mm
• Resistance: 33.612 mΩ
• Voltage Drop: 50.419 mV
• Power Loss: 75.628 mW

So that sets the PCB track thickness to be at least 0.6 mm.  I may well go with 1 mm as space should not be a problem.

Next we need to set the track impedance above a ground plane which is otherwise known as a microstrip transmission line.  Here is another very useful (and free) calculator:

https://www.eeweb.com/toolbox/edge-coupled-microstrip-impedance

If people need to read up on what an edge coupled microstrip layout is then please check out the link below.  It is essentially a method of setting the impedance of PCB tracks based upon the thickness and width of the track, the thickness of the dielectric material (FR4 PCB) and Wheeler's Equation.

https://en.wikipedia.org/wiki/Microstrip

Transmission line theory is complicated and to be honest I have no intention of attempting to simplify it...I'm not sure that I could.  Basically this is some of the RF black magic people talk about.... I'm trying to keep things simple.  I would suggest that anyone who is serious about electronics and electrical signal propagation needs to have a basic understanding of transmission line theory and how to layout PCB tracks to properly interface connectors with circuits.

Here is what I fed into to the calculator:

Trace Thickness: 35 µm (Standard 1 oz copper thickness for FR4 PCB material)
Substrate Height: 1.6 mm (Standard FR4 PCB)
Trace Width: 1.5 mm (I chose 1 mm value above but went for 1.5 mm to get the right impedance)
Trace Spacing: 0.12 mm (I chose this value as a guess after trying a few different values)
Substrate Dielectric: 4 (This is the relative permittivity of FR4 PCB material)

The calculated result gives a differential impedance of 89.8 Ω - close enough!  So all that's needed is to set the D+ and D- tracks to be 0.12 mm apart and 1.5 mm thick and try to keep the tracks the same length...If we manage that we have the 89.8 Ω impedance needed to ensure that the USB signals remain unaffected when we use the PCB.

Now that we have all of the track properties calculated we can design the PCB layout.  There is a tool in Eagle for doing this that ensures that the differential tracks are routed together.  You have to label the net names with an 'underscore P' and an 'underscore N'.  I set the label for my D+ and D- nets to 'TEST_P' and 'TEST-_N' but any sensible names will do.  I then routed the +V and GND tracks manually and then set the autorouter to route the top layer.  I cannot seem to get the differential pair tool to work otherwise.  Here is what the board layout looks like:

Edit - I have updated the design after some valuable feedback from Aamir Ahmed Khan (Thank you!) - I did not remember to set the track separation distance in my original layout, I have rectified that and my calculations.  Here is the new and now hopefully correct layout.  (Note to self - I should not rush when designing PCB layouts and writing informative blog posts!).  I found the easiest way to do this was to set the grid to 0.2 mm spacing with the alternative at 0.1 mm and route the differential tracks by hand one after the other.  That enabled me to ensure the tracks were correctly separated and of the correct thickness.  I also set the ground plane isolation to be 0.2 mm to ensure the track on the bottom layer was correctly isolated...Lets see if this works!  I hope the PCB fabricators are able to etch the board for me with such precise track isolation...I can always run a scalpel down the gap though.

I will probably get the whole thing manufactured by Elecrow and for that I will need a bill of materials.

 Qty Device Package Parts Vendor Part Number Description 1 USB 2.0 Socket USB X1 Farnell 2134385 AMP USB 2.0 connector 4 Ring_Test 1X01_LONGPAD +V, D+, D-, GND Ebay.co.uk 292175228920 Ring Test Connector 1 M02PTH3 1X02_LONGPADS JP7 Farnell 3418285 Standard 2-pin 0.1" header pins 1 USB 2.0 Connector USB-A-H JP1 Farnell 1696544 USB Connectors

Here is the PCB render:

My plan is to have ten boards made, keep two for myself and flog the rest!

That's all for now - Langster!

## Monday, 24 July 2017

### Having electronic breakout boards manufactured in China by Elecrow

I have an online shop where I sell some of the items I have designed and written about.  I normally have the PCBS made in china and then populate them and test them myself at my local hackspace or when I'm in a rush on the kitchen worktop - Note to young engineers: a surer method of annoying your significant other I have yet to find!

It is often quite stressful and difficult for me to hand solder surface mount components. I have to test and fault find the circuit and get everything working....after that shipping the orders in good time only compounds the issues.  It's all about being prepared and patient...I am not always good at being prepared and then my patience wears thin!

I get my PCBS made in China by a company called Elecrow:

https://www.elecrow.com/

They sell all sorts of useful bits and pieces for the electronics hobbyist and also have a PCB manufacturing service and now more recently a PCB assembly service.

I have had at least fifty PCBS made by Elecrow and the quality has always been excellent.  The price has always been acceptable and the service excellent.  I may have also quietly lost my temper with my ineptitude in assembling surface mount components on small printed circuit boards and decided to see how much it would actually cost to get the whole product made by Elecrow.

I saw the new service advertised on the site and clicked on the appropriate page:

https://www.elecrow.com/pcb-assembly-p-366.html

Next I uploaded the gerber files for the project in a zip file along with the bill of materials with at least two sources for the components and the package sizes.  Ensuring the design is correct and the bill of materials is correct is critical...I cannot stress this part enough!

The initial price I paid to have the project assessed and the printed circuit boards and solder stencil made was £32.05 or \$41.76 USD. This all started on a Sunday night on the 23rd of June.

A very helpful lady named Shelley got in contact within a day to say the order had been received but production would not start as they couldn't open the bill of materials spreadsheet I had sent with the gerber files.  I made the mistake of not uploading the bill of materials in the Microsoft Excel format, very quickly resolved by resending the BOM in the correct file format.

Shelley got in contact within a few days to provide a quote for fitting the standard components or for fully populating the PCB.  The full cost was another £61.41 or \$80 USD for ten fully completed PCBS which I thought was quite reasonable so I sent the money over and hoped for the best.

I also sent through some basic instructions and tips on how to populate the PCB gained from my own experience in doing it - I didn't want anyone else to struggle populating the PCBS like I had and I also wanted to be sure that when the boards arrived they worked first time!

On the 12th of July Shelley emailed to say that the boards had been manufactured and that component population was about to start.  She did say that they had issues with the Op-Amp I had chosen but this was sorted pretty quickly....luckily my circuit will work with just about any Op-Amp so I wasn't too worried.

On the 18th of July I got an email from someone named Sunshine to say that the my order was complete and shipped by DHL.  I didn't actually bother tracking it but it arrived today on the 24th of July, well packaged in a sturdy cardboard box and bubble wrap.  Each PCB was individually wrapped in a zip lock anti-static bag with some anti-static foam on the header pins.

Every single one of the boards worked perfectly.  Here are some photos of the PCB etc...I didn't take any of my smiling face!!!  The coin is a one pence sterling coin for scale.

 Populated Pressure Sensors From Elecrow!
 Check out the reflow soldering!

For the price (£93.46 or \$121.76) I am very happy with the service that Elecrow provided and I will be getting more of these boards and other boards fully populated when I need to.  Shelley did say that If I get a higher quantity of PCBS made up the price quoted would reduce.  I just hope I manage to sell them all so that I can get more things made...maybe I should spend more time advertising over designing and blogging?!??

I doubt that I will ever sell enough of these to retire but I do enjoy keeping my hand in the manufacturing process - it is very useful to know how to get things made and if I ever do come up with a cunning plan...I mean product I can realise it fairly quickly and efficiently with Elecrow's help.

That's all for now - Langster!

## Wednesday, 21 June 2017

### Myoware muscle sensor circuits from Sparkfun and others....

It's been a while since I wrote anything up and to be honest with you I haven't had much time or inclination to do any electronics outside of work....it gets that way sometimes.

Here is the previous post on this project for those that are following along:

http://langster1980.blogspot.co.uk/2017/05/graphing-data-from-venturi-tube.html

I received in the post a Myoware EMG (Electromyography) sensor kit available from Sparkfun and other vendors.  The webpage for the product is shown below:

https://www.sparkfun.com/products/13723

The idea with this circuit is to sense muscle movement when a person breathes in and out and from that correlate lung function.  How much air a person can breathe in and out is partly to do with muscle (diaphragm) and chest movement - I'm not a medical doctor so I'm a little out of my depth here...however it was part of the functionality requested for the medical device so I'm investigating solutions and this circuit is one solution.  Lets see how well it works and get some data and compare it to what would be expected.  As a healthy male of some 30+ years (in my prime!) it should show that I'm a paragon of excellence...in reality I suspect it will show that my heart and muscle function are average but more importantly present!

Here are the instructions for use:

The board itself is very simple to setup and use and the instructions are clear and concise.

This is the setup I'm going with...I'm certain there shouldn't be any issues but I don't have the buffer circuit so...it's time to man up!

I have attached the red sensor wire and blue sensor wires to electrode pads and put them on my sternum at either side of my heart.  I attached the black wire to an electrode pad and placed that on my stomach to provide a base reference.  I'm looking to measure my hearts sinus rhythm...and see how sensitive things are.  Here is the test code I've written:

(I had both the raw and sig output connected to my arduino analogue inputs A0 and A1)

//test code for Myoware EMG PCB

// variables for input pin from MyoWare PCB

// variables to store the values
int valueSig = 0;
int valueRaw = 0;

void setup() {

// begin sending over serial port
Serial.begin(9600);
}

void loop() {

// read the values from the sensor:

Serial.print(valueSig);
Serial.print(",");
Serial.print(valueRaw);
Serial.println();

// wait for a bit to not overload the port
delay(10);
}

Here is the serial output graphed for your viewing pleasure:

Here is my wife's heart rate...apparently I don't have quite the effect on her I used to!

Here is what happens when the sensors are placed on the abdomen:

So...I'm alive and so is the wife!  The Myoware picks up a good strong electrical signal when sensors are placed close to the heart...but when placed on the abdomen did not really pick up anything I could see correlating to breathing or diaphragm movement.  Either I had my sensors incorrectly placed or the circuit is not sensitive enough for this purpose.  Adjusting the gain potentiometer on the Myoware PCB did change the gain response but didn't provide the response I was looking for - It was hoped that it would be possible to correlate diaphragm muscle movement with regular breathing.

I did notice that if I activated (flexed) my abdmoninal muscles electrical signals were definitely present and well detected...maybe I don't use my diaphragm much when I breathe in and out?  I will have to investigate further.

I could not find a schematic diagram for the Myoware circuit although the shields are marked as being open source. Update - See comments below from Brian Kaminsky of Advancer Technologies.

Here is the schematic for the previous version of the device:

https://cdn.sparkfun.com/datasheets/Sensors/Biometric/Muscle%20Sensor%20Platinum%20v3.3.pdf

The main integrated circuit is an AD8648 which is a quad operational amplifier.  I suspect the two smaller devices are programmable gain devices for each of the sensor inputs and the rest of the components are associated gain and filtering requirements.

Here is the datasheet for the AD8648

Here is the datasheet for the devices marked AD A 1V (An AD 628 I think....)

The company (Advancer Technologies) that developed the Myoware PCBs also wrote this instructable which shows how a similar circuit could be developed:

http://www.instructables.com/id/Muscle-EMG-Sensor-for-a-Microcontroller/

I have seen similar circuits in the past and believe this is certainly one route to achieving the measurement of electrical signals either from the heart (ECG - ElectroCardioGrapy) or muscle movement (EMG - ElectroMyoGraphy).

I would certainly say that this circuit has been very well designed and implemented and would be very useful if one wanted to use muscle flexing signals to control an external device or detect when someone has used a muscle...so say for instance you wished to mirror your arm movement with a robotic arm then this is definitely the circuit for the job!

That is all for now - take care always, Langster!

## Thursday, 8 June 2017

### Tutorial for Xilinx DCM Clock Generator with the Mimas V2

A blog reader contacted me recently for help generating signal clock sources with the Mimas V2.  In particular they wanted a 108 MHz clock for HDMI purposes however the Spartan 6 FPGA on the Mimas V2 is capable of generating source clocks up to 1 GHz if the output is used to drive a BUFPLL.  What this means is that the clock will be generated but in order to work special internal routing is required within the FPGA.  It is a topic for another post to be honest.  For now lets only generate clocks up to 400 MHz

The datasheet for the the Spartan 6 FPGA devices is available below:

https://www.xilinx.com/support/documentation/data_sheets/ds162.pdf

Rather than write a lot of VHDL code to generate the clocks we need we are going to use a feature of Xilinx WebISE 14.7 to write the code for us - cool huh.

Lets set some parameters!  Lets generate a 200 MHz clock and send it to one of the output pins and then view this on an oscilloscope or logic probe.  If people are interested the instruction manual for the DCM clock generator is here:

DCM Clock Generator Manual

Lets fire up Xilinx WebISE and start a new project:

Choose to save the project in a suitable location on your hard disk and give the project a suitable name - I called mine DCM_Clock_Tutorial but any sensible name will do:

Make sure all the settings are the same as in the image below - these are the settings required for the FPGA device on the Mimas V2:

Click Next when ready to display the project summary page:

Now right click on the design hierachy window and select add source:

Select VHDL module and give the file a suitable name, I called mine DCM_Clock_Top_Module but another name could be used.  It should be something sensible however:

Click Next to continue and add the inputs and outputs.  I have chosen to add a signal called CLK as an input and a signal called CLKOUT_200M as an output.  If we wanted to we could leave this screen blank and write our own code later.

Click Next to continue and display the summary screen:

Click finish to return to the main project window and see the automatically generated code:

I prefer to delete most of the comments as they don't add any value at this point however...they can be left or completed if required.

At this point it is always a good idea to save things.

We will return to write VHDL code here later but for now lets add another new source, this time select IP (Core Generator and Architecture Wizard) and give the file a suitable name:

Click Next when ready and then wait for WebISE to load up all of the available IP cores for the Spartan 6 family:

Type Clock into the search field:

Click Finish and wait for WebISE to build the code and load the wizard.

Make sure the settings are as shown below:

The options selected are for the Mimas V2 which has a 100 MHz source clock.  We have also chosen to reduce jitter which should make the clock more accurate and we have decided to let WebISE select the most applicable mode for us - Click Next when ready to continue:

Ensure the same settings have been selected and click Next when ready.

Ensure the settings are the same as above and click Next when ready - for this tutorial we don't need a reset input or locked input.

These are the IO functions which will be automatically created by the wizard when the code is generated.  Click Next when ready.

These are the names that will be used for the input clock signals and output clock signals - Click Next when ready.

Click Generate when ready and wait until the code has been generated.

Now here is where we could do things in multiple ways.  We could add code to the VHDL module or we can take advantage of WebISE and have it write the code for us...I'm going to take the easy option.  Click on the newly created ClockMultiplier200M module in the Hierachy Window and then expand the CORE Generator process icon and select View HDL Instantiation Template:

Open the file and scroll down to line 67:

Select and copy the VHDL code from line 67 to line 76:

Paste this code into the VHDL top module code at line 11 in the header of the architecture function:

Now return to the HDL Instantiation Template and select the code on line 82 to line 89 and copy it. Then paste that code into the top module code on line 22 between the begin and end Behavioural lines:

Go to line 22 and change the text 'your_instance_name to something sensible, I typed clockMultiplier:

Next we need to modify the code so that the port map section connects to the inputs and outputs in the Entity section:

Next we need to generate the implementation constraints file.  Right click on the hierarchy window and select Add new source like before:

We need to create the implementation constraints code specifically for the Mimas V2.  I tend to use the original supplied by Numato Labs and then modify it to suit our purposes.  Copy and paste the code below into the text editor in WebISE:

#******************************************************************#
#                          UCF for Mimas V2                        # #                                                                  #
#******************************************************************#

CONFIG VCCAUX = "3.3" ;

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

NET "CLKOUT_200M"  LOC = T10  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | OUT_TERM = UNTUNED_50 ; #Pin 4

The above code tells the 'compiler' that the CLK input from the 100 MHz crystal oscillator is connected to pin V10 and that we would like to use pin T10 as the 200 MHz output pin on P8 pin 4. The pin has been set to provide a 50 Ohm output impedance.  I chose the T10 pin as according to the information in ug381.pdf (The DCM Clock Manager Manual) this pin - GCLK2 is a global clock pin location.

I chose to set the impedance to 50 ohms so that it can be properly measured with an oscilloscope.

Lets save our work and upload it to the FPGA - Click on the implement top module arrow button and then after those processes are complete create a bitfile.  Navigate the to folder where the project was stored and locate the newly created bitfile!  Then load up the MimasV2 Configuration tool and connect up your Mimas to your PC.  Select the appropriate COM port and then....

Then upload it to the Mimas V2 development board:

Once uploaded Pin 4 of the output Bank P8 should have a clock signal on it which can be viewed with an oscilloscope or logic probe.  In truth these clock signals are designed to be used internally within your FPGA design and not brought out to a pin.  The signal won't be particularly square or have a a fast rising edge.

Here is a photo I took of a signal from the FPGA measured with an oscilloscope - it looks more like a sine wave!

That's all for now - Langster

## Tuesday, 9 May 2017

### Graphing the Data from the Venturi Tube

In the previous post I wrote about how I 3D printed a venturi tube and updated the code with new constant values.  At the end of the post I was looking for a way to display the data graphically live.

I think I have managed it!  The previous post for those that are interested is here:

http://langster1980.blogspot.co.uk/2017/05/making-venturi-tube.html

I had been researching Python scripting and whilst this is possible I don't have the time, patience or inclination to learn another programming language - there is only so much room in my head for information!  Perhaps I will learn Python in the future and being aware of it and it's function will probably serve me well.

I was browsing through you tube and google looking for programs which graph serial data automatically from comma separated values.  I specifically made sure that the data sent out to the serial port from the arduino was comma separated...it makes it easy to import into a spreadsheet program and graph.  I would like to be able to do that real time as well.

In my searching I found this video:

https://youtu.be/yYyW16FYqE0

It describes a java applet which has been written to graph serial data directly from the arduino - just what I was looking for!  The video itself explains how to use it quite simply so I won't bother. Sufficed to say all one needs to do is select the appropriate COM port and baud rate and then complete the form with the required information and units and the graph will be displayed.

http://farrellf.com/TelemetryViewer/T...

If you haven't got Java installed that will be needed also:

Once everything is installed I would watch the video and learn how to use the applet.  The help button is quite useful! Here are the results:

Here is another screenshot:

Which is very close to the example image given when this project was first specified:

As this part of the project is almost complete, I'm going to move on to the next section which was to measure the pressure output from the ventilator using one of my pressure sensor breakout boards - not too hard to add hopefully. After that it's develop a EMG measurement circuit.

Along the way I think it might be useful to add a microSD card to log the data received along with a real time clock and finally use bluetooth communications to provide wireless serial communications. It's also time to consider powering the system - I'm looking at using 18650 lithium cells and a suitable charging circuit with protection.  After than design an enclosure and add some LEDS to show function and this project can be marked complete!  Not too far now!!!!

Take care always - Langster!

## Monday, 8 May 2017

### Making a Venturi Tube

In order to perform a little more testing on the Spirometer device I have designed a venturi tube which can be 3D printed.  It is possibly the most ugly and square shaped device ever to be designed but it will 3D print perfectly and because I designed it - I know the internal dimensions.  It was designed in the free version of google sketchup and assuming it works well I will share the design files.

The previous post for those that are interested is below:

http://langster1980.blogspot.co.uk/2017/04/create-spirometer-using-msp7002dp.html

Knowing the internal dimensions means the calculations performed will be more correct which in theory means the accuracy of the measurements will be correct.

I'm not going to go into how I designed the venturi tube - there are plenty of diagrams available.

Here is a picture of how the tube will look when printed:

 Solid Version Venturi Tube
 See Through Diagram of the Venturi Tube with dimensions
I used this and many other sites as a reference on how to make a venturi tube:

I'm going to 3D print this tomorrow but in the mean time lets repeat the calculations to calculate the areas of the first and second sections (The internal tube sections).

In order to make the measurements using the arduino we need the areas calculating for A1 and A2. The formula we are applying in total is:

$Q = A_{1}.\sqrt{\frac{2}{\mu}.\frac{P_{1}-P_{2}}{(\frac{A_{1}}{A_{2}})^{2}-1}}= A_{2}.\sqrt{\frac{2}{\mu}.\frac{P_{1}-P_{2}}{1-(\frac{A_{2}}{A_{1}})^{2}}}$

The dimensions of A1 can be calculated using:

$A_{1}=\pi r^{2}l$

$A_{1}=3.142*13^{2}*30$

$A_{1}=15929.94\: mm^{2}$

or

$A_{1}= 0.01592994\: m^{2}$

Next A2 can be calculated in the same way:

$A_{2}=\pi r^{2}l$

$A_{2}=3.142*7.5^{2}*24$

$A_{2}=4241.7\: mm^{2}$

or

$A_{2}= 0.0042417\: m^{2}$

Lets now attempt to calculate Q, the Volumetric flow rate.  Lets use a value of 320 for P1 and 200 for P2:

$Q = A_{1}.\sqrt{\frac{2}{\mu}.\frac{P_{1}-P_{2}}{(\frac{A_{1}}{A_{2}})^{2}-1}}$

Simplifying gives:

$Q = 0.01592994*\sqrt{1.63265306122*9.15737111846}$

$Q = 0.06159514771\: m^{3}/s$

And for the second thinner section:

$Q = A_{2}.\sqrt{\frac{2}{\mu}.\frac{P_{1}-P_{2}}{1-(\frac{A_{2}}{A_{1}})^{2}}}$

Simplifying gives:

$Q = 0.0042417*\sqrt{1.63265306122*129.157371118}$

$Q = 0.06159514773\: m^{3}/s$

Both values come in almost exactly the same - close enough for my requirements.  Good to know the mathematics works out!

From that as before the velocity of flow can then be calculated using:

$v_{1} = \frac{Q}{A_{1}}\:(metres/s)$

$v_{1} = \frac{0.06159514771}{0.01592994}$

$v_{1} = 3.86662772804\: m/s$

Just for completeness lets use the value for A2 also:

$v_{2} = \frac{Q}{A_{2}}$

$v_{2} = \frac{0.06159514773}{0.0042417}$

$v_{2} = 14.5213352498\: m/s$

We can now check all is correct as:

$P1 - P2 = \frac{\rho}{2}*(v_{2}^2-v_{1}^2)$

$320 - 200 = 0.6125*(14.5213352498^{2}-3.86662772804^{2})$

This actually computes to:

$P_{1}-P_{2} = 120.000000063\: Pa$

Which is really good - as we set the values for P1 and P2 to be 320 and 200 Pa to begin with!  The really small error is probably due to rounding errors creeping in with my calculations.  Not of significant importance in this case.

Here is a picture of the tube printed and displayed connected to the mask:

 The venturi tube connected to a face mask

We can now use the values for A1 and A2 in the arduino code with the newly printed venturi tube. Hopefully the accuracy will be much improved.

Here is the new code - same as before but updated with the new constants for the venturi tube.

`````` // MPX7002DP Test Code with conversion
// to volumetric flow rate and velocity
// of flow
//
// A.Lang - 2017

// This code exercises the MPX7002DP
// Pressure sensor connected to A0

#include <Average.h>

Average<float> averageValue(100);

//variables

int sampleNumber = 0;      // variable to store the sample number
int sensorPin = A0;       // select the input pin for the Pressure Sensor
int sensorValue = 0;      // variable to store the Raw Data value coming from the sensor

float averageInitialValue = 0; // variable to store the average inital value

float diffPressure = 0;     // variable to store converted kPa value
float volumetricFlow = 0;    // variable to store volumetric flow rate value
float velocityFlow = 0;     // variable to store velocity of flow value
float offset = 0;        // variable to store offset differential pressure

//constants - these will not change
const float tubeArea1 = 0.01592994; // area of venturi tube first section 0.003095 0.01592994
const float tubeArea2 = 0.0042417; // area of venturi tube second section
const float airDensity = 1.225;

void setup() {
// start serial port at 9600 bps and wait for port to open:
Serial.begin(9600);

pinMode(sensorPin, INPUT);  // Pressure sensor is on Analogue pin 0

Serial.flush();
//Serial.println();

Serial.print("Sample Number,  Raw Sensor Value, Differential Pressure,  Volumetric Flow Rate,  Velocity of Flow,");
Serial.println();
Serial.print("       ,     bits    ,      Pa     ,    m^3/second    ,     m/s    ,");
Serial.println();

// get initial sensor value
for (int i = 0; i < 100; i++) {

// read the value from the sensor:

//push sensor values to averageValue object
averageValue.push(sensorValue);
}

for (int i = 0; i < 100; i++)
{
// get average Sensor values
averageValue.get(i);

}

//calculate mean average sensor and store it
averageInitialValue = averageValue.mean();

Serial.print("Average Initial Value :");
Serial.print(averageInitialValue);
Serial.println();

}

void loop() {

//read the value from the sensor:

// initial value
sensorValue = sensorValue - (int)averageInitialValue;

// increment sample counter
sampleNumber++;

// map the Raw data to kPa
diffPressure = map(sensorValue, 0, 1023, 0, 4000);

if (sensorValue >= 0)
{
//calculate volumetric flow rate for Exhalation
volumetricFlow = tubeArea1 * (sqrt((2/airDensity) * (diffPressure/(sq(tubeArea1/tubeArea2)-1))));

//calculate velocity of flow
velocityFlow = volumetricFlow / tubeArea1;
}
// convert reading to a positive value
else if (sensorValue <= 0) {
diffPressure = diffPressure *-1;

//calculate volumetric flow rate for Inhalation
volumetricFlow = tubeArea2 * (sqrt((2/airDensity) * (diffPressure/(1-sq(tubeArea2/tubeArea1)))));

//calculate velocity of flow
velocityFlow = volumetricFlow / tubeArea2;
}

// Print the results as comma separated values for easier processing

Serial.print(sampleNumber);
Serial.print(",");
Serial.print(sensorValue);
Serial.print(",");
Serial.print(diffPressure);
Serial.print(",");
Serial.print(volumetricFlow);
Serial.print(",");
Serial.print(velocityFlow);
Serial.print(",");
Serial.println();

// wait 100 milliseconds before the next loop
// for the analog-to-digital converter and
// pressure sensor to settle after the last reading:
delay(100);

}
``````

I have added to the setup function to provide an initial average.  This zeros the sensorValue so that there are no issues with negative numbers during the calculation stage.  It is always a good idea to zero things before performing calculations.  I have also reduced the number of variables needed.

If people wish to use this code they will need to download the Average.H library from here:

https://github.com/MajenkoLibraries/Average

The library has been kindly provided by Majenko Technologies and appears to work very well.  It was much quicker to use this library than to write my own function to calculate the average!

Here is the output from the new arduino serial plotter - which is very cool!

Blue trace: Raw sensor Value
Red trace: Differential pressure value, (Positive = Exhaling, Negative = Inhaling)
Green trace: Volumetric Flow
Orange trace: Velocity of Flow

If I could adjust the scales and print each graph on a separate line I'd be half way to displaying the data as requested!

I'm going to look at python scripting to achieve this functionality as I believe it will work best.

That is all for now people - take care always!