Click here to Skip to main content
15,937,779 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
There is a device that we have to read pressure and voltage from that.To read pressure and voltage, I have to send command to the device and then wait to get my answer...For example "PCR" command gives me the pressure and "UCR" command gives me the voltage.I have already done all these things...the problem is sometimes there is no answer for the command and the device doesn't want to answer or answer later...How can I make it that if after some miliseconds the device does not answer just continue?

What I have tried:

private void getData()
            if (serialPort1.IsOpen)
                string PCR = "";
                decimal decPCR = 0;
                byte[] readCommand = { 0x50, 0x0D };
                serialPort1.Write(readCommand, 0, 2);
                int bytestoread = serialPort1.BytesToRead;
                if (bytestoread > 0)
                    byte[] input = new byte[bytestoread];
                    serialPort1.Read(input, 0, bytestoread);
                    PCR = System.Text.Encoding.UTF8.GetString(input);
                if (PCR.StartsWith("P"))
                    if (PCR.Length > 15)
                        PCR = PCR.Substring(3, PCR.IndexOf("T") - 3).Trim();
                        decPCR = Decimal.Parse(PCR, NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint);
                        tBoxPressureData.Text = decPCR + " Torr";
                        double data;
                        bool result = Double.TryParse(decPCR.ToString(), out data);
                        if (result)
                            //Take previous n records
                            var prvData = PressureChart.Series["Pressure"].Points.Reverse().Take(5).Reverse();
                            var newList = new List<PointData>();
                            foreach (var item in prvData)
                                newList.Add(new PointData(item.AxisLabel, item.YValues.First()));

                            newList.Add(new PointData(DateTime.Now.ToString("HH:mm:ss"), data));

                            PressureChart.ChartAreas[0].AxisY.Minimum = newList.Min(c => c.Y);
                            PressureChart.ChartAreas[0].AxisY.Maximum = newList.Max(c => c.Y);
                            PressureChart.ChartAreas[0].AxisY.Interval = 0.0000010;

                            fillChart(PressureChart, "Pressure", newList);


                string UCR = "";
                decimal decUCR = 0;
                byte[] readCommand2 = { 0x55, 0x0D };
                serialPort1.Write(readCommand2, 0, 2);
                int bytestoread2 = serialPort1.BytesToRead;
                if (bytestoread2 > 0)
                    byte[] input2 = new byte[bytestoread2];
                    serialPort1.Read(input2, 0, bytestoread2);
                    UCR = System.Text.Encoding.UTF8.GetString(input2);
                if (UCR.Contains("Volts") && UCR.StartsWith("V"))
                    if (UCR.Length > 15)
                        UCR = UCR.Substring(5, UCR.IndexOf("Volts") - 5).Trim();
                        decUCR = Decimal.Parse(UCR, NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint);
                        tBoxVoltageData.Text = decUCR + " Volts";
                        double data2;
                        bool result2 = Double.TryParse(decUCR.ToString(), out data2);
                        if (result2)
                            //Take previous n records
                            var prvData2 = VoltageChart.Series["Voltage"].Points.Reverse().Take(5).Reverse();
                            var newList2 = new List<PointData>();
                            foreach (var item2 in prvData2)
                                newList2.Add(new PointData(item2.AxisLabel, item2.YValues.First()));


                            newList2.Add(new PointData(DateTime.Now.ToString("HH:mm:ss"), data2));

                            VoltageChart.ChartAreas[0].AxisY.Minimum = newList2.Min(c => c.Y);
                            VoltageChart.ChartAreas[0].AxisY.Maximum = newList2.Max(c => c.Y);
                            VoltageChart.ChartAreas[0].AxisY.Interval = 0.0010;

                            fillChart(VoltageChart, "Voltage", newList2);

                MySqlCommand dbcm = new MySqlCommand(string.Format("INSERT INTO `read_data` (`pressure`,`voltage`,`date and time`) VALUES('{0}','{1}','{2}')", decPCR, decUCR, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), db);

Updated 15-Aug-22 19:10pm

1 solution

Start by making sure you can communicate with the device: use Hyperterminal or similar to make sure that everything works as expected before you even start coding.
Then at least you start from a working base: your baud rate and other communication parameters are correct before you start adding in other complexities.

When you have a working base to go from, think about how the communications work: you send a message, it should respond - that can take more than a few milliseconds: 9600 baud for example is less than 900 characters per second, plus there is the "unknown) response time taken by the device at the other end anyway.

Bear in mind that serial ports are just that: they receive data as individual characters, not whole messages - and each character takes time to arrive. So checking for input and grabbing it immediately expecting it to be the whole message probably isn't going to work unless your PC is unbelievably slow!

What I'd do is set up a secondary thread to handle all comms: it monitors for input and feeds messages back up to the main thread via an event without worrying about their content, just using the "basic packaging" of the device messages - probably just "text ending with a newline". A BackgroundWorker is a good fit here, as it provides progress reporting which can handle a whole message. This can easily be set up to provide a timeout

The higher level task then processes the message and either displays it, or converts it for addition to the DB.

And don't do DB work like that! Never concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Always use Parameterized queries instead.

When you concatenate strings, you cause problems because SQL receives commands like:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
The quote the user added terminates the string as far as SQL is concerned and you get problems. But it could be worse. If I come along and type this instead: "x';DROP TABLE MyTable;--" Then SQL receives a very different command:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Which SQL sees as three separate commands:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
A perfectly valid SELECT
A perfectly valid "delete the table" command
And everything else is a comment.
So it does: selects any matching rows, deletes the table from the DB, and ignores anything else.

So ALWAYS use parameterized queries! Or be prepared to restore your DB from backup frequently. You do take backups regularly, don't you?
Share this answer

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