Возникли проблемы с получением моего QR-сканера - PullRequest
1 голос
/ 06 июня 2019

Я не могу заставить свою программу работать должным образом ... Я работаю в системе Point of Sale, и мне нужно отсканировать статью и отобразить ее в моей программе WPF C #.У меня есть рабочий код, но странно то, что, когда я сканирую несколько раз подряд, я получаю два окна сообщения (отладка) вместо одного.Мой код выглядит следующим образом: Следующий код инициализирует мой Serialport, но не открывает соединение с ним:

private void Cb1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (string.IsNullOrEmpty(cb1.SelectedItem.ToString())) { MessageBox.Show("Er is nog niet een selectie gemaakt "); }
    else
    {
        sp = new SerialPort(cb1.SelectedItem.ToString());
        sp.BaudRate = 9600;
        sp.DataBits = 8;
        sp.Parity = Parity.None;
        sp.StopBits = StopBits.One;
        sp.Handshake = Handshake.None;
        disconnect.IsEnabled = true; //Irrelevant
    }
}

Я сделал следующую кнопку, которая проверяет, открыто ли соединение.Если соединение с последовательным портом не открыто, оно подключится и добавит обработчик событий, который ожидает данные:

private void Artikel_Scan(object sender, RoutedEventArgs e)
{
    if(sp != null)
    {
        try
        {
            if (!sp.IsOpen)
            {
                sp.Open();
                sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);
            }
            else
                sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);
        }
        catch (Exception ex) { MessageBox.Show(ex.Message); }
    }
    else
    {
        MessageBox.Show("Configure the QR Scanner Please.");
    }
}

И следующий код печатает полученные данные в окне сообщения:

private void artikel_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    byte[] buffer = new byte[20];
    Action kickoffRead = null;
    kickoffRead = delegate
    {
        sp.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
            {
                try
                {
                    int actualLength = sp.BaseStream.EndRead(ar);
                    byte[] received = new byte[actualLength+1];
                    Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                    RaiseAppSerialDataEvent(received);
                }
                catch (IO.IOException exc)
                {
                    MessageBox.Show("ERROR == > " + exc.ToString());
                }
                kickoffRead();
            }, null);
    };
    kickoffRead();
}

private void RaiseAppSerialDataEvent(byte[] Data)
{
    string Result = Encoding.Default.GetString(Data);
    MessageBox.Show(Result);
    /*Dispatcher.Invoke(new Action(() =>
    {
        artikeltxt.Text = Result;
    }));*/
}

Я закрываю свой порт, используя следующий код:

sp.DataReceived -= new SerialDataReceivedEventHandler(artikel_DataReceived);

У меня есть два QR-кода со следующей информацией:

  • 5039085 rev .-
  • 5034917

При первом сканировании первого QR-кода я получаю только одно окно сообщений, отображающее полное содержание QR-кода.Иногда, когда я сканирую второй QR-код, он также показывает полное содержание QR-кода.Однако иногда случается, что я получаю 2 отдельных окна сообщений, в которых отображается часть информации одного из QR-кодов.

У меня есть QR-сканер Datalogic Quickscan 2430, настроенный с использованием интерфейса USB-COM и режима триггера.Trigger single.

Что я могу сделать, чтобы решить мою проблему?Я немного новичок в серийном программировании, поэтому я не уверен, правильно ли я это делаю.

РЕДАКТИРОВАТЬ: Во время тестирования различных вещей, я думаю, я сломал свой сканер.Мой сканер продолжает подключаться к Windows.Когда я открываю Диспетчер устройств, он появляется в ближайшее время, а затем постоянно исчезает.Надеюсь, что производитель сможет исправить мой сканер ...

Редактировать 2: Мне удалось исправить мои проблемы с помощью @Baddack.Я поместил весь мой последовательный код в класс и вызвал функции в моем mainwindow.xaml.У меня есть кнопка, которая выполняет следующую функцию:

public void Artikel_Scan(TextBox tb1)
{
    tbartikel = tb1;
    if (!isSerialNull())
    {
        try
        {
            if (!isSerialOpen())
            {
                sp.Open();
                sp.DataReceived += new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
            }
            else
                sp.DataReceived += new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

Это моя функция DataReceived, которая запускает другую функцию с помощью Dispatcher.BeginInvoke:

private void artikel_DataReceived(object sender, IO.SerialDataReceivedEventArgs e)
{
    string data = sp.ReadExisting();
    data = data.Replace("\r", string.Empty);
    data = data.Replace("\n", string.Empty);
    data = data.Replace(Environment.NewLine, string.Empty);
    data = IllegalCharacterCheck(data);
    if (!string.IsNullOrEmpty(data))
    {
        string payload = data.Substring(1, data.Length - 1);
        Application.Current.Dispatcher.BeginInvoke(new Action(() => artikelDatareceived(payload)));
    }
}

private void artikelDatareceived(string payload)
{
    tbartikel.Text = payload;
}

После того, как текстовое поле заполнено текстом,вызывается событие TextChanged, которое закрывает мое соединение с последовательным портом и удаляет его:

public void artikel_Close()
{
    sp.DataReceived -= new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
    sp.Close();
    sp.Dispose();
}

Я проверил его, и теперь он отлично работает.

1 Ответ

1 голос
/ 08 июня 2019

Вы не обновили свой код выше, поэтому я не уверен, что именно вы изменили.Но я думаю, что ключ в том, что вы можете вызвать sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived); только один раз, в противном случае он будет подписываться на это событие несколько раз.

Проведите простой тест, создайте форму с 2 кнопками и текстовым полем.Используйте приведенный ниже код и нажмите кнопку открытия, выполните сканирование, затем закройте его.Дайте мне знать результаты.

SerialPort sp;

private void buttonOpen_Click(object sender, EventArgs e)
{
    if (sp != null)
        return;

    if (string.IsNullOrEmpty(cb1.SelectedItem.ToString())) 
    {
        MessageBox.Show("Er is nog niet een selectie gemaakt ");
        return;
    }

    sp = new SerialPort();
    sp.PortName = "COM1";   //put your comport # here
    sp.BaudRate = 9600;
    sp.DataBits = 8;
    sp.Parity = Parity.None;
    sp.StopBits = StopBits.One;
    sp.Handshake = Handshake.None;
    sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);

    sp.Open();
}

private void buttonClose_Click(object sender, EventArgs e)
{
    sp.DataReceived -= new SerialDataReceivedEventHandler(artikel_DataReceived);
    sp.Close();
    sp.Dispose();
}

private void artikel_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    string Data = sp.ReadExisting();

    this.Invoke((MethodInvoker)delegate
    {
        textBox1.Text += Data;
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...