diff --git a/DCC.cpp b/DCC.cpp
index aec1662..01c2309 100644
--- a/DCC.cpp
+++ b/DCC.cpp
@@ -38,6 +38,7 @@
 #include "TrackManager.h"
 #include "DCCTimer.h"
 #include "Railcom.h"
+#include "DCCQueue.h"
 
 // This module is responsible for converting API calls into
 // messages to be sent to the waveform generator.
@@ -157,8 +158,8 @@ void DCC::setThrottle2( uint16_t cab, byte speedCode)  {
     b[nB++] = speedCode; // for encoding see setThrottle
 
   }
-
-  DCCWaveform::mainTrack.schedulePacket(b, nB, 0);
+  if (speedCode==1) DCCQueue::scheduleEstopPacket(b, nB, 4, cab); // highest priority
+  else DCCQueue::scheduleDCCSpeedPacket( b, nB, 4, cab);
 }
 
 void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
@@ -172,7 +173,7 @@ void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
   if (byte1!=0) b[nB++] = byte1;
   b[nB++] = byte2;
 
-  DCCWaveform::mainTrack.schedulePacket(b, nB, count);
+  DCCQueue::scheduleDCCPacket(b, nB, count);
 }
 
 // returns speed steps 0 to 127 (1 == emergency stop)
@@ -238,7 +239,7 @@ bool DCC::setFn( int cab, int16_t functionNumber, bool on) {
        b[nB++] = (functionNumber & 0x7F) | (on ? 0x80 : 0);  // low order bits and state flag
        b[nB++] = functionNumber >>7 ;  // high order bits
     }
-    DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
+    DCCQueue::scheduleDCCPacket(b, nB, 4);
   }
   // We use the reminder table up to 28 for normal functions.
   // We use 29 to 31 for DC frequency as well so up to 28
@@ -339,16 +340,17 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
   // second byte is of the form 1AAACPPG, where C is 1 for on, PP the ports 0 to 3 and G the gate (coil).
   b[0] = address % 64 + 128;
   b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
-  if (onoff != 0) {
-    DCCWaveform::mainTrack.schedulePacket(b, 2, 3);      // Repeat on packet three times
-#if defined(EXRAIL_ACTIVE)
-    RMFT2::activateEvent(address<<2|port,gate);
-#endif
-  }
-  if (onoff != 1) {
+  if (onoff==0) {   // off packet only
     b[1] &= ~0x08; // set C to 0
-    DCCWaveform::mainTrack.schedulePacket(b, 2, 3);      // Repeat off packet three times
-  }
+    DCCQueue::scheduleDCCPacket(b, 2, 3);
+  } else if (onoff==1) { // on packet only
+    DCCQueue::scheduleDCCPacket(b, 2, 3);
+  } else { // auto timed on then off  
+    DCCQueue::scheduleAccOnOffPacket(b, 2, 3, 100); // On then off after 100mS
+  } 
+#if defined(EXRAIL_ACTIVE)
+  if (onoff !=0) RMFT2::activateEvent(address<<2|port,gate);
+#endif
 }
 
 bool DCC::setExtendedAccessory(int16_t address, int16_t value, byte repeats) {
@@ -398,7 +400,7 @@ whole range of the 11 bits sent to track.
     | (((~(address>>8)) & 0x07)<<4)  // shift out 8, invert, mask 3 bits, shift up 4
     | ((address & 0x03)<<1);         // mask 2 bits, shift up 1
   b[2]=value;
-  DCCWaveform::mainTrack.schedulePacket(b, sizeof(b), repeats);
+  DCCQueue::scheduleDCCPacket(b, sizeof(b), repeats);
   return true;
 }
 
@@ -417,7 +419,7 @@ void DCC::writeCVByteMain(int cab, int cv, byte bValue)  {
   b[nB++] = cv2(cv);
   b[nB++] = bValue;
 
-  DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
+  DCCQueue::scheduleDCCPacket(b, nB, 4);
 }
 
 //
@@ -435,7 +437,7 @@ void DCC::readCVByteMain(int cab, int cv, ACK_CALLBACK callback)  {
   b[nB++] = cv2(cv);
   b[nB++] = 0;
 
-  DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
+  DCCQueue::scheduleDCCPacket(b, nB, 4);
   Railcom::anticipate(cab,cv,callback);
 }
 
@@ -457,7 +459,7 @@ void DCC::writeCVBitMain(int cab, int cv, byte bNum, bool bValue)  {
   b[nB++] = cv2(cv);
   b[nB++] = WRITE_BIT | (bValue ? BIT_ON : BIT_OFF) | bNum;
 
-  DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
+  DCCQueue::scheduleDCCPacket(b, nB, 4);
 }
 
 bool DCC::setTime(uint16_t minutes,uint8_t speed, bool suddenChange) {
@@ -494,7 +496,7 @@ b[1]=0b11000001; // 1100-0001 (model time)
 b[2]=minutes % 60 ;  // MM
 b[3]= 0b11100000 | (minutes/60); // 111H-HHHH weekday not supported
 b[4]= (suddenChange ? 0b10000000 : 0) | speed;
-DCCWaveform::mainTrack.schedulePacket(b, sizeof(b), 2);
+DCCQueue::scheduleDCCPacket(b, sizeof(b), 2);
 return true; 
 }
 
@@ -844,12 +846,17 @@ byte DCC::loopStatus=0;
 
 void DCC::loop()  {
   TrackManager::loop(); // power overload checks
-  issueReminders();
+  if (DCCWaveform::mainTrack.isReminderWindowOpen()) {
+    // Now is a good time to choose a packet to be sent
+    // Either highest priority from the queues or a reminder
+    if (!DCCQueue::scheduleNext()) {
+      issueReminders();
+      DCCQueue::scheduleNext(); // push through any just created reminder
+    }
+  }
 }
 
 void DCC::issueReminders() {
-  // if the main track transmitter still has a pending packet, skip this time around.
-  if (!DCCWaveform::mainTrack.isReminderWindowOpen()) return;
   // Move to next loco slot.  If occupied, send a reminder.
   auto slot = nextLocoReminder;
   if (slot >= &speedTable[MAX_LOCOS]) slot=&speedTable[0];  // Go to start of table
diff --git a/DCCQueue.cpp b/DCCQueue.cpp
index bd9b282..1186bd5 100644
--- a/DCCQueue.cpp
+++ b/DCCQueue.cpp
@@ -26,28 +26,28 @@
 // create statics 
 DCCQueue* DCCQueue::lowPriorityQueue=new DCCQueue();
 DCCQueue* DCCQueue::highPriorityQueue=new DCCQueue();
-PENDING* DCCQueue::recycleList=nullptr;
+PendingSlot* DCCQueue::recycleList=nullptr;
 
     DCCQueue::DCCQueue() {
         head=nullptr;
         tail=nullptr;
     }
     
-    void DCCQueue::addQueue(PENDING* p) {
+    void DCCQueue::addQueue(PendingSlot* p) {
         if (tail) tail->next=p;
         else head=p;
         tail=p;
         p->next=nullptr;          
     }
 
-    void DCCQueue::jumpQueue(PENDING* p) {
+    void DCCQueue::jumpQueue(PendingSlot* p) {
         p->next=head;
         head=p;
         if (!tail) tail=p; 
     }
 
     
-    void DCCQueue::recycle(PENDING* p) {
+    void DCCQueue::recycle(PendingSlot* p) {
         p->next=recycleList;
         recycleList=p;
     }
@@ -82,7 +82,7 @@ PENDING* DCCQueue::recycleList=nullptr;
         
         
         // kill any existing throttle packets for this loco
-        PENDING * previous=nullptr;
+        PendingSlot * previous=nullptr;
         auto p=highPriorityQueue->head;
         while(p) {
             if (loco==0 || p->locoId==loco) {
@@ -121,7 +121,7 @@ PENDING* DCCQueue::recycleList=nullptr;
     bool DCCQueue::scheduleNext() {
         // check high priority queue first
         if (!DCCWaveform::mainTrack.isReminderWindowOpen()) return false;
-        PENDING* previous=nullptr;
+        PendingSlot* previous=nullptr;
         for (auto p=highPriorityQueue->head;p;p=p->next) {
             // skip over pending ACC_OFF packets which are still delayed
             if (p->type == ACC_OFF_PACKET && millis()<p->startTime) continue;
@@ -158,15 +158,15 @@ PENDING* DCCQueue::recycleList=nullptr;
         return true;   
     }
     
-    // obtain and initialise slot for a PENDING.
-    PENDING*  DCCQueue::getSlot(PendingType type, byte* packet, byte length, byte repeats,uint16_t loco) {
-        PENDING * p; 
+    // obtain and initialise slot for a PendingSlot.
+    PendingSlot*  DCCQueue::getSlot(PendingType type, byte* packet, byte length, byte repeats,uint16_t loco) {
+        PendingSlot * p; 
         if (recycleList) {
             p=recycleList;
             recycleList=p->next;
         }
         else { 
-            p=new PENDING; // need a queue entry 
+            p=new PendingSlot; // need a queue entry 
         }
         p->next=nullptr;
         p->type=type;
diff --git a/DCCQueue.h b/DCCQueue.h
index 8958d6b..4c1eacb 100644
--- a/DCCQueue.h
+++ b/DCCQueue.h
@@ -24,8 +24,8 @@
 #include "DCCWaveform.h"
 
 enum PendingType:byte {NORMAL_PACKET,ACC_ON_PACKET,ACC_OFF_PACKET,DEAD_PACKET};
-  struct PENDING {
-      PENDING* next; 
+  struct PendingSlot {
+      PendingSlot* next; 
       PendingType type;
       byte packetLength;
       byte packetRepeat;
@@ -65,20 +65,20 @@ class DCCQueue {
   private:
   
   // statics to manage high and low priority queues and recycleing of PENDINGs
-    static PENDING* recycleList;
+    static PendingSlot* recycleList;
     static DCCQueue* highPriorityQueue;
     static DCCQueue* lowPriorityQueue;
 
     DCCQueue();
     
-    PENDING*  head;
-    PENDING * tail;
+    PendingSlot*  head;
+    PendingSlot * tail;
     
-    // obtain and initialise slot for a PENDING. 
-    static PENDING*  getSlot(PendingType type, byte* packet, byte length, byte repeats, uint16_t loco);
-    static void recycle(PENDING* p);
-    void addQueue(PENDING * p);
-    void jumpQueue(PENDING * p);
+    // obtain and initialise slot for a PendingSlot. 
+    static PendingSlot*  getSlot(PendingType type, byte* packet, byte length, byte repeats, uint16_t loco);
+    static void recycle(PendingSlot* p);
+    void addQueue(PendingSlot * p);
+    void jumpQueue(PendingSlot * p);
   
 };
 #endif
\ No newline at end of file