How can i read barcode text in background in my C# app? I googled but its of no use. And other resources on stackoverflow are not close to what i need. I want to read barcode in background. And i want to know if the data is coming from barcode or key board. If the data comes from the barcode then it mustnot be displayed on textbox even though the textbox is highlighted. I got similar code for stackoverflow but if there is presence of textbox in the window then the textbox will contain barcode data; which i dont want.
Link : get barcode reader value form background monitoring
DateTime _lastKeystroke = new DateTime(0);
List<char> _barcode = new List<char>(10);
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
// check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode.Clear();
// record keystroke & timestamp
_barcode.Add(e.KeyChar);
_lastKeystroke = DateTime.Now;
// process barcode
if (e.KeyChar == 13 && _barcode.Count > 0) {
string msg = new String(_barcode.ToArray());
MessageBox.Show(msg);
_barcode.Clear();
}
}
Most barcode scanners simply act as keyboard inputs and a quick / easy work around is to place a textbox "Out of sight". An example would be something like this:
// Pseudo code (could be Web, Windows etc)
public void Form1_Load()
{
txtBarcodeScanner.Top = -10000;
txtBarcodeScanner.Left = -10000;
txtBarcodeScanner.Width = 10;
txtBarcodeScanner.Height = 10;
txtBarcodeScanner.Focus();
}
That way the input can be captured by txtBarcodeScanner but will not be visible and the barcode will not seen being captured but will fire KeyDown etc.
Barcode device like keyboard.
1 When entering the barcode, press f12
2 The enter was pressed after inserting the barcode
private void textbox_Keydown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.F12){
Textbox.Focus();
}
if(e.KeyCode == Keys.Enter){
/// after enter barcode
/// save
}
}
check user manual that came with the scanner box.!!
does your barcode scanner supports interfaceType: "usb virtual com port" ?
if yes:
you can do it using serialport() class
1) put your scanner into "usb virtual com port" by scanning that barcode.
it will popup in the device manager.
2) get your baudrate info from device manager
device manager ->
com lpt ports ->
usb serial ch341a (com6)
-> (dobule click) -> "goto tab connection point settings"
there is your baudrate parity etc. info ( write that info to connect port)
3) use this example to do the c# coding. serialport to read data
done!.
Related
Good afternoon everyone,
I'm experimenting with serial communication between c# and arduino.
To understand how the comms work with regards to sending numbers (I know, there's alot being discussed already but bear with me) I want to send the value of a trackbar to the arduino, and then translate this number in movement of a servo.
If I understand correctly, integers can't be sent directly but have to be converted into bytes first.
So for this I would convert the numeric value of the trackbar into a byte array
in C# :
byte[] Numbers;
Numbers = BitConverter.GetBytes(trackBar1.Value);
Via serial communication I would send the value
port.Write(Numbers, 0, 1);
And this is where I'm going wrong I think
The trackbar value goes from 0 to 255, so I guess I'd need to know the bytes that equal 0 to 255 to be able to adjust the last number (in my example '1') to get the correct number after translation in Arduino?
As for Arduino, I would 'translate' the bytes as follows:
int IncomingValue = Serial.parseInt();
And then I'd like to use the IncomingValue for my servo.
My question is what I'm doing incorrectly.
thanks
For those interested in tinkering with c# to arduino serial communication (just desribing the issue I had) and sending a value of a trackbar to use in arduino:
make yourself a form project and name it whatever you like.
Then create a trackbar. I will create a trackbar with a minimum value of 0 and a maximum of 255 as follows:
trackbar1.Minimum = 0;
trackbar1.Maximum = 255;
trackBar1.TickFrequency = 10; // this will set ticks every 10 units.
Now we can setup the actual communication between c# and arduino. I'll start with c#.
Opening a port:
port = new SerialPort("COM5", 9600); //Set your Arduino COM port and baud rate
port.Open();
Now we also need to create an event to close the port when the program shuts:
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (port != null && port.IsOpen)
{
port.Close();
}
}
Now we have set up the port, but we still need data to send. In our example we told we were going to send the value of the trackbar. To do this, click on your trackbar and find the trackBar1_Scroll event and double click it.
This basically creates the event of scrolling the trackbar and now we have to describe in this event what we want to happen.
We want to send the data of the trackbar via serial. The trackbar value is retrieved as follows:
trackbar1.value
Now we know how to retrieve the value, we have to look at the options of sending it, there's 3 options using port.write(), we'll use this later:
-Write(String)
-Write(Byte[], Int32, Int32)
-Write(Char[], Int32, Int32)
but as I'm working with an int, I found that the second one was the one I needed.
As you can see we need a Byte array to be able to send this, so we will cast our trackbar data into a byte array by using BitConverter and declaring a byte array called Numbers:
byte[] Numbers = BitConverter.GetBytes(trackBar1.Value);
Now we have every element we need:
The port which has been opened. We also described when to close it.
The trackbar and its data to send.
The data of the trackbar 'packaged' the correct way to be able to send it.
the only thing we didn't do is describe the scroll event, but now we have the correct data format, we can:
private void trackBar1_Scroll(object sender, EventArgs e)
{
byte[] Numbers = BitConverter.GetBytes(trackBar1.Value);
port.Write(Numbers, 0, 1);
}
so in c# our code will look like this:
public Form1()
{
InitializeComponent();
trackBar1.Minimum = 0;
trackBar1.Maximum = 255;
trackBar1.TickFrequency = 10;
port = new SerialPort("COM5", 9600);//Set your board COM
port.Open();
this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
}
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (port != null && port.IsOpen)
{
port.Close();
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
byte[] Numbers = BitConverter.GetBytes(trackBar1.Value);
port.Write(Numbers, 0, 1);
}
As for arduino, all we need to do is:
A] Start our serial
B] Read the incoming data
#include <LiquidCrystal.h> // include the LCD library
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //define the LCD display
int Number; //define the number int (the one we'll store our received trackbar value in)
void setup()
{
Serial.begin(9600); //A] Start our serial
}
void loop()
{
lcd.setCursor(0, 0); // Set the LCD cursor at the top left corner
if (Serial.available() > 0 ) { //B] Read the incoming data
nummer = Serial.read(); //
lcd.print(nummer); //
} //
else {}; //
}
I used an LCD to read the data as I couldn't figure out a way to open the serial monitor with the serial communication between c# and arduino happening.
that's why I included an LCD.
I feel explaining this is beyond the scope of this little issue I had.
I hope this helps other beginners like me in the future.
thanks to those who were helpful!
I'm making a simple program, to send information from PC to COM port. So far I have established a connection between the PC and the COM port and I can send information and see what the port received, but I have two problems, the first one is that when I send the info to an actual com port (COM port to USB cable made to echo the signal) the first time I all of the information is received. Then it becomes random, sometimes again, all of what I have written, sometimes only the first character. And sometimes nothing. My assumption is this happens because I haven't put any time-outs or anything at all. Help with this would be nice.
But the real problem that I have is that I want all of the information sent from the textbox to be sent in ASCII code since I'm making the program for communication with PLC.
Here is the code:
public Form1()
{
InitializeComponent();
}
//BTN new serial port creation - port taken from comport text box
private void button1_Click(object sender, EventArgs e)
{
System.IO.Ports.SerialPort sport = new System.IO.Ports.SerialPort(comport.Text, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
//opening the com port and sending the information from textbox1
try
{
sport.Open();
sport.Write(textBox1.Text);
}
//if there is an error - show error message
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
//Adding timestamp to received info
DateTime dt = DateTime.Now;
String dtn = dt.ToShortTimeString();
//reading the information form the com port
textBox2.AppendText("[" + dtn + "] " + "Recieved: " + sport.ReadExisting() + "\n");
//closing the port
sport.Close();
}
The problem is, you are reading every time you click the button and may not have recieved everything. You should use the SerialPort class' DataReceived event to receive your data. The event fires every time data is received through your COM port, so you can press your button to write to the port then as the data comes in you should see the event fire with your data.
Microsoft has a good definition and example here.
The event is on a separate thread, so to write it to a textbox you may have to invoke it to display it on your gui. See the example code below:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string Data = serialPort1.ReadExisting();
this.Invoke((MethodInvoker)delegate
{
textBox2.AppendText(Data);
});
}
Greeting,
OS: Windows 7 /64bit
Application: Visual Studio 2012 / C# and DotRas 1.3 Library
I am very new to c# or VS thing so please bear with me. After doing many hours R&D, I have finaly made a pppoe dialer program in C# / Dotras. This program have 3 main buttons
Create /Add PPPoE Internet Dialer Connection in network connections , working fine
Dial button, which connects the newly created dialer , working Fine
Disconnect working fine
I have added StatuBox where dialup events should appear as showed on dotras youtube video tutorial (which was for vpn, but my project is for pppoe dialer)
StatusBox Not updating the dialup events like connecting/password error/connected etc. This is the part where I am finally confused.
Following is my Code.
// Dial Button Action
private void button2_Click_1(object sender, EventArgs e)
{
using (RasDialer dialer = new RasDialer())
{
// I had to add below line to update statusTextBox Manualy , want to get rid of it by adding auto status update
this.StatusTextBox.AppendText(string.Format("{0}\r\n\r\n", "Connection in progress ...", "{0}\r\n\r\n"));
dialer.EntryName = ("pppoe2");
string username = textBox1.Text;
string passwd = textBox2.Text;
// If username is empty dont connect
if (string.IsNullOrWhiteSpace(textBox1.Text))
{
this.StatusTextBox.AppendText(string.Format("{0}\r\n", "Cancelled. Cannot continue with username/password.", "{0}\r\n"));
MessageBox.Show("Enter username.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
dialer.Credentials = new System.Net.NetworkCredential(textBox1.Text, textBox2.Text);
dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User);
dialer.Timeout = 1000;
dialer.AllowUseStoredCredentials = true;
// start dialing,
dialer.Dial();
// If dialer connects successfully update StatuTextbox
this.StatusTextBox.AppendText(string.Format("{0}\r\n\r\n", "Connected."));
}
}
private void rasDialer1_StateChanged(object sender, StateChangedEventArgs e)
{
this.StatusTextBox.AppendText(string.Format("{0}\r\n", "Status Changed"));
}
private void rasDialer1_Error(object sender, System.IO.ErrorEventArgs e)
{
this.StatusTextBox.AppendText(string.Format("{0}\r\n", "STATUS UPDATE TEXT XYZ"));
}
private void rasDialer1_DialCompleted(object sender, DialCompletedEventArgs e)
{
this.StatusTextBox.AppendText(string.Format("{0}\r\n", "STATUS UPDATE TEXT XYZ"));
}
Any help would be highly appreciable.
Ok I have managed to enable status box text append work fine.
this.Invoke((MethodInvoker)delegate
{
this.StatusTextBox.AppendText(string.Format(e.State.ToString() + "\r\n"));
});
}
Depending on how you were using it, if the background thread from the OS isn’t marshaled back to the UI thread it won’t update. Similarly to what you had done, the SynchronizingObject property on the RasDialer can be set to your form and the thread synchronization will occur automatically.
I know this is answered question however I want to know hardware required and how to setup.
I am trying to build a take-out's delivery system wherein users call and their phone number gets captured on a WINFORM.
I googled and it says I need to use TAPI API. That's fine but do I need to connect anything to the PC or will just using TAPI work?
This Link explains it in VB.net. I am looking for it in c#.net.
I have also gone through the links provided here.
But nowhere does it explain the setup. So please help.
First thing
See if your hardware supports caller ID
Add the serial port control, set it to whatever comm port your modem is on and watch for the CALLER ID number, then react
To see if your modem supports Caller ID open a serial port terminal (I like putty) and set it to the com port of your modem then call the phone number attached to that that modem, you should see something like RING 5555555555 (where 5555555555 is the phone number of the person calling you)
You may have to turn caller id on for that modem (if so)
1) Open the "Phone And Modem Options" control panel
2) Click the "Modems" tab
3) Select your modem in the list (if it is not already selected)
4) Click the "Properties" button
5) Click the "Advanced" tab
6) Type "#CID=1" into the "Extra initialization commands" edit box
Note: replace "#CID=1" with the command to enable caller id on your modem
Do not include the "AT" part of the command
Do not include the quotes
7) Click OK
8) Click OK
9) restart the computer
Here is some code for interacting with a serial port in c# (incase you need that)
public SerialPort sp;
string dataReceived = string.Empty;
private delegate void SetTextDeleg(string text);
private void FormLoad()
{
sp = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
this.sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
sp.Open();
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep(500);
string x = sp.ReadLine(); // will read to the first carriage return
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { x });
}
catch
{ }
}
private void si_DataReceived(string data)
{
dataReceived = data.Trim();
// Do whatever with the data that is coming in.
}
Also I just searched amazon for "Caller ID Modem" and there seem to be alot for between 10 and 20 dollars (US) that support this exact use. I would recommend the Trendnet TFM-561U
If you are using a phone and fax modem, just plug-in your telephone line into the modem.
Next on your windows form drag-n-drop a SerialPort control and initialize it.
this.serialPort1.PortName = "COM3";
this.serialPort1.BaudRate = 9600;
this.serialPort1.DataBits = 8;
this.serialPort1.RtsEnable = true;
this.serialPort1.DataReceived += serialPort1_DataReceived;
this.serialPort1.Open();
Pass the following command to modem in order to activate Caller-ID
this.serialPort1.WriteLine("AT#cid=1" + System.Environment.NewLine);
Handle its DataReceived event and display the received data
void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
richTextBox1.Text += this.serialPort1.ReadLine();
}
Output:
RING //On 1st Ring
DATE = xxxxx //On 2nd Ring
TIME = xxxx
NMBR = xxxxxxxxx
RING //On 3rd Ring
RING //On 4th Ring
P.S. If the telephone line sends DTMF tones as Caller-ID then you need DTMF to FSK converter to detect the number, or else you will receive the rings but not the number.
I want to create an accounting program with c# language.
I want to use a barcode reader for searching products in shop (this is optional for my program)
Now, in main form if seller uses a barcode reader get barcode value for handle method or event;
How can I get barcode value in background of Form (without text box) for handle method or event ?
Note: My barcode reader is HID (USB interface)
The barcode device behaves like a keyboard. When you have focus in a textbox, it sends characters to the textbox as if you typed them from the keyboard.
If you dont want to use a textbox, you'll need to subscribe to a keyboard event handler to capture the barcode stream.
Form1.InitializeComponent():
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form1_KeyPress);
Handler & supporting items:
DateTime _lastKeystroke = new DateTime(0);
List<char> _barcode = new List<char>(10);
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
// check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode.Clear();
// record keystroke & timestamp
_barcode.Add(e.KeyChar);
_lastKeystroke = DateTime.Now;
// process barcode
if (e.KeyChar == 13 && _barcode.Count > 0) {
string msg = new String(_barcode.ToArray());
MessageBox.Show(msg);
_barcode.Clear();
}
}
You'll have to do keep track of the "keystrokes" and look out for the "carriage return" that is sent w/ the barcode stream. That can easily be done in an array. To differentiate between user keystrokes and barcode keystrokes, one dirty trick you can do is keep track of the timing of the keystrokes.
For example, if you get a stream of keystrokes less than 100ms apart ending w/ a carriage return, you can assume it is a barcode and process accordingly.
Alternatively, if your barcode scanner is programmable, you can also send special characters or sequences.