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…

  1. //Written by Jesper Högström
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.IO.Ports;
  6.  
  7. namespace CardAPI
  8. {
  9.   internal enum Command
  10.   {
  11.     ChangeAddress = 64 + 1, // ‘A’
  12.     SendByte = 64 + 2, // ‘B’
  13.     ClearRelay = 64 + 3, // ‘C’
  14.     DisplayAddress = 64 + 4, // ‘D’
  15.     StopAll = 64 + 5, // ‘E’
  16.     ForceAddress1 = 64 + 6, // ‘F’
  17.     SetRelay = 64 + 19, // ‘S’
  18.     ToggleRelay = 64 + 20 // ‘T’
  19.   }
  20.   public class Card
  21.   {
  22.     private List m_Relays = new List();
  23.     private SerialPort com;
  24.     private int baudRate = 2400;
  25.     public Card()
  26.       : this("COM1")
  27.     {
  28.     }
  29.     public Card(string portName)
  30.     {
  31.       com = new SerialPort(portName, baudRate);
  32.       PortName = portName;
  33.       for (int relayId = 9; relayId >= 1; relayId–)
  34.         m_Relays.Add(new Relay(this, (byte)relayId));
  35.     }
  36.     private string m_PortName;
  37.     public string PortName
  38.     {
  39.       get { return m_PortName; }
  40.       set
  41.       {
  42.         if (com != null && com.IsOpen)
  43.           com.Close();
  44.         m_PortName = value;
  45.         com = new SerialPort(m_PortName, baudRate);
  46.         /* these settings seem to be default anyway.
  47.         com.DataBits = 8;
  48.         com.Parity = Parity.None;
  49.         com.StopBits = StopBits.One;
  50.          */
  51.         com.ReadTimeout = 3000;
  52.         com.WriteTimeout = 3000;
  53.         com.Open();
  54.         com.Close();
  55.       }
  56.     }
  57.     private byte m_CardAddress = 1;
  58.  
  59.     ~Card()
  60.     {
  61.       if (com.IsOpen)
  62.         com.Close();
  63.     }
  64.     private byte CheckSum(byte[] buf)
  65.     {
  66.       int res = 256 – buf[0] – buf[1] – buf[2] – buf[3];
  67.       while (res < 0)
  68.         res += 256;
  69.       return (byte)res;
  70.     }
  71.     private byte[] buf = new byte[5];
  72.     private int repeatCount = 1;
  73.     private int msDelay = 400;
  74.     internal void SendCommand(Command command, byte data)
  75.     {
  76.       buf[0] = 13; // start command
  77.       buf[1] = m_CardAddress; // address
  78.       buf[2] = (byte)command; // command
  79.       buf[3] = data; // data
  80.       buf[4] = CheckSum(buf); // checksum
  81.  
  82.       if (!com.IsOpen)
  83.         com.Open();
  84.       for (int i = 0; i < repeatCount; i++)
  85.       {
  86.         com.Write(buf, 0, 5);
  87.       }
  88.       com.Close();
  89.       System.Threading.Thread.Sleep(msDelay);
  90.  
  91.     }
  92.     public Relay this[int index]
  93.     {
  94.       get { return m_Relays[index]; }
  95.     }
  96.     public void ShowAddresses()
  97.     {
  98.       SendCommand(Command.DisplayAddress, m_CardAddress);
  99.     }
  100.     public void SetRelays(byte state)
  101.     {
  102.       SendCommand(Command.SendByte, state);
  103.     }
  104.     public void EmergencyStopAll()
  105.     {
  106.       SendCommand(Command.StopAll, 1);
  107.     }
  108.     public void StopAll()
  109.     {
  110.       SendCommand(Command.ClearRelay, 48 + 9);
  111.     }
  112.     public void StartAll()
  113.     {
  114.       SendCommand(Command.SetRelay, 48 + 9);
  115.     }
  116.   }
  117.   public class Relay
  118.   {
  119.     private byte RelayId
  120.     {
  121.       get { return (byte)(48 + m_Id); }
  122.     }
  123.     public void On()
  124.     {
  125.       m_Owner.SendCommand(Command.SetRelay, RelayId);
  126.     }
  127.     public void Off()
  128.     {
  129.       m_Owner.SendCommand(Command.ClearRelay, RelayId);
  130.     }
  131.     public void Toggle()
  132.     {
  133.       m_Owner.SendCommand(Command.ToggleRelay, RelayId);
  134.     }
  135.     private Card m_Owner;
  136.     private byte m_Id;
  137.     internal Relay(Card owner, byte id)
  138.     {
  139.       m_Owner = owner;
  140.       m_Id = id;
  141.     }
  142.   }
  143. }

Feel free to use it as you see fit.

–Jesper Högström

  • Share/Bookmark

Leave a comment

Your comment