University project - Electronic Stethoscope

@ Iggmoe - that’s post modern Briton for you…

This looks fascinating, will definietly give that a look! many thanks!

Yes I agree, I would have liked a bigger budget and freedom to choose my own hardware, but ah well, I guess industry will be much the same :slight_smile:

You are welcome!

@ Justin - The tool is perfect for PID tuning :wink:

@ Architect - i think you have stumbled on a cunning plan…so cunning you could pin a tail on it and call it a weasel :smiley:

Hey guys! I m so nearly there! I have implemented an FFT program and adapted it to my needs, all that remains is to feed my analogue input into the program!
But, the digital input is 32 Bit signed integer, whilst the program only accepts a double precision floating point number (the operation double needs to be applied to it)

What is the easiest way to convert the variable scope as listed in this line? “AnalogInput scope = new AnalogInput((Cpu.AnalogChannel)Cpu.AnalogChannel.ANALOG_0, 15);”

private void DoChart()
AnalogInput scope = new AnalogInput((Cpu.AnalogChannel)Cpu.AnalogChannel.ANALOG_0, 15);
{double Fs = 11025; // 11kHz Sampling frequency
double TimeStep = 1000.0 / Fs; // time step in mS
double HzPerBin = Fs / N;
double Delta_F = Fs / N; // 11025/8192 = 1.34 Hz/bin
double f1 = scope; // Sinusoid frequencies
double f2 = 0; // Sinusoid frequencies
double f3 = 0; // Sinusoid frequencies
double Theta1 = 2 * Pi * f1 / Fs; // Normalized frequency 1
double Theta2 = 2 * Pi * f2 / Fs; // Normalized frequency 2
double Theta3 = 2 * Pi * f3 / Fs; // Normalized frequency 3
double A1 = 1;
double A2 = 0.5;
double A3 = 0.1;
double p1 = 0;
double p2 = 0.2 * Pi;
double p3 = 0.7 * Pi;
double Noise;
double NoiseLevel = 0.1;

Convert to what?

a “double precision floating point number” according to visual studio. Having perused the msdn website, im fairly certain that is the correct term, i could however be horribly mistaken!

You need to read from the scope. You variable scope is an object. It has methods. You need to call one of its Read methods.

Im trying to achieve that, its not going well im afraid

I found this on msdn, but it doesnt seem to work for me, the same error message persists saying

"Error 1 Cannot implicitly convert type ‘Microsoft.SPOT.Hardware.AnalogInput’ to ‘double’ "

public void ConvertDoubleInt(double doubleVal) {

		int     intVal = 0;
		// Double to int conversion can overflow. 
		try {
			intVal = System.Convert.ToInt32(doubleVal);
			System.Console.WriteLine("{0} as an int is: {1}",
				doubleVal, intVal);
		} 
		catch (System.OverflowException) {
			System.Console.WriteLine(
				"Overflow in double-to-int conversion.");
		}

		// Int to double conversion cannot overflow.
		doubleVal = System.Convert.ToDouble(intVal);
		System.Console.WriteLine("{0} as a double is: {1}",
			intVal, doubleVal);
	}

Use cast.
for example:


double d = 4.9;
int i = (int)d;

Based on this error it looks like you are trying to treat an instance of an AnalogInput class as a double.

I think I see the problem from your earlier post


private void DoChart()
AnalogInput scope = new AnalogInput((Cpu.AnalogChannel)Cpu.AnalogChannel.ANALOG_0, 15); <------ Scope is an AnalogInput
{double Fs = 11025; // 11kHz Sampling frequency
double TimeStep = 1000.0 / Fs; // time step in mS
double HzPerBin = Fs / N;
double Delta_F = Fs / N; // 11025/8192 = 1.34 Hz/bin
double f1 = scope; // Sinusoid frequencies  <----------------------- Here you assign scope, the AnalogInput to a double, you need call Read
double f2 = 0; // Sinusoid frequencies
double f3 = 0; // Sinusoid frequencies
double Theta1 = 2 * Pi * f1 / Fs; // Normalized frequency 1
double Theta2 = 2 * Pi * f2 / Fs; // Normalized frequency 2
double Theta3 = 2 * Pi * f3 / Fs; // Normalized frequency 3
double A1 = 1;
double A2 = 0.5;
double A3 = 0.1;
double p1 = 0;
double p2 = 0.2 * Pi;
double p3 = 0.7 * Pi;
double Noise;
double NoiseLevel = 0.1;

it says “A field initializer cannot reference the non-static field, method, or property”

is this the method applied to convert 32 bit signed integer to floating point(double precision)?

and sure, ill paste it below

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Hardware;
using GHI.Premium.Hardware;

namespace TransformDemo
{
public partial class Form1 : Form
{
private System.Windows.Forms.DataGrid DataGrid1;
private Windale.Transform.TransformNET transformNET1;

    private int Count = 0;
    private int CountMax;
    private int N;						// Number of samples
    private int Ndisplay;
    private int N2;
    
	//-------------------------------------
	// DataGrid Variables
	//
	// Create a new DataTable.
	private DataTable dTable = new DataTable("DTable");
	//
	// Create column and row variables to be added to the DataTable
	private DataColumn dtCol;
	private DataRow dtRow;
	//
	//-------------------------------------

    public Form1()
    {
        InitializeComponent();
        transformNET1 = new Windale.Transform.TransformNET();
    }

	private void Form1_Load(object sender, System.EventArgs e)
	{

        // Set ThreadMode Property
        //
        // This property determines whether subsequent methods 
        // will operate within their own thread within the component. 
        // This method makes it possible for component methods to be 
        // performed in the fastest possible time, however it also 
        // demands that the calling application creates and manages 
        // their own threads within which the component methods are called.  
        // For now we let it run in the main application without extra threading.
        // To ensure the GUI responds, this should be done in a thread 
        // or else set ThreadMode = true (default).
        //
        //transformNET1.ThreadMode = false;

        N = 16 * 1024; 						    // Number of samples
        Ndisplay = N / 2;
        N2 = N / 2;
        MakeTable(N2);

        CountMax = 1;
        DoChart();
	}

	private void MakeTable(long N)
	{
		// Make table N rows long

		// Add column to the DataTable
		dtCol = new DataColumn();
		dtCol.ColumnName = "No";
		dtCol.AutoIncrement = true;
		dtCol.Caption = "No";
		dtCol.ReadOnly = true;
		dtCol.Unique = true;
		dTable.Columns.Add(dtCol);

		// Add column to the DataTable
		dtCol = new DataColumn();
		dtCol.ColumnName = "X (V)";
		dtCol.AutoIncrement = false;
		dtCol.Caption = "X (V)";
		dtCol.ReadOnly = false;
		dtCol.Unique = false;
		dTable.Columns.Add(dtCol);

        // Add column to the DataTable
        dtCol = new DataColumn();
        dtCol.ColumnName = "Gain (dBV)";
        dtCol.AutoIncrement = false;
        dtCol.Caption = "Gain (dBV)";
        dtCol.ReadOnly = false;
        dtCol.Unique = false;
        dTable.Columns.Add(dtCol);

		// Add column to the DataTable
		dtCol = new DataColumn();
        dtCol.ColumnName = "Spectrum (kHz)";
		dtCol.AutoIncrement = false;
        dtCol.Caption = "Spectrum (kHz)";
		dtCol.ReadOnly = false;
		dtCol.Unique = false;
		dTable.Columns.Add(dtCol);

		// Add rows to the table
		//
		dtRow = dTable.NewRow();
		dtRow["No"] = 0;
		dTable.Rows.Add(dtRow);

		long i = 0;
		for (i = 1; i < N; i++)
		{
			// Add rows to the table
			//
			dtRow = dTable.NewRow();
			dTable.Rows.Add(dtRow);
    }

		DataGrid1.DataSource = dTable;

		ClearTable();

	}

	private void ClearTable()
	{

		int i = 0;
		int j = 0;
		int Nrows = 0;
		int Ncols = 0;
		Nrows = dTable.Rows.Count;
		Ncols = dTable.Columns.Count;

		for (i = 0; i < Nrows; i++)
		{
			dtRow = dTable.Rows[i];
			for (j = 1; j < Ncols; j++)
			{
				dtRow[j] = "";
    }
}

	}


    private void btnStop_Click(object sender, EventArgs e)
    {
        btnStart.Enabled = true;
        btnStop.Enabled = false;
        Count = CountMax;  // stop the Chart updating
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        btnStart.Enabled = false;
        btnStop.Enabled = true;

        // This should be done in a thread .. for demo just run here in GUI
        //

        CountMax = 200;
        DoChart();
    }
    AnalogInput scope = new AnalogInput((Cpu.AnalogChannel)Cpu.AnalogChannel.ANALOG_0, 15);
    double scope2 = 4.9;
    int i = (int)scope2;
    private void DoChart()
    {
        int i;
        double Pi = 3.14159;
        double [] X = new double[N];
        double [] Time = new double[N];
        double [] Gain = new double[N2];
        double [] Freq = new double[N2];
        double [] PeakAmplitude = new double[N];
        double [] PeakPhase = new double[N];
        double [] PeakFrequencies = new double[N];
        double [] Phase = new double[N];

        // Input Signal Parameters
        //
        double Fs = 11025; 				            // 11kHz Sampling frequency
        double TimeStep = 1000.0 / Fs;              // time step in mS
        double HzPerBin = Fs / N;
        double Delta_F = Fs / N;				    // 11025/8192 = 1.34 Hz/bin
        double f1 = scope;                           // Sinusoid frequencies	
        double f2 = 0;                           // Sinusoid frequencies
        double f3 = 0;                           // Sinusoid frequencies		
        double Theta1 = 2 * Pi * f1 / Fs;			// Normalized frequency 1
        double Theta2 = 2 * Pi * f2 / Fs;			// Normalized frequency 2
        double Theta3 = 2 * Pi * f3 / Fs;			// Normalized frequency 3
        double A1 = 1;
        double A2 = 0.5;
        double A3 = 0.1;
        double p1 = 0;
        double p2 = 0.2 * Pi;
        double p3 = 0.7 * Pi;
        double Noise;
        double NoiseLevel = 0.1; 

        Random random = new Random();

        // Parameters
        //
        // Parameters
        //
        int AmplitudeType = 9; // MagnitudedBVNormDefMax2  dBV(Norm) = 
                               // dbV normalized to a DefMax maximum peak output. 
        int WindowType = 0;    // 0 = No window, 2 = Hanning
        int WindowOptions1 = 1;
        double Rload = 50;
        double DefMax = 10.0;
        double[] Parms = { AmplitudeType, Fs, WindowType, WindowOptions1, 0, 0, 0, Rload, DefMax };

        do
        {

            // Get input signal
            //
            double TotalTime = 0;
            for (i = 0; i < N; i++)
            {
                Noise = NoiseLevel * (float)(random.NextDouble() * 2.0 - 1);
                X[i] = A1 * System.Math.Cos(Theta1 * i + p1)
                       + A2 * System.Math.Cos(Theta2 * i + p2)
                       + A3 * System.Math.Cos(Theta3 * i + p3)
                       + Noise;
                Time[i] = TotalTime;
                TotalTime += TimeStep;
            }

            // Estimate spectrum using FFT
            // 
            transformNET1.Spectrum(ref X, ref Gain, ref Phase, ref Freq, ref PeakAmplitude, ref PeakPhase, ref PeakFrequencies, ref Parms);

            for (i = 0; i < N2; i++)
            {
                Freq[i] = Freq[i] / 1000.0;
            }

		    // Fill grid with data
		    // 
            if (Count == 0)
            {
                for (i = 0; i < N2; i++)
                {
                    dtRow = dTable.Rows[i];
                    dtRow["X (V)"] = X[i].ToString("#.###");
                    dtRow["Gain (dBV)"] = Gain[i].ToString("#.###");
                    dtRow["Spectrum (kHz)"] = Freq[i].ToString("#.###");
    }
                // Display peak frequencies
                //
                textBox1.Text = "Peak Freq: " + PeakFrequencies[0].ToString("####") + "Hz" + " @ " + PeakAmplitude[0].ToString("0.00") + "dBV";
                //textBox2.Text = textBox2.Text + ", " + PeakFrequencies[1].ToString("0:###.##") + "Hz" + " @ " + PeakAmplitude[1].ToString("0:###.##") + "dBV";

            }

            // Clear display
            //
            try
            {
                chart1.Series["Spectrum"].Points.Clear();
                chart2.Series["Signal"].Points.Clear();
            }
            catch
            {
            };

            chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 0;
            chart1.ChartAreas["ChartArea1"].AxisY.Minimum = -80;

            chart2.ChartAreas["ChartArea1"].AxisX.Minimum = 0;
            chart2.ChartAreas["ChartArea1"].AxisX.Maximum = 10;
            chart2.ChartAreas["ChartArea1"].AxisY.Minimum = -2;
            chart2.ChartAreas["ChartArea1"].AxisY.Maximum = 2;

            // Populate the Chart with current data
            //
            for (int ic = 0; ic < Ndisplay; ic++)
            {
                chart1.Series["Spectrum"].Points.AddXY(Freq[ic], Gain[ic]);
            }
            for (int ic = 0; ic < Ndisplay/40; ic++)
    {
                chart2.Series["Signal"].Points.AddXY(Time[ic], X[ic]);
            }
            chart1.Invalidate();
            chart2.Invalidate();
            Count++;

        } while (Count < CountMax); 
        Count = 0; // Reset
    }

}

}

As I mentioned above you need to use one of the Read methods:

scope.Read()

Edit1: Can you please use code tags

Edit2: Quick tutorial on how to use AnalogInput:

Hey guys, when trying to read from the analog input, I get this message, even with very simple code

An unhandled exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.Hardware.dll

What am i doing wrong? I’ve referenced everything i think

using System;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Hardware;
using GHI.Premium.Hardware;

namespace MFConsoleApplication1
{
    public class Program
    {
        public static void Main()
        {
            AnalogInput lightSensor = new AnalogInput((Cpu.AnalogChannel)Cpu.AnalogChannel.ANALOG_1,
                                                        10);
            double lightSensorReading = 0;

            while (true)
            {
                lightSensorReading = lightSensor.Read();
                Debug.Print(lightSensorReading.ToString());
                Thread.Sleep(500);
            }
        }
    }
}

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

Ah i see! ive edited the post

@ ks09aao - What line gives you the exception?

The error is gone now that i changed the analogin command, Im not sure why though!

Now when i debug my program it says “the debugging target is not an initialized state, rebooting”, why is this? the print commands do not come out in the debug window either, the debugging closes briefly after starting

using System;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Hardware;
using GHI.Premium.Hardware;
using GHI.OSHW.Hardware;



namespace MFConsoleApplication1
{
    public class Program
    {
        public static void Main()
        {
            AnalogInput lightSensor = new AnalogInput(FEZCerbuino.Pin.AnalogIn.A1);

            double lightSensorReading = 0;
            while (true)
            {
                lightSensorReading = lightSensor.Read();
                Debug.Print(lightSensorReading.ToString());
                Thread.Sleep(500);
            }
        }
                
            
            void programStarted()
            {
                Debug.Print("Program Started");
            }
        }

    }


Oh i see, so the fact that I get no output is more program related, I need to change how I manipulate the output

Is there some kind of loop I can use that would sample the amplitude every second and print it to the debug window?

Ahhh sorry daft question, yes your quite right!
This is the output from the debug window, the lines “ERROR!!! Firmware version does not match managed code version!!!” and “Cannot find any entrypoint!” are cuase for concern?

Create TS.

 Loading start at 8059dcc, end 807ac80

Assembly: mscorlib (4.2.0.0)Assembly: Microsoft.SPOT.Native (4.2.0.0)Assembly: Microsoft.SPOT.Hardware (4.2.0.0)
Assembly: Microsoft.SPOT.Graphics (4.2.0.0)Assembly: Microsoft.SPOT.TinyCore (4.2.0.0)
Assembly: Microsoft.SPOT.Hardware.SerialPort (4.2.0.0)Assembly: Microsoft.SPOT.Hardware.OneWire (4.2.0.0)
Assembly: Microsoft.SPOT.Hardware.Usb (4.2.0.0)Assembly: Microsoft.SPOT.Hardware.PWM (4.2.0.1)
Loading Deployment Assemblies.

Attaching deployed file.

Assembly: Microsoft.SPOT.IO (4.2.0.0)Attaching deployed file.

Assembly: GHI.OSHW.Hardware (4.2.4.0)***********************************************************************

*                                                                     *

* ERROR!!!!  Firmware version does not match managed code version!!!! *

*                                                                     *

*                                                                     *

* Invalid native checksum: GHI.OSHW.Hardware 0xEE697492!=0x52D307E9 *

*                                                                     *

***********************************************************************

Resolving.

The debugging target runtime is loading the application assemblies and starting execution.
Ready.

Cannot find any entrypoint!

Done.

Waiting for debug commands...

'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\mscorlib.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Native.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Graphics.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.TinyCore.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.SerialPort.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.OneWire.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.Usb.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.PWM.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.IO.dll', Symbols loaded.
The program '[21] Micro Framework application: Managed' has exited with code 0 (0x0).