Difference between revisions of "Relay Board Control"

From aquarium-doc
Jump to navigationJump to search
Line 58: Line 58:


The checksum is computed as XOR of byte 0, 1 and 2.
The checksum is computed as XOR of byte 0, 1 and 2.
The low level communication is done using one of two functions inside <code>RlyBrdCmd.c</code>.
* <code>RlyBrdInitCom</code> for initialisation of the communication
* <code>RlyBrdCmd</code> for sending commands to the boards
During the initialisation, the board responds an 8 byte sequence which seems to correspond to the SW version. Information regarding this sequence could not be found inside the user manual.
{| class="wikitable"
|+ initialisation response for 197730/197720 relay boards
|-
! Byte #!! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7
|-
| Value || 0xfe || 0x01 || 0x0b || 0xf4 || 0x01 || 0x02 || 0x0b || 0x08
|}


== Watchdog for reading/writing to serial port ==
== Watchdog for reading/writing to serial port ==

Revision as of 08:00, 5 January 2023

The following components utilise the relay board:

  • Refill Control: refilling of fresh water depending on water level
  • Feeder Control: stopping flow pumps, skimmer and actuating the feeder
  • Water Exchange Control: actuating the external pump for water exchange
  • Balling Control: actuating the pumps for mineral dosing


There are two requirements, which ask for a more sophisticated control of the relay board:

  • The dosing of minerals needs to be as precise as possible.
  • The communication with the board needs to be reinitialised and even reopened after certain periods of time.


The relay board control implements the following features:

  • Low level communication via serial port to the board
  • Watchdog for reading/writing to serial port
  • HW functionality test before executing commands
  • Monitoring and repair of relay board states
  • Avoiding conflicting access to relay board

Low level communication via serial port

This functionality is implemented in RlyBrdCtrl/RlyBrdCmd.c. The communication follows the protocol laid out in the user manual of the 197730/197730 relay boards.

Every command consists of a sequence of 4 byte.

command sequence for 197730/197720 relay boards
Byte # Content
0 command
1 board address
2 data
3 checksum

The command can assume one of 8 values, whereby the controller only uses a subset of these:

commands used for control of 197730/197720 relay boards
command # Meaning byte 0 value in board response
1 initialisation 254
2 get relay states 253
6 switch on relay 249
7 switch off relay 248

The relay boards offer functionality to connect multiple boards in a bus system. Therefore, the commands have to specify an address to identify the board for which the command is issued. The aquarium controller does not use this functionality. Low voltage board and high voltage board are connected via separate USB connections. Hence, address is always set to one.

The checksum is computed as XOR of byte 0, 1 and 2.

The low level communication is done using one of two functions inside RlyBrdCmd.c.

  • RlyBrdInitCom for initialisation of the communication
  • RlyBrdCmd for sending commands to the boards

During the initialisation, the board responds an 8 byte sequence which seems to correspond to the SW version. Information regarding this sequence could not be found inside the user manual.

initialisation response for 197730/197720 relay boards
Byte # 0 1 2 3 4 5 6 7
Value 0xfe 0x01 0x0b 0xf4 0x01 0x02 0x0b 0x08

Watchdog for reading/writing to serial port

This functionality is implemented in RlyBrdCtrl/RlyBrdWtchDg.c.

For communication with the relay boards, the application uses read and write instructions which may block the control flow at these points if the operation does not terminate.

In order to detect such events, a separate thread RlyBrdRdWrWtchDgThread monitors the duration of the read/write operations. The flag monitors how long certain flags are true:

  • RBC_Get_flgRlyBrdRdStarting provides the flag for monitoring read operations.
  • RBC_Get_flgRlyBrdWrStarting provides the flag for monitoring write operations.

The flags are set to true directly before the read/write operation and they are set to false directly after the operation.

The watch dog thread increases a counter for each second the read/write operation takes. When the counter exceeds the threshold RLYBRD_RD_WR_WTCHDG_MAX_T, the thread issues a log file entry, forces flushing of file buffers via sync(); and initiates a reboot of the device using reboot(RB_AUTOBOOT);.

HW functionality test

This functionality is implemented in RlyBrdCtrl/RlyBrdFdbck.c.

The control system connects a voltage input through one relay of each board to a GPIO pin of the Raspberry Pi.

By measuring the GPIO pin state, the control system can determine if the opening/closing of the relay really happened instead of just relying on the feedback of each board.

The feedback test evaluates three steps:

  1. Starting with an open relay, check if GPIO state is FALSE
  2. Closing the relay, check if GPIO state is TRUE
  3. Opening the relay, check if GPIO state is FALSE

The feedback test executed before relay switching sequences (e.g. feeding pattern, Balling dosing, ...) and in regular time intervals (every 30min).

Monitoring and repair of relay board states

This functionality is implemented in RlyBrdCtrl/RlyBrdMidLay.c.

Avoiding conflicting access to relay board

This functionality is implemented in RlyBrdCtrl/RlyBrdHiLay.c.

Mutual exclusion is implemented using a semaphore (mutRlyBrdSchdlr).

The semaphore is used only by the function RlyBrdSchdlr. This function is the central gateway for all other components to initiate usage of the relay board. It shall give control of the relay board to a calling component so that the calling component can execute a sequence of commands which shall not be interrupted.

The function uses two callbacks which are provided via argument and a label informing which component is using the relay board:

RlyBrdSchdlr (int TestFunc(void), void ExecFunc(void), char *lbl)

The first callback function (TestFunc) allows the calling component to determine specifically which tests needs to be carried out before the relay board can be used. For example, the Balling dosing only needs to actuate the low voltage relay board while the feeder control only actuates the high voltage relay board.

In case the test function fails, there are two recovery strategies:

  1. The communication with the relay board is reinitialised sending the related command. The test function is called again.
  2. If the test function fails again, the serial device is reopened. The test function is called again.

The second callback function (ExecFunc) gives control to the calling component for execution of the sequence. Execution is only triggered if one call of the test function returned with a successful result.