Porta seriale1 smette di ricevere se invii a porta seriale2

di il
5 risposte

Porta seriale1 smette di ricevere se invii a porta seriale2

Dispongo di un programma che per leggere dei sensori esterni collegati su porta seriale invia dei comandi e riceve le risposte su prima porta seriale 'comport'

Poi una volta elaborate le risposte ricevute dai sensori, deve inviare dei dati su una seconda porta seriale, nel codice identificata come 'comportUser'

Lato prima porta seriale funziona tutto correttamente, il comando parte, la risposta arriva, ed elaborazione avviene correttamente

Lato seconda porta seriale invece c'e' un problema serio che impedisce al software di funzionare correttamente

Quando invio caratteri sulla porta 'comportUser' (la seconda porta seriale)  poi la ricezione sulla prima porta seriale, su 'comport', non avviene piu'

Nel senso che non vengono piu' rilevati i caratteri che fisicamente arrivano sulla prima porta seriale

In sostanza il codice non entra piu' nella routine  port_DataReceived   che e' la routine destinata alla ricezione caratteri dalla prima porta seriale

Ricapitolando, anche con prima porta seriale aperta, con caratteri che fisicamente arrivano sulla prima porta seriale,  nella routine port_DataReceived   il codice non ci entra  piu' e questo ad iniziare dal momento che invio caratteri sulla seconda porta seriale

E quindi una qualche interferenza deve esserci tra le due

Ho gia' provato da codice, dopo aver inviato caratteri su seconda porta seriale a disattivare e riattivare evento ricezione su prima porta, ma non funziona, i caratteri arrivano fisicamente sulla porta seriale ma da codice non si vedono

Da cosa potrebbe dipendere la disabilitazione in ricezione della prima porta seriale?

using System;
using System.Data;
using System.Text;
using System.Drawing;
using System.IO.Ports;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;

using Test1.Properties;

namespace Test1
{
    public enum DataMode { Text, Hex }
    public enum DataModeUser { Text, Hex }

    public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };

    public partial class frmTerminal : Form
    {
        // Local Variables
        public int sensore_attuale = 1;

        public int caratteri_ricevuti_da_sensore = 0;
        public byte[] buffer_ricezione_comandi = new byte[2000]; // Array byte per buffer ricezione rs485 da sensori

        public float valore_sensore1_Z = 0;
        public float valore_sensore2_X = 0;
        public float valore_sensore3_X = 0;
        public float valore_sensore4_X = 0;
        public float valore_sensore5_X = 0;
        public float valore_sensore5_Y = 0;

        // The main control for communicating through the RS-232 port
        private SerialPort comport = new SerialPort();
        private SerialPort comportUser = new SerialPort();

        // Various colors for logging info
        private Color[] LogMsgTypeColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };

        // Temp holder for whether a key was pressed
        private bool KeyHandled = false;

        // Constructor
        public frmTerminal()   {
            // Build the form
            InitializeComponent();

            // Restore the users settings
            InitializeControlValues();

            // Enable/Disable controls based on the current state
            EnableControls();

            // When data is recieved through the port, call this method
            comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            comportUser.DataReceived += new SerialDataReceivedEventHandler(portUser_DataReceived);
            }
        
        /// <summary> Save the user's settings. </summary>
        private void SaveSettings()
        {
            Settings.Default.BaudRate = int.Parse(cmbBaudRate.Text);
            Settings.Default.DataBits = int.Parse(cmbDataBits.Text);
            Settings.Default.DataMode = CurrentDataMode;
            Settings.Default.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
            Settings.Default.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
            Settings.Default.PortName = cmbPortName.Text;

            Settings.Default.BaudRateUser = int.Parse(cmbBaudRateUser.Text);
            Settings.Default.DataBitsUser = int.Parse(cmbDataBitsUser.Text);
            Settings.Default.DataModeUser = CurrentDataMode;
            Settings.Default.ParityUser = (Parity)Enum.Parse(typeof(Parity), cmbParityUser.Text);
            Settings.Default.StopBitsUser = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBitsUser.Text);
            Settings.Default.PortNameUser = cmbPortNameUser.Text;

            Settings.Default.Offset1x = txtOffsetS1.Text;
            Settings.Default.Offset2x = txtOffsetS2.Text;
            Settings.Default.Offset3x = txtOffsetS3.Text;
            Settings.Default.Offset4x = txtOffsetS4.Text;
            Settings.Default.Offset5x = txtOffsetS5x.Text;
            Settings.Default.Offset5y = txtOffsetS5y.Text;

            Settings.Default.RoundRaw = cmbRoundRaw.Text;
            Settings.Default.RoundValue = cmbRoundValue.Text;
            Settings.Default.RoundLinear = cmbRoundLinear.Text;


            //         Settings.Default.RefreshRate = int.Parse(txtRefreshRate.Text);
 
            Settings.Default.Save();
        }

        /// <summary> Populate the form's controls with default settings. </summary>
        private void InitializeControlValues()
        {
            txtOffsetS1.Text = Settings.Default.Offset1x.ToString();
            txtOffsetS2.Text = Settings.Default.Offset2x.ToString();
            txtOffsetS3.Text = Settings.Default.Offset3x.ToString();
            txtOffsetS4.Text = Settings.Default.Offset4x.ToString();
            txtOffsetS5x.Text = Settings.Default.Offset5x.ToString();
            txtOffsetS5y.Text = Settings.Default.Offset5y.ToString();

            cmbRoundRaw.Text = Settings.Default.RoundRaw.ToString();
            cmbRoundValue.Text = Settings.Default.RoundValue.ToString();
            cmbRoundLinear.Text = Settings.Default.RoundLinear.ToString();

            cmbParity.Items.Clear(); cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
            cmbStopBits.Items.Clear(); cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));

            cmbParity.Text = Settings.Default.Parity.ToString();
            cmbStopBits.Text = Settings.Default.StopBits.ToString();
            cmbDataBits.Text = Settings.Default.DataBits.ToString();
            cmbParity.Text = Settings.Default.Parity.ToString();
            cmbBaudRate.Text = Settings.Default.BaudRate.ToString();
            CurrentDataMode = Settings.Default.DataMode;


            cmbParityUser.Items.Clear(); cmbParityUser.Items.AddRange(Enum.GetNames(typeof(Parity)));
            cmbStopBitsUser.Items.Clear(); cmbStopBitsUser.Items.AddRange(Enum.GetNames(typeof(StopBits)));

            cmbParityUser.Text = Settings.Default.ParityUser.ToString();
            cmbStopBitsUser.Text = Settings.Default.StopBitsUser.ToString();
            cmbDataBitsUser.Text = Settings.Default.DataBitsUser.ToString();
            cmbParityUser.Text = Settings.Default.ParityUser.ToString();
            cmbBaudRateUser.Text = Settings.Default.BaudRateUser.ToString();
 
            cmbPortName.Items.Clear();
            foreach (string s in SerialPort.GetPortNames())
                cmbPortName.Items.Add(s);

            if (cmbPortName.Items.Contains(Settings.Default.PortName)) 
                cmbPortName.Text = Settings.Default.PortName;
                else if (cmbPortName.Items.Count > 0) 
                cmbPortName.SelectedIndex = 0;
                else
                {
                MessageBox.Show(this, "There are no 'COM Ports' Field detected on this computer.\nPlease install a COM Port and restart this app.", "No COM Ports Installed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
                }

            cmbPortNameUser.Items.Clear();
            foreach (string s in SerialPort.GetPortNames())
                cmbPortNameUser.Items.Add(s);

            if (cmbPortNameUser.Items.Contains(Settings.Default.PortNameUser))
                cmbPortNameUser.Text = Settings.Default.PortNameUser;
                else if (cmbPortNameUser.Items.Count > 0)
                cmbPortNameUser.SelectedIndex = 0;
                else
                {
                MessageBox.Show(this, "There are no 'COM Ports User' detected on this computer.\nPlease install a COM Port and restart this app.", "No COM Ports User Installed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
                }
            }

        /// <summary> Enable/disable controls based on the app's current state. </summary>
        private void EnableControls()   {
            //Enable/disable controls based on whether the port is open or not
            gbPortSettings.Enabled = !comport.IsOpen;
            txtSendData.Enabled = btnSend.Enabled = comport.IsOpen;

            if (comport.IsOpen)
                btnOpenPort.Text = "&Close Port";
            else 
                btnOpenPort.Text = "&Open Port";

            //Enable/disable controls based on whether the port is open or not
            gbPortSettingsUser.Enabled = !comportUser.IsOpen;
            txtSendData.Enabled = btnSend.Enabled = comportUser.IsOpen;

            if (comportUser.IsOpen)
                btnOpenPort.Text = "&Close Port";
            else
                btnOpenPort.Text = "&Open Port";
            }


        /// <summary> Send the user's data currently entered in the 'send' box.</summary>
        private void SendData()
        {
            if (CurrentDataMode == DataMode.Text)  {
                //Create an ASCII encoding variable
                Encoding ascii = Encoding.ASCII;
                //Create an Unicode variable
                Encoding unicode = Encoding.Unicode;
              
                //Convert the string into a byte[]
                byte[] unicodeBytes= unicode.GetBytes(txtSendData.Text);

                //Perform the conversion from one encoding to the other
                byte[] asciiBytes = Encoding.Convert(unicode, ascii, unicodeBytes);

                //Convert the new byte[] into a char[] and then into a string.
                //This is a slightly different approach to converting to illustrate
                //the use of GetCharCount/GetChars
                char[] asciiChar = new char[ascii.GetCharCount(asciiBytes,0,asciiBytes.Length)];
                ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChar, 0);

                string sNEW = new string(asciiChar);
                //Send the user's text straight out the port
                comport.WriteLine(sNEW);
                //Show in the terminal window the user's text
                Log(LogMsgType.Outgoing, txtSendData.Text + "\n");
                }
                else
                {
                try
                    {
                    //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                    byte[] data = HexStringToByteArray(txtSendData.Text);

                    //Send the binary data out the port
                    comport.Write(data, 0, data.Length);

                    //Show the hex digits on in the terminal window
                    Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
                    }
                    catch (FormatException)
                    {
                        //Inform the user if the hex string was not properly formatted
                        Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
                    }
                }
            
            txtSendData.SelectAll();
            }


        /// <summary> Send the user's data currently entered in the 'send' box.</summary>
        private void invia_comando_lettura(int sensor_number)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 0" + sensor_number + " 00");

                //Send the binary data out the port
                comport.Write(data, 0, data.Length);
                
                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");

            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
            
            txtSendData.SelectAll();
        }

        
        
        /// <summary> Log data to the terminal window. </summary>
        /// <param name="msgtype"> The type of message to be written. </param>
        /// <param name="msg"> The string containing the message to be shown. </param>
        private void Log(LogMsgType msgtype, string msg)
        {


            rtfTerminal.Invoke(new EventHandler(delegate
            {

                int maxCaratteri = 4000;

                if (rtfTerminal.Text.Length > maxCaratteri)
                {
                    // Rimuovi i caratteri in eccesso dall'inizio
                    rtfTerminal.Text = rtfTerminal.Text.Substring(rtfTerminal.Text.Length - maxCaratteri);
                }
                
                rtfTerminal.SelectedText = string.Empty;
                rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Bold);
                rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
                rtfTerminal.AppendText(msg);
                rtfTerminal.ScrollToCaret();
            }));
        }

        /// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary>
        /// <param name="s"> The string containing the hex digits (with or without spaces). </param>
        /// <returns> Returns an array of bytes. </returns>
        private byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
          
            return buffer;
        }

        /// <summary> Converts an array of bytes into a formatted string of hex digits (ex: E4 CA B2)</summary>
        /// <param name="data"> The array of bytes to be translated into a string of hex digits. </param>
        /// <returns> Returns a well formatted string of hex digits with spacing. </returns>
        private string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            
            return sb.ToString().ToUpper();
        }

        private DataMode CurrentDataMode
        {
            get
            {
                if (rbHex.Checked) 
                    return DataMode.Hex;
                else 
                    return DataMode.Text;
            } 
            set
            {
                if (value == DataMode.Text)
                    rbText.Checked = true;
                else 
                    rbHex.Checked = true;
            }
        }

        private DataModeUser CurrentDataModeUser
        {
            get
            {
                if (rbHexUser.Checked)
                    return DataModeUser.Hex;
                else
                    return DataModeUser.Text;
            }
            set
            {
                if (value == DataModeUser.Text)
                    rbTextUser.Checked = true;
                else
                    rbHexUser.Checked = true;
            }
        }
        //Event Handlers
        

        private void frmTerminal_Shown(object sender, EventArgs e)        {
            Log(LogMsgType.Normal, String.Format("TEST1 Started at: {0}\n", DateTime.Now));
            }


        private void frmTerminal_FormClosing(object sender, FormClosingEventArgs e)        {
            //The form is closing, save the user's preferences
            SaveSettings();
            }


        private void rbText_CheckedChanged(object sender, EventArgs e)        { 
            if (rbText.Checked)   CurrentDataMode = DataMode.Text; 
            }


        private void rbHex_CheckedChanged(object sender, EventArgs e)        { 
            if (rbHex.Checked)    CurrentDataMode = DataMode.Hex;
            }


        private void cmbBaudRate_Validating(object sender, CancelEventArgs e)       { 
            int x; 
            e.Cancel = !int.TryParse(cmbBaudRate.Text, out x);
            }


        private void cmbDataBits_Validating(object sender, CancelEventArgs e)        { 
            int x; 
            e.Cancel = !int.TryParse(cmbDataBits.Text, out x); 
            }


        private void btnOpenPort_Click(object sender, EventArgs e)   {
            // If the port is open, close it.
            if (comport.IsOpen)  {
                comport.Close();
                comportUser.Close();
                }
                else
                {
                //Set the port's FIELD settings
                comport.BaudRate = int.Parse(cmbBaudRate.Text);
                comport.DataBits = int.Parse(cmbDataBits.Text);
                comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
                comport.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
                comport.PortName = cmbPortName.Text;
                comport.Open();

                //Set the port's USER settings
                comportUser.BaudRate = int.Parse(cmbBaudRateUser.Text);
                comportUser.DataBits = int.Parse(cmbDataBitsUser.Text);
                comportUser.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBitsUser.Text);
                comportUser.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParityUser.Text);
                comportUser.PortName = cmbPortNameUser.Text;
                comportUser.Open();
                }

            //Change the state of the form's controls
            EnableControls();

            //If the port is open, send focus to the send data box
            if (comport.IsOpen)  txtSendData.Focus();
            }

        private void btnSend_Click(object sender, EventArgs e)   {
            // If the port is open, close it.
            if (!comport.IsOpen) {
                //Set the port's FIELD settings
                comport.BaudRate = int.Parse(cmbBaudRate.Text);
                comport.DataBits = int.Parse(cmbDataBits.Text);
                comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
                comport.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
                comport.PortName = cmbPortName.Text;

                //Open the port
                comport.Open();
                }

            //Change the state of the form's controls
            EnableControls();
            SendData(); 
            }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (CurrentDataMode == DataMode.Text)
                {
                    string data = comport.ReadExisting();
                    caratteri_ricevuti_da_sensore = data.Length;
                    Log(LogMsgType.Incoming, data);
                }
                else
                {
                    int bytes = comport.BytesToRead;
                    caratteri_ricevuti_da_sensore += bytes;

                    byte[] buffer = new byte[bytes];
                    comport.Read(buffer, 0, bytes);

                    string risposta = ByteArrayToHexString(buffer);
                    Log(LogMsgType.Incoming, risposta);
                    Console.WriteLine("Rx: " + risposta + "      Car Ricevuti Da Sensore: " + caratteri_ricevuti_da_sensore);

                    if (caratteri_ricevuti_da_sensore > 20) caratteri_ricevuti_da_sensore = 0;

                    if (caratteri_ricevuti_da_sensore == 20)
                    {
                        int sensore_letto = buffer[2] - 100;
                        caratteri_ricevuti_da_sensore = 0;
                        Log(LogMsgType.Incoming, "-------- 20 CHAR RICEVUTI -------------" + "\n");
                        aggiorna_valori_letti(sensore_letto, risposta);
                        linearizza_valore(sensore_letto);
                        applica_offset(sensore_letto);
                        invia_stringa_per_utente();
                    }
                }
            }
            catch (Exception ex)
            {
                Log(LogMsgType.Error, "Errore in port_DataReceived: " + ex.Message + "\n");
            }
        }



        private void portUser_DataReceived(object sender, SerialDataReceivedEventArgs e)        {
            Console.WriteLine("ComPortUser Rx:      Car Ricevuti Da Sensore: " + caratteri_ricevuti_da_sensore);
            }


        private void txtSendData_KeyDown(object sender, KeyEventArgs e)        { 
            //If the user presses [ENTER], send the data now
            if (KeyHandled = e.KeyCode == Keys.Enter)          { 
                e.Handled = true; 
                SendData(); 
                } 
            }


        private void txtSendData_KeyPress(object sender, KeyPressEventArgs e)        { 
            e.Handled = KeyHandled; 
            }


        private void cmdClear_Click(object sender, EventArgs e)        {
            rtfTerminal.Text = "";
            }

       
        private void frmTerminal_Load(object sender, EventArgs e)        {
            chkSens1.Checked = true;
            chkSens2.Checked = true;
            chkSens3.Checked = true;
            chkSens4.Checked = true;
            chkSens5.Checked = true;
            }

        private void rbTextUser_CheckedChanged(object sender, EventArgs e)        {
            if (rbTextUser.Checked)  CurrentDataModeUser = DataModeUser.Text; 
            }

       
        private void aggiorna_valori_letti(int sensore_letto,string risposta)        {
            float valore_letto_x = 0; float valore_letto_y = 0; float valore_letto_z = 0;

            string testoComboBox = null;
            cmbRoundRaw.Invoke(new MethodInvoker(delegate{testoComboBox = cmbRoundRaw.Text;}));
            int decimali_arrotondamento = int.Parse(testoComboBox);

            if (sensore_letto==1) {
                valore_letto_z = (float)Math.Round(valore_sensore(risposta, "Z"), decimali_arrotondamento);
                txtDataS1.Invoke(new MethodInvoker(delegate { txtDataS1.Text = valore_letto_z.ToString(); }));
                }

            if (sensore_letto == 2)            {
                valore_letto_x = (float)Math.Round(valore_sensore(risposta, "X"), decimali_arrotondamento);
                txtDataS2.Invoke(new MethodInvoker(delegate { txtDataS2.Text = valore_letto_x.ToString(); }));
                }

            if (sensore_letto == 3)            {
                valore_letto_x = (float)Math.Round(valore_sensore(risposta, "X"), decimali_arrotondamento);
                txtDataS3.Invoke(new MethodInvoker(delegate { txtDataS3.Text = valore_letto_x.ToString(); }));
                }

            if (sensore_letto == 4)            {
                valore_letto_x = (float)Math.Round(valore_sensore(risposta, "X"), decimali_arrotondamento);
                txtDataS4.Invoke(new MethodInvoker(delegate { txtDataS4.Text = valore_letto_x.ToString(); }));
                }

            if (sensore_letto == 5)            {
                valore_letto_x = (float)Math.Round(valore_sensore(risposta, "X"), decimali_arrotondamento);
                txtDataS5x.Invoke(new MethodInvoker(delegate { txtDataS5x.Text = valore_letto_x.ToString(); }));

                valore_letto_z = (float)Math.Round(valore_sensore(risposta, "Y"), decimali_arrotondamento);
                txtDataS5y.Invoke(new MethodInvoker(delegate { txtDataS5y.Text = valore_letto_z.ToString(); }));
                }

            }


        private void applica_offset(int sensore_letto)        {
            string testoComboBox = null;
            cmbRoundValue.Invoke(new MethodInvoker(delegate { testoComboBox = cmbRoundValue.Text; }));
            int decimali_arrotondamento = int.Parse(testoComboBox);

            if (sensore_letto==1) {
                txtOffsetS1.Invoke(new MethodInvoker(delegate {if (txtOffsetS1.TextLength == 0) {txtOffsetS1.Text = "0";}}));
                double risultato = Math.Round(Convert.ToDouble(txtLinearS1.Text) + Convert.ToDouble(txtOffsetS1.Text),decimali_arrotondamento);
                txtValueS1.Invoke(new MethodInvoker(delegate { txtValueS1.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 2)            {
                txtOffsetS2.Invoke(new MethodInvoker(delegate { if (txtOffsetS2.TextLength == 0) { txtOffsetS2.Text = "0"; } }));
                double risultato = Math.Round(Convert.ToDouble(txtLinearS2.Text) + Convert.ToDouble(txtOffsetS2.Text),decimali_arrotondamento);
                txtValueS2.Invoke(new MethodInvoker(delegate { txtValueS2.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 3)            {
                txtOffsetS3.Invoke(new MethodInvoker(delegate { if (txtOffsetS3.TextLength == 0) { txtOffsetS3.Text = "0"; } }));
                double risultato = Math.Round(Convert.ToDouble(txtLinearS3.Text) + Convert.ToDouble(txtOffsetS3.Text),decimali_arrotondamento);
                txtValueS3.Invoke(new MethodInvoker(delegate { txtValueS3.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 4)            {
                txtOffsetS4.Invoke(new MethodInvoker(delegate { if (txtOffsetS4.TextLength == 0) { txtOffsetS4.Text = "0"; } }));
                double risultato = Math.Round(Convert.ToDouble(txtLinearS4.Text) + Convert.ToDouble(txtOffsetS4.Text),decimali_arrotondamento);
                txtValueS4.Invoke(new MethodInvoker(delegate { txtValueS4.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 5)            {
                txtOffsetS5x.Invoke(new MethodInvoker(delegate { if (txtOffsetS5x.TextLength == 0) { txtOffsetS5x.Text = "0"; } }));
                double risultato = Math.Round(Convert.ToDouble(txtLinearS5x.Text) + Convert.ToDouble(txtOffsetS5x.Text),decimali_arrotondamento);
                txtValueS5x.Invoke(new MethodInvoker(delegate { txtValueS5x.Text = risultato.ToString(); }));
                txtOffsetS5y.Invoke(new MethodInvoker(delegate { if (txtOffsetS5y.TextLength == 0) { txtOffsetS5y.Text = "0"; } }));
                risultato = Math.Round(Convert.ToDouble(txtLinearS5y.Text) + Convert.ToDouble(txtOffsetS5y.Text), decimali_arrotondamento);
                txtValueS5y.Invoke(new MethodInvoker(delegate { txtValueS5y.Text = risultato.ToString(); }));
                }
            }

        

        private void linearizza_valore(int sensore_letto)        {
            string testoComboBox = null;
            cmbRoundLinear.Invoke(new MethodInvoker(delegate { testoComboBox = cmbRoundLinear.Text; }));
            int decimali_arrotondamento = int.Parse(testoComboBox);
            double risultato = 0;

            if (sensore_letto == 1)    {
                txtLinearS1.Invoke(new MethodInvoker(delegate { if (txtLinearS1.TextLength == 0) { txtLinearS1.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS1.Text)>= 0 ) {risultato = Math.Round( Convert.ToDouble(txtDataS1.Text), decimali_arrotondamento);}
                    else
                    {risultato = Math.Round(360 - Convert.ToDouble(txtDataS1.Text), decimali_arrotondamento);}
                    
                txtLinearS1.Invoke(new MethodInvoker(delegate { txtLinearS1.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 2)            {
                txtLinearS2.Invoke(new MethodInvoker(delegate { if (txtLinearS2.TextLength == 0) { txtLinearS2.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS2.Text) >= 0) { risultato = Math.Round(Convert.ToDouble(txtDataS2.Text), decimali_arrotondamento); }
                    else
                    { risultato = Math.Round(360 - Convert.ToDouble(txtDataS2.Text), decimali_arrotondamento); }

                txtLinearS2.Invoke(new MethodInvoker(delegate { txtLinearS2.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 3)            {
                txtLinearS3.Invoke(new MethodInvoker(delegate { if (txtLinearS3.TextLength == 0) { txtLinearS3.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS3.Text) >= 0) { risultato = Math.Round(Convert.ToDouble(txtDataS3.Text), decimali_arrotondamento); }
                    else
                    { risultato = Math.Round(360 - Convert.ToDouble(txtDataS3.Text), decimali_arrotondamento); }

                txtLinearS3.Invoke(new MethodInvoker(delegate { txtLinearS3.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 4)            {
                txtLinearS4.Invoke(new MethodInvoker(delegate { if (txtLinearS4.TextLength == 0) { txtLinearS4.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS4.Text) >= 0) { risultato = Math.Round(Convert.ToDouble(txtDataS4.Text), decimali_arrotondamento); }
                    else
                    { risultato = Math.Round(360 - Convert.ToDouble(txtDataS4.Text), decimali_arrotondamento); }

                txtLinearS4.Invoke(new MethodInvoker(delegate { txtLinearS4.Text = risultato.ToString(); }));
                }

            if (sensore_letto == 5)            {
                txtLinearS5x.Invoke(new MethodInvoker(delegate { if (txtLinearS5x.TextLength == 0) { txtLinearS5x.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS5x.Text) >= 0) { risultato = Math.Round(Convert.ToDouble(txtDataS5x.Text), decimali_arrotondamento); }
                    else
                    {risultato = Math.Round(360 - Convert.ToDouble(txtDataS5x.Text), decimali_arrotondamento); }

                txtLinearS5x.Invoke(new MethodInvoker(delegate { txtLinearS5x.Text = risultato.ToString(); }));
                //----------------------------------------------------------------------------------------------------------
                txtLinearS5y.Invoke(new MethodInvoker(delegate { if (txtLinearS5y.TextLength == 0) { txtLinearS5y.Text = "0"; } }));

                if (Convert.ToDouble(txtDataS5y.Text) >= 0) { risultato = Math.Round(Convert.ToDouble(txtDataS5y.Text), decimali_arrotondamento); }
                    else
                    { risultato = Math.Round(360 - Convert.ToDouble(txtDataS5y.Text), decimali_arrotondamento); }

                txtLinearS5y.Invoke(new MethodInvoker(delegate { txtLinearS5y.Text = risultato.ToString(); }));
                }
            }

        private void invia_stringa_per_utente()        {
            txtValueS5y.Invoke(new MethodInvoker(delegate { if (txtValueS5y.TextLength == 0) { txtValueS5y.Text = "0.00"; } }));
            txtValueS5x.Invoke(new MethodInvoker(delegate { if (txtValueS5x.TextLength == 0) { txtValueS5x.Text = "0.00"; } }));
            txtValueS4.Invoke(new MethodInvoker(delegate { if (txtValueS4.TextLength == 0) { txtValueS4.Text = "0.00"; } }));
            txtValueS3.Invoke(new MethodInvoker(delegate { if (txtValueS3.TextLength == 0) { txtValueS3.Text = "0.00"; } }));
            txtValueS2.Invoke(new MethodInvoker(delegate { if (txtValueS2.TextLength == 0) { txtValueS2.Text = "0.00"; } }));
            txtValueS1.Invoke(new MethodInvoker(delegate { if (txtValueS1.TextLength == 0) { txtValueS1.Text = "0.00"; } }));

            string stringa_per_per_utente = string.Format("R=0.00,0.00,0.00," + txtValueS5y.Text.Replace(',', '.') + "," + txtValueS5x.Text.Replace(',', '.') + ",0.00," + txtValueS4.Text.Replace(',', '.') + "," + txtValueS3.Text.Replace(',', '.') + "," + txtValueS2.Text.Replace(',', '.') + "," + txtValueS1.Text.Replace(',', '.') + ",0.00,0.00,0.00,0.00");
            txtUserValue.Invoke(new MethodInvoker(delegate { txtUserValue.Text = stringa_per_per_utente; }));
            Console.WriteLine(stringa_per_per_utente);

            // Verifica se porta aperta, se chiusa la apre
            if (!comport.IsOpen) {
                btnOpenPort_Click(null, EventArgs.Empty);
                }

            // Conversione della stringa in un array di byte
            //           stringa_per_per_utente += (char)13; stringa_per_per_utente += (char)10;
            byte[] per_utenteByteArray = Encoding.UTF8.GetBytes(stringa_per_per_utente);

            //Send the binary data out the port
            //comportUser.Write(per_utenteByteArray, 0, per_utenteByteArray.Length);
            comportUser.Write(stringa_per_per_utente);
            Console.WriteLine("Stringa per_utente inviata");
            }


        // Timer che viene triggerato ogni txtRefreshRate  millisecondi
        // invia il comando al sensore corrente, sempre che sia abilitato, altrimenti passa al successivo
        private void tmrReadSensor_Tick(object sender, EventArgs e)   {
            // Incrementa di 1 il valore sensore_attuale
            if (sensore_attuale <5 ) sensore_attuale++;  else  sensore_attuale=1;

            // Crea una lista (o array) con i controlli
            var controlli = new[] { chkSens1, chkSens2, chkSens3, chkSens4, chkSens5 };

            // Usare l'integer per selezionare il controllo desiderato (supponendo che l'intero inizi da 1)
            var controlloDesiderato = controlli[sensore_attuale - 1]; // -1 per gestire l'indice da 0
            int numero_tentativi = 0;        // Onde evitare che inizi a girare sempre qua dentro se tutte le checkbox sono disabilitate

            while (numero_tentativi<6)   {
                numero_tentativi++;

                // Verifica se il controllo corrispondente è checked
                if (controlli[sensore_attuale - 1].Checked)      {
                    // Esegui alcune operazioni
                    Console.WriteLine("Controllo sensore " + sensore_attuale.ToString());
                    accende_textbox_valore(sensore_attuale);
                    invia_comando_lettura(sensore_attuale);
                    
                    // Operazioni personalizzate qui
                    break; // Esci dalla routine
                    }
                    else
                    {
                    // Incrementa e passa al prossimo controllo
                    sensore_attuale++;
                    if (sensore_attuale > 5) sensore_attuale = 1;
                    }
                }
            }

        private void accende_textbox_valore(int sensore_attuale)    {
            // Imposta lo sfondo giallo per ogni TextBox
            txtDataS1.BackColor = System.Drawing.Color.White;
            txtDataS2.BackColor = System.Drawing.Color.White;
            txtDataS3.BackColor = System.Drawing.Color.White;
            txtDataS4.BackColor = System.Drawing.Color.White;
            txtDataS5x.BackColor = System.Drawing.Color.White;
            txtDataS5y.BackColor = System.Drawing.Color.White;

            if (sensore_attuale == 1) txtDataS1.BackColor = System.Drawing.Color.Yellow;
            if (sensore_attuale == 2) txtDataS2.BackColor = System.Drawing.Color.Yellow;
            if (sensore_attuale == 3) txtDataS3.BackColor = System.Drawing.Color.Yellow;
            if (sensore_attuale == 4) txtDataS4.BackColor = System.Drawing.Color.Yellow;
            if (sensore_attuale == 5) { txtDataS5x.BackColor = System.Drawing.Color.Yellow; txtDataS5y.BackColor = System.Drawing.Color.Yellow; }
            }


        public float valore_sensore(string dati_risposta, string valore)   {
            // Dividi la stringa manualmente senza LINQ
            string dati_risposta_trimmata = dati_risposta.Trim();
            string[] hexArray = dati_risposta_trimmata.Split(' ');

            // Converte ogni valore esadecimale in un byte
            byte[] bytes = new byte[hexArray.Length];
            for (int i = 0; i < hexArray.Length; i++)   {
                bytes[i] = Convert.ToByte(hexArray[i], 16);
                }

            if (bytes.Length != 20)   {             // Assicurati che ci siano 20 byte
                throw new ArgumentException("La stringa deve essere composta da 20 byte esadecimali.");
                }

            // I primi tre byte devono essere 55 53
            if (bytes[0] != 0x55 || bytes[1] != 0x53 )   {
                throw new ArgumentException("La stringa non inizia con i valori previsti 55 53 .");
                }

             // Determina l'offset del valore richiesto
            //byte[] byteArray;

            byte[] byteArray;
            if (valore == "X") { byteArray = new byte[] { bytes[3], bytes[4], bytes[5], bytes[6] }; }
            else if (valore == "Y") { byteArray = new byte[] { bytes[7], bytes[8], bytes[9], bytes[10] }; }
            else if (valore == "Z") { byteArray = new byte[] { bytes[11], bytes[12], bytes[13], bytes[14] }; }
            else if (valore == "K") { byteArray = new byte[] { bytes[15], bytes[16], bytes[17], bytes[18] }; }
            else
            {
                throw new ArgumentException("Valore non riconosciuto. Usa 'X', 'Y', 'Z' o 'K'.");
            }

           
            // Converte i byte in un float
            float risultato = BitConverter.ToSingle(byteArray, 0);
            Console.WriteLine(dati_risposta + "  " + valore + "=" + risultato);
            return risultato;
            }



        // Definire una funzione per ottenere una parte dell'array
        byte[] GetSubArray(byte[] data, int offset, int length)
        {
            byte[] result = new byte[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = data[offset + i];
            }
            return result;
        }



        // Limite a minimo 10 millisecondi e max 10.000 millisecondi
        private void chkAutoRead_CheckedChanged(object sender, EventArgs e)        {
            if (chkAutoRead.Checked==true) {
                Console.WriteLine("Attivato automatico lettura sensori");
                
                // Verifica se porta aperta, se chiusa la apre
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);

                sensore_attuale = 1;

                int refreshRate;
                if (int.TryParse(txtRefreshRate.Text, out refreshRate) && refreshRate > 0)                {
                    tmrReadSensor.Interval = refreshRate;
                    }
                    else
                    {
                    MessageBox.Show("Inserire un valore numerico per il Refresh Rate valido maggiore di 0.");
                    }
                
                tmrReadSensor.Enabled = true;
                }
                else
                {
                Console.WriteLine("Disattivato automatico lettura sensori");
                tmrReadSensor.Enabled = false;
                btnOpenPort_Click(null, EventArgs.Empty);
                }
            }


        private void cmdReadXsens1_Click(object sender, EventArgs e)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 01 00");

                //Send the binary data out the port
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);
                comport.Write(data, 0, data.Length);

                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        }


        private void cmdReadXsens2_Click(object sender, EventArgs e)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 02 00");

                //Send the binary data out the port
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);
                comport.Write(data, 0, data.Length);

                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        }
  

        private void cmdReadXsens3_Click(object sender, EventArgs e)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 03 00");

                //Send the binary data out the port
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);
                comport.Write(data, 0, data.Length);

                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        }


        private void cmdReadXsens4_Click(object sender, EventArgs e)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 04 00");

                //Send the binary data out the port
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);
                comport.Write(data, 0, data.Length);

                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        }

      
        private void cmdReadZsens5_Click(object sender, EventArgs e)
        {
            try
            {
                //Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray("55 53 05 00");

                //Send the binary data out the port
                if (!comport.IsOpen) btnOpenPort_Click(null, EventArgs.Empty);
                comport.Write(data, 0, data.Length);

                //Show the hex digits on in the terminal window
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
            }
            catch (FormatException)
            {
                //Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        }


        private void cmbPortName_SelectedIndexChanged(object sender, EventArgs e)
        {
        }


        private void cmbBaudRate_SelectedIndexChanged(object sender, EventArgs e)
        {
        }


        private void cmbRoundRaw_SelectedIndexChanged(object sender, EventArgs e)
        {
        }


        private void label35_Click(object sender, EventArgs e)
        {
        }


    }

}

5 Risposte

  • Re: Porta seriale1 smette di ricevere se invii a porta seriale2

    E' possibile che il problema sia nel firmware del device a cui ti colleghi e con cui colloquiano le due seriali?

    Purtroppo, non sapendo nulla di questo device e del suo firmware, posso solo fare questa ipotesi.

  • Re: Porta seriale1 smette di ricevere se invii a porta seriale2

    No, ipotesi non perseguibile, perche' e' la prima cosa che ho controllato

    Sia la richiesta da pc verso sensori (su prima porta seriale), sia le risposte sensori verso pc (su prima porta seriale), continuano a partire ed arrivare correttamente

    E' solo il software su pc che non 'vede' piu' entrare le risposte ad iniziare dal momento che si invia qualcosa sulla seconda seriale

    Se io non invio niente sulla seconda serale (se ci metto un rem sulla riga  "comportUser.Write(stringa_per_per_utente)" ) , le risposte entrano correttamente anche nel codice

  • Re: Porta seriale1 smette di ricevere se invii a porta seriale2

           private void invia_stringa_per_utente()        {
    ...
                // Verifica se porta aperta, se chiusa la apre
                if (!comport.IsOpen) {
                    btnOpenPort_Click(null, EventArgs.Empty);
                    }
    
    ....
                comportUser.Write(stringa_per_per_utente);
    
                }

    Diciamo che per chiarezza del codice, dovendo inviare sulla seconda seriale, sarebbe meglio controllare che sia aperta la seconda seriale e non la prima anche se poi in btnOpenPort_Click le apri tutte e due.

            private void btnOpenPort_Click(object sender, EventArgs e)   {
                // If the port is open, close it.
                if (comport.IsOpen)  {
                    comport.Close();
                    comportUser.Close();
                    }
                    else
                    {
                    //Set the port's FIELD settings
                    comport.BaudRate = int.Parse(cmbBaudRate.Text);
                    comport.DataBits = int.Parse(cmbDataBits.Text);
                    comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
                    comport.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
                    comport.PortName = cmbPortName.Text;
                    comport.Open();
    
                    //Set the port's USER settings
                    comportUser.BaudRate = int.Parse(cmbBaudRateUser.Text);
                    comportUser.DataBits = int.Parse(cmbDataBitsUser.Text);
                    comportUser.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBitsUser.Text);
                    comportUser.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParityUser.Text);
                    comportUser.PortName = cmbPortNameUser.Text;
                    comportUser.Open();
                    }
    
                //Change the state of the form's controls
                EnableControls();
    
                //If the port is open, send focus to the send data box
                if (comport.IsOpen)  txtSendData.Focus();
                }

    Curiosità : come fai a sapere che il buffer di ricezione della prima seriale riceve dati che poi non elabora? Oscilloscopio, sniffer esterno, altro ?

    Confermi che i sensori rispondono SOLO se gli vengono richiesti dei dati (quindi no trasmissione  ciclica)?

    Presumo che si tratti di linea seriale RS485 : gli indirizzi dei sensori sono corretti? Hai le resistenze di terminazione del bus?

    Se fai un loop continuo di richiesta dati ad un singolo sensore (i.e ogni 1 secondo) e poi intermezzi una richiesta sulla seconda seriale il sensore sulla prima continua a rispondere?

    Analizzare il codice non è così semplice senza avere l'HW sotto mano quindi si possono solo fare ipotesi ...

  • Re: Porta seriale1 smette di ricevere se invii a porta seriale2

    Oscilloscopio + decoder segnale

    Confermo che le risposte arrivano al pc, con i parametri di trasmissione previsti, e' l'unica cosa che serve sapere ai fini del problema posto

    Analizzare il codice e' l'unica possibilita', perche' il problema e' sicuramente nel codice, i dettagli di tutto l'ambaradan hardware non hanno nessuna importanza, potrebbe essere un secondo pc collegato via rs232 al primo, e che risponde ai comandi inviati, sarebbe la stessa identica cosa

  • Re: Porta seriale1 smette di ricevere se invii a porta seriale2

    17/03/2025 - amorosik ha scritto:

    Analizzare il codice e' l'unica possibilita' ...

    Analizzandolo io non ci noto nulla di palesemente errato.

    Io presterei attenzione al timeout di ricezione (ovvero dopo aver inviato un comando di lettura ad un sensore attenderei la risposta dal sensore prima di inviare un successivo comando di lettura sulla stessa porta seriale) ... è l'unico consiglio che mi sento di darti.

Devi accedere o registrarti per scrivere nel forum
5 risposte