/// <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, cancel and change the UI ShowWarningBox(string.Format(Language.ConnectionErrorText, portName, error.Message), Language.ConnectionErrorTitle); ChangeUI(false); return; } // Change the UI ChangeUI(true); // Bootstrap the timer isTimerRunning = true; UpdateTimer(); }
private bool AcquisitionCallback() { // Make sure that the state and meter objects are valid if (!isConnected || meter == null || !meter.IsConnected) { // Disconnect and return, if not Disconnect(); return(false); } // Handle pause mode if (isPaused) { // Discard the samples, start the timer again and continue meter.Flush(); return(isTimerRunning); } // Check, if the maximum duration of missed screen updates has been exceeded if ((blankCount - 1) * timerInterval >= 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 (requires ending the current one) if (isTimerUpdatePending) { UpdateTimer(); return(false); } // Read all available packets while (meter.IsAvailable) { Packet sample; if (!meter.Receive(out sample)) { // Update the blank screen count blankCount++; // And turn the sampling on again return(isTimerRunning); } // Skip invalid packets if (!sample.ChecksumValid) { continue; } // 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; } // 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(); // Continue and skip the rest continue; } 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) { bargraphBar.Adjustment.Lower = 0; bargraphBar.Adjustment.Upper = sample.Value < 0 ? Math.Abs(Multimeter.RangeMin(sample.Mode, sample.Range)) : Multimeter.RangeMax(sample.Mode, sample.Range); bargraphBar.Adjustment.Value = Math.Abs(sample.Value); } // 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.: 4.32,12.34E-3,V // Start 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 return(isTimerRunning); }