且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将字符串和十六进制命令发送到串行端口。

更新时间:2022-11-13 10:07:13

我不清楚哪些东西不适合你。你一直说"保存"但我认为你并不是指在你的代码中保存字符串,而是在串行设备上。我不确定FE40与此有什么关系。这是"保存"的命令吗?设备上的


你说字符串出现了,这是否意味着当你用字符串调用Write时它正确地进入设备?所以问题是你的FE40没有到达那里?你知道这个设备是需要大端还是小端?你可能
需要发送积分值FE40而不是字节值吗?

 var command = 0xFE40; 

var change_screen = BitConverter.GetBytes(command);
sp.Write(change_screen,0,change_screen.Length);

SerialPort有一个带字符串的Write方法,你有什么理由手动做转换?


扩展方法可以使这些代码更易于使用,并有助于将代码与详细信息隔离开来。如果设备更复杂,那么创建一个单独的类型来包装端口也可能是更好的路径。以下是两种方法的示例(不是
测试)。

 //使用SerialPort更容易使用扩展名
公共静态类SerialPortExtensions
{
public static void Write(此SerialPort源,int值)
{
var data = BitConverter.GetBytes(value);

source.Write(data,0,data.Length);
}
}

//使用特定设备的自定义类
公共类MyDevice:IDisposable
{
// TODO:展开此项以允许您配置设备,例如奇偶校验,速度等。
public MyDevice(string portName):this(new SerialPort(portName))
{}

public MyDevice(SerialPort端口)
{
_port = port;
}

public void Open()
{
if(!_port.IsOpen)
_port.Open();
}

//将自定义设备命令放在这里
public void SetMessage(string message)
{
//这应该可以直接使用,如果没有然后使用你有
_port.Write(message)的编码代码;
}

public void SetStartupMessage(string message)
{
SetMessage(message);

//假设您需要发送一个int而不是2字节数组
_port.Write(0xFE40);
}

// IDisposable stuff让事情得到清理
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if(disposing)
{
_port?.Dispose();
_port = null;
};
}

private SerialPort _port;
}

//示例用法
class程序
{
static void Main(string [] args)
{
using(var device = new MyDevice(" COM1"))
{
device.SetStartupMessage(" Hello");
};
}
}



Hi everyone, 

I'm having some trouble sending a string and hex command to a serial port using C#. I need to send a string to a display and then save that string with a hex command. The hex command to change the start up command is FE 40. Although, I am able to successfully print the string on the display, I don't know how to save it. When starting the display that string should show up on the start-up screen. Should I convert the string to hex before sending it with the hex command? I'm new to C# so any help would be appreciated. This is what I have so far. 

// write to screen
        private void btnWrite_Click(object sender, EventArgs e)
        {

            string str = tbLine1.Text + tbLine2.Text + tbLine3.Text + tbLine4.Text;
            byte[] splash_str = Encoding.ASCII.GetBytes(str);
            byte[] change_screen = new byte[2] { 0xFE, 0x40 };

            try
            {
                sp.Write(splash_str, 0, splash_str.Length);
                //sp.Write(str);
                sp.Write(change_screen, 0, change_screen.Length);
            }
            catch (Exception E) { MessageBox.Show(E.ToString(), "Error"); }
        }


I'm unclear as to where things aren't working for you. You keep saying "save" but I assume you don't mean save the string in your code but on the serial device. I'm not sure what the FE40 has to do with this. Is that the command to "save" on the device?

You said the string shows up so does that mean that when you call Write with the string it is getting to the device properly? So the issue is that your FE40 isn't getting there? Do you know whether this device requires big endian or little? Do you maybe need to send the integral value FE40 and not the byte value?

var command = 0xFE40;

var change_screen = BitConverter.GetBytes(command);
sp.Write(change_screen, 0, change_screen.Length);

SerialPort has a Write method that takes a string, is there any reason you're manually doing the conversion?

Extension methods may make this code easier to work with and can help isolate your code from the details. If the device is more complex then creating a separate type to wrap the port may be a better route as well. Here's an example of both approaches (not tested).

//Extensions to make it easier to work with SerialPort
public static class SerialPortExtensions
{
    public static void Write ( this SerialPort source, int value )
    {
        var data = BitConverter.GetBytes(value);

        source.Write(data, 0, data.Length);
    }
}

//Custom class to work with a specific device
public class MyDevice : IDisposable
{
    //TODO: Expand this to allow you to configure your device such as parity, speed, etc
    public MyDevice ( string portName ) : this(new SerialPort(portName))
    { }

    public MyDevice ( SerialPort port )
    {
        _port = port;
    }

    public void Open ()
    {
        if (!_port.IsOpen)
            _port.Open();
    }

    //Put your custom device commands here
    public void SetMessage ( string message )
    {
        //This should work directly, if not then use your Encoding code you had
        _port.Write(message);
    }

    public void SetStartupMessage ( string message )
    {
        SetMessage(message);

        //Assuming you need to send an int and not 2 byte array
        _port.Write(0xFE40);
    }

    //IDisposable stuff so things get cleaned up
    public void Dispose ()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }                

    protected virtual void Dispose ( bool disposing )
    {
        if (disposing)
        {
            _port?.Dispose();
            _port = null;
        };
    }

    private SerialPort _port;
}

//Example usage
class Program
{
    static void Main ( string[] args )
    {
        using (var device = new MyDevice("COM1"))
        {
            device.SetStartupMessage("Hello");
        };
    }
}