Obsidean_VM/01-Documentation/Dispositivos - Manuales/Maselli/Maselli - Utility/Instrument Communication Se...

10 KiB

Instrument Communication Service

This document describes the Instrument Communication Service, a core component of the software responsible for managing all aspects of communication with connected Maselli instruments. The primary class implementing this service is Uc09_Utility.ClassSerialeStrumenti.

1. Overview and Purpose

The Instrument Communication Service acts as a central hub for bi-directional data exchange between the software application and one or more Maselli instruments. Its main purpose is to abstract the complexities of low-level communication protocols and hardware interfaces, providing a consistent way for other parts of the application to interact with instruments.

Key Responsibilities:

  • Multi-Instrument Management: Handles communication with multiple instruments, potentially on different lines or addresses.
  • Command Queuing and Dispatch: Manages a queue of commands to be sent to instruments, ensuring orderly and timely execution.
  • Protocol Implementation: Encodes outgoing commands and decodes incoming responses according to the Maselli Proprietary Serial/Socket Protocol.
  • Transport Layer Abstraction: Supports communication over both direct serial (RS-232/RS-485) connections and TCP/IP sockets (Ethernet Bridge).
  • Instrument Lifecycle Management: Handles instrument detection, recognition, initialization, active communication, and graceful disconnection.
  • Data Synchronization: Updates shared data structures (e.g., UtilityMaselli.Variabili) with values read from instruments.
  • Event Notification: Provides callbacks or events for significant communication occurrences (e.g., data received, protocol change).
  • Error Handling and Logging: Detects communication errors, retries commands, and logs relevant information.

2. Core Class: Uc09_Utility.ClassSerialeStrumenti

This class is the heart of the Instrument Communication Service.

Key Internal Components and Mechanisms:

  • Instrument Registry (ListaStrumenti):

    • A list (List<ClassStrumentoMaselli>) that holds instances of all instruments the service is configured to manage.
    • Each ClassStrumentoMaselli object contains instrument-specific details like address, function numbers, and communication state (InstrumentSerial).
  • Command Queue (QueueComandiSeriali):

    • A thread-safe queue (ConcurrentQueue<ComandoSeriale>) that stores commands submitted from various parts of the application.
    • Commands are processed in a FIFO (First-In, First-Out) manner, though the service prioritizes commands for instruments that are actively communicating.
  • Main Processing Loop (driven by _timerSerialeUtility):

    • A System.Timers.Timer periodically triggers the main logic of the service.
    • This loop iterates through the ListaStrumenti, processing each instrument based on its current communication phase (InstrumentSerial.FaseComunicazione).
    • It handles sending commands from the queue, managing timeouts, processing received data, and transitioning instruments through different communication states.
  • Physical Communication Layer:

    • Serial Port (_serialPortUtility): An instance of System.IO.Ports.SerialPort used for direct serial communication. Configured based on settings in UtilityMaselli.Setup (COM port, baud rate, etc.).
    • Socket Communication (_maselliSocketUtility): An instance of MaselliSocket.ClassMaselliSocket used when the Ethernet bridge is enabled (UtilityMaselli.Setup.EnableEthernetBridge). This class encapsulates TCP/IP client socket operations.
    • The service seamlessly switches between these layers based on configuration.
  • Protocol Encoding/Decoding Engine:

    • PreparaComando(): Constructs the full command string according to the Maselli protocol, including address, command type, function number, value, length, and checksum.
    • CalcolaChecksum(): Calculates the checksum for outgoing commands.
    • GestioneComandoRicevuto(): The primary method for parsing incoming responses. It checks for protocol errors (e.g., NOxx), identifies response types (data, image, acknowledgment), and routes data for further processing.
    • DecoderProtocolloMaselli(): Extracts values from standard data responses (!VALUE) and updates the corresponding ClassVariabile objects in UtilityMaselli.Variabili.
    • DecodificaImmagine(): Handles the more complex task of parsing and assembling image data received from instruments.
  • Communication State Machine (InstrumentSerial.FaseComunicazione):

    • Each instrument managed by the service has an associated communication phase. The service transitions instruments through these phases:
      • Initial connection attempts.
      • Sending "super commands" for recognition or protocol forcing.
      • Instrument recognition (matching response with Identifier.RecognizingStrings).
      • Sending instrument-specific startup commands.
      • LINKED state for active data exchange.
      • Handling image requests and multi-part responses.
      • Closing communication and sending exit commands.
  • Error Handling and Retries:

    • The service checks for protocol errors (NOxx) in responses.
    • Commands can have a retry count (ComandoSeriale.NumeroRipetizioni). If a command fails (timeout or error response), it can be re-queued for a limited number of retries.
    • The CommunicationHandlerLoggerService (an implementation of ILoggerService) is used to log communication errors and significant events.

3. Service Operations and Flow

3.1. Initialization and Instrument Addition

  1. The ClassSerialeStrumenti service is typically initialized once at application startup.
  2. Instruments (instances of ClassStrumentoMaselli derivatives) are added to the service using the AddStrumento() method. This registers them for management.
  3. The service attempts to open the configured communication port (serial or socket) via ApriPortaComunicazione().

3.2. Submitting Commands

  1. Other parts of the application (e.g., UI event handlers, automated processes) submit commands to instruments by calling InserisciComandoSeriale().
  2. This method populates a ComandoSeriale object with the necessary details (instrument address, command type, function number, value, etc.) and adds it to the QueueComandiSeriali.

3.3. Command Processing Cycle (Timer Tick)

  1. The _timerSerialeUtility_Elapsed event handler executes periodically.
  2. Command Sending:
    • The service checks if the communication line is free (_statoComunicazione == StatiComunicazione.LIBERO).
    • It iterates through ListaStrumenti. For each instrument, it checks its FaseComunicazione.
    • If an instrument is in a state to send commands (e.g., SEND_SUPER_COMMAND_RECOGNIZE_EQUIPMENT, LINKED), the service dequeues the next relevant command (either a special command or from QueueComandiSeriali).
    • The command is formatted using PreparaComando().
    • The formatted command is sent via _serialPortUtility.Write() or _maselliSocketUtility.Send().
    • The service transitions to a WAIT_RX state and sets a timeout for the response.
  3. Response Handling:
    • Data received on the serial port (_serialPortUtility_DataReceived) or socket (_maselliSocketUtility.eventoResponseEthBridge) triggers processing.
    • The received data is passed to GestioneComandoRicevuto().
    • This method parses the response, checks for errors, and determines the response type.
    • If it's a data response, DecoderProtocolloMaselli() updates the global UtilityMaselli.Variabili.
    • If it's an image response, DecodificaImmagine() processes the image data.
    • The command status (ComandoSeriale.Stato) is updated (e.g., OK_COMMAND, ERROR_COMMAND).
    • Relevant callbacks/events like ReceiveCallback or ModifiedReceived are invoked.
  4. State Transitions:
    • Based on successful command execution or received data, the instrument's FaseComunicazione is updated (e.g., from RECOGNIZE_EQUIPMENT to SEND_STARTUP_COMMANDS, then to LINKED).

3.4. Instrument Recognition

  • During initial phases, the service sends "super commands" (e.g., requesting instrument memory name).
  • The response is compared against Identifier.RecognizingStrings for each configured instrument.
  • Once a match is found, Identifier.EquipmentRecognized is set to true, and the instrument model may be further refined (e.g., differentiating UC07 from UC08 based on the memory name).
  • The ProtocolChangedToMaselli event can be raised if the instrument confirms it's in Maselli mode.

3.5. Data Synchronization

  • When DecoderProtocolloMaselli() successfully parses a response to a read command (V), it finds the corresponding ClassVariabile in UtilityMaselli.Variabili (based on instrument and function number) and updates its Valore property.
  • This makes the latest instrument data available to the rest of the application.

4. Interaction with Other System Components

  • UtilityMaselli.Setup: Provides configuration parameters for the communication channel (port, speed, bridge settings).
  • UtilityMaselli.Variabili: The global list of ClassVariabile objects that this service reads from (for "M" commands, using the current value in the variable if not explicitly provided in ComandoSeriale) and writes to (after "V" commands).
  • ClassStrumentoMaselli (and derivatives): Provide instrument-specific information like address, function number definitions, startup/exit commands, and recognizing strings.
  • Application Logic/UI: Submits commands via InserisciComandoSeriale() and consumes data from UtilityMaselli.Variabili. Listens to events from the service for UI updates.
  • MaselliSocket.ClassMaselliSocket: Used as the transport layer when Ethernet bridge is active.
  • CommunicationHandlerLoggerService: Used for logging errors and important communication events.

5. Service Robustness

  • Timeouts: Manages timeouts for responses to prevent indefinite blocking.
  • Retries: Failed commands can be retried a configurable number of times.
  • Checksums: Validates command integrity for serial transmission.
  • Error Logging: Provides diagnostic information for troubleshooting.
  • Concurrent Queue: Ensures thread-safe command submission.

The Instrument Communication Service is thus a critical and complex component, orchestrating the entire flow of information between the software and the physical Maselli instruments.