C# interface to Velleman k8056
For reasons I will explain later I once bought a Velleman k8056 8-channel relay card. It took me the better part of an afternoon to solder all the thingies to the board but eventually I had it looking more or less as it does in the glossy ads.
I tested it with a test application I found somewhere, and it worked! I write software on my day job, but I am still childishly impressed by controlling real world objects by means of a computer (and no – the caps lock diod doesn’t count
).
The main purpose of the board was to integrate it into another process, and that required accessing it from a .Net application. I searched the net but couldn’t find anything that did the trick, so I decided to write my own API to it. I normally do not write com-port stuff so there was a bit of a learning curve, but eventually I got it where I fund it usable. Figured you may too, so here goes…
-
//Written by Jesper Högström
-
using System;
-
using System.Collections.Generic;
-
using System.Text;
-
using System.IO.Ports;
-
-
namespace CardAPI
-
{
-
internal enum Command
-
{
-
ChangeAddress = 64 + 1, // ‘A’
-
SendByte = 64 + 2, // ‘B’
-
ClearRelay = 64 + 3, // ‘C’
-
DisplayAddress = 64 + 4, // ‘D’
-
StopAll = 64 + 5, // ‘E’
-
ForceAddress1 = 64 + 6, // ‘F’
-
SetRelay = 64 + 19, // ‘S’
-
ToggleRelay = 64 + 20 // ‘T’
-
}
-
public class Card
-
{
-
private List m_Relays = new List();
-
private SerialPort com;
-
private int baudRate = 2400;
-
public Card()
-
: this("COM1")
-
{
-
}
-
public Card(string portName)
-
{
-
com = new SerialPort(portName, baudRate);
-
PortName = portName;
-
for (int relayId = 9; relayId >= 1; relayId–)
-
m_Relays.Add(new Relay(this, (byte)relayId));
-
}
-
private string m_PortName;
-
public string PortName
-
{
-
get { return m_PortName; }
-
set
-
{
-
if (com != null && com.IsOpen)
-
com.Close();
-
m_PortName = value;
-
com = new SerialPort(m_PortName, baudRate);
-
/* these settings seem to be default anyway.
-
com.DataBits = 8;
-
com.Parity = Parity.None;
-
com.StopBits = StopBits.One;
-
*/
-
com.ReadTimeout = 3000;
-
com.WriteTimeout = 3000;
-
com.Open();
-
com.Close();
-
}
-
}
-
private byte m_CardAddress = 1;
-
-
~Card()
-
{
-
if (com.IsOpen)
-
com.Close();
-
}
-
private byte CheckSum(byte[] buf)
-
{
-
int res = 256 – buf[0] – buf[1] – buf[2] – buf[3];
-
while (res < 0)
-
res += 256;
-
return (byte)res;
-
}
-
private byte[] buf = new byte[5];
-
private int repeatCount = 1;
-
private int msDelay = 400;
-
internal void SendCommand(Command command, byte data)
-
{
-
buf[0] = 13; // start command
-
buf[1] = m_CardAddress; // address
-
buf[2] = (byte)command; // command
-
buf[3] = data; // data
-
buf[4] = CheckSum(buf); // checksum
-
-
if (!com.IsOpen)
-
com.Open();
-
for (int i = 0; i < repeatCount; i++)
-
{
-
com.Write(buf, 0, 5);
-
}
-
com.Close();
-
System.Threading.Thread.Sleep(msDelay);
-
-
}
-
public Relay this[int index]
-
{
-
get { return m_Relays[index]; }
-
}
-
public void ShowAddresses()
-
{
-
SendCommand(Command.DisplayAddress, m_CardAddress);
-
}
-
public void SetRelays(byte state)
-
{
-
SendCommand(Command.SendByte, state);
-
}
-
public void EmergencyStopAll()
-
{
-
SendCommand(Command.StopAll, 1);
-
}
-
public void StopAll()
-
{
-
SendCommand(Command.ClearRelay, 48 + 9);
-
}
-
public void StartAll()
-
{
-
SendCommand(Command.SetRelay, 48 + 9);
-
}
-
}
-
public class Relay
-
{
-
private byte RelayId
-
{
-
get { return (byte)(48 + m_Id); }
-
}
-
public void On()
-
{
-
m_Owner.SendCommand(Command.SetRelay, RelayId);
-
}
-
public void Off()
-
{
-
m_Owner.SendCommand(Command.ClearRelay, RelayId);
-
}
-
public void Toggle()
-
{
-
m_Owner.SendCommand(Command.ToggleRelay, RelayId);
-
}
-
private Card m_Owner;
-
private byte m_Id;
-
internal Relay(Card owner, byte id)
-
{
-
m_Owner = owner;
-
m_Id = id;
-
}
-
}
-
}
Feel free to use it as you see fit.
–Jesper Högström