0

I have an Arduino sending a character 'c' through COM port 3.
I have a VS2013 C# console application listening on COM3 for character 'c'. The if statement when 'c' is read launches a .ahk file.

The problem is that when I build and install my application on another computer the file will only be opened if the line is written incorrectly on the console.

I noticed this after several attempts. So as to say, when data is received console prints a new line "data received", and a second line with the data.

Ex:

Data received:
c
Data received:
c
Data received:
c

Now this will not launch the application it's supposed to. But this will:

Data received:
cData received:
Data received:
c

Notice that on both examples I have received data three times, But only on the second example the lines are not parsed correctly and it does not print the character, or has line breaks either. In one of the three times it received data. Oddly enough it is then when it launches the application.

I am charging 2 USD to print photos. Each 2 USD triggers an ahk script that takes and prints the image. So every time 2 USD are insterted i receive a ´c´. Then, after the image is printed the ahk script quits and I would like it to be reopened again once another 2 USD are inserted.

I have read about Process.Start() in Microsoft pages. I'm still learning basics so it takes me a while to think in the right direction.

I have spent hours trying to figure it out through trial and error. Making modifications to the code with what my limited ability allows me to. link to an example on how to call a process from C#.

Anyhow, here is the code which (by the way) I copy pasted from a Google search on a Microsoft help site:

using System;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

class PortDataReceived
{
    public static void Main()
    {
        SerialPort mySerialPort = new SerialPort("COM3");

        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.RtsEnable = true;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();

        Console.WriteLine("Press any key to continue...");
        Console.WriteLine();
        Console.ReadKey();
        mySerialPort.Close();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
        Console.WriteLine("Data Received:");
        Thread.Sleep(300);
        Console.Write(indata);
        Thread.Sleep(300);
        if (indata == "c")
        {
            Thread.Sleep(1000);
            //Process.Start(@"C:\Users\laptop\Desktop\print.ahk");
            Process process = new Process();
            // Configure the process using the StartInfo properties.
            process.StartInfo.FileName = "print.ahk";
            process.StartInfo.Arguments = "-n";
           //process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
            process.Start();
            process.WaitForExit();// Waits here for the process to exit.
        }
    }
}

As a bonus, I need to find a programmer that will help me implement a face detection/crop program I found here on StackOverflow. Actually found one written with python and another in C#. Have been on online sites to hire programmers but the offers seem audacious, and without any promise. Anyhow pm me if you need more info.

Community
  • 1
  • 1
Julio Sitges
  • 17
  • 1
  • 1
  • 7
  • 3
    in DataReceivedHandler, you should loop on all characters got in "indata" : you may receive more than one character when the event is triggered, even if you remove the Sleep instructions that don't seem to be useful.. – Graffito Jul 08 '15 at 15:55
  • What is it you want your program to do if it receives more than one `'c'` character? If you need your program to start the process once for each character, then you need to scan the string that was read from the serial port and start the process for each one. If you just need to start the process once, no matter how many are sent, then using `Contains()` as the answer given states will work. Unfortunately, your question is too vague to know what is the _right_ answer. – Peter Duniho Jul 08 '15 at 16:07
  • @peter I am charging 2 USD to print photos. Each 2 USD triggers an ahk script that takes and prints the image. So every time 2 USD are insterted i receive a ´c´. Then, after the image is printed the ahk script quits and I would like it to be reopened again once another 2 USD are inserted. – Julio Sitges Jul 08 '15 at 16:37
  • Based on your updated information, it seems to me that you have _two_ problems with the code. The first is simple to solve: scan the received string and start the process once for each `'c'` you find. The second requires more effort: your code will not be reliable if data is received too quickly because you block the event handler while the process runs. This may work in your specific scenario, but it is likely to break in the future; you should use a separate thread to actually start and monitor the external process, using the event handler solely to signal that other thread. – Peter Duniho Jul 08 '15 at 16:52
  • If you want help actually _fixing_ the code so that it's _correct_, please say so. Otherwise, I will assume you are fine with the incorrect answer that was already provided to you. – Peter Duniho Jul 08 '15 at 16:54
  • 1
    I am indeed content with the incorrect answer. Sir, you are twice correct, first to assume I am fine with the incorrect answer and second to specify the underlying problem of blocking the event handler while the process runs. I appreciate the effort to point it out to me and fellow users. I would like to compliment you on that. Without any further remarks. -J – Julio Sitges Jul 08 '15 at 17:28

1 Answers1

0

It looks like your sender not only sends the 'c' character but also some whitespace. So basically you just need to relax the condition in your if statement a bit.

So instead of

if (indata == "c")

please try for example

if (indata.Contains("c"))
Robert Hegner
  • 9,014
  • 7
  • 62
  • 98
  • It opens the file, and when another c is sent it opens the file again. It is what I needed. Thanks – Julio Sitges Jul 08 '15 at 16:48
  • As I noted in my comment above, this solution is not correct. If the code receives more than one character in a single receive operation, it will still only run the process once. – Peter Duniho Jul 08 '15 at 16:50
  • Don't you want `if (indata.Trim() == "c")` or `if (indata.StartsWith("c"))`? Basically you are just remove the extra CrLf and searching the whole string for c makes it harder to add other strings later because they cannot contain c. – Trisped Jul 10 '15 at 04:05