Load Cycle Test Jig =================== ![Test jig overview](img/test-jig-front.jpg) This is the control software for a machine that runs repeated rotational load cycles on (3d-printed) mechanical parts, until they fail. I was originally motivated to build this to test ISO 5211 valve adapters (related to [ISO 5211 Adapter for PVC Ball Valve][iso-5211-pvc]). But it can be used to test any mechanical joint. You can use this codebase as an example for the [`profirust`](https://github.com/rahix/profirust) PROFIBUS DP master stack running on a Raspberry Pi. [iso-5211-pvc]: https://www.printables.com/model/605515-iso-5211-adapter-for-pvc-ball-valve ## How it works A pneumatic vane cylinder twists the part back and forth at a torque set by the pressure regulator. The software counts each reversal and stops the run as soon as one of the two end-stop sensors trips, which means the part has given way and the cylinder is free to rotate past its normal travel. #### Main hardware components - pneumatic vane cylinder (FESTO [DSRL-40-180P-FW][festo-30658]) * 5/3-way solenoid valve to control the cylinder * two inductive end-stop sensors on the cylinder (detect part failure) - filter-regulator maintenance unit (regulator controls the maximum torque) * pressure switch (detect low air pressure) - stack light (white, blue, orange) - see [Stack Lights][stack-light-post] on my blog - HD44780 LCD (20×4 characters) as the operator display - WAGO [750-303][wago-750-303] PROFIBUS fieldbus coupler for I/O signals - Raspberry Pi as the PROFIBUS master, with a MAX485 transceiver (See [Running RS-485 with a MAX485 on a Raspberry Pi](#running-rs-485-with-a-max485-on-a-raspberry-pi) below) [festo-30658]: https://www.festo.com/de/en/a/30658/ [stack-light-post]: https://blog.rahix.de/stack-lights/ [wago-750-303]: https://www.wago.com/de-en/io-systems/fieldbus-coupler-profibus-dp/p/750-303 ![Control side with WAGO stack, stack light, FRL and solenoid valve](img/test-jig-controls.jpg) ## Operating modes There are two switches which control the machine: - Mode selector (continuous or single) - Start/stop button The modes do the following: - **Continuous**: The cylinder alternates left and right every 5 seconds, the counter increments on each reversal, and the run ends when a limit switch trips. This is the standard "how many cycles until it breaks" test. - **Single**: One short preparation move, then a timed swing toward the opposite end stop. This is used to measure time to failure for a single event. Once failure occurs, the buzzer on the stack light pulses to let you know it's done. The LCD shows the current state together with either the cycle counter (continuous mode) or the elapsed cycle time (single mode). ![LCD readout during a run](img/test-jig-display.jpg) ## Software architecture This is a pattern that I find to work well for control system software on hosted systems (the Linux on the Raspberry Pi in this case). It is not particularly efficient, but very simple and robust. There are three threads: - The main thread runs the 20 ms control loop that computes the control system logic (`Logic::run()`). Before and after, it copies I/O data to and from the fieldbus process image and display. - A background thread runs the PROFIBUS DP master and the cyclic data exchange with the WAGO coupler ([`fieldbus.rs`]). The cycle time is adjusted to be optimal for the selected bus speed. - A third thread drives the HD44780 LCD over I2C ([`display.rs`]). It is woken from a condvar whenever a line changes. For any further I/O channels, you'd add more threads. Data is shared through mutexes which are only locked briefly to read or update data. This is very important to ensure no thread is ever blocked for long periods of time. You can find another example of this pattern in the [crab-control-center](https://github.com/muccc-rs/crab-control-center) code. #### Source layout - [`main.rs`] runs the control loop and does the data plumbing. - [`logic.rs`] contains the actual control logic: machine mode state machine, cylinder sequencing, status reporting. - [`fieldbus.rs`] contains the PROFIBUS communication, and peripheral configuration. - [`display.rs`] is the HD44780 over I2C driver thread. - [`util.rs`] contains small helpers that mirror the ones found in industrial PLC programming (e.g. `TimerOn`, `TimerOff`, `PulseTimer`). ## PROFIBUS The fieldbus module ([`fieldbus.rs`]) contains everything related to PROFIBUS communication: - Setup a DP peripheral with `profirust` using the Linux RS-485 PHY implementation - Peripheral parameters from a vendor GSD file (this was autogenerated with profirust's [`gsdtool`](https://github.com/rahix/profirust/tree/main/gsdtool)) - Exposing the process image to the rest of the application via Mutex #### Running RS-485 with a MAX485 on a Raspberry Pi PROFIBUS uses an 11-bit character frame with even parity. The Pi's default "mini UART" (`/dev/ttyS0`) does not accept `PARENB` (=even parity bit) and is therefore not usable. The proper PL011 UART has to be enabled instead, and the MAX485's DE/RE driver-enable line has to be tied to the UART's RTS pin so the kernel can switch the transceiver in step with each frame. Switch the primary UART to the PL011 by adding the following to `/boot/firmware/config.txt` and disabling the Bluetooth HCI service: ``` dtoverlay=disable-bt ``` ```bash sudo systemctl disable --now hciuart ``` After a reboot the PL011 is available as `/dev/ttyAMA0`, which is the device the code opens in [`fieldbus.rs`]. Hardware flow control on the primary UART is not exposed by the stock overlays, so a small device tree overlay is needed that routes RTS (and optionally CTS) to a GPIO. This overlay source can be used as is: Compile and install the overlay with: ```bash dtc -@ -Hepapr -I dts -O dtb -o uart0-ctsrts.dtbo uart-ctsrts.dts sudo cp uart0-ctsrts.dtbo /boot/firmware/overlays/ ``` Then append the following line to `/boot/firmware/config.txt` and reboot: ``` dtoverlay=uart0-ctsrts ``` Wire the MAX485 so that - DI to Pi's TXD (GPIO 14) - RO to Pi's RXD (GPIO 15) - combined DE and RE pins to the RTS GPIO chosen in the overlay (GPIO 17) Add the usual 120 ohm termination at both physical ends of the bus. ## References - [`profirust`](https://github.com/rahix/profirust) * [Blog post about `profirust`](https://blog.rahix.de/profirust/) * [Blog post generally explaining PROFIBUS](https://blog.rahix.de/profibus-primer/) - [`hd44780-driver`](https://github.com/JohnDoneth/hd44780-driver) LCD display driver [`main.rs`]: ./src/main.rs [`logic.rs`]: ./src/logic.rs [`fieldbus.rs`]: ./src/fieldbus.rs [`display.rs`]: ./src/display.rs [`util.rs`]: ./src/util.rs ## License Licensed under either of - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option.