Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
2.33/5 (2 votes)
See more:
hi,
am developing c# windows appli , i have textbox,browse button, upload button.

using browse button select excel file having 7 columns,then click on upload button.

after every record sent thread must be suspended until serialport gets responce data then resume that thread. then test that responce code ($machine id(5 chars),responce code(0/1/2)#).if responce code is 0 then only send the next record.

here is the 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 Excel=Microsoft.Office.Interop.Excel;
using System.IO;
using System.Threading;
using System.IO.Ports;
using System.Text.RegularExpressions;

namespace Hand_Held_Data_Transporter
{
    public partial class Form1 : Form
    {
        String[] stream_buffer;
        String final = null;
        String machId = null, custId = null, name = null, totalBal = null, paid = null, lastPaid = null, due = null;
        
        byte[] buffer=new byte[100];
        byte btdata;
        int ucDataLen;
        int ucStart;
        int CmdDetected;
        int PostCmdStart;
        int rspCode;

        String s;
        string fName = @"C:\STL\Download\Download_" + DateTime.Now.ToString("dd MMM yy HH mm").Trim() + ".xls ";
        Thread newThread;
        Thread uploadThread;
        ManualResetEvent run = new ManualResetEvent(true);
      
        Excel.Application xlApp = default(Excel.Application);
       Excel.Workbook xlWorkBook = default(Excel.Workbook);
       Excel.Worksheet xlWorkSheet = default(Excel.Worksheet);
      


        

        public Form1()
        {
            InitializeComponent();
            progressBar1.Enabled = false;
            progressBar2.Enabled = false;

       
        }
      

        private void Browse_Click(object sender, EventArgs e)
        {

            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Filter = "All Files(*.*)|*.*";
            if (fdlg.ShowDialog() == DialogResult.OK)
            {


                textBox1.Text = fdlg.FileName;
                File.ReadAllText(textBox1.Text);

            }
        }

        public void threadUpload()
        {
            Excel.Application xlApp = new Excel.Application();
            Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(textBox1.Text, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            Excel._Worksheet xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[1];
            Excel.Range xlRange = xlWorksheet.UsedRange;
            string[] lines;
            

            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;
           // progressBar1.Visible = true;

            int k = 100 / rowCount;
            int i = 2;
            while (true)
            {
                run.WaitOne();

                if (PostCmdStart==0)
                {
                    s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
                    lines = Regex.Split(s, "[$#,]");
                    rspCode=Convert.ToInt32(lines[1]);
                }

                if (rspCode == 0 && i <= rowCount)
                {
                        PostCmdStart = 0;
                        for (int j = 1; j <= colCount; j++)
                        {

                            if (j == 1)
                                machId = xlRange.Cells[i, j].Value.ToString();


                            //upload1 = xlRange.Cells[i, j].Value.ToString();
                            if (j == 2)
                                custId = xlRange.Cells[i, j].Value.ToString();


                            if (j == 3)
                                name = xlRange.Cells[i, j].Value.ToString();

                            if (j == 4)
                                totalBal = xlRange.Cells[i, j].Value.ToString();

                            if (j == 5)
                                paid = xlRange.Cells[i, j].Value.ToString();

                            if (j == 6)
                                lastPaid = xlRange.Cells[i, j].Value.ToString("dd/MM/yyyy");
                            //MessageBox.Show("lastpaid:"+lastPaid);

                            if (j == 7)
                                due = xlRange.Cells[i, j].Value.ToString();


                            final = "$ POST," + machId + "," + custId + "," + name + "," + totalBal + "," + paid + "," + lastPaid + "," + due + " # ";


                        }

                        if (serialPort1.IsOpen)
                        {
                            if (machId.Length <= 5 && custId.Length <= 10 && name.Length <= 15 && totalBal.Length <= 7 && paid.Length <= 7 && lastPaid.Length <= 14 && due.Length <= 7)
                                serialPort1.Write(final);


                        }
                        progressBar1.Invoke((MethodInvoker)delegate
                        {
                            if (progressBar1.Value < 100)
                                progressBar1.Value += k;
                        });

                  

                i++;
                }
                else return;
               // progressBar1.Invoke((MethodInvoker)delegate { progressBar1.Value += 100; });
            }     
        }
private void Upload_Click(object sender, EventArgs e)
        {   PostCmdStart = 1;
            rspCode=0;
   Thread uploadThread = new Thread(new ThreadStart
          (threadUpload));

            uploadThread.Start();
}
 private void Form1_Load(object sender, EventArgs e)
        {
            progressBar1.Visible = false;
            progressBar2.Visible = false;
            serialPort1.Open();


            string[] ArrayComPortsNames = null;
            int index = -1;
            string ComPortName = null;

            ArrayComPortsNames = SerialPort.GetPortNames();
            do
            {
                index += 1;
                comboBox1.Items.Add(ArrayComPortsNames[index]);
            }

            while (!((ArrayComPortsNames[index] == ComPortName)
                          || (index == ArrayComPortsNames.GetUpperBound(0))));
            Array.Sort(ArrayComPortsNames);

            //want to get first out
            if (index == ArrayComPortsNames.GetUpperBound(0))
            {
                ComPortName = ArrayComPortsNames[0];
            }
            comboBox1.Text = ArrayComPortsNames[0];

}



         private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            btdata = (byte)serialPort1.ReadByte();
            if (btdata == '$')
            {
               ucStart = 1;
               ucDataLen = 0;
                buffer[ucDataLen++] = btdata;
            }
            else if ((btdata == '#') && (ucStart==1))
            {
                ucStart = 0;
               buffer[ucDataLen] = btdata;
                CmdDetected = 1;
               // OSSemPost(tmSmartCardModule_Sem);
                run.Set();
            }
            else if (ucStart==1)
            {
                buffer[ucDataLen++] = btdata;
            }
            else
            {
               ucStart = 0;
               ucDataLen = 0;
            }	
        }

it's not working. just for testing am using another appl,responce appli

.
C#
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {

              if (serialPort1.IsOpen)
              {
                  String RecievedData;
                  RecievedData = serialPort1.ReadExisting();
                  if (!(RecievedData == ""))
                  {
                      //textBox2.Text += RecievedData;
                      textBox2.Invoke((MethodInvoker)delegate { textBox2.Text += RecievedData; });
                  }
                 Thread.Sleep(100);
                  serialPort1.WriteLine("$M121,0#");
          }

      }
Posted
Updated 20-Dec-13 4:08am
v2
Comments
Ron Beyer 19-Dec-13 23:59pm    
"its not working" is not a description of a problem. Tell us what you expect, what its doing, where its doing it, what the issue is, etc.
Member 10263519 20-Dec-13 0:29am    
when i click upload button , thread should start, and send first record of excel.then immediatly another program through serialport sends responce for ex:am taking $M121,0#

then split that responce and test if it is 0(after ,) then only send next record.

so here am taking a thread in upload _click(), proces the first record and wait for responce, in serialport_datareceived() ,when it reads data (it should read complete data between $,#) then resume that suspended thread. this is my task plz help me......

am trying a lot
Sergey Alexandrovich Kryukov 20-Dec-13 0:51am    
You are quite right, but you see, the problem is not simple at all. I mean, the solution is simple, but it needs some deep understanding. There are two problem: how to get blocking read and why not attempting to suspend/resume. I answered. Please see, this is pretty interesting and not such a simple thing.
—SA
Member 10263519 20-Dec-13 2:25am    
hi,
by using above code. when i run it's giving first row , and it not receiving data(buffer is filled wilh 0x00) why am not getting.
Sergey Alexandrovich Kryukov 20-Dec-13 2:32am    
Hard to see from the first glance (do you realize that most members don't even have COM ports to test anything?)
You really need to use the debugger and see what's going on. Besides, I hope you understand that many things depend on what happen on the other end of your RS-232 cable. If you cannot simulate it by some other computer and have what you have, it makes things more difficult. What if some data you expect is simply not sent? :-)
—SA

1 solution

First of all, this is not called "suspend" and "resume". You need just a blocking call, blocking the thread until some condition, such as data ready. The methods blocking threads are the methods which put a thread in a special wait state when they are not use any CPU time until waken up. To have this with a serial port, you don't need anything special. You can just read some bytes using one of the System.IO.Ports.SerialPort.Read or Read* methods:
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport%28v=vs.110%29.aspx[^].

However, there is a very delicate problem here. Everything would work perfectly if you, for example, use ReadByte. Then your calling thread will be blocked, put to a wait state and not scheduled back to execution until it is waken up by some condition. It could be abort, timeout, or the byte arrived to the buffer, whichever comes first. All as you need. To read other bytes, read in "infinite" cycle. The thread will be either working and getting data all the time, or it will be put to the wait state.

However, the performance of such a simple solution may be insufficient, so you may need to read to the byte[] buffer:
http://msdn.microsoft.com/en-us/library/ms143549(v=vs.110).aspx[^].

Here is when you need to use caution. Here is why: your calling thread will be unblocked (waken up) even if you receive less bytes than you expected, because your thread will be waken up is only part of the data arrives. In other words, the mechanism of the transport and thread waking does not care how much data you requested, and your buffer will be incomplete, which may cause loss of data unless you take care about that.

This is explained here:
https://netmf.codeplex.com/workitem/1633[^].

What to do then? The idea is explained above, but let me make it clear: pay attention that the Read method referenced above returns the number or actually transmitted bytes. Using this number, you should infer if the operation is complete or not, and read more, in a cycle.

One more advice: better don't read characters instead of bytes, as the characters are the Unicode characters, may be represented in one or another UTF or ASCII, and so on, so you may receive more then one byte per character — unless you know perfectly what you are doing. It would be safer to read bytes and later deserialize them to string using one of the encodings:
http://msdn.microsoft.com/en-us/library/system.text.encoding%28v=vs.110%29.aspx[^].

[EDIT]

I also want to explain on thread "suspending" and "resuming" operations. They have been deprecated and are no longer supported, because are quite unsafe. Do you understand why? Instead, similar behavior can be achieved in the safe way by using event wait handles.

For understanding (your problem does not require using such things) please see my past answers:
Security on my developed dll[^],
pause running thread[^],
ManualResetEvent and AutoResetEvent in Thread[^],
Making Code Thread Safe[^].

—SA
 
Share this answer
 
v4
Comments
Member 10263519 20-Dec-13 1:02am    
ok, am also reading data(from $ to #) byte by byte and placing in byte[] buffer.then wakeup the thread to check the responce,

after reading complete, i have data as bytes in buffer.

in threadUpload() method converting into String, and spliting that string then i have responce in 2nd position (1).

then execute next record.
Sergey Alexandrovich Kryukov 20-Dec-13 1:16am    
If you need to read byte by byte, you can simply use ReadByte and then place bytes in the buffer, so it would be easiest from the standpoint of the thread blocking. You still need to apply some logic. But you can also read the array of bytes, with the precautions I explained and a bit different logic. I don't know what you are transmitting. If this is sending some data structures, you may need to learn and use Serialization...

Good luck,
—SA
[no name] 20-Dec-13 10:33am    
Once again wow! I'm learning and learning....thank you!
Sergey Alexandrovich Kryukov 20-Dec-13 10:52am    
And thank you.
—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