[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln    merge=union\n*.csproj merge=union\n*.vbproj merge=union\n*.fsproj merge=union\n*.dbproj merge=union\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "#################\n## Eclipse\n#################\n\n*.pydevproject\n.project\n.metadata\nbin/\ntmp/\n*.tmp\n*.bak\n*.swp\n*~.nib\nlocal.properties\n.classpath\n.settings/\n.loadpath\n\n# External tool builders\n.externalToolBuilders/\n\n# Locally stored \"Eclipse launch configurations\"\n*.launch\n\n# CDT-specific\n.cproject\n\n# PDT-specific\n.buildpath\n\n\n#################\n## Visual Studio\n#################\n\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Rr]elease/\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.vspscc\n.builds\n*.dotCover\n\n## TODO: If you have NuGet Package Restore enabled, uncomment this\n#packages/\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n\n# Visual Studio profiler\n*.psess\n*.vsp\n\n# ReSharper is a .NET coding add-in\n_ReSharper*\n\n# Installshield output folder\n[Ee]xpress\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish\n\n# Others\n[Bb]in\n[Oo]bj\nsql\nTestResults\n*.Cache\nClientBin\nstylecop.*\n~$*\n*.dbmdl\nGenerated_Code #added for RIA/Silverlight projects\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\n\n\n\n############\n## Windows\n############\n\n# Windows image file caches\nThumbs.db\n\n# Folder config file\nDesktop.ini\n\n\n#############\n## Python\n#############\n\n*.py[co]\n\n# Packages\n*.egg\n*.egg-info\ndist\nbuild\neggs\nparts\nbin\nvar\nsdist\ndevelop-eggs\n.installed.cfg\n\n# Installer logs\npip-log.txt\n\n# Unit test / coverage reports\n.coverage\n.tox\n\n#Translations\n*.mo\n\n#Mr Developer\n.mr.developer.cfg\n\n# Mac crap\n.DS_Store\n\n##################\n# Binary archive\n##################\n\nbin-archive/"
  },
  {
    "path": "ArduinoPrintADC/ArduinoPrintADC.ino",
    "content": "/*\n    ArduinoPrintADC.ino\n\n    Author: Seb Madgwick\n\n    Sends up to all 6 analogue inputs values in ASCII as comma separated values\n    over serial.  Each line is terminated with a carriage return character ('\\r').\n    The number of channels is sent by sending a character value of '1' to '6' to \n    the Arduino.\n    \n    Tested with \"arduino-1.0.3\" and \"Arduino Uno\".\n\n */\n\n#include <stdlib.h> // div, div_t\n\nvoid setup() {\n\n    // Enable pull-ups to avoid floating inputs\n    digitalWrite(A0, HIGH);\n    digitalWrite(A1, HIGH);\n    digitalWrite(A2, HIGH);\n    digitalWrite(A3, HIGH);\n    digitalWrite(A6, HIGH);\n    digitalWrite(A7, HIGH);\n\n    // Init serial\n    Serial.begin(115200);\n}\n\nvoid loop() {\n    static int numChans = 1;\n\n    // Received character sets number of active channels\n    while(Serial.available() > 0) {\n        char c = Serial.read();\n        if(c >= '1' && c <= '6') {\n            numChans = c - '0';\n        }\n    }\n\n    // Print ADC results for active channels\n    PrintInt(analogRead(A0));\n    if(numChans > 1) {\n        Serial.write(',');\n        PrintInt(analogRead(A1));\n    }\n    if(numChans > 2) {\n        Serial.write(',');\n        PrintInt(analogRead(A2));\n    }\n    if(numChans > 3) {\n        Serial.write(',');\n        PrintInt(analogRead(A3));\n    }\n    if(numChans > 4) {\n        Serial.write(',');\n        PrintInt(analogRead(A6));\n    }\n    if(numChans > 5) {\n        Serial.write(',');\n        PrintInt(analogRead(A7));\n    }\n    Serial.write('\\r'); // print new line\n}\n\n// Fast int to ASCII conversion\nvoid PrintInt(int i) {\n    static const char asciiDigits[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };\n    div_t n;\n    int print = 0;\n    if(i < 0) {\n        Serial.write('-');\n        i = -i;\n    }\n    if(i >= 10000) {\n        n = div(i, 10000);\n        Serial.write(asciiDigits[n.quot]);\n        i = n.rem;\n        print = 1;\n    }\n    if(i >= 1000 || print) {\n        n = div(i, 1000);\n        Serial.write(asciiDigits[n.quot]);\n        i = n.rem;\n        print = 1;\n    }\n    if(i >= 100 || print) {\n        n = div(i, 100);\n        Serial.write(asciiDigits[n.quot]);\n        i = n.rem;\n        print = 1;\n    }\n    if(i >= 10 || print) {\n        n = div(i, 10);\n        Serial.write(asciiDigits[n.quot]);\n        i = n.rem;\n    }\n    Serial.write(asciiDigits[i]);\n}\n"
  },
  {
    "path": "README.md",
    "content": "Serial-Oscilloscope\n===================\n\nSerial Oscilloscope is a Windows application that plots comma-separated variables within any incoming serial steam as channels on a real-time oscilloscope. The application also functions as a basic serial terminal, received bytes are printed to the terminal and typed characters are transmitted. The project uses Michael Bernstein's [oscilloscope library](http://www.oscilloscope-lib.com/) to plot up to 9 channels on 3 different oscilloscope with view and trigger menus.\n\nSerial Oscilloscope is compatible with any serial stream containing comma-separated values terminated by a new-line character (\"\\r\"). For example, \"11,22,33\\r\" will be interpreted as values 11, 22 and 33 for channels 1, 2 and 3 respectively. The serial stream can also include non numerical characters which will be ignored. For example, \"a=0.5,blue,x=3.14,t1t2t3,8\\r\\n\" will be interpreted as values 0.5, 3.14, 123 and 8 for channels 1, 2, 3 and 4 respectively.\n\nThe source files also include an Arduino sketch to send analogue input values over serial.  Up to 6 ADC channels can be enabled by sending the characters \"1\" to \"6\" to the Arduino.  Enabling more channels will reduce the sample rate.\n\nIn the [YouTube video](http://www.youtube.com/watch?v=jgMG0UQ2_pc) I show the Arduino and Serial Oscilloscope being used to plot data from an [IR distance sensor]( https://www.sparkfun.com/products/242), a [triple-axis accelerometer]( https://www.sparkfun.com/products/9269) and a [microphone]( https://www.sparkfun.com/products/9964).\n\nPrecompiled binary files can be [downloaded](http://www.x-io.co.uk/serial-oscilloscope/) from the x-io website.\n\nVersion history\n---------------\n\n* **v1.0**  Initial release\n* **v1.1**  Supports non-standard baud rates.  Disable terminal feature added.\n* **v1.2**  Fixed memory leak and bug that prevent plotting of negative numbers.\n* **v1.3**  No longer ignores \".\" for plotting decimal values.\n* **v1.4**  Clear terminal menu item added\n* **v1.5**  Log to file tool.  Remove non-numerical characters from port names.\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/CsvFileWriter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.IO;\nusing System.Globalization;\n\nnamespace Serial_Oscilloscope\n{\n    class CsvFileWriter\n    {\n        /// <summary>\n        /// File path of CSV file.\n        /// </summary>\n        public string FilePath { get; private set; }\n\n        /// <summary>\n        /// Internal flag used to disable writes during file close.\n        /// </summary>\n        private bool writesEnabled;\n\n        /// <summary>\n        /// Stream Writer to write to file.\n        /// </summary>\n        private StreamWriter streamWriter;\n\n        /// <summary>\n        /// Constructor.\n        /// </summary>\n        /// <param name=\"filePath\"></param>\n        public CsvFileWriter(string filePath)\n        {\n            FilePath = filePath;\n            writesEnabled = true;\n            streamWriter = null;\n        }\n\n        /// <summary>\n        /// Close CSV file.\n        /// </summary>\n        public void CloseFile()\n        {\n            List<string> fileNames = new List<string>();\n            writesEnabled = false;\n            streamWriter.Close();\n        }\n\n        /// <summary>\n        /// Write array of values as line of CSVs in file.\n        /// </summary>\n        /// <param name=\"values\"></param>\n        public void WriteCSVline(float[] values)\n        {\n            if (writesEnabled)\n            {\n                // Open file\n                if (streamWriter == null)\n                {\n                    streamWriter = new System.IO.StreamWriter(FilePath, false);\n                }\n\n                // Write line\n                string csvLine = \"\";\n                for(int i = 0; i <values.Length; i++){\n                    csvLine += values[i].ToString(CultureInfo.InvariantCulture);\n                    if (i < values.Length - 1)\n                    {\n                        csvLine += \",\";\n                    }\n                }\n                streamWriter.WriteLine(csvLine);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormGetValue.Designer.cs",
    "content": "﻿namespace Serial_Oscilloscope\n{\n    partial class FormGetValue\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.textBoxValue = new System.Windows.Forms.TextBox();\n            this.labelValue = new System.Windows.Forms.Label();\n            this.buttonOK = new System.Windows.Forms.Button();\n            this.SuspendLayout();\n            // \n            // textBoxValue\n            // \n            this.textBoxValue.Location = new System.Drawing.Point(55, 12);\n            this.textBoxValue.Name = \"textBoxValue\";\n            this.textBoxValue.Size = new System.Drawing.Size(100, 20);\n            this.textBoxValue.TabIndex = 1;\n            this.textBoxValue.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxValue_KeyPress);\n            // \n            // labelValue\n            // \n            this.labelValue.AutoSize = true;\n            this.labelValue.Location = new System.Drawing.Point(12, 15);\n            this.labelValue.Name = \"labelValue\";\n            this.labelValue.Size = new System.Drawing.Size(37, 13);\n            this.labelValue.TabIndex = 0;\n            this.labelValue.Text = \"Value:\";\n            // \n            // buttonOK\n            // \n            this.buttonOK.Location = new System.Drawing.Point(161, 10);\n            this.buttonOK.Name = \"buttonOK\";\n            this.buttonOK.Size = new System.Drawing.Size(75, 23);\n            this.buttonOK.TabIndex = 2;\n            this.buttonOK.Text = \"OK\";\n            this.buttonOK.UseVisualStyleBackColor = true;\n            this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);\n            // \n            // FormGetValue\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(246, 48);\n            this.Controls.Add(this.labelValue);\n            this.Controls.Add(this.buttonOK);\n            this.Controls.Add(this.textBoxValue);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"FormGetValue\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Enter Value\";\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormGetValue_FormClosed);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.TextBox textBoxValue;\n        private System.Windows.Forms.Label labelValue;\n        private System.Windows.Forms.Button buttonOK;\n    }\n}"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormGetValue.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Serial_Oscilloscope\n{\n    /// <summary>\n    /// Dialog form to get text value from user.\n    /// </summary>\n    public partial class FormGetValue : Form\n    {\n        /// <summary>\n        /// Value entered by user.\n        /// </summary>\n        public string value { get; private set; }\n\n        /// <summary>\n        /// Constructor.\n        /// </summary>\n        public FormGetValue()\n        {\n            InitializeComponent();\n        }\n\n        /// <summary>\n        /// textBoxValue KeyPress event to close form when Enter key pressed.\n        /// </summary>\n        private void textBoxValue_KeyPress(object sender, KeyPressEventArgs e)\n        {\n            if (e.KeyChar == '\\r')\n            {\n                Close();\n            }\n        }\n\n        /// <summary>\n        /// buttonOK Click event to close form.\n        /// </summary>\n        private void buttonOK_Click(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        /// <summary>\n        /// FormGetValue FormClosed event to store value entered by user.\n        /// </summary>\n        private void FormGetValue_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            value = textBoxValue.Text;\n        }\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormGetValue.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormTerminal.Designer.cs",
    "content": "﻿namespace Serial_Oscilloscope\n{\n    partial class FormTerminal\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.menuStrip = new System.Windows.Forms.MenuStrip();\n            this.toolStripMenuItemSerialPort = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemBaudRate = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem9600 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem19200 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem38400 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem57600 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem115200 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem230400 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem460800 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem921600 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemOther = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemTerminal = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemEnabled = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemClear = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemOsciloscope = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemChannels123 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemChannels456 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemChannels789 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemHelp = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemAbout0 = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemSourceCode = new System.Windows.Forms.ToolStripMenuItem();\n            this.statusStrip = new System.Windows.Forms.StatusStrip();\n            this.toolStripStatusLabelSamplesReceived = new System.Windows.Forms.ToolStripStatusLabel();\n            this.toolStripStatusLabelSampleRate = new System.Windows.Forms.ToolStripStatusLabel();\n            this.textBox = new System.Windows.Forms.TextBox();\n            this.toolStripMenuItemLogToFile = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemStartLogging = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItemStopLogging = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuStrip.SuspendLayout();\n            this.statusStrip.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // menuStrip\n            // \n            this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItemSerialPort,\n            this.toolStripMenuItemBaudRate,\n            this.toolStripMenuItemTerminal,\n            this.toolStripMenuItemOsciloscope,\n            this.toolStripMenuItemLogToFile,\n            this.toolStripMenuItemHelp});\n            this.menuStrip.Location = new System.Drawing.Point(0, 0);\n            this.menuStrip.Name = \"menuStrip\";\n            this.menuStrip.Size = new System.Drawing.Size(584, 24);\n            this.menuStrip.TabIndex = 0;\n            this.menuStrip.Text = \"menuStrip1\";\n            // \n            // toolStripMenuItemSerialPort\n            // \n            this.toolStripMenuItemSerialPort.Name = \"toolStripMenuItemSerialPort\";\n            this.toolStripMenuItemSerialPort.Size = new System.Drawing.Size(72, 20);\n            this.toolStripMenuItemSerialPort.Text = \"Serial Port\";\n            this.toolStripMenuItemSerialPort.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.toolStripMenuItemSerialPort_DropDownItemClicked);\n            // \n            // toolStripMenuItemBaudRate\n            // \n            this.toolStripMenuItemBaudRate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItem9600,\n            this.toolStripMenuItem19200,\n            this.toolStripMenuItem38400,\n            this.toolStripMenuItem57600,\n            this.toolStripMenuItem115200,\n            this.toolStripMenuItem230400,\n            this.toolStripMenuItem460800,\n            this.toolStripMenuItem921600,\n            this.toolStripMenuItemOther});\n            this.toolStripMenuItemBaudRate.Name = \"toolStripMenuItemBaudRate\";\n            this.toolStripMenuItemBaudRate.Size = new System.Drawing.Size(72, 20);\n            this.toolStripMenuItemBaudRate.Text = \"Baud Rate\";\n            this.toolStripMenuItemBaudRate.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.toolStripMenuItemBaudRate_DropDownItemClicked);\n            // \n            // toolStripMenuItem9600\n            // \n            this.toolStripMenuItem9600.Name = \"toolStripMenuItem9600\";\n            this.toolStripMenuItem9600.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem9600.Text = \"9600\";\n            // \n            // toolStripMenuItem19200\n            // \n            this.toolStripMenuItem19200.Name = \"toolStripMenuItem19200\";\n            this.toolStripMenuItem19200.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem19200.Text = \"19200\";\n            // \n            // toolStripMenuItem38400\n            // \n            this.toolStripMenuItem38400.Name = \"toolStripMenuItem38400\";\n            this.toolStripMenuItem38400.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem38400.Text = \"38400\";\n            // \n            // toolStripMenuItem57600\n            // \n            this.toolStripMenuItem57600.Name = \"toolStripMenuItem57600\";\n            this.toolStripMenuItem57600.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem57600.Text = \"57600\";\n            // \n            // toolStripMenuItem115200\n            // \n            this.toolStripMenuItem115200.Name = \"toolStripMenuItem115200\";\n            this.toolStripMenuItem115200.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem115200.Text = \"115200\";\n            // \n            // toolStripMenuItem230400\n            // \n            this.toolStripMenuItem230400.Name = \"toolStripMenuItem230400\";\n            this.toolStripMenuItem230400.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem230400.Text = \"230400\";\n            // \n            // toolStripMenuItem460800\n            // \n            this.toolStripMenuItem460800.Name = \"toolStripMenuItem460800\";\n            this.toolStripMenuItem460800.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem460800.Text = \"460800\";\n            // \n            // toolStripMenuItem921600\n            // \n            this.toolStripMenuItem921600.Name = \"toolStripMenuItem921600\";\n            this.toolStripMenuItem921600.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItem921600.Text = \"921600\";\n            // \n            // toolStripMenuItemOther\n            // \n            this.toolStripMenuItemOther.Name = \"toolStripMenuItemOther\";\n            this.toolStripMenuItemOther.Size = new System.Drawing.Size(110, 22);\n            this.toolStripMenuItemOther.Text = \"Other\";\n            // \n            // toolStripMenuItemTerminal\n            // \n            this.toolStripMenuItemTerminal.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItemEnabled,\n            this.toolStripMenuItemClear});\n            this.toolStripMenuItemTerminal.Name = \"toolStripMenuItemTerminal\";\n            this.toolStripMenuItemTerminal.Size = new System.Drawing.Size(66, 20);\n            this.toolStripMenuItemTerminal.Text = \"Terminal\";\n            // \n            // toolStripMenuItemEnabled\n            // \n            this.toolStripMenuItemEnabled.Checked = true;\n            this.toolStripMenuItemEnabled.CheckOnClick = true;\n            this.toolStripMenuItemEnabled.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.toolStripMenuItemEnabled.Name = \"toolStripMenuItemEnabled\";\n            this.toolStripMenuItemEnabled.Size = new System.Drawing.Size(116, 22);\n            this.toolStripMenuItemEnabled.Text = \"Enabled\";\n            this.toolStripMenuItemEnabled.CheckStateChanged += new System.EventHandler(this.toolStripMenuItemEnabled_CheckStateChanged);\n            // \n            // toolStripMenuItemClear\n            // \n            this.toolStripMenuItemClear.Name = \"toolStripMenuItemClear\";\n            this.toolStripMenuItemClear.Size = new System.Drawing.Size(116, 22);\n            this.toolStripMenuItemClear.Text = \"Clear\";\n            this.toolStripMenuItemClear.Click += new System.EventHandler(this.toolStripMenuItemClear_Click);\n            // \n            // toolStripMenuItemOsciloscope\n            // \n            this.toolStripMenuItemOsciloscope.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItemChannels123,\n            this.toolStripMenuItemChannels456,\n            this.toolStripMenuItemChannels789});\n            this.toolStripMenuItemOsciloscope.Name = \"toolStripMenuItemOsciloscope\";\n            this.toolStripMenuItemOsciloscope.Size = new System.Drawing.Size(83, 20);\n            this.toolStripMenuItemOsciloscope.Text = \"Osciloscope\";\n            // \n            // toolStripMenuItemChannels123\n            // \n            this.toolStripMenuItemChannels123.CheckOnClick = true;\n            this.toolStripMenuItemChannels123.Name = \"toolStripMenuItemChannels123\";\n            this.toolStripMenuItemChannels123.Size = new System.Drawing.Size(176, 22);\n            this.toolStripMenuItemChannels123.Text = \"Channels 1, 2 and 3\";\n            this.toolStripMenuItemChannels123.CheckStateChanged += new System.EventHandler(this.toolStripMenuItemChannels123_CheckStateChanged);\n            // \n            // toolStripMenuItemChannels456\n            // \n            this.toolStripMenuItemChannels456.CheckOnClick = true;\n            this.toolStripMenuItemChannels456.Name = \"toolStripMenuItemChannels456\";\n            this.toolStripMenuItemChannels456.Size = new System.Drawing.Size(176, 22);\n            this.toolStripMenuItemChannels456.Text = \"Channels 3, 4 and 5\";\n            this.toolStripMenuItemChannels456.Click += new System.EventHandler(this.toolStripMenuItemChannels456_CheckStateChanged);\n            // \n            // toolStripMenuItemChannels789\n            // \n            this.toolStripMenuItemChannels789.CheckOnClick = true;\n            this.toolStripMenuItemChannels789.Name = \"toolStripMenuItemChannels789\";\n            this.toolStripMenuItemChannels789.Size = new System.Drawing.Size(176, 22);\n            this.toolStripMenuItemChannels789.Text = \"Channels 7, 8 and 9\";\n            this.toolStripMenuItemChannels789.CheckStateChanged += new System.EventHandler(this.toolStripMenuItemChannels789_CheckStateChanged);\n            // \n            // toolStripMenuItemHelp\n            // \n            this.toolStripMenuItemHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItemAbout0,\n            this.toolStripMenuItemSourceCode});\n            this.toolStripMenuItemHelp.Name = \"toolStripMenuItemHelp\";\n            this.toolStripMenuItemHelp.Size = new System.Drawing.Size(44, 20);\n            this.toolStripMenuItemHelp.Text = \"Help\";\n            // \n            // toolStripMenuItemAbout0\n            // \n            this.toolStripMenuItemAbout0.Name = \"toolStripMenuItemAbout0\";\n            this.toolStripMenuItemAbout0.Size = new System.Drawing.Size(141, 22);\n            this.toolStripMenuItemAbout0.Text = \"About\";\n            this.toolStripMenuItemAbout0.Click += new System.EventHandler(this.toolStripMenuItemAbout_Click);\n            // \n            // toolStripMenuItemSourceCode\n            // \n            this.toolStripMenuItemSourceCode.Name = \"toolStripMenuItemSourceCode\";\n            this.toolStripMenuItemSourceCode.Size = new System.Drawing.Size(141, 22);\n            this.toolStripMenuItemSourceCode.Text = \"Source Code\";\n            this.toolStripMenuItemSourceCode.Click += new System.EventHandler(this.toolStripMenuItemSourceCode_Click);\n            // \n            // statusStrip\n            // \n            this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripStatusLabelSamplesReceived,\n            this.toolStripStatusLabelSampleRate});\n            this.statusStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;\n            this.statusStrip.Location = new System.Drawing.Point(0, 342);\n            this.statusStrip.Name = \"statusStrip\";\n            this.statusStrip.Size = new System.Drawing.Size(584, 20);\n            this.statusStrip.TabIndex = 1;\n            this.statusStrip.Text = \"statusStrip1\";\n            // \n            // toolStripStatusLabelSamplesReceived\n            // \n            this.toolStripStatusLabelSamplesReceived.Name = \"toolStripStatusLabelSamplesReceived\";\n            this.toolStripStatusLabelSamplesReceived.Size = new System.Drawing.Size(203, 15);\n            this.toolStripStatusLabelSamplesReceived.Text = \"toolStripStatusLabelSamplesReceived\";\n            // \n            // toolStripStatusLabelSampleRate\n            // \n            this.toolStripStatusLabelSampleRate.Name = \"toolStripStatusLabelSampleRate\";\n            this.toolStripStatusLabelSampleRate.Size = new System.Drawing.Size(174, 15);\n            this.toolStripStatusLabelSampleRate.Text = \"toolStripStatusLabelSampleRate\";\n            // \n            // textBox\n            // \n            this.textBox.BackColor = System.Drawing.Color.Black;\n            this.textBox.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.textBox.Font = new System.Drawing.Font(\"Courier New\", 8.25F);\n            this.textBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(0)))));\n            this.textBox.Location = new System.Drawing.Point(0, 24);\n            this.textBox.Multiline = true;\n            this.textBox.Name = \"textBox\";\n            this.textBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;\n            this.textBox.Size = new System.Drawing.Size(584, 318);\n            this.textBox.TabIndex = 1;\n            this.textBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);\n            // \n            // toolStripMenuItemLogToFile\n            // \n            this.toolStripMenuItemLogToFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.toolStripMenuItemStartLogging,\n            this.toolStripMenuItemStopLogging});\n            this.toolStripMenuItemLogToFile.Name = \"toolStripMenuItemLogToFile\";\n            this.toolStripMenuItemLogToFile.Size = new System.Drawing.Size(77, 20);\n            this.toolStripMenuItemLogToFile.Text = \"Log To File\";\n            // \n            // toolStripMenuItemStartLogging\n            // \n            this.toolStripMenuItemStartLogging.Name = \"toolStripMenuItemStartLogging\";\n            this.toolStripMenuItemStartLogging.Size = new System.Drawing.Size(152, 22);\n            this.toolStripMenuItemStartLogging.Text = \"Start Logging\";\n            this.toolStripMenuItemStartLogging.Click += new System.EventHandler(this.toolStripMenuItemStartLogging_Click);\n            // \n            // toolStripMenuItemStopLogging\n            // \n            this.toolStripMenuItemStopLogging.Enabled = false;\n            this.toolStripMenuItemStopLogging.Name = \"toolStripMenuItemStopLogging\";\n            this.toolStripMenuItemStopLogging.Size = new System.Drawing.Size(152, 22);\n            this.toolStripMenuItemStopLogging.Text = \"Stop Logging\";\n            this.toolStripMenuItemStopLogging.Click += new System.EventHandler(this.toolStripMenuItemStopLogging_Click);\n            // \n            // FormTerminal\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(584, 362);\n            this.Controls.Add(this.textBox);\n            this.Controls.Add(this.statusStrip);\n            this.Controls.Add(this.menuStrip);\n            this.MainMenuStrip = this.menuStrip;\n            this.Name = \"FormTerminal\";\n            this.Text = \"FormTerminal\";\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormTerminal_FormClosed);\n            this.Load += new System.EventHandler(this.FormTerminal_Load);\n            this.menuStrip.ResumeLayout(false);\n            this.menuStrip.PerformLayout();\n            this.statusStrip.ResumeLayout(false);\n            this.statusStrip.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.MenuStrip menuStrip;\n        private System.Windows.Forms.StatusStrip statusStrip;\n        private System.Windows.Forms.TextBox textBox;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemSerialPort;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemOsciloscope;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemHelp;\n        private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelSamplesReceived;\n        private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelSampleRate;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemBaudRate;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem9600;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem19200;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem38400;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem57600;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem115200;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem230400;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem460800;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem921600;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemChannels123;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemChannels456;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemChannels789;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemAbout0;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemSourceCode;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemOther;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemTerminal;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemEnabled;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemClear;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemLogToFile;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemStartLogging;\n        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemStopLogging;\n    }\n}\n\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormTerminal.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing System.IO.Ports;\nusing System.Text.RegularExpressions;\nusing System.Globalization;\n\nnamespace Serial_Oscilloscope\n{\n    public partial class FormTerminal : Form\n    {\n        #region Variables and objects\n\n        /// <summary>\n        /// Timer to update terminal textbox at fixed interval.\n        /// </summary>\n        private System.Windows.Forms.Timer formUpdateTimer = new System.Windows.Forms.Timer();\n\n        /// <summary>\n        /// SerialPort object.\n        /// </summary>\n        private SerialPort serialPort = new SerialPort();\n\n        /// <summary>\n        /// Sample counter to calculate performance statics.\n        /// </summary>\n        private SampleCounter sampleCounter = new SampleCounter();\n\n        /// <summary>\n        /// TextBoxBuffer containing text printed to terminal.\n        /// </summary>\n        private TextBoxBuffer textBoxBuffer = new TextBoxBuffer(4096);\n\n        /// <summary>\n        /// ASCII buffer for decoding CSVs in serial stream.\n        /// </summary>\n        private string asciiBuf = \"\";\n\n        /// <summary>\n        /// Oscilloscope channel values decoded from serial stream.\n        /// </summary>\n        private float[] channels = new float[9] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};\n\n        /// <summary>\n        /// Oscilloscope for channels 1, 2 and 3.\n        /// </summary>\n        private Oscilloscope oscilloscope123 = Oscilloscope.CreateScope(\"Oscilloscope/Oscilloscope_settings.ini\", \"\");\n\n        /// <summary>\n        /// Oscilloscope for channels 4, 5 and 6.\n        /// </summary>\n        private Oscilloscope oscilloscope456 = Oscilloscope.CreateScope(\"Oscilloscope/Oscilloscope_settings.ini\", \"\");\n\n        /// <summary>\n        /// Oscilloscope for channels 7, 8 and 9.\n        /// </summary>\n        private Oscilloscope oscilloscope789 = Oscilloscope.CreateScope(\"Oscilloscope/Oscilloscope_settings.ini\", \"\");\n\n        /// <summary>\n        /// CSV file writer.\n        /// </summary>\n        private CsvFileWriter csvFileWriter = null;\n\n        #endregion\n\n        /// <summary>\n        /// Constructor.\n        /// </summary>\n        public FormTerminal()\n        {\n            InitializeComponent();\n        }\n\n        #region Form load and close\n\n        /// <summary>\n        /// From load event.\n        /// </summary>\n        private void FormTerminal_Load(object sender, EventArgs e)\n        {\n            // Set form caption\n            this.Text = Assembly.GetExecutingAssembly().GetName().Name + \" (Port Closed)\";\n\n            // Set oscilloscope captions\n            oscilloscope123.Caption = \"Channels 1, 2 and 3\";\n            oscilloscope456.Caption = \"Channels 4, 5 and 6\";\n            oscilloscope789.Caption = \"Channels 7, 8 and 9\";\n\n            // Refresh serial port list\n            RefreshSerialPortList();\n\n            // Select default baud rate\n            toolStripMenuItem115200.Checked = true;\n\n            // Setup form update timer\n            formUpdateTimer.Interval = 50;\n            formUpdateTimer.Tick += new EventHandler(formUpdateTimer_Tick);\n            formUpdateTimer.Start();\n        }\n\n        /// <summary>\n        /// Form close event.\n        /// </summary>\n        private void FormTerminal_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            CloseSerialPort();\n            toolStripMenuItemStopLogging.PerformClick();\n        }\n\n        #endregion\n\n        #region Terminal textbox\n\n        /// <summary>\n        /// formUpdateTimer Tick event to update terminal textbox.\n        /// </summary>\n        void formUpdateTimer_Tick(object sender, EventArgs e)\n        {\n            // Print textBoxBuffer to terminal\n            if (textBox.Enabled && !textBoxBuffer.IsEmpty())\n            {\n                textBox.AppendText(textBoxBuffer.Get());\n                if (textBox.Text.Length > textBox.MaxLength)    // discard first half of textBox when number of characters exceeds length\n                {\n                    textBox.Text = textBox.Text.Substring(textBox.Text.Length / 2, textBox.Text.Length - textBox.Text.Length / 2);\n                }\n            }\n            else\n            {\n                textBoxBuffer.Clear();\n            }\n\n            // Update sample counter values\n            toolStripStatusLabelSamplesReceived.Text = \"Samples Recieved: \" + sampleCounter.SamplesReceived.ToString();\n            toolStripStatusLabelSampleRate.Text = \"Sample Rate: \" + sampleCounter.SampleRate.ToString();\n        }\n\n        /// <summary>\n        /// textBox KeyPress to send character to serial port.\n        /// </summary>\n        private void textBox_KeyPress(object sender, KeyPressEventArgs e)\n        {\n            SendSerialPort(e.KeyChar);\n            e.Handled = true;   // don't print character\n        }\n\n        #endregion\n\n        #region Menu strip\n\n        /// <summary>\n        /// toolStripMenuItemSerialPort DropDownItemClicke event to select or close serial port.\n        /// </summary>\n        private void toolStripMenuItemSerialPort_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)\n        {\n            // Close serial port and refresh list is refresh item clicked\n            if (e.ClickedItem.Text == \"Refresh List\")\n            {\n                CloseSerialPort();\n                RefreshSerialPortList();\n                return;\n            }\n\n            // Close serial port if checked port name clicked\n            if (((ToolStripMenuItem)e.ClickedItem).Checked)\n            {\n                CloseSerialPort();\n                ((ToolStripMenuItem)e.ClickedItem).Checked = false;\n                return;\n            }\n\n            // Check only selected item\n            foreach (ToolStripMenuItem toolStripMenuItem in ((ToolStripMenuItem)toolStripMenuItemSerialPort).DropDownItems)\n            {\n                toolStripMenuItem.Checked = false;\n            }\n            ((ToolStripMenuItem)e.ClickedItem).Checked = true;\n\n            // Open serial port\n            if (!OpenSerialPort())\n            {\n                ((ToolStripMenuItem)e.ClickedItem).Checked = false;     // uncheck serial port if open fails\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemSerialPort DropDownItemClicke event to select baud rate.\n        /// </summary>\n        private void toolStripMenuItemBaudRate_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)\n        {\n            if ((ToolStripMenuItem)e.ClickedItem == toolStripMenuItemOther)\n            {\n                FormGetValue formGetValue = new FormGetValue();\n                formGetValue.ShowDialog();\n                ((ToolStripMenuItem)e.ClickedItem).Text = \"Other (\" + formGetValue.value + \")\";\n                ((ToolStripMenuItem)e.ClickedItem).Checked = false;\n            }\n\n            // Do nothing if baud already selected\n            if (((ToolStripMenuItem)e.ClickedItem).Checked)\n            {\n                return;\n            }\n\n            // Check only selected item\n            foreach (ToolStripMenuItem toolStripMenuItem in ((ToolStripMenuItem)toolStripMenuItemBaudRate).DropDownItems)\n            {\n                toolStripMenuItem.Checked = false;\n            }\n            ((ToolStripMenuItem)e.ClickedItem).Checked = true;\n\n            // Open serial port\n            if (!OpenSerialPort())\n            {\n                RefreshSerialPortList();    // refresh port list if open fails, this also ensures port object is closed\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemEnabled CheckStateChanged event to toggle enabled state of the terminal text box.\n        /// </summary>\n        private void toolStripMenuItemEnabled_CheckStateChanged(object sender, EventArgs e)\n        {\n            if (toolStripMenuItemEnabled.Checked)\n            {\n                textBox.Enabled = true;\n            }\n            else\n            {\n                textBox.Enabled = false;\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemClear Click event to clear terminal text box.\n        /// </summary>\n        private void toolStripMenuItemClear_Click(object sender, EventArgs e)\n        {\n            textBox.Text = \"\";\n        }\n\n        /// <summary>\n        /// toolStripMenuItemChannels123 CheckStateChanged event to toggle show state of oscilloscope form.\n        /// </summary>\n        private void toolStripMenuItemChannels123_CheckStateChanged(object sender, EventArgs e)\n        {\n            if (toolStripMenuItemChannels123.Checked)\n            {\n                oscilloscope123.ShowScope();\n            }\n            else\n            {\n                oscilloscope123.HideScope();\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemChannels456 CheckStateChanged event to toggle show state of oscilloscope form.\n        /// </summary>\n        private void toolStripMenuItemChannels456_CheckStateChanged(object sender, EventArgs e)\n        {\n            if (toolStripMenuItemChannels456.Checked)\n            {\n                oscilloscope456.ShowScope();\n            }\n            else\n            {\n                oscilloscope456.HideScope();\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemChannels789 CheckStateChanged event to toggle show state of oscilloscope form.\n        /// </summary>\n        private void toolStripMenuItemChannels789_CheckStateChanged(object sender, EventArgs e)\n        {\n            if (toolStripMenuItemChannels789.Checked)\n            {\n                oscilloscope789.ShowScope();\n            }\n            else\n            {\n                oscilloscope789.HideScope();\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemStartLogging Click event to select file location and start logging\n        /// </summary>\n        private void toolStripMenuItemStartLogging_Click(object sender, EventArgs e)\n        {\n            SaveFileDialog saveFileDialog = new SaveFileDialog();\n            saveFileDialog.Title = \"Select File Location\";\n            saveFileDialog.Filter = \"CSV files (*.csv)|*.csv\";\n            saveFileDialog.OverwritePrompt = false;\n            saveFileDialog.FileName = \"LoggedData\";\n            if (saveFileDialog.ShowDialog() == DialogResult.OK)\n            {\n                csvFileWriter = new CsvFileWriter(saveFileDialog.FileName.ToString());\n                toolStripMenuItemStartLogging.Enabled = false;\n                toolStripMenuItemStopLogging.Enabled = true;\n            }\n        }\n\n        /// <summary>\n        /// toolStripMenuItemStopLogging Click event to stop logging and close file\n        /// </summary>\n        private void toolStripMenuItemStopLogging_Click(object sender, EventArgs e)\n        {\n            if (csvFileWriter != null)\n            {\n                csvFileWriter.CloseFile();\n                csvFileWriter = null;\n            }\n            toolStripMenuItemStartLogging.Enabled = true;\n            toolStripMenuItemStopLogging.Enabled = false;\n        }\n\n        /// <summary>\n        /// toolStripMenuItemAbout Click event to display version details.\n        /// </summary>\n        private void toolStripMenuItemAbout_Click(object sender, EventArgs e)\n        {\n            MessageBox.Show(Assembly.GetExecutingAssembly().GetName().Name + \" \" + Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() + \".\" + Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString(), \"About\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n        }\n\n        /// <summary>\n        /// toolStripMenuItemSourceCode Click event to open web browser.\n        /// </summary>\n        private void toolStripMenuItemSourceCode_Click(object sender, EventArgs e)\n        {\n            try\n            {\n                System.Diagnostics.Process.Start(\"https://github.com/xioTechnologies/Serial-Oscilloscope\");\n            }\n            catch { }\n        }\n\n        #endregion\n\n        #region Serial port\n\n        /// <summary>\n        /// Updates toolStripMenuItemSerialPort DropDownItems to include all available serial port.\n        /// </summary>\n        private void RefreshSerialPortList()\n        {\n            ToolStripItemCollection toolStripItemCollection = toolStripMenuItemSerialPort.DropDownItems;\n            toolStripItemCollection.Clear();\n            toolStripItemCollection.Add(\"Refresh List\");\n            foreach (string portName in System.IO.Ports.SerialPort.GetPortNames())\n            {\n                toolStripItemCollection.Add(\"COM\" + Regex.Replace(portName.Substring(\"COM\".Length, portName.Length - \"COM\".Length), \"[^.0-9]\", \"\\0\"));\n            }\n        }\n\n        /// <summary>\n        /// Opens serial port. Displays error in MessageBox if unsuccessful.\n        /// </summary>\n        /// <returns>\n        /// true if successful.\n        /// </returns>\n        private bool OpenSerialPort()\n        {\n            string portName = null;\n            int baudRate = 0;\n\n            // Get selected port name\n            foreach (ToolStripMenuItem toolStripMenuItem in ((ToolStripMenuItem)toolStripMenuItemSerialPort).DropDownItems)\n            {\n                if (toolStripMenuItem.Checked)\n                {\n                    portName = toolStripMenuItem.Text;\n                    break;\n                }\n            }\n            if (portName == null)\n            {\n                return false;\n            }\n\n            // Get selected baud rate\n            foreach (ToolStripMenuItem toolStripMenuItem in ((ToolStripMenuItem)toolStripMenuItemBaudRate).DropDownItems)\n            {\n                if (toolStripMenuItem.Checked)\n                {\n                    try\n                    {\n                        baudRate = Convert.ToInt32((new Regex(\"[^0-9]\")).Replace(toolStripMenuItem.Text, \"\"));  // convert text to int ignoring all non-numerical characters\n                    }\n                    catch\n                    {\n                        baudRate = 0;\n                    }\n                    break;\n                }\n            }\n\n            // Open serial port\n            CloseSerialPort();\n            try\n            {\n                serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);\n                serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);\n                serialPort.Open();\n                this.Text = Assembly.GetExecutingAssembly().GetName().Name + \" (\" + portName + \", \" + baudRate.ToString() + \")\";\n                sampleCounter.Reset();\n                return true;\n            }\n            catch (Exception e)\n            {\n                MessageBox.Show(e.Message, \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Hand);\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Closes serial port.\n        /// </summary>\n        private void CloseSerialPort()\n        {\n            try\n            {\n                serialPort.Close();\n            }\n            catch { }\n            this.Text = Assembly.GetExecutingAssembly().GetName().Name + \" (Port Closed)\";\n        }\n\n        /// <summary>\n        /// Sends character to serial port.\n        /// </summary>\n        /// <param name=\"c\">\n        /// Character to send to serial port.\n        /// </param>\n        private void SendSerialPort(char c)\n        {\n            try\n            {\n                serialPort.Write(new char[] { c }, 0, 1);\n            }\n            catch { }\n        }\n\n        /// <summary>\n        /// serialPort DataReceived event to print characters to terminal and process bytes through serialDecoder.\n        /// </summary>\n        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)\n        {\n            try\n            {\n                // Get bytes from serial port\n                int bytesToRead = serialPort.BytesToRead;\n                byte[] readBuffer = new byte[bytesToRead];\n                serialPort.Read(readBuffer, 0, bytesToRead);\n\n                // Process each byte\n                foreach (byte b in readBuffer)\n                {\n                    // Parse character to textBoxBuffer\n                    if ((b < 0x20 || b > 0x7F) && b != '\\r')    // replace non-printable characters with '.'\n                    {\n                        textBoxBuffer.Put(\".\");\n                    }\n                    else if (b == '\\r')     // replace carriage return with '↵' and valid new line\n                    {\n                        textBoxBuffer.Put(\"↵\" + Environment.NewLine);\n                    }\n                    else\n                    {\n                        textBoxBuffer.Put(((char)b).ToString());\n                    }\n\n                    // Extract CSVs and parse to Oscilloscope\n                    if (asciiBuf.Length > 128)\n                    {\n                        asciiBuf = \"\";  // prevent memory leak\n                    }\n                    if ((char)b == '\\r')\n                    {\n                        // Split string to comma separated variables (ignore non numerical characters)\n                        string[] csvs = (new Regex(@\"[^0-9\\-,.]\")).Replace(asciiBuf, \"\").Split(',');\n\n                        // Extract each CSV as oscilloscope channel \n                        int channelIndex = 0;\n                        foreach (string csv in csvs)\n                        {\n                            if (csv != \"\" && channelIndex < 9)\n                            {\n                                channels[channelIndex++] = float.Parse(csv, CultureInfo.InvariantCulture);\n                            }\n                        }\n\n                        // Update oscilloscopes if channel values changed\n                        if (channelIndex > 0)\n                        {\n                            oscilloscope123.AddScopeData(channels[0], channels[1], channels[2]);\n                            oscilloscope456.AddScopeData(channels[3], channels[4], channels[5]);\n                            oscilloscope789.AddScopeData(channels[6], channels[7], channels[8]);\n                            sampleCounter.Increment();\n                        }\n\n                        // Write to file if enabled\n                        if (csvFileWriter != null)\n                        {\n                            csvFileWriter.WriteCSVline(channels);\n                        }\n\n                        // Reset buffer\n                        asciiBuf = \"\";\n                    }\n                    else\n                    {\n                        asciiBuf += (char)b;\n                    }\n                }\n            }\n            catch { }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/FormTerminal.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"menuStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"statusStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>132, 17</value>\n  </metadata>\n  <metadata name=\"$this.TrayHeight\" type=\"System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>79</value>\n  </metadata>\n</root>"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Oscilloscope/Oscilloscope.cs",
    "content": "using System;\nusing System.Text;\nusing System.Drawing;\nusing System.Windows.Forms;\nusing System.Runtime.InteropServices;\n\n/*\n * C# Wrapper around the Oscilloscope DLL\n * \n * (C)2006 Dustin Spicuzza\n *\n * This library interface is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; only\n * version 2.1 of the License.\n * \n * Some comments/function declarations taken from the original \n * \"oscilloscope-lib\" documentation.\n * \n * Oscilloscope Properties added by: Frank Greenlee, April, 2010\n * MessageBoxes replaced with Exceptions by: Sebastian Madgwick, February, 2011\n * \"Osc_DLL.dll\" replaced with Osc_DLL_path by: Sebastian Madgwick, May, 2011\n * \n */\n\n/************************************************************************\n*\n*  Quick Reference: Publicly Available Methods and Properties \n*\n*************************************************************************\n\n*************************************************************************\n*\n*  Public Methods\n*\n*************************************************************************\n\n   Method: CreateScope() \n   \n   Creates an instance of the Oscilloscope. The Initialization file \n   is not used in this version of the method.\n  \n   Lifetime:   static\n   Parameters: void\n   Return:     reference of type Oscilloscope to the instance if successful\n               null if not successful\n\n*************************************************************************\n\n   Method: CreateScope ( string, string )\n \n   Creates an instance of the Oscilloscope. The Initialization file \n   is used (if found) in this version of the method.\n\n   Lifetime:   static\n   Parameters: string: Filenmae of intialization file\n               string: Filename suffix\n   Return:     reference of type Oscilloscope to the instance if successful\n               null if not successful\n\n*************************************************************************\n\n   Method: ShowScope ()\n  \n   Displays the Oscilloscope. After the instance is created it will not \n   become visible until this method is called.\n   \n   Lifetime:   instance\n   Parameters: void\n   Return:     void\n\n*************************************************************************\n\n   Method: HideScope ()\n \n   Makes the Oscilloscope invisible non-destructively.\n  \n   Lifetime:   instance\n   Parameters: void\n   Return:     void\n\n*************************************************************************\n\n   Method: ClearScope ()  \n   \n   Clears the Oscilloscope's buffers.\n  \n   Lifetime:   instance\n   Parameters: void\n   Return:     void\n\n*************************************************************************\n\n   Method: AddScopeData ( double, double, double )  \n   \n   Adds one new data point to each of the three traces.\n  \n   Lifetime:   instance\n   Parameters: double: 3X New data points, one for each trace.\n   Return:     void\n\n*************************************************************************\n\n   Method: AddExternalScopeData ( double )  \n   \n   Sends a new data point to the external trigger input, which is used \n   for triggering when the Oscilloscope's Trigger Source is set to \n   EXTERNAL_TRIG.\n  \n   Lifetime:   instance\n   Parameters: double: External Trigger Data Point\n   Return:     void\n\n*************************************************************************\n\n   Method: UpdateScope ()  \n   \n   Quickly updates the Oscilloscope traces, for use when there is a gap\n   in the dta stream.\n  \n   Lifetime:   instance\n   Parameters: void\n   Return:     void\n\n*************************************************************************\n\n   Method: Dispose ()\n \n   Releases the Oscilloscope resources back to the system and removes\n   the Oscilloscope from the display. Also sets the _disposed flag to\n   true. Any future calls or property accesses will be ignored and \n   will set a SCOPE_DISPOSED_ERROR into LastError.\n\n   Lifetime:   instance\n   Parameters: void\n   Return:     void\n  \n*************************************************************************\n*\n*  Public Properties -- all of these are class instance members.\n*\n*************************************************************************\n    \n   Property: LastError\n    \n   An application can check this to see if there has been an \n   error, even when error message displays are turned off. \n   If it is non-zero (!=NO_ERROR), there has been an error \n   and the value refers to one of the listed error constants.\n    \n   When setting LastError the value is ignored and LastError\n   is set to its defaul value, NO_ERROR. The application\n   should do this after finding a non-zero error value, as it is \n   not done automatically; the error code value will persist \n   until it is manually reset.\n   \n   Value:   int, equal to one of the error constants\n   Access:  Read/Write (any write resets LastError to NO_ERROR\n   Default: 0 (NO_ERROR)\n    \n**************************************************************************\n\n   Property: ErrorMessagesOn\n     \n   If set to \"true\", a throw new Exception will appear when there is an error. \n   When debugging is completed it may be desirable to set ErrorMessagesOn \n   to \"false.\"  The LastError variable will work regardless of this \n   setting and may be checked even when there is no instance of the \n   Oscilloscope class.\n     \n   Value:   bool\n   Access:  Read/Write\n   Default: true\n\n**************************************************************************\n\n   Property: ControlPanelVisible\n    \n   Displays or hides the control panel at the bottom of the \n   oscilloscope display.\n     \n   Value:   bool\n   Access:  Read/Write\n   Default: true (also can be define in the intialization \n            file, if it is used)\n\n**************************************************************************\n\n   Property: Left\n     \n   Sets the horizontal position of the oscilloscope on the screen, \n   specified as the number of pixels from the left edge of the screen\n   to the left edge of the oscilloscope form.\n    \n   Value:   int, Range: 0-Current Screen Width\n   Access:  Read/Write    \n   Default: Somewhere on the Screen (also can be defined in the \n            intialization file, if it is used)\n\n**************************************************************************\n\n   Property: Top\n     \n   Sets the vertical position of the oscilloscope on the screen, \n   specified as the number of pixels from the top edge of the screen\n   to the top edge of the oscilloscope form.\n    \n   Value:   int, Range: 0-Current Screen Height\n   Access:  Read/Write\n   Default: Somewhere on the Screen (also can be defined in \n            the intialization file, if it is used)\n\n**************************************************************************\n\n   Property: Width\n     \n   Sets the Width of the oscilloscope form in pixels.\n    \n   Value:   int, Range: 40-Current Screen Width\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if it is used)\n\n**************************************************************************\n\n   Property: Height\n     \n   Sets the Height of the oscilloscope form in pixels.\n    \n   Value:   int, Range: 40-Current Screen Height\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if used)\n  \n**************************************************************************\n\n   Property: CellSize\n    \n   Sets the size of a grid cell in pixels; sets both height\n   and width of grid cells to this single property setting.\n    \n   Value:   int, Range: 10-150\n   Access:  Read/Write\n   Default: 40 (also can be defined in the initialization file, if it is \n            used)\n \n**************************************************************************\n\n   Property: SamplesPerGridCell\n     \n   Sets the number of samples per grid cell on the horizontal (time) axis.\n   The value will be adjusted to closest valid number (see the DLL \n   documentation).\n     \n   WARNING: if this setting is too low and the data stream is too fast\n   a buffer overrun can be caused, which will have no indicator other\n   than the DLL locking up.\n\n   Value:   double, Range 0.10000-20,000\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if it is used)\n \n**************************************************************************\n\n   Property: Caption\n     \n   Sets the caption at the top of the oscilloscope form.\n     \n   Value:   string, Range 0-250 characters\n   Access:  Write Only\n   Default: \"Oscilloscope\" (also can be defined in the \n            initialization file, if it is used)\n\n**************************************************************************\n\n   Property: AmplitudeScale1\n     \n   Sets the Amplitude Scale of Trace 1's grid divisions, in binary steps/grid \n   cell. The value will be adjusted to closest valid number (see the DLL \n   documentation).\n     \n   Value:   double, Range: 0.00001-100,000.00000\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if it is used)\n  \n**************************************************************************\n\n   Property: AmplitudeScale2\n     \n   Sets the Amplitude Scale Trace 2's grid divisions, in binary steps/grid \n   cell. The value will be adjusted to closest valid number (see the DLL \n   documentation).\n     \n   Value:   double, Range: 0.00001-100,000.00000\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if it is used)\n\n**************************************************************************\n\n   Property: AmplitudeScale3\n     \n   Sets the Amplitude Scale Trace 3's grid divisions, in binary steps/grid \n   cell. The value will be adjusted to closest valid number (see the DLL \n   documentation).\n     \n   Value:   double, Range: 0.00001-100,000.00000\n   Access:  Read/Write\n   Default: (->fill this in) (also can be defined in the \n            initialization file, if it is used)\n\n**************************************************************************\n\n   Property: VerticalOffset1\n     \n   Sets the Vertical Offset of Trace 1, in units of of Trace 1's\n   AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, \n            if it is used)\n\n**************************************************************************\n\n   Property: VerticalOffset2\n     \n   Sets the Vertical Offset of Trace 2, in units of of Trace 2's\n   AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, \n            if it is used)\n\n**************************************************************************\n\n   Property: VerticalOffset3\n     \n   Sets the Vertical Offset of Trace 3, in units of of Trace 3's\n   AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, \n            if it is used)\n\n**************************************************************************\n\n   Property: TriggerLevel1\n     \n   Sets the Trigger Offset of Trace 1, in units of Trace 1's AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, if \n            it is used)\n \n**************************************************************************\n\n   Property: TriggerLevel2\n     \n   Sets the Trigger Offset of Trace 2, in units of Trace 2's AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, if \n            it is used)\n\n**************************************************************************\n\n   Property: TriggerLevel3\n     \n   Sets the Trigger Offset of Trace 3, in units of Trace 3's AmplitudeScale.\n     \n   Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n   Access:  Read/Write\n   Default: 0.00000 (also can be defined in the initialization file, if \n            it is used)\n  \n**************************************************************************\n\n   Property: TriggerSource\n     \n   Sets the Oscilloscope's Trigger Source. The constants TRACE1_TRIG,\n   TRACE2_TRIG, TRACE3_TRIG and EXTERNAL_TRIG are provided for conenience.\n     \n   Value:   int, Range 0-3 (TRACE1_TRIG-EXTERNAL_TRIG)\n   Access:  Read/Write\n   Default: TRACE1_TRIG (also can be defined in the initialization file, if \n            it is used)\n\n**************************************************************************\n\n   Property: TriggerEdge\n     \n   Sets the Trigger Edge Detection Mode. Any valid negative int sets it \n   Negative Edge Triggered, any valid positive int sets it Positive Edge \n   Triggered, and 0 set it to disabled. The constants FALLING_EDGE_TRIG,\n   RISING_EDGE_TRIG and DISABLED_TRIG are provided for convenience.\n     \n   Value:   int, Range: see above\n   Access:  Read/Write\n   Default: DISABLED_TRIG (also can be defined in the initialization file, \n            if it is used)\n \n**************************************************************************\n\n   Property: TriggerDelay\n     \n   Sets the Trigger Delay, in number of samples (see DLL Documentation).\n     \n   Value:   int, RangeL 0-Any valid positive int value\n   Access:  Read/Write\n   Default: 0 (also can be defined in the initialization file, if it is \n            used)\n\n**************************************************************************\n\n   Property: TraceDisplayWidth\n     \n   Returns the width of the current trace display area in pixels.\n     \n   Value:   int\n   Access:  Read Only\n   Default: N/A\n \n**************************************************************************\n\n   Property: TraceDisplayHeight\n     \n   Returns the height of the current trace display area in pixels.\n     \n   Value:   int\n   Access:  Read Only\n   Default: N/A\n  \n**************************************************************************\n*\n*  Miscellaneous Public Resources\n*\n**************************************************************************\n\n   --> Trigger Source Constants (int's):\n   TRACE1_TRIG = 0;\n   TRACE2_TRIG = 1;\n   TRACE3_TRIG = 2;\n   EXTERNAL_TRIG = 3;\n\n   --> Trigger Mode Constants (int's):\n   FALLING_EDGE_TRIG = -1; \n   RISING_EDGE_TRIG = 1;\n   DISABLED_TRIG = 0;\n\n   --> Error Constants (int's):\n   NO_ERROR = 0;\n   SCOPE_CREATION_ERROR = 1;\n   SCOPE_HANDLE_ERROR = 2;\n   SCOPE_DISPOSED_ERROR = 3;\n   LEFT_RANGE_ERROR = 4;\n   TOP_RANGE_ERROR = 5;\n   WIDTH_RANGE_ERROR = 6;\n   HEIGHT_RANGE_ERROR = 7;\n   CELLSIZE_RANGE_ERROR = 8;\n   SAMPLESPERGRIDCELL_RANGE_ERROR = 9;\n   CAPTIONSIZE_ERROR = 10;\n   CELLAMPLITUDESCALE_RANGE_ERROR = 11;\n   VERTICALOFFSET_RANGE_ERROR = 12;\n   TRIGGERLEVEL_RANGE_ERROR = 13;\n   TRIGGERSOURCE_RANGE_ERROR = 14;\n   TRIGGERDELAY_RANGE_ERROR = 15;\n   SCOPE_TRIGGERSOURCE_ERROR = 16;\n   SCOPE_TRIGGEREDGE_ERROR = 17;\n   SCOPE_NOT_VISIBLE = 18;\n\n**************************************************************************/\n\n\n// Begin Oscilloscope DLL Wrapper Implementation\nnamespace Serial_Oscilloscope\n{\n    sealed class Oscilloscope : IDisposable\n    {\n        const string Osc_DLL_path = \"Oscilloscope/Osc_DLL.dll\";\n\n        #region External declarations\n\n        /******************************************\n         *                                         *\n         * Import Essential Oscilloscope Functions *\n         *                                         *\n         ******************************************/\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int AtOpenLib\n            (int Prm);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeCreate(\n            int Prm,\n            [MarshalAs(UnmanagedType.LPStr)] StringBuilder P_IniName,\n            [MarshalAs(UnmanagedType.LPStr)] StringBuilder P_IniSuffix);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeDestroy\n            (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeShow\n            (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeHide\n            (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeCleanBuffers\n            (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ShowNext\n            (int ScopeHandle,\n            double[] PArrDbl);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ExternalNext\n            (int ScopeHandle,\n            ref double PDbl);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int QuickUpDate\n            (int ScopeHandle);\n\n        /******************************************\n         *                                        *\n         * Import Oscilloscope Attribute Controls *\n         *                                        *\n         * ****************************************\n         * \n         * Import Set functions:\n        */\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetPanelState\n          (int ScopeHandle, int VizState);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetFormPos\n          (int ScopeHandle, int FormLeft, int FormTop);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetFormSize\n          (int ScopeHandle, int FormWidth, int FormHeight);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetCellPixelSize\n          (int ScopeHandle, int CellPixelSize);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetCellSampleSize\n          (int ScopeHandle, double CellSampleSize);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetCaption\n          (int ScopeHandle,\n          [MarshalAs(UnmanagedType.LPStr)] StringBuilder P_ZeroTermStr);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetAmpScale\n          (int ScopeHandle, int BeamNum, double AmpScale);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetAmpOffset\n          (int ScopeHandle, int BeamNum, double AmpOffset);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetTriggerLevel\n          (int ScopeHandle, int BeamNum, double TriggerLevel);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetTriggerSourse\n          (int ScopeHandle, int BeamNum);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetActiveTriggerEdge\n          (int ScopeHandle, int TriggerEdge);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeSetTrigHoldOffSmplsNum\n          (int ScopeHandle, int HoldOffVsl);\n\n        /* \n         * Import Get functions:\n         */\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetFormLeft\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetFormTop\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetFormWidth\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetFormHeight\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetScreenWidth\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetScreenHeight\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetCellPixelSize\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern double ScopeGetCellSampleSize\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetPanelState\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern double ScopeGetAmpScale\n          (int ScopeHandle, int Beam);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern double ScopeGetAmpOffset\n          (int ScopeHandle, int Beam);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern double ScopeGetTriggerLevel\n          (int ScopeHandle, int Beam);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetTriggerSourse\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetActiveTriggerEdge\n          (int ScopeHandle);\n\n        [DllImport(Osc_DLL_path, CallingConvention = CallingConvention.Cdecl)]\n        private static extern int ScopeGetTrigHoldOffSmplsNum\n          (int ScopeHandle);\n\n        #endregion\n\n        // Property Control Constants (provided for convenience)\n        //\n        // Trigger Source Constants \n        public const int TRACE1_TRIG = 0, TRACE2_TRIG = 1, TRACE3_TRIG = 2, EXTERNAL_TRIG = 3;\n        //\n        // Trigger Type Constants\n        public const int FALLING_EDGE_TRIG = -1, RISING_EDGE_TRIG = 1, DISABLED_TRIG = 0;\n\n        /// <summary>\n        /// Error Constants\n        /// </summary>\n        public const int NO_ERROR = 0;\n        public const int SCOPE_CREATION_ERROR = 1;\n        public const int SCOPE_HANDLE_ERROR = 2;\n        public const int SCOPE_DISPOSED_ERROR = 3;\n        public const int LEFT_RANGE_ERROR = 4;\n        public const int TOP_RANGE_ERROR = 5;\n        public const int WIDTH_RANGE_ERROR = 6;\n        public const int HEIGHT_RANGE_ERROR = 7;\n        public const int CELLSIZE_RANGE_ERROR = 8;\n        public const int SAMPLESPERGRIDCELL_RANGE_ERROR = 9;\n        public const int CAPTIONSIZE_ERROR = 10;\n        public const int CELLAMPLITUDESCALE_RANGE_ERROR = 11;\n        public const int VERTICALOFFSET_RANGE_ERROR = 12;\n        public const int TRIGGERLEVEL_RANGE_ERROR = 13;\n        public const int TRIGGERSOURCE_RANGE_ERROR = 14;\n        public const int TRIGGERDELAY_RANGE_ERROR = 15;\n        public const int SCOPE_TRIGGERSOURCE_ERROR = 16;\n        public const int SCOPE_TRIGGEREDGE_ERROR = 17;\n        public const int SCOPE_NOT_VISIBLE = 18;\n\n        #region Static members\n        static bool initialized = false;\n\n        /// <summary>\n        /// Creates a new Oscilloscope. Returns the object if successful,\n        /// otherwise returns null. Generally, if it returns null then\n        /// it cannot find the correct DLL to load\n        /// </summary>\n        /// <returns>Oscilloscope instance</returns>\n        public static Oscilloscope CreateScope()\n        {\n            return CreateScope(\"NO_INI_FILE\", \"NON\");\n        }\n\n        /// <summary>\n        /// Creates a new Oscilloscope. Returns the object if successful,\n        /// otherwise returns null. Generally, if it returns null then\n        /// it cannot find the correct DLL to load\n        /// </summary>\n        /// <param name=\"IniName\">Name of INI file with scope settings</param>\n        /// <param name=\"IniSuffix\">Section name suffix (see manual)</param>\n        /// <returns>Oscilloscope instance</returns>\n        public static Oscilloscope CreateScope(string IniName, string IniSuffix)\n        {\n            int handle;\n\n            _Scope_Visible = false;\n            try\n            {\n                if (!initialized)\n                {\n                    // initialize\n                    if (AtOpenLib(0) == -1)\n                    {\n                        ShowError(SCOPE_CREATION_ERROR);\n                        return null;\n                    }\n                    // Set to true\n                    initialized = true;\n                }\n            }\n            catch\n            {\n                // Return the Error\n                ShowError(SCOPE_CREATION_ERROR);\n                return null;\n            }\n\n            // Create the Oscilloscope Instance\n            handle = ScopeCreate(0, new StringBuilder(IniName), new StringBuilder(IniSuffix));\n\n            if (handle != 0)\n            {\n                return new Oscilloscope(handle);\n            }\n            ShowError(SCOPE_CREATION_ERROR);\n            return null;\n        }\n\n        #endregion\n\n        private int scopeHandle;\n        private bool _disposed = false;\n\n        // Class Constructors\n        private Oscilloscope()\n        {\n        }\n\n        private Oscilloscope(int handle)\n        {\n            scopeHandle = handle;\n        }\n\n        // Class Destructor\n        ~Oscilloscope()\n        {\n            Dispose();\n        }\n\n        /// <summary>\n        /// Shows the scope.\n        /// </summary>\n        public void ShowScope()\n        {\n            if (!_disposed)\n            {\n                _Scope_Visible = true;\n                ScopeShow(scopeHandle);\n            }\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /// <summary>\n        /// Hides the scope from view\n        /// </summary>\n        public void HideScope()\n        {\n            if (!_disposed)\n            {\n                _Scope_Visible = false;\n                ScopeHide(scopeHandle);\n            }\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /// <summary>\n        /// Clears the buffer of the scope\n        /// </summary>\n        public void ClearScope()\n        {\n            if (!_disposed)\n                ScopeCleanBuffers(scopeHandle);\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /// <summary>\n        /// Add data to the scope traces.\n        /// </summary>\n        /// <param name=\"beam1\">Data for first beam</param>\n        /// <param name=\"beam2\">Data for second beam</param>\n        /// <param name=\"beam3\">Data for third beam</param>\n        public void AddScopeData(double beam1, double beam2, double beam3)\n        {\n            if (!_disposed)\n            {\n                double[] PArrDbl = new double[3];\n                PArrDbl[0] = beam1;\n                PArrDbl[1] = beam2;\n                PArrDbl[2] = beam3;\n\n                ShowNext(scopeHandle, PArrDbl);\n            }\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /// <summary>\n        /// Add data to the 'external' trigger function signal. This value is used\n        /// when TriggerSource == EXTERNAL_TRIG.\n        /// </summary>\n        /// <param name=\"data\">The data</param>\n        public void AddExternalScopeData(double data)\n        {\n            if (!_disposed)\n                ExternalNext(scopeHandle, ref data);\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /// <summary>\n        /// Quickly refreshes screen of oscilloscope. Calling this function is\n        /// not usually required. Recommended for using in situations when \n        /// intensive data stream is going into oscilloscope\n        /// </summary>\n        public void UpdateScope()\n        {\n            if (!_disposed)\n            {\n                QuickUpDate(scopeHandle);\n            }\n            else\n                ShowError(SCOPE_DISPOSED_ERROR);\n        }\n\n        /*****************************************\n        *                                        *\n        * C# wrapper for Oscilloscope Properties * \n        *                                        *\n        *****************************************/\n\n        private static bool _ErrorMessagesOn = true;\n        private static int _LastError = NO_ERROR;\n        private static bool _Scope_Visible = false;\n\n        /// <summary>\n        /// Property: LastError\n        /// \n        /// An application can check this to see if there has been an \n        /// error, even when error message displays are turned off. \n        /// If it is non-zero (!=NO_ERROR), there has been an error \n        /// and the value refers to one of the listed error constants.\n        /// \n        /// When setting LastError the value is ignored and LastError\n        /// is set to its defaul value, NO_ERROR. The application\n        /// should do this after finding an error value here, as it is \n        /// not done automatically; the error code value will persist \n        /// until it is manually reset.\n        ///\n        /// Value:   int, equal to one of the error constants\n        /// Access:  Read/Write (any write resets LastError to NO_ERROR\n        /// Default: 0 (NO_ERROR)\n        /// </summary>\n        public int LastError\n        {\n            set { _LastError = NO_ERROR; }\n            get { return _LastError; }\n        }\n\n        /// <summary>\n        /// Property: ErrorMessagesOn\n        /// \n        /// If ErrorMessagesOn is set to \"true\", a throw new Exception will appear \n        /// when there is an error. When debugging is completed it may be \n        /// desirable to set ErrorMessagesOn to \"false.\"\n        /// \n        /// Value:   bool\n        /// Access:  Read/Write\n        /// Default: true\n        /// </summary>\n        public bool ErrorMessagesOn\n        {\n            set { _ErrorMessagesOn = value; }\n            get { return _ErrorMessagesOn; }\n        }\n\n        /// <summary>\n        /// Property: ControlPanelVisible\n        ///\n        /// Displays or hides the control panel at the bottom of the \n        /// oscilloscope display\n        /// \n        /// Value:   bool\n        /// Access:  Read/Write\n        /// Default: true (also can be define in the intialization \n        ///          file, if used)\n        /// </summary>\n        public bool ControlPanelVisible\n        {\n            set\n            {\n                int Ret = 0;\n\n                if (!_disposed)\n                {\n                    if (value)\n                        Ret = ScopeSetPanelState(scopeHandle, 1);\n                    else\n                        Ret = ScopeSetPanelState(scopeHandle, 0);\n                    if (Ret != scopeHandle)\n                        ShowError(SCOPE_HANDLE_ERROR);\n                }\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n            }\n\n            get\n            {\n                if (!_disposed)\n                {\n                    if (ScopeGetPanelState(scopeHandle) == 1)\n                        return false;\n                    else\n                        return true;\n                }\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Property: Left\n        /// \n        /// Sets the horizontal position of the oscilloscope on the screen, \n        /// specified as the number of pixels from the left edge of the screen\n        /// to the left edge of the oscilloscope form.\n        ///\n        /// Value:   int, Range: 0-Current Screen Width\n        /// Access:  Read/Write    \n        /// Default: Somewhere on the Screen (also can be defined in the \n        ///          intialization file, if used)\n        /// </summary>\n        public int Left\n        {\n            set\n            {\n                int MonitorWidth, MonitorHeight;\n\n                GetMonitorDimensions(out MonitorWidth, out MonitorHeight);\n                if ((value < 0) || (value > MonitorWidth))\n                    ShowError(LEFT_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = 0, Top;\n\n                        Top = ScopeGetFormTop(scopeHandle);\n                        Ret = ScopeSetFormPos(scopeHandle, value, Top);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetFormLeft(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: Top\n        /// \n        /// Sets the vertical position of the oscilloscope on the screen, \n        /// specified as the number of pixels from the top edge of the screen\n        /// to the top edge of the oscilloscope form.\n        ///\n        /// Value:   int, Range: 0-Current Screen Height\n        /// Access:  Read/Write\n        /// Default: Somewhere on the Screen (also can be defined in \n        ///          the intialization file, if used)\n        /// </summary>\n        public int Top\n        {\n            set\n            {\n                int MonitorWidth, MonitorHeight;\n\n                GetMonitorDimensions(out MonitorWidth, out MonitorHeight);\n                if ((value < 0) || (value > MonitorHeight))\n                    ShowError(TOP_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = 0, Left;\n\n                        Left = ScopeGetFormLeft(scopeHandle);\n                        Ret = ScopeSetFormPos(scopeHandle, Left, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetFormTop(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: Width\n        /// \n        /// Sets the Width of the oscilloscope form in pixels.\n        ///\n        /// Value:   int, Range: 40-Current Screen Width\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public int Width\n        {\n            set\n            {\n                int MonitorWidth, MonitorHeight;\n\n                GetMonitorDimensions(out MonitorWidth, out MonitorHeight);\n                if ((value < 40) || (value > MonitorWidth))\n                    ShowError(WIDTH_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = 0, Height;\n\n                        Height = ScopeGetFormHeight(scopeHandle);\n                        Ret = ScopeSetFormSize(scopeHandle, value, Height);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetFormWidth(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: Height\n        /// \n        /// Sets the Height of the oscilloscope form in pixels.\n        ///\n        /// Value:   int, Range: 40-Current Screen Height\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public int Height\n        {\n            set\n            {\n                int MonitorWidth, MonitorHeight;\n\n                GetMonitorDimensions(out MonitorWidth, out MonitorHeight);\n                if ((value < 40) || (value > MonitorHeight))\n                    ShowError(HEIGHT_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = 0, Width;\n\n                        Width = ScopeGetFormWidth(scopeHandle);\n                        Ret = ScopeSetFormSize(scopeHandle, Width, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetFormHeight(scopeHandle);\n                else\n                    ShowError(SCOPE_HANDLE_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: CellSize\n        ///\n        /// Sets the size of a grid cell in pixels; sets both height\n        /// and width of cells to the single parameter setting.\n        ///\n        /// Value:   int, Range: 10-150\n        /// Access:  Read/Write\n        /// Default: 40 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public int CellSize\n        {\n            set\n            {\n                if ((value < 10) || (value > 150))\n                    ShowError(CELLSIZE_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetCellPixelSize(scopeHandle, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetCellPixelSize(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: SamplesPerGridCell\n        /// \n        /// Sets the number of samples per grid cell on the horizontal (time) axis.\n        /// The value will be adjusted to closest valid number (see the DLL \n        /// documentation).\n        /// \n        /// WARNING: if this setting is too low and the data stream is too fast\n        /// a buffer overrun can be caused, which will have no indicator other\n        /// than the DLL locking up.\n        /// \n        /// Value:   double, Range 0.10000-20,000\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public double SamplesPerGridCell\n        {\n            set\n            {\n                if ((value < 0.10000) || (value > 20000.00000))\n                    ShowError(SAMPLESPERGRIDCELL_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetCellSampleSize(scopeHandle, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetCellSampleSize(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: Caption\n        /// \n        /// Sets the caption at the top of the oscilloscope form.\n        /// \n        /// Value:   string, Range 0-250 characters\n        /// Access:  Write Only\n        /// Default: \"Oscilloscope\" (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public string Caption\n        {\n            set\n            {\n                if (value.Length > 250)\n                    ShowError(CAPTIONSIZE_ERROR);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetCaption(scopeHandle, new StringBuilder(value));\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Property: AmplitudeScale1\n        /// \n        /// Sets the Amplitude Scale of Trace 1's grid divisions, in binary steps/grid cell\n        /// The value will be adjusted to closest valid number (see the DLL documentation)\n        /// \n        /// Value:   double, Range: 0.00001-100,000.00000\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public double AmplitudeScale1\n        {\n            set\n            {\n                if ((value < 0.00001) || (value > 100000.00000))\n                    ShowError(CELLAMPLITUDESCALE_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpScale(scopeHandle, 0, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpScale(scopeHandle, 0);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: AmplitudeScale2\n        /// \n        /// Sets the Amplitude Scale Trace 2's grid divisions, in binary steps/grid cell\n        /// The value will be adjusted to closest valid number (see the DLL documentation)\n        /// \n        /// Value:   double, Range: 0.00001-100,000.00000\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public double AmplitudeScale2\n        {\n            set\n            {\n                if ((value < 0.00001) || (value > 100000.00000))\n                    ShowError(CELLAMPLITUDESCALE_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpScale(scopeHandle, 1, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpScale(scopeHandle, 1);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: AmplitudeScale3\n        /// \n        /// Sets the Amplitude Scale of Trace 3's grid divisions, in binary steps/grid cell\n        /// The value will be adjusted to closest valid number (see the DLL documentation)\n        /// \n        /// Value:   double, Range: 0.00001-100,000.00000\n        /// Access:  Read/Write\n        /// Default: (->fill this in) (also can be defined in the \n        ///          initialization file, if used)\n        /// </summary>\n        public double AmplitudeScale3\n        {\n            set\n            {\n                if ((value < 0.00001) || (value > 100000.00000))\n                    ShowError(CELLAMPLITUDESCALE_RANGE_ERROR, 0);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpScale(scopeHandle, 2, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpScale(scopeHandle, 2);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: VerticalOffset1\n        /// \n        /// Sets the Vertical Offset of Trace 1, in units of of Trace 1's\n        /// AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double VerticalOffset1\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(VERTICALOFFSET_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpOffset(scopeHandle, 0, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpOffset(scopeHandle, 0);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: VerticalOffset2\n        /// \n        /// Sets the Vertical Offset of Trace 2, in units of of Trace 2's\n        /// AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double VerticalOffset2\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(VERTICALOFFSET_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpOffset(scopeHandle, 1, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpOffset(scopeHandle, 1);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: VerticalOffset3\n        /// \n        /// Sets the Vertical Offset of Trace 3, in units of of Trace 3's\n        /// AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double VerticalOffset3\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(VERTICALOFFSET_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetAmpOffset(scopeHandle, 2, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetAmpOffset(scopeHandle, 2);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerLevel1\n        /// \n        /// Sets the Trigger Offset Trace 1, in units of Trace 1's AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double TriggerLevel1\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(TRIGGERLEVEL_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetTriggerLevel(scopeHandle, 0, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetTriggerLevel(scopeHandle, 0);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerLevel2\n        /// \n        /// Sets the Trigger Offset Trace 2, in units of Trace 2's AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double TriggerLevel2\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(TRIGGERLEVEL_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetTriggerLevel(scopeHandle, 1, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetTriggerLevel(scopeHandle, 1);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerLevel3\n        /// \n        /// Sets the Trigger Offset Trace 3, in units of Trace 3's AmplitudeScale.\n        /// \n        /// Value:   double, Range: -1,000,000.00000-+1,000,000.00000\n        /// Access:  Read/Write\n        /// Default: 0.00000 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public double TriggerLevel3\n        {\n            set\n            {\n                if ((value < -1000000.0000) || (value > 1000000.00000))\n                    ShowError(TRIGGERLEVEL_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetTriggerLevel(scopeHandle, 2, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetTriggerLevel(scopeHandle, 2);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0.00000;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerSource\n        /// \n        /// Sets the Oscilloscope's Trigger Source. The Constants TRACE1_TRIG,\n        /// TRACE2_TRIG, TRACE3_TRIG and EXTERNAL_TRIG are provided for conenience.\n        /// \n        /// Value:   int, Range 0-3 (TRACE1_TRIG-EXTERNAL_TRIG)\n        /// Access:  Read/Write\n        /// Default  TRACE1_TRIG (also can be defined in the initialization file, if used)\n        /// </summary>\n        public int TriggerSource\n        {\n            set\n            {\n                if (!_Scope_Visible)\n                    ShowError(SCOPE_NOT_VISIBLE);\n                else if ((value < TRACE1_TRIG) || (value > EXTERNAL_TRIG))\n                    ShowError(TRIGGERSOURCE_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        try\n                        {\n                            int Ret = ScopeSetTriggerSourse(scopeHandle, value);\n                            if (Ret != scopeHandle)\n                                ShowError(SCOPE_HANDLE_ERROR);\n                        }\n                        catch\n                        {\n                            ShowError(SCOPE_TRIGGERSOURCE_ERROR);\n                            Dispose();\n                        }\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetTriggerSourse(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerEdge\n        /// \n        /// Sets the Trigger Edge Detection Mode. Any valid negative int sets it \n        /// Negative Edge Triggered, any valid positive int sets it Positive Edge \n        /// Triggered, and 0 set it to disabled. The constants FALLING_EDGE_TRIG,\n        /// RISING_EDGE_TRIG and DISABLED_TRIG are provided for convenience.\n        /// \n        /// Value:   int, Range: see above\n        /// Access;  Read/Write\n        /// Default: DISABLED_TRIG (also can be defined in the initialization file, \n        ///          if used)\n        /// </summary>\n        public int TriggerEdge\n        {\n            set\n            {\n                if (!_Scope_Visible)\n                    ShowError(SCOPE_NOT_VISIBLE);\n                else if (!_disposed)\n                {\n                    int Edge;\n\n                    try\n                    {\n                        if (value < 0)\n                            Edge = -1;\n                        else if (value > 0)\n                            Edge = 1;\n                        else\n                            Edge = 0;\n                        int Ret = ScopeSetActiveTriggerEdge(scopeHandle, Edge);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    catch\n                    {\n                        ShowError(SCOPE_TRIGGEREDGE_ERROR);\n                        Dispose();\n                    }\n                }\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetActiveTriggerEdge(scopeHandle);\n                else\n                    ShowError(SCOPE_HANDLE_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: TriggerDelay\n        /// \n        /// Controls the Trigger Delay, in number of samples.\n        /// (see DLL Documentation)\n        /// \n        /// Value:   int, RangeL 0-Any valid positive int value\n        /// Access:  Read/Write\n        /// Default: 0 (also can be defined in the initialization file, if used)\n        /// </summary>\n        public int TriggerDelay\n        {\n            set\n            {\n                if (value < 0)\n                    ShowError(TRIGGERDELAY_RANGE_ERROR, value);\n                else\n                {\n                    if (!_disposed)\n                    {\n                        int Ret = ScopeSetTrigHoldOffSmplsNum(scopeHandle, value);\n                        if (Ret != scopeHandle)\n                            ShowError(SCOPE_HANDLE_ERROR);\n                    }\n                    else\n                        ShowError(SCOPE_DISPOSED_ERROR);\n                }\n            }\n\n            get\n            {\n                if (!_disposed)\n                    return ScopeGetTrigHoldOffSmplsNum(scopeHandle);\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: TraceDisplayWidth\n        /// \n        /// Returns the width of the current trace display area display in pixels.\n        /// \n        /// Value:   int\n        /// Access:  Read Only\n        /// Default: N/A\n        /// </summary>\n        public int TraceDisplayWidth\n        {\n            get\n            {\n                if (!_disposed)\n                    return (ScopeGetScreenWidth(scopeHandle));\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Property: TraceDisplayHeight\n        /// \n        /// Returns the height of the current trace display area in pixels.\n        /// \n        /// Value:   int\n        /// Access:  Read Only\n        /// Default: N/A\n        /// </summary>\n        public int TraceDisplayHeight\n        {\n            get\n            {\n                if (!_disposed)\n                    return (ScopeGetScreenHeight(scopeHandle));\n                else\n                    ShowError(SCOPE_DISPOSED_ERROR);\n                return 0;\n            }\n        }\n\n        /// <summary>\n        /// Method to Display Error Messages, overload for errors that have no associated\n        /// data (fundamental DLL communication errors, except for CAPTIONSIZE_ERROR). \n        /// </summary>\n        /// <param name=\"MessageNum\">int: Error Number</param>\n        private static void ShowError(int ErrorNum)\n        {\n            _LastError = ErrorNum;\n            if (_ErrorMessagesOn)\n            {\n                switch (ErrorNum)\n                {\n                    case SCOPE_CREATION_ERROR:\n                        throw new Exception(\"Oscilloscope Creation Failed.\");\n                    case SCOPE_HANDLE_ERROR:\n                        throw new Exception(\"Oscilloscope Access Failed.\");\n                    case SCOPE_DISPOSED_ERROR:\n                        throw new Exception(\"Oscilloscope has been Disposed.\");\n                    case CAPTIONSIZE_ERROR:\n                        throw new Exception(\"Caption Too Long.\");\n                    case SCOPE_TRIGGERSOURCE_ERROR:\n                        throw new Exception(\"The Oscilloscope threw a Set Trigger Source Exception and must be Closed.\");\n                    case SCOPE_TRIGGEREDGE_ERROR:\n                        throw new Exception(\"The Oscilloscope threw a Set Trigger Edge Exception and must be Closed.\");\n                    case SCOPE_NOT_VISIBLE:\n                        throw new Exception(\"This Property Cannot be Accessed when the Oscilloscope is in Hide Mode.\");\n                }\n            }\n        }\n\n        /// <summary>\n        /// Method to Display Error Messages, overload for range errors in property \n        /// that are type integer.\n        /// </summary>\n        /// <param name=\"MessageNum\">int: Error Number</param>\n        /// <param name=\"ErrorValue\">int: The Value That Caused the Error</param>\n        private static void ShowError(int ErrorNum, int ErrorValue)\n        {\n            _LastError = ErrorNum;\n            if (_ErrorMessagesOn)\n            {\n                switch (ErrorNum)\n                {\n                    case LEFT_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Left Out of Range: {0}.\", ErrorValue));\n                    case TOP_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Top Out Of Range: {0}.\", ErrorValue));\n                    case WIDTH_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Width Out of Range: {0}\", ErrorValue));\n                    case HEIGHT_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Height Out Of Range: {0}.\", ErrorValue));\n                    case CELLSIZE_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope CellSize Out of Range: {0}.\", ErrorValue));\n                    case TRIGGERSOURCE_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Trigger Source Out of Range: {0}.\", ErrorValue));\n                    case TRIGGERDELAY_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope Trigger Delay Out of Range: {0}.\", ErrorValue));\n\n                }\n            }\n        }\n\n        /// <summary>\n        /// Method to Display Error Messages, overload for range errors in properties \n        /// that are type double.\n        /// </summary>\n        /// <param name=\"MessageNum\">int: Error Number</param>\n        /// <param name=\"ErrorValue\">double: The Value That Caused the Error</param>\n        private static void ShowError(int ErrorNum, double ErrorValue)\n        {\n            _LastError = ErrorNum;\n            if (_ErrorMessagesOn)\n            {\n                switch (ErrorNum)\n                {\n                    case SAMPLESPERGRIDCELL_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope SamplesPerGridCell Out of Range: {0}\", ErrorValue));\n                    case CELLAMPLITUDESCALE_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Scope CellAmplitideScale Out of Range: {0}\", ErrorValue));\n                    case VERTICALOFFSET_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Vertical Offset Out of Range: {0}\", ErrorValue));\n                    case TRIGGERLEVEL_RANGE_ERROR:\n                        throw new Exception(string.Format(\"Trigger Level Out of Range: {0}\", ErrorValue));\n                }\n            }\n        }\n\n        public static void GetMonitorDimensions(out int Width, out int Height)\n        {\n            Size Monitor = SystemInformation.PrimaryMonitorSize;\n            Width = Monitor.Width;\n            Height = Monitor.Height;\n        }\n\n        #region IDisposable Members\n\n        /// <summary>\n        /// Dispose the object - call this to release the oscilloscope resources.\n        /// </summary>\n        public void Dispose()\n        {\n            if (!_disposed)\n            {\n                ScopeDestroy(scopeHandle);\n                _disposed = true;\n            }\n        }\n\n        /// <summary>\n        /// Flag indicating if the object is already disposed.\n        /// /// </summary>\n        public bool IsDisposed\n        {\n            get\n            {\n                return _disposed;\n            }\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Oscilloscope/Oscilloscope_settings.ini",
    "content": "[Oscilloscope]\nOscVrulFontName=Arial\nOscVrulFontSize=8\nOscVrulFontStyleBold=0\nOscVrulFontStyleItalic=0\nOscBackColor=00222222\nOscGridColor=00404040\nOscHorScaleColor=00FFFFFF\nOscBeam0Color=000000FF\nOscBeam1Color=0000FF00\nOscBeam2Color=00FF0000\nOscVrulGenFontColor=00FFFFFF\nOscZeroLineColor=00FFFFFF\nOscOscCaption=Oscilloscope\nShowSecondBeam=1\nShowThirdBeam=1\nShowTestButton=0\nBuffersRecordType=1\nCreateSecondBeam=1\nCreateThirdBeam=1\nSpreadViewTiming=1\nEventsProcDivider=0\nGridRefreshDivider=50\nGridCellPixelsSize=15\nTriggerEnable=0\nTriggerSource=0\nFirstTriggerLevel=0.0000000000\nSecondTriggerLevel=0.0000000000\nThirdTriggerLevel=0.0000000000\nExtrnTriggerLevel=0.0000000000\nTimeSamplesPerCell=20.0000000000\nBeam0VertScale=10.0000000000\nBeam1VertScale=10.0000000000\nBeam2VertScale=10.0000000000\nBeam0VertOffset=0.0000000000\nBeam1VertOffset=0.0000000000\nBeam2VertOffset=0.0000000000\nScopeFormHeight=400\nScopeFormWidth=600\nScopeStayOnTop=0\nShowTriggerControls=1\nShowOscJaggies=0\nShowOscHexVal=0\nShowHexCheckBox=0\nScopeShowAutoSweep=0\nScopeAutoSweep=0\nScopeAutoSweepDivider=4\nScopeShowHints=1\nProducer_Vendor_Name=+972 507669424 Michael Bernstein, E_Mail: brnstin@cheerful.com\nBfrSmplSize=32000\nScopeInputDumpSize=32000\nScopePolylineOptimize=0\n[Miscellaneous]\nReadDelayPerSample=0\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace Serial_Oscilloscope\n{\n    static class Program\n    {\n        /// <summary>\n        /// The main entry point for the application.\n        /// </summary>\n        [STAThread]\n        static void Main()\n        {\n            Application.EnableVisualStyles();\n            Application.SetCompatibleTextRenderingDefault(false);\n            Application.Run(new FormTerminal());\n        }\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Serial Oscilloscope\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"x-io Technologies Limited\")]\n[assembly: AssemblyProduct(\"Serial Oscilloscope\")]\n[assembly: AssemblyCopyright(\"Copyright © x-io Technologies Limited 2013\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"dd5e52ed-ab85-46f6-a820-4d740c7456af\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.5.*\")]\n//[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.17929\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Serial_Oscilloscope.Properties\n{\n\n\n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources\n    {\n\n        private static global::System.Resources.ResourceManager resourceMan;\n\n        private static global::System.Globalization.CultureInfo resourceCulture;\n\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources()\n        {\n        }\n\n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager\n        {\n            get\n            {\n                if ((resourceMan == null))\n                {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Serial_Oscilloscope.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n\n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture\n        {\n            get\n            {\n                return resourceCulture;\n            }\n            set\n            {\n                resourceCulture = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.17929\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Serial_Oscilloscope.Properties\n{\n\n\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"10.0.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase\n    {\n\n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n\n        public static Settings Default\n        {\n            get\n            {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>\n"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/SampleCounter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Serial_Oscilloscope\n{\n    /// <summary>\n    /// Sample counter. Tracks number of packets received and packet rate.\n    /// </summary>\n    class SampleCounter\n    {\n        /// <summary>\n        /// Timer to calculate packet rate.\n        /// </summary>\n        private System.Windows.Forms.Timer timer;\n\n        /// <summary>\n        /// Number of packets received.\n        /// </summary>\n        public int SamplesReceived { get; private set; }\n\n        /// <summary>\n        /// Sample receive rate as packets per second.\n        /// </summary>\n        public int SampleRate { get; private set; }\n\n        /// <summary>\n        /// Variable used to calculate packet rate.\n        /// </summary>\n        private int prevSamplesReceived;\n\n        /// <summary>\n        /// Constructor.\n        /// </summary>\n        public SampleCounter()\n        {\n            // Initialise variables\n            prevSamplesReceived = 0;\n            SamplesReceived = 0;\n\n            // Setup timer\n            timer = new System.Windows.Forms.Timer();\n            timer.Interval = 1000;\n            timer.Tick += new EventHandler(timer_Tick);\n            timer.Start();\n        }\n\n        /// <summary>\n        /// Increments packet counter.\n        /// </summary>\n        public void Increment()\n        {\n            SamplesReceived++;\n        }\n\n        // Zeros packet counter.\n        public void Reset()\n        {\n            prevSamplesReceived = 0;\n            SamplesReceived = 0;\n            SampleRate = 0;\n        }\n\n        /// <summary>\n        /// timer Tick event to calculate packet rate.\n        /// </summary>\n        void timer_Tick(object sender, EventArgs e)\n        {\n            SampleRate = SamplesReceived - prevSamplesReceived;\n            prevSamplesReceived = SamplesReceived;\n        }\n    }\n}"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/Serial Oscilloscope.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">x86</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{37F93890-5296-4350-8F67-28BCC26CD6F2}</ProjectGuid>\n    <OutputType>WinExe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Serial_Oscilloscope</RootNamespace>\n    <AssemblyName>Serial Oscilloscope</AssemblyName>\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|x86' \">\n    <PlatformTarget>x86</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|x86' \">\n    <PlatformTarget>x86</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Deployment\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.Windows.Forms\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"CsvFileWriter.cs\" />\n    <Compile Include=\"FormGetValue.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"FormGetValue.designer.cs\">\n      <DependentUpon>FormGetValue.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"FormTerminal.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"FormTerminal.Designer.cs\">\n      <DependentUpon>FormTerminal.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Oscilloscope\\Oscilloscope.cs\" />\n    <Compile Include=\"SampleCounter.cs\" />\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"TextBoxBuffer.cs\" />\n    <EmbeddedResource Include=\"FormGetValue.resx\">\n      <DependentUpon>FormGetValue.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"FormTerminal.resx\">\n      <DependentUpon>FormTerminal.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n    </Compile>\n    <Content Include=\"Oscilloscope\\Oscilloscope_settings.ini\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n    <None Include=\"Properties\\Settings.settings\">\n      <Generator>SettingsSingleFileGenerator</Generator>\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\n    </None>\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Settings.settings</DependentUpon>\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"Oscilloscope\\Osc_DLL.dll\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/TextBoxBuffer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Serial_Oscilloscope\n{\n    /// <summary>\n    /// TextBox FIFO buffer.\n    /// </summary>\n    class TextBoxBuffer\n    {\n        /// <summary>\n        /// Size of buffer in bytes.\n        /// </summary>\n        private int size;\n\n        /// <summary>\n        /// Buffer array.\n        /// </summary>\n        private char[] buffer;\n\n        /// <summary>\n        /// Buffer in position index.\n        /// </summary>\n        private int inPos = 0;\n\n        /// <summary>\n        /// Buffer out position index.\n        /// </summary>\n        private int outPos = 0;\n\n        /// <summary>\n        /// Constructor.\n        /// </summary>\n        /// <param name=\"size\">\n        /// Size of buffer.\n        /// </param>\n        public TextBoxBuffer(int size)\n        {\n            this.size = size;\n            buffer = new char[this.size];\n        }\n\n        /// <summary>\n        /// Returns value indicating if buffer is empty.\n        /// </summary>\n        /// <returns>\n        /// Value indicating if buffer is empty.\n        /// </returns>\n        public bool IsEmpty()\n        {\n            return inPos == outPos;\n        }\n\n        /// <summary>\n        /// Adds string to buffer.\n        /// </summary>\n        /// <param name=\"str\">\n        /// String to add to buffer.\n        /// </param>\n        public void Put(string str)\n        {\n            foreach (char c in str)\n            {\n                buffer[inPos] = c;\n                if (++inPos == size - 1)\n                {\n                    inPos = 0;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Gets buffer contents.\n        /// </summary>\n        /// <returns>\n        /// Buffer contents.\n        /// </returns>\n        public string Get()\n        {\n            string str = \"\";\n            while (inPos != outPos)\n            {\n                str += buffer[outPos];\n                if (++outPos == size - 1)\n                {\n                    outPos = 0;\n                }\n            }\n            return str;\n        }\n\n        /// <summary>\n        /// Clears buffer.\n        /// </summary>\n        public void Clear()\n        {\n            inPos = 0;\n            outPos = 0;\n        }\n    }\n}"
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope/VisualStudio_CleanUp.bat",
    "content": "@echo off\n\nREM Remove files generated by compiler in this directory and all subdirectories.\nREM Essential release files are kept.\n\necho Removing \"*.csproj.user\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.csproj.user\"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.exe.config\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.exe.config\"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.vshost.exe.config\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.vshost.exe.config\"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.pdb\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.pdb\"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.vshost.application\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.vshost.application\"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.vshost.exe\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.vshost.exe \"') do del \"%%i\" /f /q\necho.\n\necho Removing \"*.vshost.exe.manifest\" files...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*.vshost.exe.manifest \"') do del \"%%i\" /f /q\necho.\n\necho Removing \"obj\" directory...\nrd \"%~p0obj\" /s /q\necho.\n\necho Removing \"Debug\" directories recursively...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*Debug\"') do if \"%%~ni\"==\"Debug\" rd \"%%i\" /s /q\necho.\n\necho Removing \"app.publish\" directories recursively...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*app.publish\"') do rd \"%%i\" /s /q\necho.\n\necho Removing \"*_mcr\" directories recursively...\nfor /f \"delims==\" %%i in ('dir /b /on /s \"%~p0*_mcr\"') do rd \"%%i\" /s /q\necho.\n\necho \"%~n0.bat\" done."
  },
  {
    "path": "Serial Oscilloscope/Serial Oscilloscope.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Serial Oscilloscope\", \"Serial Oscilloscope\\Serial Oscilloscope.csproj\", \"{37F93890-5296-4350-8F67-28BCC26CD6F2}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{37F93890-5296-4350-8F67-28BCC26CD6F2}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{37F93890-5296-4350-8F67-28BCC26CD6F2}.Debug|x86.Build.0 = Debug|x86\n\t\t{37F93890-5296-4350-8F67-28BCC26CD6F2}.Release|x86.ActiveCfg = Release|x86\n\t\t{37F93890-5296-4350-8F67-28BCC26CD6F2}.Release|x86.Build.0 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  }
]