8 Channel USB Relay with MacHIDMBS

Hi all,

I just got myself an 8 Channel USB Relay that I intend to control with the MacHIDMBS PlugIn. The relay looks similar to this one: https://www.sainsmart.com/sainsmart-4-channel-12-v-usb-relay-board-module-controller-for-automation-robotics-1.html

I am able to establish a connection successfully and read out properties from the relay such as ProductID, VendorID and SerialNumber using MacHIDMBS.

However does anyone have experience what exactly to do to get the individual relays switching? According to the technical documentation it expects an 0x50 at the beginning (I assume this has been done through MacHIDMBS.Connect). It is ready to receive commands after 0x51. I am trying to send messages via MacHIDMBS.SendMessage and MacHIDMBS.SendMessageMemory, however the relay never reacts.
Does anyone have experience with those relays on Xojo?

Thanks a lot,

Are you sure it is a HID Device at all?

Well, I thought so. I used the example “USB HID Devices Mac” coming with the MBS USB Plug-In. My relay is listed there and following the comment in the example the “MacHIDMBS” class could be used to talk to it.

It has an FTDI chip. So it could be a serial device

I tried with the SerialControl, however when listing all Serial-connected devices on my MacBook, it does not appear there.

It basically is this relay and documentation by the V-USB team exists, however just as .dll.

The .dll shows how to handle the relay, however this I would love to realize in Xojo directly.

[quote]static int rel_onoff( USBDEVHANDLE dev, int is_on, int relaynum )
unsigned char buffer[10];
int err = -1;
unsigned char cmd1, cmd2, mask, maskval;

if ( relaynum < 0 && (-relaynum) <= 8 ) {
    mask = 0xFF;
    cmd2 = 0;
    if (is_on) {
       cmd1 = 0xFE;
       maskval = (unsigned char)( (1U << (-relaynum)) - 1 );
    } else {
        cmd1 = 0xFC;
        maskval = 0;
} else {
    if ( relaynum <= 0 || relaynum > 8 ) {
        printerr("Relay number must be 1-8\

return 1;
mask = (unsigned char)(1U << (relaynum-1));
cmd2 = (unsigned char)relaynum;
if (is_on) {
cmd1 = 0xFF;
maskval = mask;
} else {
cmd1 = 0xFD;
maskval = 0;

You’d need ftdi vcp drivers i guess. Not sure of apple provides those for you

Thanks, Derk! Let me have a look for those.

Found this for you, on the web:

Communication Parameters:
8 Data, 1 Stop, No Parity
Baud rate : 9600

FIRST channel commands:
OFF command: FF 01 00 (HEX) or 255 1 0 (DEC)
ON command: FF 01 01 (HEX) or 255 1 1 (DEC)

SECOND channel commands:
OFF command: FF 02 00 (HEX) or 255 2 0 (DEC)
ON command: FF 02 01 (HEX) or 255 2 1 (DEC)

THIRD channel commands:
OFF command: FF 03 00 (HEX) or 255 3 0 (DEC)
ON command: FF 03 01 (HEX) or 255 3 1 (DEC)

FOURTH channel commands:
OFF command: FF 04 00 (HEX) or 255 4 0 (DEC)
ON command: FF 04 01 (HEX) or 255 4 1 (DEC)

That’s for the four channel version.

Great, thanks, Derk. It is working now. I actually still use the MacHIDMBS class and then send the following commands as you suggested.

dim mb as New MemoryBlock(2)

'switching relays ON with 255
mb.byte(1)=4 'relay number 1-8

'switching relays OFF with 253
mb.byte(1)=4 'relay number 1-8



Please check the HIDAPI classes for doing this cross platform:

Thanks, Christian!

On Mac it works well with the HIDAPI classes. I transfer the same memoryblock through HIDAPIDeviceMBS.SendFeatureReport and receive back an “8” from Mac.

On Windows however I supposed it would work the same, however it returns me a “-1” as soon as I transfer the same memoryblock. Whether using HIDAPIDeviceMBS.SendFeatureReport or HIDAPIDeviceMBS.Write makes no difference.

Any idea what I should do differently for Windows applications?

Thank you,

I think Windows is more picky about the block sizes.
So can you ask for Report size and than make sure your block matches?

and block may need to be 1 bigger to put the report ID in the first byte:

[code] // Send a Feature Report to the device
dim buf as new MemoryBlock(17)

buf.UInt8Value(0) = 2 // First byte is report number
buf.UInt8Value(1) = &ha0
buf.UInt8Value(2) = &h0a
dim r as integer
r = d.SendFeatureReport(buf)

Thanks, Christian!

It is working now since - as you said - Windows expected an extra byte upfront. The solution below works well for Mac and Windows with the HIDAPI Class.

dim res as integer
dim mb as New MemoryBlock(9)

mb.byte(0)=0 'always 0
mb.byte(1)=255 '255: single on, 253: single off, 254: all on, 252: all off
mb.byte(2)=1 'relay number (1-8)

Hi Everyone,
I recently purchased what looks like the same relay-board module, so I was glad to see this conversation since mine has absolutely no specs or info with it.

I have not been successful in getting any kind of response from the board, aside from illuminating the USB LED on the board. When I unplug and re-plug the USB cable, I can hear all of the relays activating, so I’m pretty confident that it’s alive and well. Also, it’s pretty clear that this board is using COM5.

So here are my questions: am I supposed to have some sort of additional driver or the like, such as MacHIDMBS PlugIn that was mentioned in the initial posting or is the Xojo Serial control enough? I’m running on Windows, so I don’t have an option to use that. Is there a Windows version? Is it necessary when using the Xojo “Serial” control?

Regarding my code, I’m using the following (BTW, my Serial control is named TestSerial, which I hijacked from another Xojo example program):
In the Window “Open” event, I execute the following code:

TestSerial.SerialPort = System.SerialPort( SerialPortPopup.ListIndex ) 'this is also from the hijacked code... 'Communication Parameters: '8 Data, 1 Stop, No Parity 'Baud rate : 9600 TestSerial.Bits=Serial.Baud9600 TestSerial.Stop=Serial.StopBits1 TestSerial.Parity=Serial.ParityNone TestSerial.Baud=Serial.Baud9600

I’ve placed the following code in the “Action” event of a push button control… I’ve tried many variations of it, but this is pretty much what I’ve learned from this conversation. Please let me know where I’ve erred or if there’s something more that I need to do.

[code]Dim mb as new MemoryBlock(4)
dim res as integer

'Initialize the communication with the module
mb.byte(0)= &h0
mb.byte(1)=&h50 '255: single on, 253: single off, 254: all on, 252: all off
mb.byte(2)=&h51 'relay number (1-8)

'Attempt to turn on all relays
mb.byte(0)= &h0
mb.byte(1)=&h252 '255: single on, 253: single off, 254: all on, 252: all off
mb.byte(2)=&h1 'relay number (1-8) - another bump to try to turn on relay 1

I would greatly appreciate any help that you could offer - my autopilot lawnmower hangs in the balance! Thanks in advance for your help,

How does device register with system?
Does it sign up as serial device or as HID device? Or something else?

Does it show up in System.SerialPort list?

Yes, the following code executes successfully and COM5 is added to the popup listbox when the code is executed. That would lead me to believe that it is a serial device. Is that a reasonable assumption?

[code]// Populate the popup menu with all of the
// serial ports the system has installed.
Dim count As Integer
count = System.SerialPortCount

For i As Integer = 0 To count - 1
SerialPortPopup.AddRow( System.SerialPort( i ).Name )

yes. So try Serial control.

The control is the Serial control (it’s the control that looks like a USB plug in the library). Is my code using something that conflicts with that? I’m in unfamiliar territory here, so I would greatly appreciate any direction you could give.