diff --git a/AstroEQ/AstroEQ.ino b/AstroEQ/AstroEQ.ino
index 5e6e56ddcd8e12ad6aaea15f40089af6dd65d445..3b7d8e99b7caee7cfef85ac3a14fcb3b3b9b27d1 100644
--- a/AstroEQ/AstroEQ.ino
+++ b/AstroEQ/AstroEQ.ino
@@ -9,36 +9,77 @@
  
   Works with EQ5, HEQ5, and EQ6 mounts (Not EQ3-2, they have a different gear ratio)
  
-  Current Verison: 3.5 
+  Current Verison: 3.6
 */
 
 #include "synta.h"
 
-//Create an instance of the mount
-Synta synta(1281,4505600,32368,16,31289);
-
-//Synta synta(e,a,b,g,s);
+//Synta synta(e,a,b,g,s,scalar);
 //
 // e = version number (this doesnt need chaning)
 //
 // a = number of steps per complete axis revolution. 
+// aVal = 64 * motor steps per revolution * ratio
+// where ratio is the gear ratio from motor to axis. E.g. for an HEQ5 mount, this is 705
+// and motor steps is how many steps per one revolution of the motor. E.g. a 1.8degree stepper has 200 steps/revolution
 //
-// b = sidereal rate. This again depends on number of microsteps per step.
+// b = sidereal rate. This again depends on number of microsteps per step. 
+// bVal = 620 * aVal / 86164.0905   (round UP to nearest integer)
 //
 // g = high speed multiplyer. This is the EQMOD recommended default. In highspeed mode, the step rate will be 16 times larger.
 //
 // s = steps per worm revolution
+// sVal = aVal / Worm Gear Teeth
+// where worm gear teeth is how many teeth on the main worm gear. E.g. for an HEQ5 this is 135
+//
+// mount specifics can be found here: http://tech.groups.yahoo.com/group/EQMOD/database?method=reportRows&tbl=5
+//
+// Summary of mounts (Untested):
+//
+// HEQ5 Pro/Syntrek/SynscanUpgrade:
+// aVal = 9024000
+// bVal = 64933
+// sVal = 66845
+// scalar = 1
+//
+// EQ6 Pro/Syntrek/SynscanUpgrade:
+// aVal = 9024000
+// bVal = 64933
+// sVal = 50133
+// scalar = 1
+//
+// EQ5 Synscan/SynscanUpgrade:
+// aVal = 9011200
+// bVal = 64841
+// sVal = 31289
+// scalar = 1
+//
+// EQ4/5 Mount upgraded with the Dual motor kit (non Goto) -- This is the only one I have tested, the others are theoretical
+// aVal = 26542080
+// bVal = 190985
+// sVal = 184320
+// scalar = 10   -> This is vital that it be set as 10!!!
 //
-// mount specifics can be found here: http://tech.groups.yahoo.com/group/EQMOD/database?method=reportRows&tbl=5&sortBy=5
+// EQ3 Mount upgraded with the Dual motor kit (non Goto)
+// aVal = 23961600
+// bVal = 172418
+// sVal = 184320
+// scalar = 10   -> This is vital that it be set as 10!!!
 //
-// The motor portion of the code I have is written is for EQ5 Mounts.
-// It may work for EQ6 mounts if you change the numbers above to:
-// (1281,4512000,32466,16,50133)
-// And possibly for HEQ5 mounts if you change the numbers above to:
-// (1281,4512000,32466,16,66844)
+// Other mounts:
+// aVal = 64 * motor steps per revolution * ratio
+// bVal = 620 * aVal / 86164.0905   (round UP to nearest integer)
+// sVal = aVal / Worm Gear Teeth
+// scalar = depends on aVal, see notes below
 //
+//Create an instance of the mount
+//If aVal is roughly greater than 10000000 (ten million), the number needs to be scaled down by some factor
+//to make it smaller than that limit. In my case I have chosen 10 as it nicely scales the
+//a and s values. Hence below, I have set scalar to 10.
+
+Synta synta(1281,26542080,190985,16,184320,10);
 
-//Define the two axes
+//Define the two axes (swap if RA and DEC motors are reversed)
 #define RA 0
 #define DC 1
 
@@ -86,12 +127,18 @@ void setup()
   configureTimer(); //setup the motor pulse timers.
 }
 
-
 void loop(){
   char decodedPacket[11]; //temporary store for completed command ready to be processed
   if (Serial.available()) { //is there a byte in buffer
     char recievedChar = Serial.read(); //get the next character in buffer
     Serial1.print(recievedChar);
+    if(recievedChar == 'T'){
+      testMode();
+      return;
+    } else if(recievedChar == 'S'){
+      stepMode();
+      return;
+    }
     char decoded = synta.recieveCommand(decodedPacket,recievedChar); //once full command packet recieved, decodedPacket returns either error packet, or valid packet
     if (decoded == 1){ //Valid Packet
       decodeCommand(synta.command(),decodedPacket); //decode the valid packet
@@ -101,6 +148,64 @@ void loop(){
   }
 }
 
+void testMode(){
+  while(Serial.available()){
+    Serial.read(); //Clear the buffer
+  }
+  while(1){
+    delay(100);
+    Serial.print('.');
+    if (Serial.read()=='C') {
+      while(Serial.available()){
+        Serial.read(); //Clear the buffer
+      }
+      break;
+    }
+  }
+  digitalWrite(enablePin[0],LOW);
+  for(long i = 0L; i < 12800L;i++){
+    delayMicroseconds(7990);
+    writeSTEP1(HIGH);
+    delayMicroseconds(10);
+    writeSTEP1(LOW);
+    long check = i % 64L;
+    if(check == 0){
+      char out[20] = {0};
+      sprintf(out,"%ld\n",i);
+      Serial.print(out);
+    }
+  }
+}
+void stepMode(){
+  digitalWrite(enablePin[0],LOW);
+  while(Serial.available()){
+    Serial.read(); //Clear the buffer
+  }
+  while(1){
+    delay(10);
+    Serial.print('.');
+    char bleh = Serial.read();
+    if (bleh=='L') {
+      while(Serial.available()){
+        Serial.read(); //Clear the buffer
+      }
+      break;
+    } else if (bleh=='C') {
+      writeSTEP1(HIGH);
+      delayMicroseconds(10);
+      writeSTEP1(LOW);
+    } else if (bleh=='R') {
+      for(int i = 0;i<32;i++){
+        Serial.print("boo\n");
+        writeSTEP1(HIGH);
+        delayMicroseconds(10);
+        writeSTEP1(LOW);
+        delayMicroseconds(1000);
+      }
+    }
+  }
+}
+
 void decodeCommand(char command, char* packetIn){ //each command is axis specific. The axis being modified can be retrieved by calling synta.axis()
   char response[11]; //generated response string
   unsigned long responseData; //data for response
@@ -111,15 +216,21 @@ void decodeCommand(char command, char* packetIn){ //each command is axis specifi
         break;
     case 'a': //readonly, return the aVal (steps per axis)
         responseData = synta.cmd.aVal(synta.axis()); //response to the a command is stored in the aVal function for that axis.
+        responseData /= synta.scalar();
         break;
     case 'b': //readonly, return the bVal (sidereal rate)
         responseData = synta.cmd.bVal(synta.axis()); //response to the b command is stored in the bVal function for that axis.
+        responseData /= synta.scalar();
+        if (synta.cmd.bVal(synta.axis()) % synta.scalar()){
+          responseData++; //round up
+        }
         break;
     case 'g': //readonly, return the gVal (high speed multiplier)
         responseData = synta.cmd.gVal(synta.axis()); //response to the g command is stored in the gVal function for that axis.
         break;
     case 's': //readonly, return the sVal (steps per worm rotation)
         responseData = synta.cmd.sVal(synta.axis()); //response to the s command is stored in the sVal function for that axis.
+        responseData /= synta.scalar();
         break;
     case 'f': //readonly, return the fVal (axis status)
         responseData = synta.cmd.fVal(synta.axis()); //response to the f command is stored in the fVal function for that axis.
@@ -190,40 +301,36 @@ void decodeCommand(char command, char* packetIn){ //each command is axis specifi
   }
 }
 
-//
-//Everything below this point needs to be customised for your motor driver. As yet code below here is untested
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
+
 
 //Calculates the rate based on the recieved I value 
 void calculateRate(){
   
-  //steps per second = IVal / BVal; for lowspeed move
-  //or steps per second = IVal / (BVal * gVal); for highspeed move 
+  //seconds per step = IVal / BVal; for lowspeed move
+  //or seconds per step = IVal / (BVal * gVal); for highspeed move 
   //
   //whether to use highspeed move or not is determined by the GVal;
   //
+  //clocks per step = 16000000 * seconds per step
   
   unsigned long rate;
+  unsigned long clockRate = 1600000L; //1/10th the actual clock to prevent numbers getting too big for an unsigned long
   if((synta.cmd.GVal(synta.axis()) == 2)||(synta.cmd.GVal(synta.axis()) == 1)){ //Normal Speed
-    rate = 2000000L * synta.cmd.IVal(synta.axis());
+    rate = clockRate * synta.cmd.IVal(synta.axis());
     rate /= synta.cmd.bVal(synta.axis());
   } else if ((synta.cmd.GVal(synta.axis()) == 0)||(synta.cmd.GVal(synta.axis()) == 3)){ //High Speed
-    rate = 2000000L * synta.cmd.IVal(synta.axis());
+    rate = clockRate * synta.cmd.IVal(synta.axis());
     rate /= (synta.cmd.bVal(synta.axis()) * synta.cmd.gVal(synta.axis()));
   }
-  
+  char check[100] = {0};
+  sprintf(check,"%ld,%ld,%ld,%ld\n",clockRate,synta.cmd.IVal(synta.axis()),synta.cmd.bVal(synta.axis()),rate);
+  Serial1.print(check);
+  rate *= 10; //corrects for clock rate being set to 1/10th of the required to prevent numbers getting too big for an unsigned long.
   //Now truncate to an unsigned int with a sensible max value (the int is to avoid register issues with the 16 bit timer)
   if(rate < 539){ //We do 65535 - result as timer counts up from this number to 65536 then interrupts
     timerOVF[synta.axis()] = 64997L;
+  } else if (rate > 65534L) {
+    timerOVF[synta.axis()] = 1L;
   } else {
     timerOVF[synta.axis()] = 65535L - rate;
   }
@@ -288,6 +395,14 @@ void gotoMode(){
 }
 
 void motorStop(boolean caller){
+      if(synta.axis()){ //switch off correct axis
+        TIMSK4 &= ~(1<<TOIE4); //disable timer
+      } else {
+        TIMSK3 &= ~(1<<TOIE3); //disable timer
+      }
+      synta.cmd.gotoEn(synta.axis(),0); //Cancel goto mode
+      synta.cmd.stopped(synta.axis(),1); //mark as stopped
+      /*
   if(!synta.cmd.stopped(synta.axis())){ //only has an effect if not already stopped
     if(!caller && !synta.cmd.gotoEn(synta.axis())){ //If not in goto mode, then decellerate
       synta.cmd.HVal(synta.axis(), (64997 - timerOVF[synta.axis()])); //work out where in decelleration curve we are to know how many steps to run
@@ -309,7 +424,7 @@ void motorStop(boolean caller){
       synta.cmd.HVal(synta.axis(), (496 - synta.cmd.HVal(synta.axis()))); //find steps
       gotoPosn[synta.axis()] =  synta.cmd.jVal(synta.axis()) + (synta.cmd.stepDir(synta.axis()) * synta.cmd.HVal(synta.axis())); //current position
     }
-  }
+  }*/
 }
 
 void motorEnable(){
@@ -373,26 +488,44 @@ ISR(TIMER4_OVF_vect) {
 }
 
 void motorStep(byte motor){
-  static byte divider = 0;
+  static byte divider[2] = {0};
   if(motor){
     writeSTEP2(HIGH);
-    delayMicroseconds(2);
+    delayMicroseconds(15);
     writeSTEP2(LOW);
   } else {
     writeSTEP1(HIGH);
-    delayMicroseconds(2);
+    delayMicroseconds(15);
     writeSTEP1(LOW);
   }
-  divider++;
-  if((divider & 7) == 0){
-    synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + synta.cmd.stepDir(motor)));
-    if(synta.cmd.gotoEn(motor)){
-      long stepsLeft = gotoPosn[motor] - synta.cmd.jVal(motor);
-      stepsLeft *= synta.cmd.stepDir(motor);
-      if(stepsLeft <= 0){
-        motorStop(1);
-      } else if (stepsLeft < 124){
-        timerOVF[motor] -= 304; //decelleration region
+  if(synta.cmd.stepDir(motor) < 0){
+    divider[motor]--;
+    if (divider[motor] == -1){
+      divider[motor] = synta.scalar() - 1;
+      synta.cmd.jVal(motor, (synta.cmd.jVal(motor) - 1));
+      if(synta.cmd.gotoEn(motor)){
+        long stepsLeft = gotoPosn[motor] - synta.cmd.jVal(motor);
+        stepsLeft *= synta.cmd.stepDir(motor);
+        if(stepsLeft <= 0){
+          motorStop(1);
+        } else if (stepsLeft < 124){
+          //timerOVF[motor] -= 304; //decelleration region
+        }
+      }
+    }
+  } else {
+    divider[motor]++;
+    if (divider[motor] >= synta.scalar()){
+      divider[motor] = 0;
+      synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + 1));
+      if(synta.cmd.gotoEn(motor)){
+        long stepsLeft = gotoPosn[motor] - synta.cmd.jVal(motor);
+        stepsLeft *= synta.cmd.stepDir(motor);
+        if(stepsLeft <= 0){
+          motorStop(1);
+        } else if (stepsLeft < 124){
+          //timerOVF[motor] -= 304; //decelleration region
+        }
       }
     }
   }
diff --git a/AstroEQ/synta.cpp b/AstroEQ/synta.cpp
index 133ce437df90741b6a84729fdc5b3fd7e7e01fd1..e5b19d7c2c36c1d3687f8481a5adb544d999a5e0 100644
--- a/AstroEQ/synta.cpp
+++ b/AstroEQ/synta.cpp
@@ -1,11 +1,12 @@
 
 #include "synta.h"
 
-Synta::Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal){
+Synta::Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar){
   validPacket = 0;
   _axis = 0;
   commandIndex = 0;
   clearBuffer(commandString,sizeof(commandString));
+  _scalar = scalar;
   cmd.init(eVal, aVal, bVal, gVal, sVal);
 }
 
@@ -147,3 +148,7 @@ byte Synta::axis(byte axis){
   }
   return _axis;
 }
+
+byte Synta::scalar(){
+  return _scalar;
+}
diff --git a/AstroEQ/synta.h b/AstroEQ/synta.h
index e3fabb714b5ac23c263d0732607214bba9488f03..a698025af3cc5da89ba47321dc49dc786557e2ad 100644
--- a/AstroEQ/synta.h
+++ b/AstroEQ/synta.h
@@ -11,11 +11,12 @@
   
   class Synta{
     public:
-      Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal);
+      Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar);
       Commands cmd;
       void assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData);
       char recieveCommand(char* dataPacket, char character);
       byte axis(byte axis = 2); //make target readonly to outside world.
+      byte scalar();
       char command(); //make current command readonly to outside world.
       
       unsigned long hexToLong(char* hex);
@@ -35,6 +36,7 @@
       
       byte _axis;
       char _command;
+      byte _scalar;
       
       static const char startInChar;
       static const char startOutChar;
diff --git a/README b/README
index c0edb1d9439eb2dabbf7fd33edfe931ca138e74f..c3733d0a242c7de4feea24bd0e36b81b709c24b9 100644
--- a/README
+++ b/README
@@ -1,17 +1,26 @@
 AstroEQ Arduino code. Hardware schematics to follow
 
-Currently it doesn't track at the correct speed, I am working on it. Will add a ZIP download when it is properly functional.
+As of current, I have got the firmware tracking at the correct speed.
+It should work with most EQ mounts, including ones with custom gearing and custom stepper motors.
+
+Getting the mount to track at the correct speed does require some calculation, but all is explained in the arduino file.
+Also included are some example values for different Skywatcher mounts. These are untested, but should work in theory.
+At the moment the only tested mount an EQ5 mount with the dual axis motor upgrade (non goto).
+
+If anyone has success with the example numbers I have provided, please let me know.
+Also if you have problems getting the numbers to work, open an issue thread and I will see if I can help.
+
 
 /*
   Code written by Thomas Carpenter 2012
   
-  With thanks Chris over at the EQMOD Yahoo group for explaining the Skywatcher protocol
+  With thanks Chris over at the EQMOD Yahoo group.
   
   
   Equatorial mount tracking system for integration with EQMOD using the Skywatcher/Synta
   communication protocol.
  
-  Works with EQ5, HEQ5, and EQ6 mounts
+  Works with EQ3, EQ5, HEQ5, and EQ6 mounts. Along With custom mounts.
  
-  Current Verison: 3.5 
+  Current Verison: 3.6 
 */
\ No newline at end of file