Difference between revisions of "Relay Board Control"

From aquarium-doc
Jump to navigationJump to search
Line 20: Line 20:
== Low level communication via serial port ==
== Low level communication via serial port ==
This functionality is implemented in <code>RlyBrdCtrl/RlyBrdCmd.c</code>.
This functionality is implemented in <code>RlyBrdCtrl/RlyBrdCmd.c</code>.
The communication follows the protocol laid out in the [https://asset.conrad.com/media10/add/160267/c1/-/gl/000197720ML02/bedienungsanleitung-197720-conrad-components-197720-relaiskarte-baustein-12-vdc-24-vdc.pdf user manual of the 197730/197730 relay boards].
Every command consists of a sequence of 4 byte.
{| class="wikitable"
|+ command sequence for 197730/197720 relay boards
|-
! Byte # !! Content
|-
| 0 || command
|-
| 1 || board address
|-
| 2 || data
|-
| 3 || checksum
|}
The checksum is computed as XOR of byte 0, 1 and 2.


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

Revision as of 07:35, 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 checksum is computed as XOR of byte 0, 1 and 2.

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.