Difference between revisions of "Relay Board Control"
| Line 79: | Line 79: | ||
Additionally, the function checks the response of the relay board. | Additionally, the function checks the response of the relay board. | ||
The response of the relay board sporadically deviates from the response defined in the user manual. | The response of the relay board sporadically deviates from the response defined in the user manual. | ||
Specified is a response which can be computed as <code>255 - command #</code>. | |||
After some time of operation the board changes to responding with <code> command #</code>. | |||
After some more time of operation, the board may change back to the specified response. | |||
The control adapts to this toggling response behaviour. | |||
Expected response is computed accordingly. Each byte of the board's response is checked. | |||
== Watchdog for reading/writing to serial port == | == Watchdog for reading/writing to serial port == | ||
Revision as of 08:11, 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.
| 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:
| 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.
RlyBrdInitComfor initialisation of the communicationRlyBrdCmdfor sending commands to the boards
Both commands use the semaphore mutexRlyBrd to guarantee exclusive access to the devices.
Both commands check the length of the response from the board and issue an error if the length is not as expected.
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.
| Byte # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| Value | 0xfe | 0x01 | 0x0b | 0xf4 | 0x01 | 0x02 | 0x0b | 0x08 |
The command RlyBrdInitCom checks if the relay board responds with this sequence.
The command RlyBrdCmd checks the checksum of the board's response.
Additionally, the function checks the response of the relay board.
The response of the relay board sporadically deviates from the response defined in the user manual.
Specified is a response which can be computed as 255 - command #.
After some time of operation the board changes to responding with command #.
After some more time of operation, the board may change back to the specified response.
The control adapts to this toggling response behaviour.
Expected response is computed accordingly. Each byte of the board's response is checked.
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_flgRlyBrdRdStartingprovides the flag for monitoring read operations.RBC_Get_flgRlyBrdWrStartingprovides 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:
- Starting with an open relay, check if GPIO state is
FALSE - Closing the relay, check if GPIO state is
TRUE - 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:
- The communication with the relay board is reinitialised sending the related command. The test function is called again.
- 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.