diff --git a/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.cpp b/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.cpp
index 66e92d01..79127df1 100644
--- a/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.cpp
+++ b/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.cpp
@@ -308,6 +308,7 @@ esp_err_t mcp2515::ViewRegisters()
 
 esp_err_t mcp2515::Write(const CAN_frame_t* p_frame, TickType_t maxqueuewait /*=0*/)
   {
+  OvmsRecMutexLock lock(&m_mutex);
   uint8_t buf[16];
   uint8_t id[4];
 
@@ -317,6 +318,12 @@ esp_err_t mcp2515::Write(const CAN_frame_t* p_frame, TickType_t maxqueuewait /*=
     return ESP_OK;
     }
 
+  // if there are frames waiting in the TX queue, add the new one there as well:
+  if (uxQueueMessagesWaiting(m_txqueue))
+    {
+    return QueueWrite(p_frame, maxqueuewait);
+    }
+
   // check for free TX buffer:
   uint8_t txbuf;
   uint8_t* p = m_spibus->spi_cmd(m_spi, buf, 1, 1, CMD_READ_STATUS);
@@ -370,6 +377,7 @@ esp_err_t mcp2515::Write(const CAN_frame_t* p_frame, TickType_t maxqueuewait /*=
 // Returns true if this function needs to be called again (another frame may need handling or all error interrupts are not yet handled)
 bool mcp2515::AsynchronousInterruptHandler(CAN_frame_t* frame, bool * frameReceived)
   {
+  OvmsRecMutexLock lock(&m_mutex);
   uint8_t buf[16];
 
   *frameReceived = false;
diff --git a/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.h b/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.h
index e4d00cb8..430f8ef8 100644
--- a/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.h
+++ b/vehicle/OVMS.V3/components/mcp2515/src/mcp2515.h
@@ -35,6 +35,7 @@
 #include "freertos/queue.h"
 #include "can.h"
 #include "spi.h"
+#include "ovms_mutex.h"
 
 // MCP2515 SPI commands:
 #define CMD_RESET         0b11000000
@@ -107,6 +108,7 @@ class mcp2515 : public canbus
     int m_clockspeed;
     int m_cspin;
     int m_intpin;
+    OvmsRecMutex m_mutex;
   };
 
 #endif //#ifndef __MCP2515_H__
