diff --git a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex
index 927c242cb3c7e861b09480f21f86698687bc1a6e..21bfd9a40eaedb1542a45cb20107300c55cb250d 100644
Binary files a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex and b/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex differ
diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex
index 895673397d5081bc0660615f974f02b6eae609f0..ab805ea8f1a1288a922e97052757517482ce02d0 100644
Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex and b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex differ
diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex
index d39e268e140895ad3e3ce1e44de744e0c078d78d..f1d4060f99ed224defc1076c96fba5e0d819c1bf 100644
Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex and b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex differ
diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex
index 569fcdc4cd949740bb827bd8367f7f724dcdfba5..54ab1d1831cc9065572d3f6a84df62dbf63dc198 100644
Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex and b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex differ
diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex
index 569fcdc4cd949740bb827bd8367f7f724dcdfba5..54ab1d1831cc9065572d3f6a84df62dbf63dc198 100644
Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex and b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex differ
diff --git a/AstroEQ-ConfigUtility/hex/hexNames.txt b/AstroEQ-ConfigUtility/hex/hexNames.txt
index 183619299eb5be5596e071c36826f9925a90ea71..a766f48b6e554bcf49c57a4829cd4cb343925567 100644
--- a/AstroEQ-ConfigUtility/hex/hexNames.txt
+++ b/AstroEQ-ConfigUtility/hex/hexNames.txt
@@ -1,8 +1,8 @@
-AstroEQArduinoMega1280(Legacy)	6.5
-AstroEQArduinoMega2560(Legacy)	6.5
-AstroEQATMega162Based(Legacy)	6.5
-AstroEQV4-EQ5Board	6.5
-AstroEQV4-DIYBoard(includingKits)	6.5
+AstroEQArduinoMega1280(Legacy)	6.7
+AstroEQArduinoMega2560(Legacy)	6.7
+AstroEQATMega162Based(Legacy)	6.7
+AstroEQV4-EQ5Board	6.7
+AstroEQV4-DIYBoard(includingKits)	6.7
 AstroEQArduinoMega1280(Legacy)EEPROMReader	1.2
 AstroEQArduinoMega2560(Legacy)EEPROMReader	1.2
 AstroEQATMega162Based(Legacy)EEPROMReader	1.2
diff --git a/AstroEQ-Firmware/AstroEQ6.ino b/AstroEQ-Firmware/AstroEQ6.ino
index 77a205894deffcc2931814bf69cc9efbb7f666e1..0391101b0cfc3f9378bb4f71f09547aa0c34ab21 100644
--- a/AstroEQ-Firmware/AstroEQ6.ino
+++ b/AstroEQ-Firmware/AstroEQ6.ino
@@ -9,7 +9,7 @@
  
   Works with EQ5, HEQ5, and EQ6 mounts
  
-  Current Verison: 6.5
+  Current Verison: 6.7
 */
 
 //Only works with ATmega162, and Arduino Mega boards (1280 and 2560)
@@ -145,8 +145,8 @@ void systemInitialiser(){
   if(!checkEEPROM()){
     while(1); //prevent AstroEQ startup if EEPROM is blank.
   }
-  minSpeed[RA] = synta.cmd.siderealIVal[RA]+1;//+(synta.cmd.siderealIVal[RA]>>4);
-  minSpeed[DC] = synta.cmd.siderealIVal[DC]+1;//+(synta.cmd.siderealIVal[DC]>>4);
+  minSpeed[RA] = synta.cmd.siderealIVal[RA]>>1;//2x sidereal rate.
+  minSpeed[DC] = synta.cmd.siderealIVal[DC]>>1;//[minspeed is the point at which acceleration curves are enabled]
   calculateRate(RA); //Initialise the interrupt speed table. This now only has to be done once at the beginning.
   calculateRate(DC); //Initialise the interrupt speed table. This now only has to be done once at the beginning.
   gotoDecelerationLength[RA] = calculateDecelerationLength(RA);
@@ -198,20 +198,10 @@ int main(void)
       pinMode(modePin[j],OUTPUT);
       digitalWrite(modePin[j],state[j]);
     }
-//    pinMode(modePins[i][0],OUTPUT); //enable the mode pins
-//    pinMode(modePins[i][1],OUTPUT); //enable the mode pins
-//    digitalWrite(modePins[i][0],modeState[highSpeed[i]][0]);
-//    digitalWrite(modePins[i][1],modeState[highSpeed[i]][1]);
 #else
     for(byte j = 0; j < 3; j++){
       pinMode(modePin[j],OUTPUT);
       digitalWrite(modePin[j],state[j]);
-//      pinMode(modePins[i][0],OUTPUT); //enable the mode pins
-//      pinMode(modePins[i][1],OUTPUT); //enable the mode pins
-//      pinMode(modePins[i][2],OUTPUT); //enable the mode pins
-//      digitalWrite(modePins[i][0],modeState[highSpeed[i]][0]);
-//      digitalWrite(modePins[i][1],modeState[highSpeed[i]][1]);
-//      digitalWrite(modePins[i][2],modeState[highSpeed[i]][2]);
     }
 #endif
     pinMode(resetPin[i],OUTPUT); //enable the reset pin
@@ -548,7 +538,7 @@ void gotoMode(byte axis){
   gotoRunning[axis] = 1; //start the goto.
 }
 
-void timerEnable(byte motor, byte mode) {
+inline void timerEnable(byte motor, byte mode) {
   //if (mode){
     //FCPU/8
   //  timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn0)); //0x0
@@ -575,50 +565,111 @@ inline void timerDisable(byte motor) {
   timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn1) | (1<<CSn0));//00x
 }
 
+//As there is plenty of FLASH left, then to improve speed, I have created two motorStart functions (one for RA and one for DEC)
 void motorStart(byte motor, unsigned int gotoDeceleration){
+  if (motor == RA) {
+    motorStartRA(gotoDeceleration);
+  } else {
+    motorStartDC(gotoDeceleration);
+  }
+}
+void motorStartRA(unsigned int gotoDeceleration){
+  unsigned int IVal = synta.cmd.IVal[RA];
+  unsigned int currentIVal;
+  interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt
+  currentIVal = currentMotorSpeed(RA);
+  interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt
 #ifdef DEBUG
   Serial1.println(F("IVal:"));
-  Serial1.println(synta.cmd.IVal[motor]);
+  Serial1.println(IVal);
   Serial1.println();
 #endif
-  
-  unsigned int startSpeed = minSpeed[motor];
-  if(synta.cmd.stopped[motor]) {
-    if (synta.cmd.IVal[motor] > startSpeed){ //With guiding running this may occur as minSpeed is just slower than sidereal speed.
-      startSpeed = synta.cmd.IVal[motor];
+  unsigned int startSpeed;
+  unsigned int stoppingSpeed;
+  if (IVal > minSpeed[RA]){
+    stoppingSpeed = IVal;
+  } else {
+    stoppingSpeed = minSpeed[RA];
+  }
+  if(synta.cmd.stopped[RA]) {
+    startSpeed = stoppingSpeed;
+  } else {
+    if (currentIVal < minSpeed[RA]) {
+      startSpeed = currentIVal;
+    } else {
+      startSpeed = stoppingSpeed;
     }
+  }
+ 
+  interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt
+  synta.cmd.currentIVal[RA] = synta.cmd.IVal[RA];
+  currentMotorSpeed(RA) = startSpeed;
+  stopSpeed[RA] = stoppingSpeed;
+  interruptCount(RA) = 1;
+  if(synta.cmd.stopped[RA]) { //if stopped, configure timers
+    digitalWrite(dirPin[RA],encodeDirection[RA]^synta.cmd.dir[RA]); //set the direction
+    stepIncrementRepeat[RA] = 0;
+    distributionSegment(RA) = 0;
+    int* decelerationSteps = (int*)&decelerationStepsLow(RA); //low and high are in sequential registers so we can treat them as an int in the sram.
+    *decelerationSteps = -gotoDeceleration;
+    timerCountRegister(RA) = 0;
+    interruptOVFCount(RA) = timerOVF[RA][0];
+    timerEnable(RA,highSpeed[RA]);
+    synta.cmd.setStopped(RA, 0);
+  }
+  interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt
+#ifdef DEBUG
+  Serial1.println(F("StartSpeed:"));
+  Serial1.println(startSpeed);
+  Serial1.println();
+#endif
+}
+
+void motorStartDC(unsigned int gotoDeceleration){
+  unsigned int IVal = synta.cmd.IVal[DC];
+  unsigned int currentIVal;
+  interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt
+  currentIVal = currentMotorSpeed(DC);
+  interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt
+#ifdef DEBUG
+  Serial1.println(F("IVal:"));
+  Serial1.println(IVal);
+  Serial1.println();
+#endif
+  unsigned int startSpeed;
+  unsigned int stoppingSpeed;
+  if (IVal > minSpeed[DC]){
+    stoppingSpeed = IVal;
   } else {
-    if ((synta.cmd.IVal[motor] > startSpeed) || (synta.cmd.currentIVal[motor] > startSpeed)){ //With guiding running this may occur as minSpeed is just slower than sidereal speed.
-      if (synta.cmd.IVal[motor] > synta.cmd.currentIVal[motor]){
-        startSpeed = synta.cmd.IVal[motor];
-      } else {
-        startSpeed = synta.cmd.currentIVal[motor];
-      }
+    stoppingSpeed = minSpeed[DC];
+  }
+  if(synta.cmd.stopped[DC]) {
+    startSpeed = stoppingSpeed;
+  } else {
+    if (currentIVal < minSpeed[DC]) {
+      startSpeed = currentIVal;
+    } else {
+      startSpeed = stoppingSpeed;
     }
   }
  
-  /*else if ((startSpeed > 650) && (synta.cmd.currentIVal[motor] <= 650)){
-    startSpeed = 650; //if possible start closer to the target speed to avoid *very* long accelleration times. 
-  }*/
-  byte oldSREG = SREG;
-  cli();
-  stopSpeed[motor] = startSpeed;
-  synta.cmd.currentIVal[motor] = synta.cmd.IVal[motor];
-  SREG = oldSREG;
-  if(synta.cmd.stopped[motor]) { //if stopped, configure timers
-    digitalWrite(dirPin[motor],encodeDirection[motor]^synta.cmd.dir[motor]); //set the direction
-    stepIncrementRepeat[motor] = 0;
-    interruptCount(motor) = 1;
-    currentMotorSpeed(motor) = startSpeed;//minSpeed[motor];
-    distributionSegment(motor) = 0;
-    int* decelerationSteps = (int*)&decelerationStepsLow(motor); //low and high are in sequential registers so we can treat them as an int in the sram.
+  interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt
+  synta.cmd.currentIVal[DC] = synta.cmd.IVal[DC];
+  currentMotorSpeed(DC) = startSpeed;
+  stopSpeed[DC] = stoppingSpeed;
+  interruptCount(DC) = 1;
+  if(synta.cmd.stopped[DC]) { //if stopped, configure timers
+    digitalWrite(dirPin[DC],encodeDirection[DC]^synta.cmd.dir[DC]); //set the direction
+    stepIncrementRepeat[DC] = 0;
+    distributionSegment(DC) = 0;
+    int* decelerationSteps = (int*)&decelerationStepsLow(DC); //low and high are in sequential registers so we can treat them as an int in the sram.
     *decelerationSteps = -gotoDeceleration;
-    timerCountRegister(motor) = 0;
-    interruptControlRegister(motor) |= interruptControlBitMask(motor);
-    interruptOVFCount(motor) = timerOVF[motor][0];
-    timerEnable(motor,highSpeed[motor]);
-    synta.cmd.setStopped(motor, 0);
+    timerCountRegister(DC) = 0;
+    interruptOVFCount(DC) = timerOVF[DC][0];
+    timerEnable(DC,highSpeed[DC]);
+    synta.cmd.setStopped(DC, 0);
   }
+  interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt
 #ifdef DEBUG
   Serial1.println(F("StartSpeed:"));
   Serial1.println(startSpeed);
@@ -626,25 +677,64 @@ void motorStart(byte motor, unsigned int gotoDeceleration){
 #endif
 }
 
+//As there is plenty of FLASH left, then to improve speed, I have created two motorStop functions (one for RA and one for DEC)
 void motorStop(byte motor, byte emergency){
+  if (motor == RA) {
+    motorStopRA(emergency);
+  } else {
+    motorStopDC(emergency);
+  }
+}
+
+void motorStopRA(byte emergency){
+  if (emergency) {
+    //trigger instant shutdown of the motor in an emergency.
+    timerDisable(RA);
+    synta.cmd.setGotoEn(RA,0); //Not in goto mode.
+    synta.cmd.setStopped(RA,1); //mark as stopped
+    readyToGo[RA] = 0;
+    gotoRunning[RA] = 0;
+  } else if (!synta.cmd.stopped[RA]){  //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving?
+    //trigger ISR based decelleration
+    //readyToGo[RA] = 0;
+    synta.cmd.setGotoEn(RA,0); //No longer in goto mode.
+    gotoRunning[RA] = 0;
+    interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt
+    if(synta.cmd.currentIVal[RA] < minSpeed[RA]){
+      if(stopSpeed[RA] > minSpeed[RA]){
+        stopSpeed[RA] = minSpeed[RA];
+      }
+    }/* else {
+      stopSpeed[RA] = synta.cmd.currentIVal[RA];
+    }*/
+    synta.cmd.currentIVal[RA] = stopSpeed[RA] + 1;//synta.cmd.stepIncrement[motor];
+    interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt
+  }
+}
+
+void motorStopDC(byte emergency){
   if (emergency) {
     //trigger instant shutdown of the motor in an emergency.
-    timerDisable(motor);
-    synta.cmd.setGotoEn(motor,0); //Not in goto mode.
-    synta.cmd.setStopped(motor,1); //mark as stopped
-    readyToGo[motor] = 0;
-    gotoRunning[motor] = 0;
-  } else if (!synta.cmd.stopped[motor]){  //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving?
+    timerDisable(DC);
+    synta.cmd.setGotoEn(DC,0); //Not in goto mode.
+    synta.cmd.setStopped(DC,1); //mark as stopped
+    readyToGo[DC] = 0;
+    gotoRunning[DC] = 0;
+  } else if (!synta.cmd.stopped[DC]){  //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving?
     //trigger ISR based decelleration
     //readyToGo[motor] = 0;
-    synta.cmd.setGotoEn(motor,0); //No longer in goto mode.
-    gotoRunning[motor] = 0;
-    interruptControlRegister(motor) &= ~interruptControlBitMask(motor); //Disable timer interrupt
-    if(stopSpeed[motor] > minSpeed[motor]){
-      stopSpeed[motor] = minSpeed[motor];
-    }
-    synta.cmd.currentIVal[motor] = stopSpeed[motor] + 1;//synta.cmd.stepIncrement[motor];
-    interruptControlRegister(motor) |= interruptControlBitMask(motor); //enable timer interrupt
+    synta.cmd.setGotoEn(DC,0); //No longer in goto mode.
+    gotoRunning[DC] = 0;
+    interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt
+    if(synta.cmd.currentIVal[DC] < minSpeed[DC]){
+      if(stopSpeed[DC] > minSpeed[DC]){
+        stopSpeed[DC] = minSpeed[DC];
+      }
+    }/* else {
+      stopSpeed[DC] = synta.cmd.currentIVal[DC];
+    }*/
+    synta.cmd.currentIVal[DC] = stopSpeed[DC] + 1;//synta.cmd.stepIncrement[motor];
+    interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt
   }
 }
 
diff --git a/AstroEQ-Firmware/HardwareSerial.cpp b/AstroEQ-Firmware/HardwareSerial.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2bde9208bb8ffa49ea369b884777130222f45a88
--- /dev/null
+++ b/AstroEQ-Firmware/HardwareSerial.cpp
@@ -0,0 +1,665 @@
+/*
+  HardwareSerial.cpp - Hardware serial library for Wiring
+  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+  
+  Modified 23 November 2006 by David A. Mellis
+  Modified 28 September 2010 by Mark Sproul
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "Arduino.h"
+#include "wiring_private.h"
+
+// this next line disables the entire HardwareSerial.cpp, 
+// this is so I can support Attiny series and any other chip without a uart
+#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
+
+#include "HardwareSerial.h"
+
+// Define constants and variables for buffering incoming serial data.  We're
+// using a ring buffer (I think), in which head is the index of the location
+// to which to write the next incoming character and tail is the index of the
+// location from which to read. MAX SIZE IS 128 for this implementation!!
+#if (RAMEND < 1000)
+  #define SERIAL_BUFFER_SIZE 16
+#else
+  #define SERIAL_BUFFER_SIZE 96
+#endif
+
+template<class T> inline T modulo(T head) { //Not a true '%' function, but it is all that is required by this library!
+  if(head >= SERIAL_BUFFER_SIZE){
+    head -= SERIAL_BUFFER_SIZE;
+  }
+  return head;
+}
+
+struct ring_buffer
+{
+  unsigned char buffer[SERIAL_BUFFER_SIZE];
+  volatile unsigned char head;
+  volatile unsigned char tail;
+};
+
+#if defined(USBCON)
+  ring_buffer rx_buffer = { { 0 }, 0, 0};
+  ring_buffer tx_buffer = { { 0 }, 0, 0};
+#endif
+#if defined(UBRRH) || defined(UBRR0H)
+  ring_buffer rx_buffer  =  { { 0 }, 0, 0 };
+  ring_buffer tx_buffer  =  { { 0 }, 0, 0 };
+#endif
+#if defined(UBRR1H)
+  ring_buffer rx_buffer1  =  { { 0 }, 0, 0 };
+  ring_buffer tx_buffer1  =  { { 0 }, 0, 0 };
+#endif
+#if defined(UBRR2H)
+  ring_buffer rx_buffer2  =  { { 0 }, 0, 0 };
+  ring_buffer tx_buffer2  =  { { 0 }, 0, 0 };
+#endif
+#if defined(UBRR3H)
+  ring_buffer rx_buffer3  =  { { 0 }, 0, 0 };
+  ring_buffer tx_buffer3  =  { { 0 }, 0, 0 };
+#endif
+
+inline void store_char(unsigned char c, ring_buffer *buffer)
+{
+  register unsigned char i asm("r25");
+  register unsigned char tail asm("r24");
+  asm volatile (
+    "push %0   \n\t"
+    "push %1   \n\t"
+    "push r30   \n\t"
+    "push r31   \n\t"
+    ::"r" (i), "r" (tail):
+  );
+  i = modulo((unsigned char)(buffer->head+1));// % SERIAL_BUFFER_SIZE;
+  // if we should be storing the received character into the location
+  // just before the tail (meaning that the head would advance to the
+  // current location of the tail), we're about to overflow the buffer
+  // and so we don't write the character or advance the head.
+  tail = buffer->tail;
+  if (i != tail) {
+    buffer->buffer[buffer->head] = c;
+    buffer->head = i;
+  }
+  asm volatile (
+    "pop r31   \n\t"
+    "pop r30   \n\t"
+    "pop %1   \n\t"
+    "pop %0   \n\t"
+    :"=r" (i), "=r" (tail)::
+  );
+}
+
+#if !defined(USART0_RX_vect) && defined(USART1_RX_vect)
+// do nothing - on the 32u4 the first USART is USART1
+#else
+#if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \
+    !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \
+	!defined(SIG_UART_RECV)
+  #error "Don't know what the Data Received vector is called for the first UART"
+#else
+  void serialEvent() __attribute__((weak));
+  void serialEvent() {}
+  #define serialEvent_implemented
+#if defined(USART_RX_vect)
+  ISR(USART_RX_vect,ISR_NAKED)
+#elif defined(SIG_USART0_RECV)
+  ISR(SIG_USART0_RECV,ISR_NAKED)
+#elif defined(SIG_UART0_RECV)
+  ISR(SIG_UART0_RECV,ISR_NAKED)
+#elif defined(USART0_RX_vect)
+  ISR(USART0_RX_vect,ISR_NAKED)
+#elif defined(SIG_UART_RECV)
+  ISR(SIG_UART_RECV,ISR_NAKED)
+#endif
+  {
+    register unsigned char c asm("r18");
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = SREG;
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+  #if defined(UDR0)
+    c =  UDR0;
+  #elif defined(UDR)
+    c =  UDR;
+  #else
+    #error UDR not defined
+  #endif
+    store_char(c, &rx_buffer);
+    asm volatile (
+      "pop %0       \n\t"
+      : "=a" (c)::
+    );
+    SREG = c;
+    asm volatile (
+      "pop %0       \n\t"
+      "reti         \n\t"
+      : "=a" (c)::
+    );
+  }
+#endif
+#endif
+
+#if defined(USART1_RX_vect)
+  void serialEvent1() __attribute__((weak));
+  void serialEvent1() {}
+  #define serialEvent1_implemented
+  ISR(USART1_RX_vect,ISR_NAKED)
+  {
+    register unsigned char c asm("r18");
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = SREG;
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = UDR1;
+    store_char(c, &rx_buffer1);
+    asm volatile (
+      "pop %0       \n\t"
+      : "=a" (c)::
+    );
+    SREG = c;
+    asm volatile (
+      "pop %0       \n\t"
+      "reti         \n\t"
+      : "=a" (c)::
+    );
+  }
+#elif defined(SIG_USART1_RECV)
+  #error SIG_USART1_RECV
+#endif
+
+#if defined(USART2_RX_vect) && defined(UDR2)
+  void serialEvent2() __attribute__((weak));
+  void serialEvent2() {}
+  #define serialEvent2_implemented
+  ISR(USART2_RX_vect,ISR_NAKED)
+  {
+    register unsigned char c asm("r18");
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = SREG;
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = UDR2;
+    store_char(c, &rx_buffer2);
+    asm volatile (
+      "pop %0       \n\t"
+      : "=a" (c)::
+    );
+    SREG = c;
+    asm volatile (
+      "pop %0       \n\t"
+      "reti         \n\t"
+      : "=a" (c)::
+    );
+  }
+#elif defined(SIG_USART2_RECV)
+  #error SIG_USART2_RECV
+#endif
+
+#if defined(USART3_RX_vect) && defined(UDR3)
+  void serialEvent3() __attribute__((weak));
+  void serialEvent3() {}
+  #define serialEvent3_implemented
+  ISR(USART3_RX_vect,ISR_NAKED)
+  {
+    register unsigned char c asm("r18");
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = SREG;
+    asm volatile (
+      "push %0       \n\t"
+      :: "a" (c):
+    );
+    c = UDR3;
+    store_char(c, &rx_buffer3);
+    asm volatile (
+      "pop %0       \n\t"
+      : "=a" (c)::
+    );
+    SREG = c;
+    asm volatile (
+      "pop %0       \n\t"
+      "reti         \n\t"
+      : "=a" (c)::
+    );
+  }
+#elif defined(SIG_USART3_RECV)
+  #error SIG_USART3_RECV
+#endif
+
+void serialEventRun(void)
+{
+#ifdef serialEvent_implemented
+  if (Serial.available()) serialEvent();
+#endif
+#ifdef serialEvent1_implemented
+  if (Serial1.available()) serialEvent1();
+#endif
+#ifdef serialEvent2_implemented
+  if (Serial2.available()) serialEvent2();
+#endif
+#ifdef serialEvent3_implemented
+  if (Serial3.available()) serialEvent3();
+#endif
+}
+
+
+#if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect)
+// do nothing - on the 32u4 the first USART is USART1
+#else
+#if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect)
+  #error "Don't know what the Data Register Empty vector is called for the first UART"
+#else
+#if defined(UART0_UDRE_vect)
+ISR(UART0_UDRE_vect, ISR_NAKED)
+#elif defined(UART_UDRE_vect)
+ISR(UART_UDRE_vect, ISR_NAKED)
+#elif defined(USART0_UDRE_vect)
+ISR(USART0_UDRE_vect, ISR_NAKED)
+#elif defined(USART_UDRE_vect)
+ISR(USART_UDRE_vect, ISR_NAKED)
+#endif
+{
+  register unsigned char tail asm("r25");
+  register unsigned char head asm("r24");
+  register unsigned char ch asm("r18");
+  asm volatile (
+    "push %0       \n\t"
+    :: "r" (tail):
+  );
+  tail = SREG;
+  asm volatile (
+    "push %0       \n\t"
+    "push %1       \n\t"
+    "push %2       \n\t"
+    "push r30       \n\t"
+    "push r31       \n\t"
+    :: "r" (tail), "r" (head), "r" (ch):
+  );
+  tail = tx_buffer.tail;
+  head = tx_buffer.head;
+  if (head == tail) {
+	// Buffer empty, so disable interrupts
+#if defined(UCSR0B)
+    cbi(UCSR0B, UDRIE0);
+#else
+    cbi(UCSRB, UDRIE);
+#endif
+  }
+  else {
+    // There is more data in the output buffer. Send the next byte
+    ch = tx_buffer.buffer[tail];
+    tx_buffer.tail = modulo(++tail);
+    //tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
+	
+  #if defined(UDR0)
+    UDR0 = ch;
+  #elif defined(UDR)
+    UDR = ch;
+  #else
+    #error UDR not defined
+  #endif
+  }
+  asm volatile (
+    "pop  r31       \n\t"
+    "pop  r30       \n\t"
+    "pop  %2       \n\t"
+    "pop  %1       \n\t"
+    "pop  %0       \n\t"
+    :"=r" (tail), "=r" (head), "=r" (ch)::
+  );
+  SREG = tail;
+  asm volatile (
+    "pop  %0       \n\t"
+    "reti          \n\t"
+    :"=r" (tail)::
+  );
+}
+#endif
+#endif
+
+#ifdef USART1_UDRE_vect
+ISR(USART1_UDRE_vect, ISR_NAKED)
+{
+  register unsigned char tail asm("r25");
+  register unsigned char head asm("r24");
+  register unsigned char ch asm("r18");
+  asm volatile (
+    "push %0       \n\t"
+    :: "r" (tail):
+  );
+  tail = SREG;
+  asm volatile (
+    "push %0       \n\t"
+    "push %1       \n\t"
+    "push %2       \n\t"
+    "push r30       \n\t"
+    "push r31       \n\t"
+    :: "r" (tail), "r" (head), "r" (ch):
+  );
+  tail = tx_buffer1.tail;
+  head = tx_buffer1.head;
+  if (head == tail) {
+	// Buffer empty, so disable interrupts
+    cbi(UCSR1B, UDRIE1);
+  }
+  else {
+    // There is more data in the output buffer. Send the next byte
+    head = tx_buffer1.buffer[tail];
+    tx_buffer1.tail = modulo(++tail);
+    //tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;
+	
+    UDR1 = head;
+  }
+  asm volatile (
+    "pop  r31       \n\t"
+    "pop  r30       \n\t"
+    "pop  %2       \n\t"
+    "pop  %1       \n\t"
+    "pop  %0       \n\t"
+    :"=r" (tail), "=r" (head), "=r" (ch)::
+  );
+  SREG = tail;
+  asm volatile (
+    "pop  %0       \n\t"
+    "reti          \n\t"
+    :"=r" (tail)::
+  );
+}
+#endif
+
+#ifdef USART2_UDRE_vect
+ISR(USART2_UDRE_vect, ISR_NAKED)
+{
+  register unsigned char tail asm("r25");
+  register unsigned char head asm("r24");
+  register unsigned char ch asm("r18");
+  asm volatile (
+    "push %0       \n\t"
+    :: "r" (tail):
+  );
+  tail = SREG;
+  asm volatile (
+    "push %0       \n\t"
+    "push %1       \n\t"
+    "push %2       \n\t"
+    "push r30       \n\t"
+    "push r31       \n\t"
+    :: "r" (tail), "r" (head), "r" (ch):
+  );
+  tail = tx_buffer2.tail;
+  head = tx_buffer2.head;
+  if (head == tail) {
+	// Buffer empty, so disable interrupts
+    cbi(UCSR2B, UDRIE2);
+  }
+  else {
+    // There is more data in the output buffer. Send the next byte
+    head = tx_buffer2.buffer[tail];
+    tx_buffer2.tail = modulo(++tail);
+    //tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;
+	
+    UDR2 = head;
+  }
+  asm volatile (
+    "pop  r31       \n\t"
+    "pop  r30       \n\t"
+    "pop  %2       \n\t"
+    "pop  %1       \n\t"
+    "pop  %0       \n\t"
+    :"=r" (tail), "=r" (head), "=r" (ch)::
+  );
+  SREG = tail;
+  asm volatile (
+    "pop  %0       \n\t"
+    "reti          \n\t"
+    :"=r" (tail)::
+  );
+}
+#endif
+
+#ifdef USART3_UDRE_vect
+ISR(USART3_UDRE_vect, ISR_NAKED)
+{
+  register unsigned char tail asm("r25");
+  register unsigned char head asm("r24");
+  register unsigned char ch asm("r18");
+  asm volatile (
+    "push %0       \n\t"
+    :: "r" (tail):
+  );
+  tail = SREG;
+  asm volatile (
+    "push %0       \n\t"
+    "push %1       \n\t"
+    "push %2       \n\t"
+    "push r30       \n\t"
+    "push r31       \n\t"
+    :: "r" (tail), "r" (head), "r" (ch):
+  );
+  tail = tx_buffer3.tail;
+  head = tx_buffer3.head;
+  if (head == tail) {
+	// Buffer empty, so disable interrupts
+    cbi(UCSR3B, UDRIE3);
+  }
+  else {
+    // There is more data in the output buffer. Send the next byte
+    head = tx_buffer3.buffer[tail];
+    tx_buffer3.tail = modulo(++tail);
+    //tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;
+	
+    UDR3 = head;
+  }
+  asm volatile (
+    "pop  r31       \n\t"
+    "pop  r30       \n\t"
+    "pop  %2       \n\t"
+    "pop  %1       \n\t"
+    "pop  %0       \n\t"
+    :"=r" (tail), "=r" (head), "=r" (ch)::
+  );
+  SREG = tail;
+  asm volatile (
+    "pop  %0       \n\t"
+    "reti          \n\t"
+    :"=r" (tail)::
+  );
+}
+#endif
+
+
+// Constructors ////////////////////////////////////////////////////////////////
+
+HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
+  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+  volatile uint8_t *udr,
+  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
+{
+  _rx_buffer = rx_buffer;
+  _tx_buffer = tx_buffer;
+  _ubrrh = ubrrh;
+  _ubrrl = ubrrl;
+  _ucsra = ucsra;
+  _ucsrb = ucsrb;
+  _udr = udr;
+  _rxen = rxen;
+  _txen = txen;
+  _rxcie = rxcie;
+  _udrie = udrie;
+  _u2x = u2x;
+}
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+void HardwareSerial::begin(unsigned long baud)
+{
+  uint16_t baud_setting;
+  bool use_u2x = true;
+
+#if (F_CPU == 16000000UL) || (F_CPU == 24000000UL)
+  // hardcoded exception for compatibility with the bootloader shipped
+  // with the Duemilanove and previous boards and the firmware on the 8U2
+  // on the Uno and Mega 2560.
+  if (baud == 57600) {
+    use_u2x = false;
+  }
+#endif
+
+try_again:
+  
+  if (use_u2x) {
+    *_ucsra = 1 << _u2x;
+    baud_setting = (F_CPU / 4 / baud - 1) / 2;
+  } else {
+    *_ucsra = 0;
+    baud_setting = (F_CPU / 8 / baud - 1) / 2;
+  }
+  
+  if ((baud_setting > 4095) && use_u2x)
+  {
+    use_u2x = false;
+    goto try_again;
+  }
+
+  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
+  *_ubrrh = baud_setting >> 8;
+  *_ubrrl = baud_setting;
+
+  sbi(*_ucsrb, _rxen);
+  sbi(*_ucsrb, _txen);
+  sbi(*_ucsrb, _rxcie);
+  cbi(*_ucsrb, _udrie);
+}
+
+void HardwareSerial::end()
+{
+  // wait for transmission of outgoing data
+  while (_tx_buffer->head != _tx_buffer->tail)
+    ;
+
+  cbi(*_ucsrb, _rxen);
+  cbi(*_ucsrb, _txen);
+  cbi(*_ucsrb, _rxcie);  
+  cbi(*_ucsrb, _udrie);
+  
+  // clear any received data
+  _rx_buffer->head = _rx_buffer->tail;
+}
+
+int HardwareSerial::available(void)
+{
+  unsigned int difference = SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail;
+  return modulo(difference);
+  //return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
+}
+
+int HardwareSerial::peek(void)
+{
+  if (_rx_buffer->head == _rx_buffer->tail) {
+    return -1;
+  } else {
+    return _rx_buffer->buffer[_rx_buffer->tail];
+  }
+}
+
+int HardwareSerial::read(void)
+{
+  // if the head isn't ahead of the tail, we don't have any characters
+  if (_rx_buffer->head == _rx_buffer->tail) {
+    return -1;
+  } else {
+    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
+    _rx_buffer->tail = modulo(++_rx_buffer->tail);//(unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
+    return c;
+  }
+}
+
+void HardwareSerial::flush()
+{
+  while (_tx_buffer->head != _tx_buffer->tail)
+    ;
+}
+
+size_t HardwareSerial::write(uint8_t c)
+{
+  unsigned char i = modulo((unsigned char)(_tx_buffer->head+1));//(unsigned char)((_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE);
+	
+  // If the output buffer is full, there's nothing for it other than to 
+  // wait for the interrupt handler to empty it a bit
+  // ???: return 0 here instead?
+  while (i == _tx_buffer->tail)
+    ;
+	
+  _tx_buffer->buffer[_tx_buffer->head] = c;
+  _tx_buffer->head = i;
+	
+  sbi(*_ucsrb, _udrie);
+  
+  return 1;
+}
+
+HardwareSerial::operator bool() {
+	return true;
+}
+
+// Preinstantiate Objects //////////////////////////////////////////////////////
+
+#if defined(UBRRH) && defined(UBRRL)
+  HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
+#elif defined(UBRR0H) && defined(UBRR0L)
+  HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
+#elif defined(USBCON)
+  // do nothing - Serial object and buffers are initialized in CDC code
+#else
+  #error no serial port defined  (port 0)
+#endif
+
+#if defined(UBRR1H)
+  HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
+#endif
+#if defined(UBRR2H)
+  HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
+#endif
+#if defined(UBRR3H)
+  HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
+#endif
+
+#endif // whole file
+
diff --git a/AstroEQ-Firmware/HardwareSerial.h b/AstroEQ-Firmware/HardwareSerial.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf4924c6d4abf4b54f5197592f5dfcc9cfd721c6
--- /dev/null
+++ b/AstroEQ-Firmware/HardwareSerial.h
@@ -0,0 +1,81 @@
+/*
+  HardwareSerial.h - Hardware serial library for Wiring
+  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Modified 28 September 2010 by Mark Sproul
+*/
+
+#ifndef HardwareSerial_h
+#define HardwareSerial_h
+
+#include <inttypes.h>
+
+#include "Stream.h"
+
+struct ring_buffer;
+
+class HardwareSerial : public Stream
+{
+  private:
+    ring_buffer *_rx_buffer;
+    ring_buffer *_tx_buffer;
+    volatile uint8_t *_ubrrh;
+    volatile uint8_t *_ubrrl;
+    volatile uint8_t *_ucsra;
+    volatile uint8_t *_ucsrb;
+    volatile uint8_t *_udr;
+    uint8_t _rxen;
+    uint8_t _txen;
+    uint8_t _rxcie;
+    uint8_t _udrie;
+    uint8_t _u2x;
+  public:
+    HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
+      volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+      volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+      volatile uint8_t *udr,
+      uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
+    void begin(unsigned long);
+    void end();
+    virtual int available(void);
+    virtual int peek(void);
+    virtual int read(void);
+    virtual void flush(void);
+    virtual size_t write(uint8_t);
+    using Print::write; // pull in write(str) and write(buf, size) from Print
+    operator bool();
+};
+
+#if defined(UBRRH) || defined(UBRR0H)
+  extern HardwareSerial Serial;
+#elif defined(USBCON)
+  #include "USBAPI.h"
+//  extern HardwareSerial Serial_;  
+#endif
+#if defined(UBRR1H)
+  extern HardwareSerial Serial1;
+#endif
+#if defined(UBRR2H)
+  extern HardwareSerial Serial2;
+#endif
+#if defined(UBRR3H)
+  extern HardwareSerial Serial3;
+#endif
+
+extern void serialEventRun(void) __attribute__((weak));
+
+#endif
diff --git a/AstroEQ-Firmware/README.txt b/AstroEQ-Firmware/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..27a871b022f4a326a6527b2a8a3ee2ce81420336
--- /dev/null
+++ b/AstroEQ-Firmware/README.txt
@@ -0,0 +1,8 @@
+Replace the following two files:
+
+HardwareSerial.h
+HardwareSerial.cpp
+
+In the directory:
+
+<arduino install>\hardware\arduino\cores\arduino
\ No newline at end of file
diff --git a/AstroEQ-Firmware/synta.cpp b/AstroEQ-Firmware/synta.cpp
index c7cec63807e64531d94f41ca9ef75c06b4eb857f..00a8f11363e686a7ca8c023975e4879a68d6af70 100644
--- a/AstroEQ-Firmware/synta.cpp
+++ b/AstroEQ-Firmware/synta.cpp
@@ -9,7 +9,7 @@ void Synta::initialise(unsigned long eVal){
   clearBuffer(commandString,sizeof(commandString));
   //scalar[0] = EEPROM.readByte(scalar1_Address) - 1;
   //scalar[1] = EEPROM.readByte(scalar2_Address) - 1;
-  cmd.init(eVal, 8);
+  cmd.init(eVal, 1);
 }
 
 const char Synta::startInChar = ':';
diff --git a/Downloads/AstroEQ6-ConfigUtility.zip b/Downloads/AstroEQ6-ConfigUtility.zip
index 47be68ba69a3c813f8660702a1c95a906bffb6c5..eb3b2d8015c249a9070c5de83baec0166a9abdd9 100644
Binary files a/Downloads/AstroEQ6-ConfigUtility.zip and b/Downloads/AstroEQ6-ConfigUtility.zip differ
diff --git a/Downloads/AstroEQ6-Firmware.zip b/Downloads/AstroEQ6-Firmware.zip
index e462e011368a2be9cfd6dc00d4b3dc89125bf0a2..2aa1d9281e62b1b49ec1ffc10f3f1fae9a355ecd 100644
Binary files a/Downloads/AstroEQ6-Firmware.zip and b/Downloads/AstroEQ6-Firmware.zip differ
diff --git a/README b/README
index cb7a613ef18fbb5f7161a4fa28af6e18769fd0eb..ff9df85f9d487966df2495744867cdafe3893ea8 100644
--- a/README
+++ b/README
@@ -1,6 +1,4 @@
-Last Updated: 10/11/2013
-
-To use version 6.5 you will need to download the lastest config utility. There were changes made to the utility which are required for compatibility with firmware version 6.5.
+Last Updated: 31/12/2013
 
 A small number of AstroEQ controllers are available to purchase. These can be bought from me on the AstronomyShed forum. 
 Just send me a PM on Astronomy Shed (http://www.astronomyshed.co.uk/forum/memberlist.php?mode=viewprofile&u=2603).
@@ -25,7 +23,7 @@ The EQMOD Project can be found at: http://eq-mod.sourceforge.net/
 
   Works with EQ3, EQ5, HEQ5, and EQ6 mounts. Along With custom mounts.
  
-  Current Software Verison: 6.5
+  Current Software Verison: 6.7
   Current Hardware Version: 4.1
 
 ---------------------------------------------------------------------------------------