170 lines
6.9 KiB
Markdown
170 lines
6.9 KiB
Markdown
Load Cycle Test Jig
|
||
===================
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
## 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).
|
||
|
||

|
||
|
||
## 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: <https://github.com/HiassofT/AtariSIO/blob/master/contrib/rpi/uart-ctsrts.dts>
|
||
|
||
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
|
||
<http://www.apache.org/licenses/LICENSE-2.0>)
|
||
- MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||
<http://opensource.org/licenses/MIT>)
|
||
|
||
at your option.
|