diff --git a/src/libDevCom/CMakeLists.txt b/src/libDevCom/CMakeLists.txt
index 87d8cca9d43c44d15bbf0d0ae36c2b5311f1b746..cdfc2e2edec3f8822636c0c1c452d83108ddc6da 100644
--- a/src/libDevCom/CMakeLists.txt
+++ b/src/libDevCom/CMakeLists.txt
@@ -15,6 +15,7 @@ target_sources(DevCom
   I2CCom.cpp
   I2CDevComuino.cpp
   PCA9548ACom.cpp
+  PCA9547Com.cpp
 
   SPICom.cpp
 
diff --git a/src/libDevCom/PCA9547Com.cpp b/src/libDevCom/PCA9547Com.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..17caadf288c3eca7dbb1aeb7eaaaab1295014ebb
--- /dev/null
+++ b/src/libDevCom/PCA9547Com.cpp
@@ -0,0 +1,319 @@
+#include "PCA9547Com.h"
+
+#include "DeviceComRegistry.h"
+#include "Logger.h"
+REGISTER_DEVCOM(PCA9547, I2CCom)
+
+#include "ComIOException.h"
+#include "ScopeLock.h"
+
+PCA9547Com::PCA9547Com(uint8_t deviceAddr, uint8_t channel,
+                       std::shared_ptr<I2CCom> com)
+    : I2CCom(deviceAddr),
+      m_com(com),
+      m_muxAddr(com->deviceAddr()),
+      m_channel(channel) {}
+
+PCA9547Com::~PCA9547Com() {}
+
+void PCA9547Com::write_reg32(uint32_t address, uint32_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg32(address, data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_reg16(uint32_t address, uint16_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg16(address, data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_reg8(uint32_t address, uint8_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg8(address, data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_reg32(uint32_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg32(data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_reg16(uint16_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg16(data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_reg8(uint8_t data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_reg8(data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_block(uint32_t address,
+                             const std::vector<uint8_t>& data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_block(address, data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::write_block(const std::vector<uint8_t>& data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->write_block(data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+uint32_t PCA9547Com::read_reg32(uint32_t address) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint32_t data = 0;
+    try {
+        data = m_com->read_reg32(address);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint32_t PCA9547Com::read_reg24(uint32_t address) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint32_t data = 0;
+    try {
+        data = m_com->read_reg24(address);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint16_t PCA9547Com::read_reg16(uint32_t address) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint16_t data = 0;
+    try {
+        data = m_com->read_reg16(address);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint8_t PCA9547Com::read_reg8(uint32_t address) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint8_t data = 0;
+    try {
+        data = m_com->read_reg8(address);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint32_t PCA9547Com::read_reg32() {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint32_t data = 0;
+    try {
+        data = m_com->read_reg32();
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint32_t PCA9547Com::read_reg24() {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint32_t data = 0;
+    try {
+        data = m_com->read_reg24();
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint16_t PCA9547Com::read_reg16() {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint16_t data = 0;
+    try {
+        data = m_com->read_reg16();
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+uint8_t PCA9547Com::read_reg8() {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    uint8_t data = 0;
+    try {
+        data = m_com->read_reg8();
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+    return data;
+}
+
+void PCA9547Com::read_block(uint32_t address, std::vector<uint8_t>& data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->read_block(address, data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::read_block(std::vector<uint8_t>& data) {
+    ScopeLock lock(m_com);
+
+    m_com->write_reg8(0xF8 + m_channel);
+
+    m_com->setDeviceAddr(deviceAddr());
+    try {
+        m_com->read_block(data);
+        restore_com();
+    } catch (const ComIOException& e) {
+        restore_com();
+        throw;
+    }
+}
+
+void PCA9547Com::lock() {
+    logger(logDEBUG4) << __PRETTY_FUNCTION__ << " -> PCA9547Com locked!";
+    m_com->lock();
+}
+
+void PCA9547Com::unlock() {
+    logger(logDEBUG4) << __PRETTY_FUNCTION__ << " -> PCA9547Com unlocked!";
+    m_com->unlock();
+}
+
+void PCA9547Com::restore_com() {
+    m_com->setDeviceAddr(m_muxAddr);
+    m_com->write_reg8(0);
+}
diff --git a/src/libDevCom/PCA9547Com.h b/src/libDevCom/PCA9547Com.h
new file mode 100644
index 0000000000000000000000000000000000000000..37e320e24e09f3f8452a963a9205010f84576fee
--- /dev/null
+++ b/src/libDevCom/PCA9547Com.h
@@ -0,0 +1,109 @@
+#ifndef PCA9547COM_H
+#define PCA9547COM_H
+
+#include <memory>
+
+#include "I2CCom.h"
+
+//! \brief PCA9547 Low Voltage 8-Channel I2C Switch with Reset
+/**
+ * [Datasheet](https://www.nxp.com/docs/en/data-sheet/PCA9547.pdf)
+ *
+ * Implements I2C communicatoin with a device that is connected to the
+ * manager using the PCA9547 multiplexer. The I2C calls are forwarded
+ * to right device using the internal `com` object as follows:
+ *
+ *  1. Enable only PCA9547's `channel` output
+ *  2. Change `com` target device address to `deviceAddr`
+ *  3. Perform requested I2C operation using `com`
+ *  4. Restore `com` target device address to PCA9547
+ *  5. Disable all PCA9547's channels
+ *
+ * The implementation assumes that the state of the PCA9547 control
+ * register can be changed externally (ie: in parallel process). This
+ * is why it always enables the desired channel.
+ *
+ * All channels are disabled at the end in case of parallel PCA9547
+ * devices. This way only a single multiplexed I2C bus is available
+ * for any communication request to any parallel PCA9547 device.
+ *
+ * The internal `com` object should target the PCA9547 device. The
+ * device address should not be changed after creating the object, as
+ * it is cached by the constructor.
+ */
+class PCA9547Com : public I2CCom {
+ public:
+    /**
+     * \param deviceAddr Target device address to which all I2C calls are
+     * forwarded \param channel Output channel to which the device is connected
+     * to \param com Internal `com` device targettign the PCA9547.
+     */
+    PCA9547Com(uint8_t deviceAddr, uint8_t channel,
+               std::shared_ptr<I2CCom> com);
+    virtual ~PCA9547Com();
+
+    /** Write commands @{ */
+
+    virtual void write_reg32(uint32_t address, uint32_t data);
+    virtual void write_reg16(uint32_t address, uint16_t data);
+    virtual void write_reg8(uint32_t address, uint8_t data);
+
+    virtual void write_reg32(uint32_t data);
+    virtual void write_reg16(uint16_t data);
+    virtual void write_reg8(uint8_t data);
+
+    virtual void write_block(uint32_t address,
+                             const std::vector<uint8_t>& data);
+    virtual void write_block(const std::vector<uint8_t>& data);
+
+    /** @} */
+
+    /** Read commands @{ */
+
+    virtual uint32_t read_reg32(uint32_t address);
+    virtual uint32_t read_reg24(uint32_t address);
+    virtual uint16_t read_reg16(uint32_t address);
+    virtual uint8_t read_reg8(uint32_t address);
+
+    virtual uint32_t read_reg32();
+    virtual uint32_t read_reg24();
+    virtual uint16_t read_reg16();
+    virtual uint8_t read_reg8();
+
+    virtual void read_block(uint32_t address, std::vector<uint8_t>& data);
+    virtual void read_block(std::vector<uint8_t>& data);
+
+    /** @} */
+
+    /** Request exclusive access to device (if m_com is DevComuino)
+     *
+     * If a single hardware bus is used to connect multiple devices,
+     * the access to all of them should be locked to remove changes
+     * of cross-talk.
+     *
+     * Throw `std::runtime_error` on error.
+     *
+     */
+    virtual void lock();
+
+    /** Release exclusive access to device (if m_com is DevComuino)
+     *
+     * Throw `std::runtime_error` on error.
+     *
+     */
+    virtual void unlock();
+
+ private:
+    std::shared_ptr<I2CCom> m_com;
+    uint8_t m_muxAddr;
+    uint8_t m_channel;
+
+    //! Restore multiplexer communication into default state
+    /**
+     * Sets the `m_com` device address to the mux address
+     * and disables all of the channels.
+     */
+    void restore_com();
+};
+
+#endif  // PCA9547COM_H