Sainsmart Usb继电器控制

时间:2016-05-29 23:13:25

标签: c#

我已购买SainSmart 16 Channel controller USB HID Programmable Control Relay Module来控制相应的16通道继电器板。

提供的源代码非常糟糕,但包括一个cmd行程序,可以很好地控制继电器。我试图使用C#创建一个GUI来向程序发送命令。我在这个网站上做了一些阅读,但我并没有走得太远。

最终我需要发送参数" afEd5打开01"然后暂停几秒,然后发送参数" afEd5关闭01"到CommandApp.exe。

非常感谢任何帮助,谢谢。

更新:到目前为止找出了大部分编码,我现在只有一个小问题是CommandApp.exe的位置。我更喜欢它位于应用程序的主要exe而不是C的根目录。

using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace GenesisDigitalInterface
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    // Toggle Power Button relay
    private void PowerButton_Click(object sender, EventArgs e)
    {
        Process controlusb = new Process();
        controlusb.StartInfo = new ProcessStartInfo("C:\\CommandApp.exe");
        controlusb.StartInfo.Arguments = "afEd5 open 01";
        controlusb.StartInfo.UseShellExecute = false;
        controlusb.StartInfo.LoadUserProfile = true;
        controlusb.StartInfo.RedirectStandardInput = true;
        controlusb.StartInfo.RedirectStandardOutput = true;
        controlusb.StartInfo.RedirectStandardError = true;
        controlusb.Start();
        Thread.Sleep(100);
        controlusb.StartInfo = new ProcessStartInfo("C:\\CommandApp.exe");
        controlusb.StartInfo.Arguments = "afEd5 close 01";
        controlusb.StartInfo.UseShellExecute = false;
        controlusb.StartInfo.LoadUserProfile = true;
        controlusb.StartInfo.RedirectStandardInput = true;
        controlusb.StartInfo.RedirectStandardOutput = true;
        controlusb.StartInfo.RedirectStandardError = true;
        controlusb.Start();
    }
        }

    }
}

3 个答案:

答案 0 :(得分:0)

我猜您错误地初始化了ProcessStartInfo。它将程序名称作为参数,但我不知道你传递了什么,所以我猜你应该通过"C:\\CommandApp.exe"并且你应该传递"afEd5 open 01"作为其参数,而不是启动过程。

所以代码应如下所示:

Process controlusb = new Process();
controlusb.StartInfo = new ProcessStartInfo("C:\\CommandApp.exe");
controlusb.StartInfo.Arguments = "afEd5 open 01";
controlusb.StartInfo.UseShellExecute = false;
controlusb.StartInfo.LoadUserProfile = true;
controlusb.StartInfo.RedirectStandardInput = true;
controlusb.StartInfo.RedirectStandardOutput = true;
controlusb.StartInfo.RedirectStandardError = true;
controlusb.Start();

答案 1 :(得分:0)

我最近不得不在我们正在开发的测试夹具中使用这个特殊的电路板。该文档包含一个没有描述或示例的十六进制值表。字节数据包的长度为 17 个字节,并具有地址、开/关命令和一些反向地址检查字节。其余字节对于单次开启和关闭是“固定的”。我在 C# 中组合了一个 Windows 应用程序,用于操作每个单独的继电器。 (一次一个。我从来没有让全开和全关工作。)我将在此处包含代码,但我希望我能附上整个解决方案。

注意事项:

  1. Relay On 命令是:hex = 0x46,0x46(是的,两个字节相同。
  2. 继电器关闭命令是:hex = 0x30, 0x30
  3. 需要进行地址转换才能获得正确的中继。 IE。 Relay #1 = 0x30, Relay #2 is 0x31, etc...我将值放入静态字节数组中,并使用继电器整数描述、1,2等作为索引返回十六进制地址。我认为这样更容易。
  4. 我根据需要在 TX 字符串中更新 On/Off 的两个字节。(连同地址。)
  5. ***特别注意:“额外”控制字节(为什么???)对于开启和关闭是不同的。在我的代码中,我构建了两个字节字符串。一个处理开启的控制字节,另一个处理关闭的控制字节。
  6. 注意:这个程序有一个返回数据缓冲区(Rxbuffer),我期待某种确认或至少是命令回显,但中继板没有返回任何内容。

除此之外,它似乎有效。祝你好运!

16 Channel Test UI Pic

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

// 16ChannelTest.cs  v1.0
// Program to test C# operation of Sain SMART 16 Channel Serial Relay Board
// 7/1/2021 - mwille
// Program "assumes" Com4 is the Serial Relay Board. - Will post an error msg in the textbox if it can't find Com4.
// Developed to support testing and calibration of controller boards.
//

namespace _16ChannelTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
                       
        static byte[] TXbuffer = new byte[17] {0x3A,0x46,0x45,0x30,0x35,0x30,0x30,0x30,0x30,0x46,0x46,0x30,0x30,0x46,0x45,0x0D,0x0A};
        static byte[] Convert_Address = new byte[17] { 0x00,0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 };
        static byte[] T_On_Chk_Value = new byte[17] { 0x00,0x45, 0x44, 0x43, 0x42, 0x41, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x46 };
        static byte[] T_Off_Chk_Value = new byte[17] { 0x00, 0x44, 0x43, 0x42, 0x41, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x46, 0x45 };
        static byte[] RXbuffer = new byte[18];
        static int Relay_Number = 1;
        
        private void btn_Start_Click_1(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM4";
            serialPort1.BaudRate = 9600;

            try
            {
                serialPort1.Open();
            }
            catch (Exception exc)
            {
                tb_Logging.AppendText("Exception Thrown \r\n");
                tb_Logging.AppendText("" + exc);
                tb_Logging.AppendText("\r\n");
            }

            if (serialPort1.IsOpen)
            {              
                tb_Logging.AppendText("Data Logging Started...");
                tb_Logging.AppendText("\r\n");
            }
        }

        public void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (serialPort1.BytesToRead == 17)
                serialPort1.Read(RXbuffer, 0, 17);

            /* Return to UI thread */
            this.Invoke(new EventHandler(DisplayText));

            serialPort1.DiscardInBuffer();
        }

        private void DisplayText(object sender, EventArgs e)
        {
            tb_Logging.AppendText("--> ");
            tb_Logging.AppendText(BitConverter.ToString(RXbuffer));
            tb_Logging.AppendText("\r\n");
        }

        private void clear_RX_Buffer()
        {
            for (int i = 0; i < 19; i++)
            {
                RXbuffer[i] = 0x00;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen)
                serialPort1.Close();
        }

        private void Send_Relay_Cmd(byte Relay_ID, byte RCmd, byte Check)     // Relay_ID = 1->16, RCmd = 0x46 to turn-on, 0x30 to turn-off, Check = manufacturer set value??? 
        {
            // If the port is closed, don't try to send a character.
            if (!serialPort1.IsOpen) return;

            serialPort1.DiscardInBuffer();

            // If the port is Open, setup byte[] array with appropriate elements.

            // First, assign hex address using numeric pointer.           
            TXbuffer[8] = Relay_ID;     //Relay Address

            TXbuffer[9] = RCmd;     // Control Byte #1 - 
            TXbuffer[10] = RCmd;    // Control Byte #2 - 0x46 to turn-on, 0x30 to turn-off            

            TXbuffer[14] = Check;    //Some kind of reverse order check???
            
            Thread.Sleep(500);

            // Send the TXbuffer
            serialPort1.Write(TXbuffer, 0, 17);

            Thread.Sleep(500);

            write_Text();
        }
                
        private void write_Text()
        {
            tb_Logging.AppendText("<-- ");
            tb_Logging.AppendText(BitConverter.ToString(TXbuffer));
            tb_Logging.AppendText("\r\n");
        }

        // This is the Turn-On button function. It performs the majority of byte formatting for the TX function.
        private void Btn_T_On_Click(object sender, EventArgs e)
        {
            byte Relay_Address;
            byte Relay_Cmd;
            byte Relay_Check_Byte;

            // Using the integer number as the index, return the manufacturers specific hex address byte.
            Relay_Address = Convert_Address[Relay_Number];

            // Since this is the "Turn-On" button, set the command 
            Relay_Cmd = 0x46;

            // Using the integer number as the index, return the manufacturers specific hex check byte.
            Relay_Check_Byte = T_On_Chk_Value[Relay_Number];

            Send_Relay_Cmd(Relay_Address,Relay_Cmd,Relay_Check_Byte);
        }

        private void Btn_T_Off_Click(object sender, EventArgs e)
        {
            byte Relay_Address;
            byte Relay_Cmd;
            byte Relay_Check_Byte;

            // Using the integer number as the index, return the manufacturers specific hex address byte.
            Relay_Address = Convert_Address[Relay_Number];

            // Since this is the "Turn-On" button, set the command 
            Relay_Cmd = 0x30;

            // Using the integer number as the index, return the manufacturers specific hex check byte.
            Relay_Check_Byte = T_Off_Chk_Value[Relay_Number];

            Send_Relay_Cmd(Relay_Address, Relay_Cmd, Relay_Check_Byte);
        }
                
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 1;
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 2;
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 3;
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 4;
        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 5;
        }

        private void radioButton6_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 6;
        }

        private void radioButton7_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 7;
        }

        private void radioButton8_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 8;
        }

        private void radioButton9_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 9;
        }

        private void radioButton10_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 10;
        }

        private void radioButton11_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 11;
        }

        private void radioButton12_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 12;
        }

        private void radioButton13_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 13;
        }

        private void radioButton14_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 14;
        }

        private void radioButton15_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 15;
        }

        private void radioButton16_CheckedChanged(object sender, EventArgs e)
        {
            Relay_Number = 16;
        }
    }
}

答案 2 :(得分:-1)

我尝试使用https://github.com/ondrej1024/crelay/files/194375/sain-usb-hid.c.txt中的代码,但它对我不起作用。我之前尝试了许多其他解决方案,但它们也不适用于我。

所以,我为SainSmart 16通道控制器USB HID可编程控制继电器(一个替换CommandApp.exe的控制台应用程序)编写了自己的代码。你可以用它。

代码如下:

Process controlusb = new Process();
controlusb.StartInfo = new ProcessStartInfo("C:\\sain-usb-hid-relay-16.exe");
controlusb.StartInfo.Arguments = "1 1";
controlusb.StartInfo.UseShellExecute = false;
controlusb.StartInfo.LoadUserProfile = true;
controlusb.StartInfo.RedirectStandardInput = true;
controlusb.StartInfo.RedirectStandardOutput = true;
controlusb.StartInfo.RedirectStandardError = true;
controlusb.Start();

用法:sain-usb-hid-relay-16.exe Param1 Param2

参数1:

T or t  - Test of relays from 1 to 16 by ON and OFF. Use Param2 as delay in msec.
A or a  - All relays.
1..16   - Relay number.

参数2:

1 or 0  - 1 = Relay to ON, 0 = Relay to OFF.

示例:

Example: sain-usb-hid-relay-16.exe 5 1
     - Relay #5 is ON.
Example: sain-usb-hid-relay-16.exe 10 0
     - Relay #10 is OFF.
Example: sain-usb-hid-relay-16.exe a 1
     - All relays is ON.
Example: sain-usb-hid-relay-16.exe t 3000
     - All relays will test ON and OFF with each delay = 3000 msec.

sain-usb-hid-relay-16.exe a 1
Relay 65535 ON

sain-usb-hid-relay-16.exe a 0
Relay 65535 OFF

Where 65535 = All relays.

您可以在其他应用中使用它,像“sain-usb-hid-relay-16.exe a 1&gt; result.txt”一样执行app 然后您可以读取文件“result.txt”来解析结果。