So I am developing a console application which is able to read and write to/from Arduino through Serial Port. At the moment I got a switch statement to read incoming data from Arduino and depending on the incoming data I will write to the Arduino a couple of messages.
string incoming = port.ReadExisting();
string questionMark = "?";
string carriageReturn = "\r";
string text = string.Empty;
switch (incoming)
{
case "#r\r":
port.Write(questionMark+ "*" + carriageReturn);
break;
case "#{":
port.Write("#" + text);
break;
default:
Console.WriteLine("Unknown command sent by the Arduino\n Command: " + incoming);
break;
}
Now, I am testing out the application with another application to read and write it and when I send to the console application the "#r\r" it will give
Unknown command sent by the Arduino\n Command: "#r\r".
I've found the problem and it comes from the carriage return or \r.
Do you have any idea how could I solve this problem? I want to receive the carriage return because it is the end of it.
Related
I have 1 gsm 32 port with name is xr21v1414 USB UART
I have tested another AT COMMAND which works fine like
AT
USSD
but if i use COMMAND :
serialPort.WriteLine("AT" + System.Environment.NewLine);
Thread.Sleep(200);
serialPort.WriteLine("AT+CMGF=1" + System.Environment.NewLine);
Thread.Sleep(200);
serialPort.WriteLine("AT+CMGL=\"ALL\"" + System.Environment.NewLine);
Thread.Sleep(200);
responded with
serialPort.ReadExisting();
is empty (OK only)
AT
OK
AT+CMGF=1
OK
AT+CMGL="ALL"
OK
But if I switch to another gsm, Command work fine. I have list SMS.
This is my setting :
SerialPort serialPort = new SerialPort();
serialPort.PortName = m.ToString();
serialPort.BaudRate = 115200;
serialPort.DataBits = 8;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.StopBits = StopBits.One;
serialPort.Parity = Parity.None;
serialPort.ReadTimeout = 20000;
serialPort.WriteTimeout = 20000;
serialPort.WriteBufferSize = 1024;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
How could i resolve the problem ,please ?
I am quite sure that the OK response you get is because you have aborted the current command line by using Thread.Sleep(200) instead of reading and parsing the response you get back from the modem, waiting for the Final Result Code before sending the next command.
The first linked answer above is to a question whose code which is slightly worse because it does not even have a sleep, but even having one is utterly wrong. Just as you would not write a HTTP client that ignores the responses a HTTP server send it, you should not write a AT command program that ignores the responses the modems sends it.
TL;DR You MUST change your code to read and parse every single response line that the modem sends you, waiting for the Final Result Code before sending the next command. See the linked answers for more details.
In Tera Term I'm connecting to a serial device over USB (on startup select radiobutton "serial" and correct port). Once connected I only change the default speed to 115200 (in setup=> serial port).
After this, tera term asks me to fill in commands like so:
Command>
I fill in the device specific command. In this case it's "PC" and I receive an expected response ie. "ABC"
Now I'm trying to do the same in C#. Unfortunately the response I get is always the same as the command I actually type in.
So If I type in "PC", the response is "PC", but I expect "ABC". Other commands have the same problem. Command "?" responds with "?" while I expect "CBA".
If I type in a faulty command => then I get the message "Unknown command"
So I suspect the device actually gets the right command.
I'm using the following code:
SerialPort COMport = new SerialPort(Port_Name, Baud_Rate); //Create a new SerialPort Object (defaullt setting -> 8N1)
COMport.DataReceived += new SerialDataReceivedEventHandler(sPort_dataReceived);
COMport.ErrorReceived += new SerialErrorReceivedEventHandler(sPort_ErrorReceived);
COMport.BaudRate = 115200;
COMport.Parity = Parity.None;
COMport.DataBits = 8;
COMport.StopBits = StopBits.One;
COMport.RtsEnable = true;
COMport.Handshake = Handshake.None;
COMport.Open();
COMport.WriteLine(Data);
Thread.Sleep(1000); // Just discovered after a lot of testing that this is necessary to read the response before the Comport closes
COMport.Close();
Then I do the following:
private void sPort_dataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
MessageBox.Show(indata);
}
I've tried different things, but I can't get this to work. Hopefully it's because I'm new to this. I've never worked with Tera term before.
Thanks in advance,
Some (but definately not all) things I've tried:
tried this guys advise and code: https://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport
downloaded and tried from here: https://www.xanthium.in/building-opensource-gui-based-serial-port-communication-program-dot-net-framework-and-arduino#simple-serial-source-code (Although my device is not arduino)
Tried to add "\r\n" : C# Errors with SerialPort WriteLine commands
EDIT EDIT EDIT EDIT
So I found out more. If I use the following code (Write instead of WriteLine), I do get good results but not every time:
Sending the full command now: "Command>PC"
string Command1 = txtCommand.Text;
Command1 = Command1 + "\r\n";
string CommandSent;
int Length, j = 0;
Length = Command1.Length;
for (int i = 0; i < Length; i++)
{
CommandSent = Command1.Substring(j, 1);
ComPort.Write(CommandSent);
j++;
}
The first time, now I get good results. The second time I get "Unknow Command", the 3rd time => good results, 4th = "Unknown Command"... etc...
It always seems to work 1 time well, then 1 time not.
I can only get it to work consistently if I switch the command formatting:
First time command: "Command>PC"
Second time command: "PC"
Third time command : "Command>PC"
Fourth time command: "PC"
etc...
I've already tried to clear the buffer before sending but no effect.
ComPort.DiscardInBuffer();
ComPort.DiscardOutBuffer();
The Newline seemed to be a problem.
I needed to use Comport.Write (instead of WriteLine). Then Also I needed to append a carriage return "\r" but NO newline '\n' as I previously thought. (the incoming data showed a newline after the "Command>" making it impossible to send another meaningfull command => the cause of this was '\n' => removing it solved the problem)
This is my current code that seems to work (I no longer need to append "Command>", just sending the command as is):
if (thecommand == "")
{
ComPort.Write("\r"); //start from a clean slate
return;
}
ComPort.DiscardInBuffer();
ComPort.DiscardOutBuffer();
string Command1 = thecommand + "\r";
ComPort.Write(Command1);
I am trying to automate the remote server shell commands through Plink. And one of the things which I did is grep command.
Now suppose if results lots of data then I just want to break the command.
Generally from PuTTY you just do Ctrl-C or Ctrl-Break and it will break the command.
What's the alternative for Plink?
Do not run Plink from C# application to implement SSH. Use a native .NET implementation of SSH, like SSH.NET. – It will give you a complete control over the connection and you won't have have to use hacks like sending Ctrl+C.
var client = new SshClient("example.com", "username", "password");
client.Connect();
SshCommand command = client.CreateCommand("grep pattern file");
IAsyncResult result = command.BeginExecute();
using (var outputReader = new StreamReader(command.OutputStream))
using (var extendedReader = new StreamReader(command.ExtendedOutputStream))
{
int read = 0;
while (read < 10240)
{
string s;
s = outputReader.ReadToEnd();
read += s.Length;
Console.Write(s);
s = extendedReader.ReadToEnd();
read += s.Length;
Console.Write(s);
}
}
command.CancelAsync();
Also, you can use -m switch to stop grep after certain number of matches.
I'm trying to show sms messages in modem (I use my phone as modem),
Port connect successfully by using AT commands
and I can Import the number and date but the body of message show as number.
this is my code :
port.Write("AT" + System.Environment.NewLine);
Thread.Sleep(1000);
port.WriteLine("AT+CMGF=1" + System.Environment.NewLine);
Thread.Sleep(1000);
port.WriteLine("AT+CMGL=\"ALL\"\r" + System.Environment.NewLine); //("AT+CMGL=\"REC UNREAD\"\r");
Thread.Sleep(3000);
MessageBox.Show(port.ReadExisting());
What is the best option to send text to the default printer?
The printer is a Zebra, and the text is a string of ZPL.
Many examples out there are with font size, graphics, points (x,y). Very confusing.
But I need to send the string and the printer does its work.
You can open the port directly using a p/invoke to OpenFile if you are connected using LPT or COM ports, but otherwise you will need to use the print ticket APIs to create a RAW formatted job. See http://support.microsoft.com/?kbid=322091 for a helper class which calls the appropriate platform functions to allows RAW print jobs from C#.
Is your Zebra printer on a network?
If so, this will work-
// Printer IP Address and communication port
string ipAddress = "10.3.14.42";
int port = 9100;
// ZPL Command(s)
string ZPLString =
"^XA" +
"^FO50,50" +
"^A0N50,50" +
"^FDHello, World!^FS" +
"^XZ";
try
{
// Open connection
using (System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient())
{
client.Connect(ipAddress, port);
// Write ZPL String to connection
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(client.GetStream()))
{
writer.Write(ZPLString);
writer.Flush();
}
}
}
catch (Exception ex)
{
// Catch Exception
}
I've used this library successfully as well for USB.