im using mobitek gsm modem and the source code it used is in VB. now i want to convert the code into c#. the code that i have trouble with is intModemStatus = SMS.ModemInit(frmModem.txtPort.Text, ""). after that, the code will go through with select case as below:
intModemStatus = SMS.ModemInit(frmModem.txtPort.Text, "")
Select Case intModemStatus
Case 0
FrmModem.txtText.Text = "GSM Modem Not Connected!"
'[VB - Module1] frmModem.txtText = "GSM Modem Not Connected!"
Exit Sub
Case 1
FrmModem.txtText.Text = "CONNECTED!"
'[VB - Module1] frmModem.txtText = "GSM Modem Connected!"
Exit Sub
Case 2
FrmModem.txtText.Text = "PIN Required!"
'[VB - Module1] frmModem.txtText = "PIN Required!"
Exit Sub
Case 3
FrmModem.txtText.Text = "Incorrect PIN Entered! Warning after 3 tries of incorrect PIN entered, your SIM card will be blocked by TELCO!"
'[VB - Module1] frmModem.txtText = "Incorrect PIN entered! Warning: after 3 tries of incorrect PIN entered, your SIM card will be blocked by TELCO!"
Exit Sub
Case 4
FrmModem.txtText.Text = "Your SIM card is blocked by TELCO!"
'[VB - Module1] frmModem.txtText = "Your SIM card is blocked by TELCO!"
Exit Sub
Case 5
FrmModem.txtText.Text = "Your SIM card has problem!"
'[VB - Module1] frmModem.txtText = "Your SIM card has problem!"
Exit Sub
Case Else
FrmModem.txtText.Text = "GSM Modem Not Connected!"
'[VB - Module1] frmModem.txtText = "GSM Modem Not Connected!"
Exit Sub
End Select
i have converted everything into c# includes with the switch case like this:
int ModemStatus = sms.ModemInit(txtPort.Text, "");
switch (intModemStatus)
{
case 0:
txtText.Text = "GSM Modem Not Connected!";
//[VB - Module1] frmModem.txtText = "GSM Modem Not Connected!"
return;
break;
case 1:
txtText.Text = "CONNECTED!";
//[VB - Module1] frmModem.txtText = "GSM Modem Connected!"
return;
break;
case 2:
txtText.Text = "PIN Required!";
//[VB - Module1] frmModem.txtText = "PIN Required!"
return;
break;
case 3:
txtText.Text = "Incorrect PIN Entered! Warning after 3 tries of incorrect PIN entered, your SIM card will be blocked by TELCO!";
//[VB - Module1] frmModem.txtText = "Incorrect PIN entered! Warning: after 3 tries of incorrect PIN entered, your SIM card will be blocked by TELCO!"
return;
break;
case 4:
txtText.Text = "Your SIM card is blocked by TELCO!";
//[VB - Module1] frmModem.txtText = "Your SIM card is blocked by TELCO!"
return;
break;
case 5:
txtText.Text = "Your SIM card has problem!";
//[VB - Module1] frmModem.txtText = "Your SIM card has problem!"
return;
break;
default:
txtText.Text = "GSM Modem Not Connected!";
//[VB - Module1] frmModem.txtText = "GSM Modem Not Connected!"
return;
break;
}
however, i am having trouble with this code int ModemStatus = sms.ModemInit(txtPort.Text, "");. it said that
Argument 1cannot convert string to short.
the best overloaded method match for mobitekSMSAPI5.ModemInit(short, string) have some invalid argument.
then i tried to change int ModemStatus = sms.ModemInit(txtPort.Text, ""); but it says the same.
to use the mobitek gsm modem, i required to add reference of MobitekSMSAPI5 and i did. the switch code will determine if the modem have been connected or else.
i am really hoping for someone to step up solving this problem. im stuck in the middle and i did not know where to start. any kinds of helps are appreciated. thank you.
here is my error:
when im using this code it appears:
short port;
if (!short.TryParse(txtPort.Text, out port))
{
throw new Exception("Failed to parse port");
// or any other handling - depends on your needs
}
int ModemStatus = sms.ModemInit(port, "");
now it appears different error when im changing the code like below.
sms.ModemInit accepts short as a first parameter. As long as your were dealing with VB.Net, conversion of string into short was done implicitly. It was possible due to compiler's Option Strict option, which is disabled by default. When enabled this option allows only implicit widening conversions. When disabled (default state) this option allows both implicit narrowing and widening conversions.
In C# however narrowing implicit conversions are forbidden, and this is why your translated code fails. So you need to parse your string value explicitly and pass a parsed number to the method:
short port = short.Parse(txtPort.Text);
int ModemStatus = sms.ModemInit(port, "");
or, even better, use TryParse to avoid possible exceptions:
short port;
if (!short.TryParse(txtPort.Text, out port))
{
throw new Exception("Failed to parse port");
// or any other handling - depends on your needs
}
int ModemStatus = sms.ModemInit(port, "");
Your problem is just a couple of casting issues. The first one is related to the port number, the ModemInit method expects a short value but your passing a string, so you have already fixed that by using short.TryParse.
The other issue is your return type, the ModemInit method seems to return it's own custom enum value, if all your interested in is the integer value then all you need to do is cast it as an int.
int ModemStatus = (int)sms.ModemInit(port, "");
I would do this:
short shortValue = 0;
if (short.TryParse(txtPort.Text, out shortValue))
{
... continue using shortValue
}
else
{
...Tell user the value must be a number
}
This way you handle the condition of an user entering a non-number (without resorting to exceptions)
As the error clearly states, you can't pass a string as a short.
You need to call short.Parse().
Related
I have a device which sends "go" through serial communication. I want my application to act on that command, however it seems to have some kind of a bug.
The following code doesn't enter the if-statement, however when I print dataIN1 in a textbox is does print "go" in the textbox.
dataIN1 = serialPort1.ReadExisting(); // Read incoming data from serial port 1
if (dataIN1 == "go") { //if 'go' is send, check cBox and start program for programming
Weirdly the following change does work:
dataIN1 = serialPort1.ReadExisting(); // Read incoming data from serial port 1
textBox1.Invoke((MethodInvoker)delegate { textBox1.Text = dataIN1;});
string test2 = textBox1.Text;
if (test2 == "go") { //if 'go' is send, check cBox and start program for programming
dataIN1 is a global string.
putting dataIN1 directly in test2 doesn't work as well.
I also tried:
string test = dataIN1;
string test2 = Test + dataIN1;
In case it sends g and o separately.
I don't want to use a textbox for it to work, does anyone has any ideas on how to tackle this problem?
This code is working
this code is not working
We have an application (C#) that up till today has worked fine.
It communicates with a laravel website to manage the sites data.
So there are some validation points that occur, the application does checks with out SSO provider for authentication. Then it passes some of the user's information over to the site so the site can create a user / send back user id for further entry points.
I have literally not touched this in months - and its been working without a problem.
Today I get a message its not working and so I start digging.
Can somebody explain THIS one?
C# Code For Validating User - Notice the response from the site.
The Laravel API Routes File on the route in question.
public function validation(Request $request) {
//Check if user exists if they do then just return. If they dont we need to create them in the system.
$user = User::where('email', $request['Email'])->first();
if($user == null) {
$nuser = new User();
$nuser->first_name = $request['FName'];
$nuser->last_name = $request['LName'];
$nuser->email = $request['Email'];
$nuser->token = $request['Token'];
switch($request['Role']) {
case 1:
$nuser->user_level = 1;
break;
case 2:
$nuser->user_level = 2;
break;
case 3:
$nuser->user_level = 3;
break;
case 4:
$nuser->user_level = 4;
break;
default:
$nuser->user_level = 4;
break;
}
try {
$nuser->save();
return json_encode($nuser);
}catch(\Exception $e) {
Log::error($e->getMessage());
}
}else{
switch($request['Role']) {
case 1:
$user->user_level = 1;
break;
case 2:
$user->user_level = 2;
break;
case 3:
$user->user_level = 3;
break;
case 4:
$user->user_level = 4;
break;
default:
$user->user_level = 4;
break;
}
try {
$user->save();
return json_encode($user);
}catch(\Exception $e) {
Log::error($e->getMessage());
}
}
}
So the end user of the C# application decided to overwrite the ini file with the website in it (for quick swaps between dev and production for the development team)....I noticed new entries in the development server's database from yesterday....end user then tries to put it back to the production server. But left off the s in https - and like any good website - it auto redirects to its https counterpart.
Cue RestClient trying to follow the redirect with a GET.
Updated the INI fixing the typo, tell user to close the application and reopen it to reload the INI data. Have our network team lock down the network folder containing the INI to read only unless its a member of the development team. And we're back rolling.
I want to do serial port communication with a machine which uses RS232-USB ports.
I am using serial port class. I am very new to the concept. In my first Machine interfacing I only had to do the serialport.readLine( to get the readings from the machine and there was no need to send ACK /NAK). but for the new machine interface the document says following things:
The following is an example of the RA500 communication:
Computer :<05h 31h 0dh>
RA500 :1st line of information
Computer :<06h 0dh>
RA500 :2nd line of information
Computer :<06h 0dh>
RA500 :”EOF”<0dh>
What i understood from this is i have to write to comport before reading from it. this is what i am doing in my code:
ACK = "06 0d"; NAK = "15 0d"; str = "05 31 0d";
while (count <= 5)
{
rx = ComPortDataReceived(str);
if (!string.IsNullOrEmpty(rx))
{
str = ACK;
returnReading += rx;
}
else if (string.IsNullOrEmpty(rx)) str = NAK;
count++;
}
private string ComPortDataReceived(string str)
{
string Rx = string.Empty;
string exceptionMessage = string.Empty;
try
{
byte[] bytes = str.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
comPort.Write(bytes, 0, bytes.Length);
Rx = comPort.ReadExisting();
PEHRsLibrary.writeTextFile(DateTime.Now + " RxString :" + Rx);
return Rx;
}
catch(Exception e){}
when i use this code i am receiving empty strings as responce. but if i use comPort.ReadExisting() only without using comPort.Write i am receving a string with all the readings but the probblem is it only gives one line of information and dosnt give 2nd or 3rd line readings.
when i try using comPort.ReadLine() after Write() I am getting Timeout exception.
i dont know what i am doing wrong in this case. I am writing ACk after receving 1st line but not receving 2nd line. Next thing i am gonna try is read() as byte and then convert it to string instead of using ReadExisting(). Any other way i can do this?
I am developing an application for GSM Modems (D-Link DWM-156) in C#.Net using AT commands. I have a problem sending English SMS.
I try to send "hello", But I receive □□□□ in my phone or ...exept hello.
serialPort1.DataBits = 8;
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
serialPort1.DiscardInBuffer();
serialPort1.DiscardOutBuffer();
serialPort1.WriteLine("AT\r");
Thread.Sleep(2000);
serialPort1.WriteLine("AT+CMGF=1\r");
Thread.Sleep(1000);
serialPort1.WriteLine("AT+CMGS=\"09390149196\"\r")
Thread.Sleep(2000);
serialPort1.WriteLine("hello" + "\x1A");
Thread.Sleep(1000);
Few fixes (maybe more but I don't see full-code).
Do not use WriteLine() but Write() because for \r (alone) is the command line and result code terminator character.
SerialPort.WriteLine() by default writes a usASCII encoded string but your GSM modem expect strings encoded as specified with an AT command. Set SerialPort.Encoding property to a specific encoding and send CSCS command. You can ask supported encodings with CSCS=? AT command. Even if default GSM should apply I'd avoid to rely implicitly on this.
You do not need to wait after each command but you have to wait for modem answer (checking for OK or ERROR strings).
From docs:
A command line is made up of three elements: the prefix, the body, and the termination character. The command line prefix consists of the characters "AT" or "at" [...] The termination character may be selected by a user option (parameter S3), the default being CR.
In pseudo-code:
void SendCommand(string command) {
serialPort.Write(command + "\r");
// Do not put here an arbitrary wait, check modem's response
// Reading from serial port (use timeout).
CheckResponse();
}
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.BaudRate = 9600;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.GetEncoding("iso-8859-1");
serialPort.DiscardInBuffer();
serialPort.DiscardOutBuffer();
SendCommand("AT"); // "Ping"
SendCommand("AT+CMGF=1"); // Message format
SendCommand("AT+CSCS=\"PCCP437\""); // Character set
SendCommand("AT+CMGS=\"123456\"") // Phone number
SendCommand("hello" + "\x1A"); // Message
To check response (absolutely avoid arbitrary waits!) you can start with something like this (raw untested adaption so you may need some debugging, see also this post):
AutoResetEvent _receive;
string ReadResponse(int timeout)
{
string response = string.Empty;
while (true)
{
if (_receive.WaitOne(timeout, false))
{
response += _port.ReadExisting();
}
else
{
if (response.Length > 0)
throw new InvalidOperationException("Incomplete response.");
else
throw new InvalidOperationException("No response.");
}
// Pretty raw implementation, I'm not even sure it covers
// all cases, a better parsing would be appreciated here.
// Also note I am assuming verbose V1 output with both \r and \n.
if (response.EndsWith("\r\nOK\r\n"))
break;
if (response.EndsWith("\r\n> "))
break;
if (response.EndsWith("\r\nERROR\r\n"))
break;
}
return response;
}
Adding _receive.Reset() just before you send your command and of course also adding OnPortDataReceived as handler for SerialPort.DataReceived event:
void OnPortDataReceived(object sender,
SerialDataReceivedEventArgs e)
{
if (e.EventType == SerialData.Chars)
_receive.Set();
}
If you have some trouble (but you can connect) you may replace \r with \n. Some modems incorrectly (assuming <CR> has not been mapped to anything else than 13 using S3 parameter) use this character as command line terminator by default (even if it should be present in output only for V1 verbose output). Either change your code or send appropriate S3.
Whenever I say "Search for" something, my web browser will open will a random search term. It's almost if the computer couldn't understand me. I even spoke pure U.S. English and it still didn't quite get it. (Windows Form App C#)
Scenario 1: I said "Search for Facebook" and Google opened and the search text said "baseball"
Scenario 2: I said "Search for cars" and Google opened and the search text said "cost"
Scenario 3: I said "cat chases mouse" and Google opened and the search text said "and cat feces miles"
Is there anyway to better way to train the speech recognition?
//Search Google
default:
if (speech.ToLower().Contains("search for")) // See if the string contains the 'search for' string.
{
string query = speech.Replace("search for", ""); // Remove the 'search for' text.
// Old code (does not make the text fully URL safe)
// query = query.Replace(' ', '+');
query = System.Web.HttpUtility.UrlEncode(query);
string url = "https://www.google.com/search?q=" + query;
System.Diagnostics.Process.Start(url);
}
break;
string Speech = e.Result.Text;
if (Speech == "I WANT TO SEARCH SOMETHING")
{
QEvent = Speech;
wiki.SpeakAsync("what do you want to search");
Speech = string.Empty;
}
else if (Speech != string.Empty && QEvent == "I WANT TO SEARCH SOMETHING")
{
Process.Start("http://google.com/search?q=" + Speech);
QEvent = string.Empty;
Num = rnd.Next(1, 4);
if (Num == 1) { wiki.SpeakAsync("Alright, I am searching " + Speech + " in google"); }
else if (Num == 2) { wiki.SpeakAsync("ok sir, I am searching " + Speech); }
else if (Num == 3) { wiki.SpeakAsync("Alright, I am searching "); }
Speech = string.Empty;
}
The <dictation> tag in SAPI grammars tends to have lower accuracy than the pure dictation grammar, mostly because the <dictation> tag doesn't take advantage of context (which hugely improves accuracy).
That being said, however, if you open up the Control Panel and search for "speech", you will find the Speech Recognition control panel, which has an item 'Train your computer to better understand you'. Run through this several times and accuracy should improve.
Also, microphone choice is critical. A good quality headset microphone will do wonders for accuracy. Webcam or desk microphones tend not to do well, as the audio levels vary too much.