Как я могу прочитать строку из OpenNETCF.IO.Ports.SerialPort?

1

Я пишу команды на ленточный принтер, используя OpenNETCF.IO.Ports.SerialPort следующим образом:

public static bool SendCommandToPrinter(string cmd)
{
    bool success; // init'd to false by default
    try
    {
        SerialPort serialPort = new SerialPort();
        serialPort.BaudRate = 19200;
        serialPort.Handshake = Handshake.XOnXOff;
        serialPort.Open();
        serialPort.Write(cmd);
        serialPort.Close();
        success = true;
    }
    catch // may not need a try/catch block, as success defaults to false
    {
        success = false;
    }
    return success;
}

... теперь мне нужно прочитать значение, возвращаемое из вызова "get val", но я не знаю, как, и я не смог найти, как это сделать. У меня есть следующее начало, но не знаю, как "заполнить пробел":

string getDeviceLang = string.Format("! U1 getvar {0}device.languages{0}", quote); 

public static string GetSettingFromPrinter(string cmd)
{
    string settingVal = string.Empty;

    SerialPort serialPort = new SerialPort();
    serialPort.BaudRate = 19200;
    serialPort.Handshake = Handshake.XOnXOff;
    serialPort.Open();
    serialPort.Write(cmd); // do I even need this call to write?
    settingVal = serialPort.Read() // ???
    serialPort.Close();
    return settingVal;
}

Метод OpenNETCF.IO.Ports.SerialPort Read() принимает массив байтов ("буфер"), за которым следует int ("offset") и другой int ("count") и возвращает int. Я не знаю, что использовать в качестве аргументов или что делать с результатом int.

ОБНОВИТЬ

Я попробовал это:

public static string GetSettingFromPrinter(string cmd)
{
    string settingVal = string.Empty;
    try
    {
        SerialPort serialPort = new SerialPort();
        serialPort.BaudRate = 19200;
        serialPort.Handshake = Handshake.XOnXOff;
        serialPort.Open();
        serialPort.Write(cmd);
        // testing...
        settingVal = serialPort.ReadLine();
        serialPort.Close();
        return settingVal;
    }
    catch (Exception x)
    {
        MessageBox.Show(x.ToString());
        return settingVal;
    }
}

... но это вознаграждает меня менее чем удовлетворительным, "System.NotSupportedException: еще не в OpenNETCF.IP.Ports.SerialPort.ReadTo (значение строки) в..."

ОБНОВЛЕНИЕ 2

Я добавил:

serialPort.ReadTimeout = 500;// made no difference

ОБНОВЛЕНИЕ 3

Исходя из этого, я попытался заставить его работать так:

public class PrintUtils
{
    static SerialPort _serialPort;
    static bool keepReading = true;
    static string settingVal = string.Empty;
    . . .

public static string GetSettingFromPrinter(string cmd)
{
    Thread readThread = new Thread(ReadSetting());
    try
    {
        _serialPort = new SerialPort();
        _serialPort.BaudRate = 19200;
        _serialPort.Handshake = Handshake.XOnXOff;
        _serialPort.Open();
        while (keepReading)
        {
            _serialPort.WriteLine(cmd);
        }
        _serialPort.Close();
        return settingVal;
    }
    catch (Exception x)
    {
        MessageBox.Show(x.ToString());
        return settingVal;
    }
}

public static void ReadSetting()
{
    while (keepReading)
    {
        try
        {
            settingVal = _serialPort.ReadLine();
            keepReading = settingVal.Equals(string.Empty);
        }
        catch (Exception ex) { MessageBox.Show(ex.ToString());}
    }
}

... но я получаю "Метод" PDAClient.PrintUtils.Read(), на который ссылаются без круглых скобок "в этой строке:

Thread readThread = new Thread(Read);

Если я дам это parens:

Thread readThread = new Thread(ReadSetting());

... он говорит мне: "Аргумент" 1 ": невозможно преобразовать из" void "в System.Threading.ThreadStart"

-and:

"Наилучшее перегруженное соответствие метода для System.Threading.Thread.Thread(System.Threading.ThreadStart) имеет некоторые недопустимые аргументы"

ОБНОВЛЕНИЕ 4

И с помощью этого кода:

public static string GetSettingFromPrinter(string cmd)
{
    string setting = string.Empty;
    byte[] buffer = null;
    try
    {
        SerialPort serialPort = new SerialPort();
        serialPort = new SerialPort();
        serialPort.BaudRate = 19200;
        serialPort.Handshake = Handshake.XOnXOff;
        serialPort.ReadTimeout = 500;
        serialPort.Open();
        serialPort.Write(cmd);
        setting = Convert.ToString(serialPort.Read(buffer, 0, buffer.Length));
        serialPort.Close();
        return setting;
    }
    catch (Exception x)
    {
        MessageBox.Show(x.ToString());
        return setting;
    }
}

Я получаю NRE.

ОБНОВЛЕНИЕ 5

Эта попытка:

serialPort.WriteLine(cmd);
setting = serialPort.ReadExisting();

... заканчивается очень похоже на первое обновление ("System.NotSupportedException: еще не в OpenNETCF.IP.Ports.SerialPort.ReadExisting() at...")

ОБНОВЛЕНИЕ 6

Хорошо, я включил псевдокод в комментарий ctacke, и теперь у меня есть это:

const string quote = "\"";
. . .
string getDeviceLang = string.Format("! U1 getvar {0}device.languages{0}", quote);
. . .
String deviceLanguage = PrintUtils.GetSettingFromPrinter(getDeviceLang);

public static string GetSettingFromPrinter(string cmd)
{
    string setting = string.Empty;
    try
    {
        SerialPort serialPort = new SerialPort();
        serialPort = new SerialPort();
        serialPort.BaudRate = 19200;
        serialPort.Handshake = Handshake.XOnXOff;
        serialPort.ReadTimeout = 500;
        serialPort.Open();
        serialPort.WriteLine(cmd); // or Write()

        // get a synchronous, newline-delimited response
        StringBuilder response = new StringBuilder();
        char c;
        do
        {
            c = (char)serialPort.ReadByte();
            response.Append(c);
        } while(c != '\n');

        serialPort.Close();
        return setting;
    }
    catch (Exception x)
    {
        MessageBox.Show(x.ToString());
        return setting;
    }

... но он "висит" - кажется, существует бесконечный цикл в цикле do... while.

ОБНОВЛЕНИЕ 7

Я добавил это после "ReadByte":

MessageBox.Show(c.ToString());

... и все это показывает мне ничто (MessageBox без "внутреннего текста"); Я позволил ему появиться 32 раза, прежде чем я смонтировал устройство.

ОБНОВЛЕНИЕ 8

Хорошо, тогда я исправляюсь - я не использовал OpenNETCF SerialPort, поскольку такой вещи нет. Поэтому я пытаюсь это сделать, основываясь на предоставленном псевдокоде ctacke. Я сейчас пытаюсь использовать:

Port serialPort = new Port();
serialPort.Settings = whateverPortSettingsYouNeed;
serialPort.Open();
serialPort.Send(cmd);

... но я не знаю, что должно быть "anyPortSettingsYouNeed", нет метода "Отправить", и я не знаю, что использовать вместо ReadByte()

ОБНОВЛЕНИЕ 9

У меня есть это сейчас для настроек:

BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = 19200;
//bps.ByteSize = ?;
//bps.Parity = None;
//bps.StopBits = 1;
Port serialPort = new Port();
serialPort.Settings = bps;

... но, как вы можете видеть, я не знаю, какие значения должны быть.

ОБНОВЛЕНИЕ 10

Это компилирует:

public static string GetSettingFromPrinter(string cmd)
{
    string setting = string.Empty;
    try
    {
        BasicPortSettings bps = new BasicPortSettings();
        bps.BaudRate = BaudRates.CBR_19200;
        bps.Parity = OpenNETCF.IO.Serial.Parity.none;
        bps.StopBits = OpenNETCF.IO.Serial.StopBits.one; //bps.StopBits.one;
        Port serialPort = new Port("COM1:", bps);
        byte[] outputBytes = System.Text.Encoding.ASCII.GetBytes(cmd);
        serialPort.Output = outputBytes;
        serialPort.Open();
        byte[] bites = serialPort.Input;
        setting = bites.ToString();
        serialPort.Close();
        return setting;
    }
    catch (Exception x)
    {
        MessageBox.Show(x.ToString());
        return setting;
    }
}

... Теперь я посмотрю, действительно ли это работает...

ОБНОВЛЕНИЕ 11

Я узнал (трудный путь), что мне пришлось открыть порт до установки Output val; это сейчас:

serialPort.Open();
byte[] outputBytes = Encoding.ASCII.GetBytes(cmd);
serialPort.Output = outputBytes;
byte[] inputBytes = serialPort.Input;
setting = inputBytes.ToString();

... но то, что читается в настройке, - "System.Byte []"

Что мне нужно, чтобы фактически получить значение в inputBytes, а не просто увидеть представление его типа?

  • 1
    Поскольку вы изменили библиотеки, весь ваш предыдущий код становится спорным. Настройки, которые вам известны, но они выглядят как 19200, без проверки четности, 1 стоповый бит и т. Д. Чтобы отправить данные, укажите их в свойстве «Вывод». Чтобы прочитать данные, прочитайте свойство Input.
  • 0
    Хорошо, я попробую.
Показать ещё 4 комментария
Теги:
serial-port
compact-framework
windows-ce
opennetcf

2 ответа

1
Лучший ответ

Первое, что я замечаю, это то, что вы используете класс SerialPort который означает, что вы используете код из SDF 1.x, который относится к 2005 году в самом последнем. Не уверен, что я был бы слишком восторжен по этому поводу. Я создал библиотеку с открытым исходным кодом, которая содержит только класс Port после этого кода, но она работает иначе - она была смоделирована после объектной модели последовательного порта VB6. Я, честно говоря, даже не помню, кто написал код в SDF 1.x - возможно, был я, возможно, не был. Я думаю, что не просто судить по стилю кода, который я вижу.

Я задавался вопросом, почему вы не просто использовали встроенный файл CF-серий, но если вы используете SDF 1.x, скорее всего, вы используете версию CF, которая предваряет включение API последовательного порта.

Что касается того, который вы используете сейчас, я думаю, что это несколько зависит от того, как ожидается возвращение данных, но псевдокод будет выглядеть примерно так:

var port = new SerialPort;
port.Settings = whateverPortSettingsYouNeed;
port.Open();

....
// send the command
port.Send(myCommand);

// get a synchronous, newline-delimited response
var response = new StringBuilder();
char c;
do
{
    c = (char)port.ReadByte();
    // see if it actually read anything
    if(c == '\0')
    {
        // wait a little bit, then try again - you will want to put in a timeout here
        Thread.Sleep(10);
        continue;
    } 
    response.Append(c);
    // you may want to check for response "reasonableness" here
} while(c != \n');

DoSomethingWithResponse(response);
  • 0
    Я использую библиотеку OpenNETCF - это SerialPort я использую.
  • 0
    Я не согласен. Последовательная библиотека Codeplex имеет класс Port не SerialPort . Он также не имеет методов Read() или Write . Основываясь на опубликованном вами коде, вы используете SerialPort из SDF 1x, который представляет собой совершенно отдельную кодовую базу с совершенно другой объектной моделью и для которого предназначен вышеуказанный псевдокод (хотя обычно он работает с любой реализацией, поскольку псевдокод).
Показать ещё 2 комментария
2

Он считывает байты. Буфер - это где байты считываются (как изменено смещением и количеством), а возвращаемое значение - количество прочитанных байтов. Типичный материал типа потока.

Документы находятся здесь: http://msdn.microsoft.com/en-us/library/ms143549(v=vs.90).aspx

  • 0
    Эти документы не предназначены для SerialPort OpenNETCF, который, похоже, не имеет никаких документов. Он может быть использован таким же образом, но у него нет примера кода, только «теория».
  • 0
    Ах я вижу. Не понял, что вы используете CF Opennet. Я уверен, что они придерживаются того же соглашения API.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню