Using SerialPort class to read response from connected device - c#

I'm using C#'s SerialPort class to try and send a AT command to a device and get a response back. I've verified it works correctly in HyperTerminal, if I send a command of AT it responds back with OK. However, in my console app, if I send AT, it replies back with an echo AT. The code is below, any insight into what I'm doing wrong in my receiving code would be greatly appreciated:
ComPort.DataReceived += new SerialDataReceivedEventHandler(ComPort_DataReceived);
public void Open()
{
Console.WriteLine();
//close port if already open.
if (ComPort.IsOpen)
{
ComPort.Close();
}
//setup port.
ComPort.PortName = ConfigurationManager.AppSettings["PortName"].ToString();
ComPort.BaudRate = Convert.ToInt32(ConfigurationManager.AppSettings["BaudRate"]);
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.DtrEnable = true;
ComPort.RtsEnable = true;
if (Convert.ToBoolean(ConfigurationManager.AppSettings["HWFlowControlEnabled"]))
{
ComPort.Handshake = Handshake.RequestToSend;
}
//open port.
Console.WriteLine("Opening port " + ComPort.PortName + "...");
ComPort.Open();
Console.WriteLine("Opened port " + ComPort.PortName);
}
void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string message = ComPort.ReadExisting();
Console.WriteLine("RECEIVED: " + message);
if (message.IndexOf("OK") > -1)
{
ReceivedOK = true;
}
}

I think the default is to echo your commands back to you, then the OK. Send an ATE0 first to turn off echo:
http://tigger.cc.uic.edu/depts/accc/network/dialin/modem_codes.html

By default, the device (a modem I guess) is configured to echo all communication back. There are AT commands to turn echo on and off. Also, several hardware signalling approaches exist to control the flow of data. Have a look here for a basic overview.
It's quite a while (> 10 years actually) since I was doing modem communications, so I'm sorry in case my answer isn't 100% precise.

Related

Why C# Serial port not working with AT+CGSN

Im trying to get IMEI of a Samsung S7 device. I tried with AT+CGSN via Putty which worked perfectly. When I tried the same with C# SerialPort returns empty string.
Sending AT\r\n on C# SerialPort giving "OK" as expected and all other AT commands are also working except this
It looks bit wired for me on why it was not working for the specific commands where others are working.
Here is the sample.
private static string GetMobileSerialNumber(string PortName)
{
string Serial = "";
SerialPort serialPort = new SerialPort();
serialPort.PortName = PortName;
serialPort.BaudRate = 154200;
serialPort.Handshake = Handshake.None;
serialPort.ReadBufferSize = 16384;
try
{
if (!(serialPort.IsOpen))
serialPort.Open();
serialPort.Write("AT+CGSN\r\n");
Thread.Sleep(1000);
Serial = serialPort.ReadExisting();
serialPort.Close();
Console.WriteLine(Serial);
return Serial;
}
catch (Exception ex)
{
//MessageBox.Show("Error in opening/writing to serial port :: " + ex.Message, "Error!");
return "";
}
}
Sample also available here
PuTTY and teraterm filtering /n /r similar parameters CR LF byte commands.
your cmd wrong

Connecting to NI USB to 232/4 failure

Currently trying to send basic messages through an NI USB-232/4 to a power supply. While connecting with my code, the messages will not get sent through, and the PORT led remains red/orange.
When connecting with the power supply's code, messages can be received perfectly fine, the PORT led turns green. The power supply reacts to commands given.
When connecting the supplied program trough virtual serial ports to a terminal, the messages sent are identical to the messages my program is sending. When input directly from a terminal window to the power supply, the commands work fine. Again, the port led turns green while connecting through the terminal.
The serial settings, as far as I can tell, are identical to those that both the supplied program and the terminal are using. However, the power supply refuses to accept the messages.
public Serial(){
ThreadSafe.serialVoltage.Enqueue("*IDN?");
ThreadSafe.serialVoltage.Enqueue("SYST:REM\n");
ThreadSafe.serialVoltage.Enqueue("INST SECO");
ThreadSafe.serialVoltage.Enqueue("OUTP 1");
ThreadSafe.serialVoltage.Enqueue("VOLT 9V");
}
public void ListenForVoltageChange()
{
string result;
_serialPort = new System.IO.Ports.SerialPort();
OpenPort();
Thread.Sleep(1000);
while (true) {
if (!ThreadSafe.serialVoltage.IsEmpty) {
ThreadSafe.serialVoltage.TryDequeue(out result);
Debug.WriteLine(result);
_serialPort.WriteLine(result);
}
Thread.Sleep(1000);
}
}
public bool OpenPort()
{
Debug.WriteLine("Port Open");
Debug.WriteLine(_serialPort.IsOpen);
if (!_serialPort.IsOpen)
{
_serialPort.PortName = "COM4";
_serialPort.BaudRate = 9600;
_serialPort.Parity = System.IO.Ports.Parity.None;
_serialPort.DataBits = 8;
_serialPort.StopBits = System.IO.Ports.StopBits.One;
_serialPort.RtsEnable = false;
_serialPort.Handshake = System.IO.Ports.Handshake.None;
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
try
{ _serialPort.Open(); }
catch { return false; }
}
return true;
}

unable to communicate with obd-II

I am trying to communicate with ECUsim 2000 which is OBD-ll ECU simulator (link). Yet, responses I always receive from device are something like "??" or "?" (when I run programs like TouchScan or OBD Auto Doctor, they successfully reads data so device is working properly). I am sending comand in C# via
serialPort1.Write("010D\r")
and I am receiving signal in SerialPort's DataReceived event as
message = "Data Received: " + serialPort1.ReadExisting();
this.Invoke(new EventHandler(displayText));
I do not now what I am missing. Here is the full source code
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 115200;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Handshake = System.IO.Ports.Handshake.None;
serialPort1.Open();
}
private void button1_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Write("010D\r");
}
}
private void displayText(object sender, EventArgs e)
{
textBox1.AppendText(message + "\n");
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
message = "Data Received: " + serialPort1.ReadExisting();
this.Invoke(new EventHandler(displayText));
}
Default communication settings of ECUsim 2000 are
Baud Rate: 115200
Data bits: 8
Parity: none
Stop bits:1
protocol is ISO 15765-4 and there are two switches on the device which are protocol attribute CAN ID 29/11 bit and CAN Baud Rate 500 kbps/250kbps. Maybe, the problem are related with these such that there is no proper communication set.
Another question -> Is there a way to set protocol (like ISO 15765-4) in serial communication?
There are two problems related with the code given.
1) There are two connector on the ECUsim 2000. One of them is type B USB port, other one is Diagnostic Link Connector (DLC). If one wants to get connected to device via type B USB port, baud rate is: 115200. If DLC is used, Baud Rate is most probably either 9600 or 38400. Here, connection is made through scan tool, therefore (for my case) baud rate 38400 worked for me.
2) As mentioned in the comment, In order to get data, Read() method of SerialPort must be used. It can be used as the following code:
int buffSize = 1024;
bool cont = true;
int count = 0;
byte[] bff = new byte[buffSize];
string returnVal = string.Empty;
count = serialPort1.Read(bff, 0, buffSize);
returnVal += System.Text.Encoding.Default.GetString(bff, 0, count);

Get last call duration using AT+CLCC command

I coded a program to dial automatically when phone is connected to the laptop and get the last call duration.I used AT+CLCC command to get current call status..Though it should return the Some string value as .......etc i got nothing like that so far...Here is my code..
_serialPort.BaudRate = 9600;
_serialPort.Parity = Parity.None;
_serialPort.DataBits = 8;
_serialPort.StopBits = StopBits.One;
_serialPort.Handshake = Handshake.None;
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_serialPort.DtrEnable = true;
_serialPort.RtsEnable = true;
string phonenr = "";
// string mesaj;
if (!_serialPort.IsOpen)
{
_serialPort.Open();
}
_serialPort.WriteLine("AT\r");
{
Console.WriteLine("Enter the phone number:", phonenr);
phonenr = Console.ReadLine();
_serialPort.WriteLine("ATD" + phonenr + ";" + "\r");
Console.WriteLine("Ring...");
Thread.Sleep(10000);
_serialPort.WriteLine("AT+CLCC");
_serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
//As a seperate function....
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
What is the wrong with this code????How can i get the response as the format ...etc ???
AT+CLCC command does not provide information about the last call. It provides information during a call (during dialing/ringing/waiting etc). Read this for detailed information
I think you can make the phone to output last call details automatically to the terminal, when the call is disconnected but I'm not sure if it provides call duration. You might have to monitor/record the time manually with your application
I have seen other posts where you have asked similar questions. I would recommend using a simple serial port terminal (putty or terminal etc.) to communicate with the phone and grasp the AT commands concept, before moving on to controlling the phone using your own code.

SerialPort First Command OK. Second Command Error

I'm writing a serialport app to talk to a Bluetooth module over serial port. The first At command I send to the device runs fine and I get a response of the module version. All subsequent commands fail with a response of ERROR.
Part of the code is here:
namespace PhoneApp
{
public partial class Form1 : Form
{
//SerialPort myport = OPenPort.OpenIt();
SerialPort myport = new SerialPort();
public Form1()
{
InitializeComponent();
myport.PortName = "COM3";
myport.BaudRate = 115200;
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.StopBits = StopBits.One;
myport.NewLine = System.Environment.NewLine;
myport.ReadTimeout = 500;
myport.WriteTimeout = 500;
myport.DtrEnable = false;
myport.RtsEnable = false;
myport.WriteBufferSize = 4096;
myport.ReadBufferSize = 4096;
myport.Handshake = Handshake.None;
myport.Encoding = System.Text.Encoding.ASCII;
if (!myport.IsOpen)
{
myport.Open();
}
calling.Visible = false;
myport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
mycommand.Text = #"AT+BGVER";
the button which sends the command. The device requires a newline after each comand.
private void button2_Click(object sender, EventArgs e)
{
try
{
myport.WriteLine(mycommand.Text.Trim());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Not sure what I'm missing here.
Thanks for the replies. i found the problem. In fact I had to use myport.Write instead of myport.WriteLine. I deleted the line myport.NewLine and I appended "\r" to every command. Now the device responds as expected. As for DTR and RTS they are not required by the device according to the vendor
Not sure if this solves your problem, but I noticed that you don't have flow control enabled (e.g. myport.RtsEnable = false; myport.DtrEnable = false;).
Have you checked the documentation to make sure that the Bluetooth module doesn't require it? Typically devices with 115kbps and higher need flow control.
Another thing to check is the NewLine constant. You set it to the sys default which is likely Cr+Lf. Make sure that the module expects that.

Categories