예제 #1
0
        /// <summary>
        /// Establish a connection to the DMM.
        /// </summary>
        /// <param name="portName">The name of the serial port to use.</param>
        private void Connect(string portName)
        {
            // Validate the port name
            if (string.IsNullOrWhiteSpace(portName))
            {
                return;
            }

            // Initialize the multimeter object
            meter = new Multimeter(portName);

            // Set the alive flag and clear the blank counter
            isAlive    = true;
            blankCount = 0;

            // Try to establish the connection
            Exception error = meter.Connect();

            if (error != null)
            {
                // If there was any error, exit, as there is no recovery from this
                MessageBox.Show(string.Format(Language.ConnectionErrorText, portName, error.Message),
                                Language.ConnectionErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                ChangeUI(false);
                return;
            }

            // Change the UI
            ChangeUI(true);

            // Start the timer
            acquisitionTimer.Start();
        }
예제 #2
0
        private void acquisitionTimer_Tick(object sender, EventArgs e)
        {
            // Make sure that the state and meter objects are valid
            if (!isConnected || meter == null || !meter.IsConnected)
            {
                // Disconnect and return, if not
                Disconnect();
                return;
            }

            // Stop the timer
            acquisitionTimer.Stop();

            // Handle pause mode
            if (isPaused)
            {
                // Discard the samples, start the timer again and continue
                meter.Flush();
                acquisitionTimer.Start();
                return;
            }

            // Check, if the maximum duration of missed screen updates has been exceeded
            if ((blankCount - 1) * acquisitionTimer.Interval >= 1000)
            {
                // Clear the readout, bargraph and alive flag after a certain number of missed updates
                isAlive = false;
                UpdateStatusLabels();
                ClearReadout();
                ClearBargraph();
            }

            // Always update the blank count (it will be reset if there was a successful update)
            blankCount++;

            // Handle pending timer updates
            if (isTimerUpdatePending)
            {
                UpdateTimer();
            }

            // Read all available packets
            Packet sample  = new Packet();
            bool   success = false;

            while (meter.IsAvailable)
            {
                if (!meter.Receive(out sample))
                {
                    // Update the blank screen count
                    blankCount++;

                    // And turn the sampling on again
                    acquisitionTimer.Start();
                    return;
                }

                // Skip invalid packets
                if (!sample.ChecksumValid)
                {
                    continue;
                }

                // Set the success flag
                success = true;
            }

            // Check, if the reception was successful
            if (!success)
            {
                // Start the timer again
                acquisitionTimer.Start();
                return;
            }

            // Clear the blank screen count and set the alive flag after a successful reception
            blankCount = 0;
            if (!isAlive)
            {
                isAlive = true;
                UpdateStatusLabels();
            }

            // Handle regular display
            // Set the mode label accordingly first
            bool validMode = true;
            bool valueMode = true;

            switch (sample.Mode)
            {
            case Mode.Ampere:
                modeLabel.Text = Language.ModeCurrent;
                break;

            case Mode.AmpereMicro:
                modeLabel.Text = Language.ModeCurrent;
                break;

            case Mode.AmpereMilli:
                modeLabel.Text = Language.ModeCurrent;
                break;

            case Mode.ContinuityOhm:
                modeLabel.Text = Language.ModeContinuity;
                break;

            case Mode.DiodeVolt:
                modeLabel.Text = Language.ModeDiode;
                break;

            case Mode.ResistanceOhm:
                modeLabel.Text = Language.ModeResistance;
                break;

            case Mode.VoltAC:
                modeLabel.Text = Language.ModeVoltageAC;
                break;

            case Mode.VoltDC:
                modeLabel.Text = Language.ModeVoltageDC;
                break;

            case Mode.Squarewave:
                modeLabel.Text = Language.ModeSquarewave;
                valueMode      = false;
                break;

            default:
                modeLabel.Text = Language.ModeUnknown;
                valueMode      = false;
                validMode      = false;
                break;
            }

            // Compare the last range with the current one
            if (lastMode != sample.Mode)
            {
                ClearStatistics();
                lastMode = sample.Mode;
            }

            // Allocate variables for the number parsing
            bool negative = false;
            int  integer = 0, fractional = 0, exponent = 0, precision = 0;
            char unit = '\0', unitPrefix = '\0';

            // Attempt to parse the number
            if (validMode && valueMode)
            {
                validMode = Multimeter.Parse(sample, out negative, out integer, out fractional, out exponent, out precision, out unit, out unitPrefix);
            }

            // Check, if the mode is invalid or that the number is OL
            bool overloaded = Multimeter.IsOverloaded(sample);

            if (overloaded && valueMode) // Overload
            {
                // Update the value and unit labels
                valueLabel.Text = "OL";
                unitLabel.Text  = unit.ToString();

                // Fill the bargraph
                FillBargraph();
            }
            else if (!validMode || !valueMode)
            {
                // No valid mode
                valueLabel.Text = "";
                unitLabel.Text  = "";

                // Clear the bargraph
                ClearBargraph();

                // Cancel and skip the rest
                acquisitionTimer.Start();
                return;
            }
            else
            {
                // Just format the value according to the precision
                valueLabel.Text = precision < 1 ? integer.ToString() :
                                  string.Format("{0}{1}.{2:D" + precision.ToString() + "}", negative ? "-" : "", integer, fractional);
                // Also update the unit label
                unitLabel.Text = unitPrefix == '\0' ? unit.ToString() : string.Format("{0}{1}", unitPrefix, unit);
            }

            // Update the UI
            if (!overloaded)
            {
                // Update the bargraph
                bargraphBar.Minimum = 0;
                bargraphBar.Maximum = sample.Value < 0 ? Math.Abs(Multimeter.RangeMin(sample.Mode, sample.Range)) : Multimeter.RangeMax(sample.Mode, sample.Range);
                bargraphBar.Value   = Math.Abs(sample.Value);

                // Calculate the double value
                double currentValue = Math.Pow(10, exponent) * (integer + (fractional * Math.Pow(10, -precision)));
                if (negative)
                {
                    currentValue = -currentValue;
                }

                // Update the min statistics
                if (resetStatistics || minValue > currentValue)
                {
                    minValue           = currentValue;
                    minValueLabel.Text = valueLabel.Text + unitLabel.Text;
                }

                // Update the max statistics
                if (resetStatistics || maxValue < currentValue)
                {
                    maxValue           = currentValue;
                    maxValueLabel.Text = valueLabel.Text + unitLabel.Text;
                }

                // Unset the statistics flag
                if (resetStatistics)
                {
                    resetStatistics = false;
                }
            }

            // Handle record mode only for valid value modes
            if (isRecording)
            {
                // Calculate the offset in seconds
                TimeSpan delta = sample.ReceptionTime - recordingStart;

                // Assemble the line, e.g.: 2022/04/29 10:25:03,4.32,12.34E-3,V
                // Start with date and time
                recordingBuffer.AppendFormat("{0} {1}", sample.ReceptionTime.ToLongDateString(), sample.ReceptionTime.ToLongTimeString());
                // Followed by the delimiter
                recordingBuffer.Append(GetCSVDelimiter());
                // Continue with the time offset
                recordingBuffer.AppendFormat(new NumberFormatInfo()
                {
                    NumberDecimalSeparator = GetCSVFractionalSeparator().ToString(), NumberDecimalDigits = 2
                },
                                             "{0:E}", delta.TotalSeconds);
                // Followed by the delimiter
                recordingBuffer.Append(GetCSVDelimiter());
                // Followed by the value
                if (overloaded) // Overload
                {
                    recordingBuffer.Append("OL");
                }
                else if (precision < 1) // Integer value
                {
                    recordingBuffer.AppendFormat("{0}E{1}", integer, exponent);
                }
                else // Fixed point value
                {
                    recordingBuffer.AppendFormat("{0}{1}{2}{3:D" + precision.ToString() + "}E{4}", negative ? "-" : "", integer,
                                                 GetCSVFractionalSeparator(), fractional, exponent);
                }
                // Followed by the delimiter
                recordingBuffer.Append(GetCSVDelimiter());
                // Followed by the unit
                recordingBuffer.Append(unit);
                // And a final line break
                recordingBuffer.AppendLine();

                // Update the running for label and increment the sample counter
                recordingCount++;
                UpdateStatusLabels();
            }

            // Start the timer again
            acquisitionTimer.Start();
        }