Since there is an up-to 30 V voltage difference between the two grounds, it's better to use some sort of galvanic isolation between the two systems.
Low to medium speeds (up to 10Mbps with some optoisolators)
For instance you can use an optoisolator:
simulate this circuit – Schematic created using CircuitLab
Values are shown just as an example, and assume that you are using an optocoupler with a current transfer ratio (CTR) not much smaller than 100%.
Higher speed (up to 150Mbps)
If you need to go at very high speed (e.g. 100Mbps), you can also use an SiO2-isolation barrier based digital isolator, such as ISO7710.
Unlike conventional optoisolators, they do not use an LED and a photodetector, but they transmit a signal through a capacitor, by OOK modulation.
However, they are more expensive with respect optoisolators, and you need also decoupling capacitors on both sides.
How to reduce cost
Instead of using 20 isolated channels, you can try to implement some parallel-to-serial conversion in the first system, and a serial-to-parallel conversion in the second system. In this way, you'll have to send just 3 signals: data, clock, and a frame/load/chip select signal.
simulate this circuit
The Parallel-in serial-out (PISO) register converts your 20 parallel inputs to a single serial stream. The serial-input parallel-output performs the opposite operation.
When you pulse (low pulse in case of a 74xx165) the
PARALLEL_LOAD signal, then you load the parallel datas into the PISO shift register. On each clock pulse,
DOUT will reflect the value of the next parallel input. The clock and such
DOUT is transmitted across the isolation system of your choice.
The SIPO register will receive the clock and the data value (note! you might need to invert the received clock signal according to your PISO/SIPO clock edge sensitivity!). After you have sent all the data bits, pulse the
OUTPUT_LOAD signal, to update the outputs of your SIPO register.
If you have a microcontroller, then you can avoid the PISO register and connect the SPI outputs (clock, MOSI, and two GPIOs for
OUTPUT_LOAD) lines to the isolator. You can also use a port expander instead of the SIPO register, but that would be an overkill, since you would use it just a mere SIPO register (typically cheaper and available from a number of manufacturers, so you are not stuck with just one).
NOTE: in the circuit diagram above GNDs and VDDs are not shown.