Click here to Skip to main content
15,887,676 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
GoodMorning;I'm working on an application in C # that makes the communication between a temperature controller and a PC via RS232, I need to read the address and the current temperature regulator for that I developed a code to respond to this but I have a load probleme.When I want to read two values or more at the same time this is virtually impossible because he can only read a single value in the time .And when I want to use values stored in a database given as the address, the program runs the database several times but resend to me only the first element to the serial port and get blocked after.
Help me please because I'm really blocked.
Thank you very much
*this is a part of my concerned code :)
------------------------------------------------------------------------------------

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Data.SqlClient;
using System.IO.Ports;
namespace projet
{
    public partial class Form1 : Form
    {
        Motdepasse motdepasse = new Motdepasse();
 
        Configuration conf = new Configuration();
      
        int[] nb_preced = new int[100];
        static int nbr_it = 0;
           public static int adresse_courant = 0;
        static bool bTimeOutInterCar = false;
        static int k, l=0, m, p;
        //string EtuveASupprimer;
        ListViewItem[] it = new ListViewItem[100];
        string RxString = "";
        string x;
        public Form1()
        {
            InitializeComponent();
            configPort();
            //InitializeTimerScrutation();
            this.listView1.FullRowSelect = true;     // Select the item and subitems when selection is made.
             nbr_it = 0;
            charger_listView();
            //adressetuve();
             //Etuve_OFF();
             timerhour.Start();
            try
            {
                
               InitializeMyTimer();
            
            }
            catch (Exception Er) { MessageBox.Show("Erreur " + Er.Message); }
           
        }
        private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
        {
                              this.Close();
             }
        private void communicationPortToolStripMenuItem_Click(object sender, EventArgs e)
        {
          
            timer2.Stop();
            if (serialPort.IsOpen) serialPort.Close();
            Configuration f = new Configuration();
            f.ShowDialog();
            //adressetuve();
            timer2.Start();
       }
        public void charger_listView()
        {
            StringBuilder ligne1 = new StringBuilder();
            StringBuilder ligne2 = new StringBuilder();
            try
            {
                Program.connexion.Open();
                string mySelectQuery = "SELECT Label,Adresse FROM Oven order by Label";
                SqlCommand myCommand = new SqlCommand(mySelectQuery, Program.connexion);
                SqlDataReader myReader = myCommand.ExecuteReader();
                while (myReader.Read())
                {
                    ligne1 = new StringBuilder();
                   ligne2 = new StringBuilder();
                    for (int i = 0; i < myReader.FieldCount; i += 2)
                    {
                        ligne1.Append(myReader[i].ToString());
                       ligne2.Append(myReader[i + 1].ToString());
                        it[nbr_it] = new ListViewItem();
                        it[nbr_it].Text = ligne1.ToString();
                        it[nbr_it].SubItems.Add(ligne2.ToString());
                        it[nbr_it].SubItems.Add("NC");
                     
                        this.it[nbr_it].SubItems[0].ForeColor = Color.Red;
                        this.listView1.Items.Add(it[nbr_it]);
                       nbr_it++;
                    }
                }
                myReader.Close();
            }
            catch (Exception z) { MessageBox.Show(z.ToString()); }
            Program.connexion.Close();
                       
        }
        private void timerhour_Tick(object sender, EventArgs e)
        {
            DateTime DateNow = DateTime.Now;
            THour.Text = DateNow.Hour.ToString("d2") + ":" + DateNow.Minute.ToString("d2") + ":" + DateNow.Second.ToString("d2");
           
        }
        private void InitializeMyTimer()
        {
            // Set the interval for the timer.
            timer1.Interval = 1000;
            // Connect the Tick event of the timer to its event handler.
            //timer1.Tick += new EventHandler(IncreaseProgressBar);
            timer1.Tick += new EventHandler(timer1_Tick);
            // Start the timer.
            timer1.Start();
        }
        private void DisplayData2(string msg)
        {
            lread.Invoke(new EventHandler(delegate
            {
    
               // textBox1.Text = msg;
                lread.Text = msg;
  
            }));
        }
        private void DisplayData1(string msg)
        {
            area.Invoke(new EventHandler(delegate
            {
               area.Text = msg;
                        }));
        }
        private byte[] HexToByte(string msg)
        {
           msg = msg.Replace(" ", "");
          
            byte[] comBuffer = new byte[msg.Length / 2];
            opert.Text = msg.Length.ToString();
          
            for (int i = 0; i < msg.Length; i += 2)
       
                comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);
     
            //
            return comBuffer;
        }
        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] comBuffer = new byte[300];
           serialPort.Read(comBuffer, 0, comBuffer.Length);
          
            string s1 = Encoding.ASCII.GetString(comBuffer);
            StringBuilder st1 = new StringBuilder(s1, 50);
  
            ArrayList trame1 = new ArrayList(50);
           //trame1.Add(st1);
            //trame.Clear();
            trame1.Add(st1[0]);
            trame1.Add(st1[1]);
            trame1.Add(st1[2]);
            trame1.Add(st1[3]);
            trame1.Add(st1[4]);
            trame1.Add(st1[5]);
            trame1.Add(st1[6]);
            //trame1.Add(st1[7]);
          
            String sList1 = "";
            int i = 0;
            for (i = 1; i < trame1.Count; i++)
            {
                sList1 += trame1[i];
              
                //sList1 = "";
            }
         
            try
            {
                if (double.Parse(sList1) - double.Parse(sList1) == 0)
                {
                    //Substring(0, 2)
                    try
                    {
                        SqlCommand myCommand = new SqlCommand("UPDATE Oven SET Area = '" + sList1.Substring(0, 2) + "',Operation = '" + sList1.Substring(2, 4) + "'WHERE Adresse = " + double.Parse(sList1.Substring(0, 2)) + "", Program.connexion);
                        
                        Program.connexion.Open();
                        myCommand.ExecuteNonQuery();
                    }
                    catch (Exception z) { MessageBox.Show(z.ToString()); }
                    Program.connexion.Close();
                    DisplayData2(sList1);
                   DisplayData1(sList1.Substring(2, 4));
                    x = sList1.Substring(0, 2);
                   
                }
            }
            catch (Exception)
            { }
            //string y = sList1;
            //textBox3.Text = y;
            }
        private void timer1_Tick(object sender, EventArgs e)
        {
         //if (serialPort.IsOpen == false) serialPort.Open();
           // configPort();
            //now open the port
    // lectur("20");
      //adressetuve();
            Program.connexion.Open();
                SqlCommand commande = new SqlCommand("select Adresse from Oven", Program.connexion);
                SqlDataReader reader = commande.ExecuteReader();
                while (reader.Read())
                {   
                    //lectur(reader[0].ToString());
                    System.Threading.Thread.Sleep(1000);
                  textBox3.Text += reader[0].ToString();
                  System.Threading.Thread.Sleep(100);
                }
                reader.Close();
         
            Program.connexion.Close();
            
       for (int i = 0; i < listView1.Items.Count; i++)
       { 
//           //System.Threading.Thread.Sleep(1000);
//           lectur(it[i].SubItems[1].Text.ToString());
        
       if (x == it[i].SubItems[1].Text)
       {it[i].SubItems[2].Text = ("OFF");
           this.it[i].SubItems[0].ForeColor = Color.Cyan;
       }
       else
       {
           it[i].SubItems[2].Text = ("NC");
           this.it[i].SubItems[0].ForeColor = Color.Green;
       }
//            //test(it[i].SubItems[1].Text);
//          textBox2.Text += it[i].SubItems[1].Text;
}
}
    
       
        private void initialiszTimer2()
        {
            timer2.Interval = 1000;
            timer2.Tick += new EventHandler(timer2_Tick);
            timer2.Start();// Start the timer.
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            if (serialPort.IsOpen == false) serialPort.Open();
           // configPort();
            //now open the port
            byte[] newMsg = new byte[20];
           
            try
            {
               
            }
            catch (FormatException)
            {
              
            }
         
        }
        public void ecrire(string adresse, string consigne)
        {
            uint bcc = 0;
            ArrayList trame_ecriture = new ArrayList();
            ArrayList Adr = new ArrayList();
            ArrayList Consigne = new ArrayList();
            StringBuilder adr = new StringBuilder(adresse);
            StringBuilder cons = new StringBuilder(consigne);
            for (int s = 0; s < adresse.Length; s++)
            {
                if (adresse.Length == 1) { Adr.Add(48); Adr.Add(48); }
                Adr.Add(Convert.ToInt32(adr[s]));
                Adr.Add(Convert.ToInt32(adr[s]));
            }
            for (int s = 0; s < consigne.Length; s++)
            {
                Consigne.Add(Convert.ToInt32(cons[s]));
            }
            trame_ecriture.Add(4);
            trame_ecriture.AddRange(Adr);
            trame_ecriture.Add(2);
            trame_ecriture.Add(83);
            trame_ecriture.Add(76);
            trame_ecriture.AddRange(Consigne);
            trame_ecriture.Add(46);
            trame_ecriture.Add(48);
            trame_ecriture.Add(3);
            for (int s = 6; s < trame_ecriture.Count; s++)
            {
                bcc = bcc ^ Convert.ToUInt32(trame_ecriture[s]);
            }
            trame_ecriture.Add(bcc);
            envoie(trame_ecriture);
        }
         public void lectur(string adresse)
        {
           
            ArrayList trame_ecriture = new ArrayList();
            ArrayList Adr = new ArrayList();
            
            StringBuilder adr = new StringBuilder(adresse);
          
            for (int s = 0; s < adresse.Length; s++)
            {
                if (adresse.Length == 1) { Adr.Add(30); Adr.Add(30); }
                //Adr.Add(Convert.ToInt32(adr[s]).ToString());
                Adr.Add(Convert.ToString(adr[s],16));
                Adr.Add(" ");
                Adr.Add(Convert.ToString(adr[s],16));
               Adr.Add(" ");
            }
        
            trame_ecriture.Add("04");
            trame_ecriture.Add(" ");
            trame_ecriture.AddRange(Adr);
            trame_ecriture.Add(" ");
            trame_ecriture.Add("50");
            trame_ecriture.Add(" ");
            trame_ecriture.Add("56");
            trame_ecriture.Add(" ");
            trame_ecriture.Add("05");
            trame_ecriture.Add(" ");
            int i = 0;
            string List = "";
            for (i = 0; i < trame_ecriture.Count-1; i++)
            {
                List += trame_ecriture[i];
            }
            //
         textBox1.Text = List;
         //
            if (serialPort.IsOpen == false) serialPort.Open();
            byte[] newMsg1 = new byte[20];
            try
            {
                //convert the message to byte array
                newMsg1 = HexToByte(List);
                //opert.Text = newMsg1.ToString();
                //send the message to the port
                serialPort.Write(newMsg1, 0, newMsg1.Length);
            
            }
            catch (FormatException)
            {
            }
        }
        
        public void adressetuve()
        {
            try
            {
                Program.connexion.Open();
                SqlCommand commande = new SqlCommand("select Adresse,Temperat_Con_1 from Oven", Program.connexion);
                SqlDataReader reader = commande.ExecuteReader();
                while (reader.Read())
                {
                    lectur(reader[0].ToString());
                }
                reader.Close();
            }
            catch (Exception z) { MessageBox.Show(z.ToString()); }
            Program.connexion.Close();
    
        }
        public void envoie(ArrayList liste)
        {
            if (serialPort.IsOpen == false) serialPort.Open();
            Byte[] T = new Byte[liste.Count];
            for (int s = 0; s < T.Length; s++)
            {
                T[s] = Convert.ToByte(liste[s]);
            }
            serialPort.Write(T, 0, T.Length);
            serialPort.Close();
        }
       
 
    }
Posted
Updated 18-May-11 1:40am
v2
Comments
Olivier Levrey 18-May-11 7:41am    
I just changed the code tag into pre tag. Maybe you will want to update your question to keep only the relevant part of your code. Posting so much code usually discourages most of us...

1 solution

I didn't read all your code... but check that:

1- if you read incoming data too quiclky, chances are the second read will fail: use Sleep between several read operations to give time to the device to process the command and reply.

2- same thing if you write and immediately want to read something.

3- if you use threads (I didn't see any in your code but just in case) make sure you access your port safely using lock when needed (or other synchronization mechanisms).
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 18-May-11 14:56pm    
Sleep is pretty bad solution. Read will not fail, the code will be blocked until data is available. Anyway, there is a BytesToRead property to check it up. It's more important for writing, not to overwhelm the buffer.

Not using threads would be extremely stupid.

Most likely, the problem is in the application-level protocol. By the way, I know how bad is the firmware of industial-grade devices, they can have all kinds of bugs both in implementation and documentation.

--SA
Olivier Levrey 19-May-11 3:31am    
Sleep is sometimes necessary. Read will block untill data is available: correct. But it doesn't mean you will receive the complete answer from the device (I had the case several times in past). The only way to ensure the answer is received completely is waiting for a special character (usually '\r') which means something like "end of transmission".
Unfortunately, not all devices do this. Thanksfully it becomes very rare nowadays, but as you stated industrial devices are often buggy and they sometimes forget to implement this essential feature...
And only an "evil" Sleep can be used to workaround this.
Sergey Alexandrovich Kryukov 20-May-11 13:55pm    
I don't mean Sleep in general. I mean sleep to some assumed period of time in assumption that data must be ready.
Now, end-of-transmission is one of working solutions. This is the thing: industrial-grade devices often has impossibly illiterate control system and extremely buggy. I thing I observe slow improvement (not satisfactory though) and slow going away from RS-232. In one case I tried to make our supplier to re-program communication firmware, supervised their work for a long while and got limited success; at least managed to work without those sleeps; it was very difficult; people did not understand most basic concepts...
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900