04 September, 2015

Home Automation: How to activate a relay via USB on Windows to control devices (blinds, lights, etc)



Although it is most economic and versatile use Arduino as a programmable electronic board, so we avoid the known unreliability of Windows, when you want to activate a equipment is sometimes easier to use a USB relay, either because we have a computer that has to be always on, or for other reasons, allowing us to theoretically control up to 8 switches for each USB connector on the same PC. 
I had to replace an old system that used the LPT1 port for controlling a time alarm (not compatible with Win XP or 7) so after investigating it I bought 2 pcs. of this USB-controlled relay  in Aliexpress.

And if we want to control multiple devices there are up to 8 channels (relays) in the same unit, with each relay 10A capacity, so the possibilities are very extended.




The most difficult part was to control it; my PC sometimes couldn't detect it (bad cable quality I chose), and the seller did not send the libraries for programming the unit. 
Luckily Google found them by "USBRelayExtLib", but my joy in a well, the command app "CommandApp_USBRelay" did not work either as manager or using XP or later, so I had to try using directly the included library with Autoit, thanks to some friends that had left the details to be automated in the Forum of Autoit, Thank you!!
The unit does not include the cable, but better use one of those included with Arduino boards (USB male to female), which are high quality with mesh avoiding any interference:
The program I use is this, I simply need to activate the alarm four seconds with this script , which thanks to Autoit I could convert it to an .exe  in the blink of an eye:


This would be the script (copy and paste it in Scite AutoIT editor):


#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=relay.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include

#cs
1. call usb_relay_init() to init the lib.
2. call usb_relay_device_enumerate() to get all the device pluged into pc
3. call usb_relay_device_open() open the device you need
4. other operation funcation:
call usb_relay_device_open_one_relay_channel() to open one way relay
call usb_relay_device_open_all_relay_channel() to open all relays
call usb_relay_device_close_one_relay_channel()to close one way relay
call usb_relay_device_close_all_relay_channel()to close all relays
#ce
$Serial = "abcde"
Global $hDllRelay = DllOpen("usb_relay_device.dll")

$aRet = DllCall( $hDllRelay, "ptr:cdecl", "usb_relay_device_enumerate" )
If @error Then
  MsgBox(16, "error", "usb_relay_device_enumerate", 3)
  Exit
EndIf
;_ArrayDisplay($aRet, "$aRet")
$ptr = $aRet[0]

$tag_usb_relay_device_info = "ptr serial_number;ptr device_path;uint relay_type;int relay_next"
;$tag_usb_relay_device_info = "ptr serial_number;ptr device_path;uint relay_type;ptr relay_next"

$t_usb_relay_device_info = DllStructCreate( $tag_usb_relay_device_info, $ptr )
If @error Then
    MsgBox(0, "", "Error in DllStructCreate " & @error);
    Exit
EndIf
$ptr_serial_number = DllStructGetData( $t_usb_relay_device_info, "serial_number" )
ConsoleWrite( "$ptr_serial_number = " & $ptr_serial_number & @CRLF )
$ptr_device_path = DllStructGetData( $t_usb_relay_device_info, "device_path" )
ConsoleWrite( "$ptr_device_path = " & $ptr_device_path & @CRLF )
$relay_type = DllStructGetData( $t_usb_relay_device_info, "relay_type" )
ConsoleWrite( "$relay_type = " & $relay_type & @CRLF )
$relay_next = DllStructGetData( $t_usb_relay_device_info, "relay_next" )
ConsoleWrite( "$relay_next = " & $relay_next & @CRLF )

; Buffer for serial number for max. 32 characters
$tag_serial_number = "char[32]"

; Fill buffer with data from the memory location given by the pointer
$t_serial_number = DllStructCreate( $tag_serial_number, $ptr_serial_number )

; Get serial number as a string
$s_serial_number = DllStructGetData( $t_serial_number, 1 )

; Print serial number
ConsoleWrite( "$s_serial_number = " & $s_serial_number & @CRLF )

$aRet1 = DllCall( $hdllrelay, "int", "usb_relay_init" )
ConsoleWrite($aRet1[0] & @LF)

;Hemos cogido en $s_serial_number el número de serie del primero que tenemos conectado
$aRet = DllCall( $hdllrelay, "int:cdecl", "usb_relay_device_open_with_serial_number", "str", $s_serial_number, "uint", 5 )
If @error Then
  ConsoleWrite( "Errorcode: " & @error & @CRLF )
Else
  ConsoleWrite( "Handle: " & $aRet[0] & @CRLF )
EndIf
$para1 = "int"
$para2 = $aRet[0]
$para3 = "int"
$para4 = 1

$aRet2 = DllCall($hdllrelay, "int:cdecl", "usb_relay_device_open_one_relay_channel", $para1, $para2, $para3, $para4)
ConsoleWrite($aRet2[0] & @LF)

Sleep(4000) ;Paramos 4 segundos antes de cerrar de nuevo el relé

$aRet2 = DllCall($hdllrelay, "int:cdecl", "usb_relay_device_close_one_relay_channel", $para1, $para2, $para3, $para4)
ConsoleWrite($aRet2[0] & @LF)

DllClose($hdllrelay)

If you examine the program and have some programming experience, you see it is quite simple to interpret; I just discovered Autoit and I think I'll use it for more things in the future.
If we want to control more relays, please note that this program simply take the first relay connected and activate it, so we have to identify the Serial Number (5 letters) of each of them with either the "GuiApp_English.exe" included with the library, or with the script itself.

And here it is the relay for alarm clock, connected to the computer, and protected with clear tape to prevent any shortcircuit:


Happy hacking!!

Sources: 
Programming USBRelay Control (Windows )
Programming USBRelay (Linux)
ControlCode under Pithon
Autoit Forum on the use of its library with Autoit Download AutoIt3 in Autoit.com

No comments :

Post a Comment