How to get ByVac BV4627 relay controller working with bash (intro)

This how-to has multiple pages. This page is introduction, to prove its working.

Check also theory behind why relays and why this BV4627 in here.

    • If you want to get ByVac BV4627 relay controller/board working, start with logging in to your Raspberry Pi or to your linux PC. You should know how to do it by now.
    • As in this stage we do not care about any security, switch ASAP to root user with following command:
sudo su -
  • Plug in BV4627 relay-controller to USB port. If you are using Raspberry Pi, you should use powered USB hub and plug it there not directly to RPi! Most probably this BV4627 board can get enough power also when plugged directly to RPi USB port but I am not taking that risk.  If you want to experiment plug it in directly to RPi and start turning relays on one by one to increase power consumption.
  • BV4627 is using FT232 USB-Serial interface and after you have plugged it in and run command:
lsusb
  • ….you should be able to find it in the list:

Bus 001 Device 008: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

  • Now check what is the device name what “magically appeared”. For that run command:
ls -lrt /dev/ttyUSB*
  • Output should be something following, at least by default on RPi:

crw-rw—T 1 root dialout 188, 0 Jun 21 09:13 /dev/ttyUSB0

  • If you have multiple devices, take the last (bottom) one. Above example has only one: /dev/ttyUSB0

Now its time to create two scripts. You can use editor nano for that or vi or something else. I don’t care how you do that. Plenty of vi/nano how-to’s in the net. Where were we…. yeah two scripts….lets name them relay_service.sh and relay.sh .

In first script change device name if your device is not /dev/ttyUSB0 ! (SERIALDEVICE variable)

  • relay_service.sh – save following code to that file
#!/bin/bash

# this script generally starts connection with relayboard and forwards commands
# Argo Ellisson 2014, BashPi.org, usage licence: GNU General Public License (GPL) Version 3
# version 1.1


# this device should have been created by udev rule - following symlink should exist and point to ttyUSB0 or something else
SERIALDEVICE="/dev/ttyUSB0"

# file for passing commands to relays - created in ramdisk for performance reasons
COMMANDFILE="/dev/shm/relaycommands.lst"

# cycle to try keep things running - not essential
while [ true ]; do

        # what code below generally does is that it configures serialdevice using stty and then forwards there all commands what will be written to COMMANDFILE

        # check does SERIALDEVICE exist

        if [ -c ${SERIALDEVICE} ]; then

           # configure serialdevice
           # these parameters may change if different device is used. 
           # Speed 9600 is enough for relayboard

           stty -F ${SERIALDEVICE} 9600 -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

           # open serialdevice for writing and assign file descriptor 3 to it
           exec 3>${SERIALDEVICE}
           # could be opened also for reading as below in case we want some feedback from relayboard. Not in current scope.
           # exec 3<>${SERIALDEVICE}

           # send few Carriage Returns / CR-s to serialdevice to initiate connection
           # this is optional step but we are not taking any chances
           echo -en "\xD" >&3
           sleep 2
           echo -en "\xD" >&3
           sleep 2
           echo -en "\xD" >&3
           sleep 2

           # set up commandfile - this is what we use to get commands from one or many other scripts
           echo -en "\xD" > ${COMMANDFILE}
           chmod 666 ${COMMANDFILE}
   
           # tail commandfile and redirect results to file descriptor 3 which is serialdevice
           tail -f ${COMMANDFILE} >&3
   
           # close file descriptor if tail exits
           exec 3<&-

        else

           echo "${SERIALDEVICE} does not exist or is not character device"

        fi

        sleep 60

done
  • relay.sh – save following code to that file
#!/bin/bash

# this script is a wrapper for BV4627f relay board
# It generally translates plain simple on-off commands to characters what relayboard expects
# also it provides on-off functionality with duration 
# Argo Ellisson 2014, BashPi.org, usage licence: GNU General Public License (GPL) Version 3
# version 1.1

COMMANDFILE="/dev/shm/relaycommands.lst"

usage() {
echo "USAGE: relay.sh <relay> <command> <delay>"
echo "WHERE:"
echo "Relay: [a-h]|[A-H]"
echo "Command: on|off|onfor|offfor"
echo "Delay: number of seconds to after which to turn on or off relay [0-3600]"
echo "All options are mandatory, including DELAY. Use delay 0 for now."
exit 1
}


if [ $# -eq 3 ];then 

##### LOG #####
DATE=`date`
echo "${DATE} relay:${1}  op:${2} duration:${3} sec"
##### LOG END #####

# relay selection
# this is a good place for relay aliases also - note "lights" below

case "$1" in
        a|A|lights)  RELAY="\x41"
        ;;
        b|B)  RELAY="\x42"
        ;;
        c|C)  RELAY="\x43"
        ;;
        d|D)  RELAY="\x44"
        ;;
        e|E)  RELAY="\x45"
        ;;
        f|F)  RELAY="\x46" 
        ;;
        g|G)  RELAY="\x47" 
        ;;
        h|H)  RELAY="\x48"
        ;;
        *) echo "incorrect relay chosen"
        usage
        ;;
esac

# timer config. using it always as its simpler

if [ $3 != "0" ];then
        if echo "$3" | grep -qE ^\-?[0-9]?\.?[0-9]+$; then
                # calculate time
                TIME=$(echo "$3" |awk '{print int($1*13.6);}')
                if [ $TIME -gt 65000 ];then
                        echo "Delay is too big, max ~4700sec/79min/1.3hours"
                        usage
                fi
                if [ $TIME -lt 1 ];then
                        $TIME=1
                fi
                # convert to hex
                DELAY=`echo -n "$TIME" |od -t x1 |head -1|awk 'BEGIN{ORS=""}{ for (i=2;i<=NF;i++)print "\x"$i}'`

        else
                echo "Delay is not positive number!"
                usage
        fi

else
        DELAY="\x31"
fi

# Command selection - note that as duration is not supported by relayboard, we send actually 2 commands to relayboard in case of onfor/offfor commands 
# First command in case construct below and second command as USUAL
case "$2" in
        on|ON)  COMM="\x31"
        ;;
        off|OFF) COMM="\x30"
        ;;
        onfor|ONFOR) COMM="\x30"
        # onfor - usual command does timed switch off so first switch that relay on
        echo -en "\x1b\x5b\x31${RELAY}" >> ${COMMANDFILE}
        # note that USUAL command is actually "OFF" above
        ;;
        offfor|OFFFOR)  COMM="\x31"
        # offfor - usual command does timed switch on so first switch that relay off
        echo -en "\x1b\x5b\x30${RELAY}" >> ${COMMANDFILE}
        # note that USUAL command is actually "ON" above
        ;;
        *) echo "incorrect command"
        usage
        ;;
esac

# put USUAL command together / Comma \x2c / ESC \x1b / [ \x5b
COMMAND="\x1b\x5b${COMM}\x2c${DELAY}${RELAY}"

# DEBUG
#echo $RELAY
#echo $COMM
#echo $DELAY
#echo $COMMAND

# echo command to outputfile
echo -en "${COMMAND}" >> ${COMMANDFILE}

exit 0

fi

usage
  • Now its good time to make these two scripts executable with following command
chmod u+x ./relay*.sh
  • Almost done, run service script in background
./relay_service.sh &
  • Ready to use! Run relay script to turn on/off relays f.e. to turn on relays a and b run following (note delay 0 seconds as a last parameter). Run commands couple of times, there may be some glitches.
./relay.sh a on 0
./relay.sh b on 0
  • To turn relays off, just replace parameter on with off in commands above… If you run script without parameters, it displays usage information like supported commands etc.:

USAGE: relay.sh <relay> <command> <delay>
WHERE:
Relay: [a-h]|[A-H]
Command: on|off|onfor|offfor
Delay: number of seconds to after which to turn on or off relay [0-3600]
All options are mandatory, including DELAY. Use delay 0 for now.

Did you notice commands onfor and offfor? I wrote in relay-introduction page that BV4627 board supports switching with timer. With these extra options you can additionally to delayed switching also switch relays on or off for certain time. Relay script just sends two commands to the relays f.e. if you want to turn on relay A for 5 seconds and execute command “./relay.sh a onfor 5” , relay script just sends command to turn relay a on and right after that command to turn off with 5 second delay. So its a little extra to originally supported functionality.

  • If you got all that and it was really boring you can amuse yourself by making some noise with relays. Following command run really fast on my PC, if you are interested in numbers then it was able to send about 100 commands (50 times on and off) to the board per second. RPi managed about 12 commands per second.
while true; do for f in a b c d e f g h; do ./relay.sh $f offfor 0.1;done ; date ; done

Scripts in this page were tested on:

  • Raspberry Pi Model B 512MB RAM. OS: Raspbian Wheezy, released in 2014-01-07. All updates installed on 1. september 2014.
  • Almost random pc with x86-64 architecture, running Ubuntu 12.04 (precise)

Shopping list:

  • BV4627 relay-controller: ByVac shop 36£ + shipping, you may check also Ebay. Note that there exists two versions of that board from which cut-down version does not have USB interface what is used in this how-to.
  • USB cable:  A (plug/male) – mini B (plug/male)
  • For RPi I suggest to use also powered USB hub

If you found this useful, say thanks, click on some banners or donate, I can always use some beer money.

NEXT How to get ByVac BV4627 relay controller working with bash (advanced)