diff --git a/Configuration.h b/Configuration.h
index 0d991d8..f13c519 100644
--- a/Configuration.h
+++ b/Configuration.h
@@ -23,6 +23,13 @@ Licence: GPL
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
+class RepRap;
+class Platform;
+class Move;
+class Heat;
+class GCodes;
+class Webserver;
+
#define ABS_ZERO -273.15
#define FLASH_LED 'F' // Type byte of a message that is to flash an LED; the next two bytes define
@@ -52,5 +59,6 @@ Licence: GPL
#define PHP_ECHO 2
#define PHP_PRINT 3
#define NO_PHP 99
+#define START_FEED_RATE 200
#endif
diff --git a/GCodes.h b/GCodes.h
index f1ab3ca..1ceb1a9 100644
--- a/GCodes.h
+++ b/GCodes.h
@@ -36,6 +36,10 @@ class GCodes
private:
void ActOnGcode();
+ boolean Seen(char c);
+ float GetFValue();
+ int GetIValue();
+ void SetUpMove();
Platform* platform;
boolean active;
@@ -43,9 +47,13 @@ class GCodes
unsigned long lastTime;
char gcodeBuffer[GCODE_LENGTH];
int gcodePointer;
+ int readPointer;
boolean moveAvailable;
boolean heatAvailable;
- float moveBuffer[DRIVES];
+ float moveBuffer[DRIVES+1]; // Last is feedrate
+ boolean drivesRelative; // All except X, Y and Z
+ boolean axesRelative; // X, Y and Z
+ char gCodeLetters[DRIVES + 1]; // Extra is for F
};
#endif
diff --git a/GCodes.ino b/GCodes.ino
index efee0dd..6beea00 100644
--- a/GCodes.ino
+++ b/GCodes.ino
@@ -24,7 +24,6 @@ Licence: GPL
GCodes::GCodes(Platform* p, Webserver* w)
{
active = false;
- //Serial.println("GCodes constructor");
platform = p;
webserver = w;
}
@@ -41,19 +40,111 @@ void GCodes::Init()
active = true;
moveAvailable = false;
heatAvailable = false;
+ readPointer = -1;
+ drivesRelative = false;
+ axesRelative = false;
+ gCodeLetters = GCODE_LETTERS;
}
-
+void GCodes::SetUpMove()
+{
+ reprap.GetMove()->GetCurrentState(moveBuffer);
+ for(char i = 0; i < DRIVES; i++)
+ {
+ if(i < AXES)
+ {
+ if(Seen(gCodeLetters[i]))
+ {
+ if(axesRelative)
+ moveBuffer[i] += GetFValue();
+ else
+ moveBuffer[i] = GetFValue();
+ }
+ } else
+ {
+ if(Seen(gCodeLetters[i]))
+ {
+ if(drivesRelative)
+ moveBuffer[i] = GetFValue();
+ else
+ moveBuffer[i] = GetFValue(); //***TODO need to store old values and subtract them here
+ }
+ }
+ }
+ if(Seen(gCodeLetters[DRIVES]))
+ moveBuffer[DRIVES] = GetFValue();
+ moveAvailable = true;
+}
void GCodes::ActOnGcode()
{
- platform->Message(HOST_MESSAGE, "GCode: ");
- platform->Message(HOST_MESSAGE, gcodeBuffer);
- platform->Message(HOST_MESSAGE, "
\n");
+ int code;
+
+ if(Seen('G'))
+ {
+ code = GetIValue();
+ switch(code)
+ {
+ case 1:
+ SetUpMove();
+ break;
+
+ case 90:
+ drivesRelative = false;
+ axesRelative = false;
+ break;
+
+ case 91:
+ drivesRelative = true;
+ axesRelative = true;
+ break;
+
+ default:
+ platform->Message(HOST_MESSAGE, "GCodes - invalid G Code: ");
+ platform->Message(HOST_MESSAGE, gcodeBuffer);
+ platform->Message(HOST_MESSAGE, "
\n");
+ }
+ return;
+ }
+
+ if(Seen('M'))
+ {
+ code = GetIValue();
+ switch(code)
+ {
+ case 82:
+ drivesRelative = false;
+ break;
+
+ case 83:
+ drivesRelative = true;
+ break;
+
+ default:
+ platform->Message(HOST_MESSAGE, "GCodes - invalid M Code: ");
+ platform->Message(HOST_MESSAGE, gcodeBuffer);
+ platform->Message(HOST_MESSAGE, "
\n");
+ }
+ return;
+ }
+
+ if(Seen('T'))
+ {
+ code = GetIValue();
+ switch(code)
+ {
+
+
+ default:
+ platform->Message(HOST_MESSAGE, "GCodes - invalid T Code: ");
+ platform->Message(HOST_MESSAGE, gcodeBuffer);
+ platform->Message(HOST_MESSAGE, "
\n");
+ }
+ }
+
}
-
void GCodes::Spin()
{
if(!active)
@@ -73,7 +164,7 @@ void GCodes::Spin()
if(gcodePointer >= GCODE_LENGTH)
{
- platform->Message(HOST_MESSAGE, "GCodes: G Code buffer length overflow.");
+ platform->Message(HOST_MESSAGE, "GCodes: G Code buffer length overflow.
\n");
gcodePointer = 0;
gcodeBuffer[0] = 0;
}
@@ -85,7 +176,7 @@ boolean GCodes::ReadMove(float* m)
{
if(!moveAvailable)
return false;
- for(char i = 0; i < DRIVES; i++)
+ for(char i = 0; i <= DRIVES; i++)
m[i] = moveBuffer[i];
moveAvailable = false;
}
@@ -93,7 +184,47 @@ boolean GCodes::ReadMove(float* m)
boolean GCodes::ReadHeat(float* h)
{
-
+
+}
+
+
+boolean GCodes::Seen(char c)
+{
+ readPointer = 0;
+ while(gcodeBuffer[readPointer])
+ {
+ if(gcodeBuffer[readPointer] == c)
+ return true;
+ readPointer++;
+ }
+ readPointer = -1;
+ return false;
+}
+
+
+float GCodes::GetFValue()
+{
+ if(readPointer < 0)
+ {
+ platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode float before a search.
\n");
+ return 0.0;
+ }
+ float result = (float)strtod(&gcodeBuffer[readPointer + 1], NULL);
+ readPointer = -1;
+ return result;
+}
+
+
+int GCodes::GetIValue()
+{
+ if(readPointer < 0)
+ {
+ platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode int before a search.
\n");
+ return 0;
+ }
+ int result = (int)strtol(&gcodeBuffer[readPointer + 1], NULL, 0);
+ readPointer = -1;
+ return result;
}
diff --git a/Move.h b/Move.h
index 2b116b6..53ed3e2 100644
--- a/Move.h
+++ b/Move.h
@@ -32,6 +32,7 @@ class Move
void Spin();
void Exit();
void Qmove();
+ void GetCurrentState(float m[]);
private:
@@ -39,8 +40,10 @@ class Move
GCodes* gCodes;
unsigned long lastTime;
boolean active;
+ float currentFeedrate;
float currentPosition[AXES]; // Note - drives above AXES are always relative moves
- float nextMove[DRIVES];
+ float nextMove[DRIVES + 1]; // Extra is for feedrate
+ char scratchString[STRING_LENGTH];
};
diff --git a/Move.ino b/Move.ino
index 6afbdfd..d5bfde8 100644
--- a/Move.ino
+++ b/Move.ino
@@ -22,7 +22,6 @@ Licence: GPL
Move::Move(Platform* p, GCodes* g)
{
- //Serial.println("Move constructor");
platform = p;
gCodes = g;
active = false;
@@ -33,7 +32,10 @@ void Move::Init()
lastTime = platform->Time();
for(char i = 0; i < DRIVES; i++)
platform->SetDirection(i, FORWARDS);
- active = true;
+ for(char i = 0; i <= AXES; i++)
+ currentPosition[i] = 0.0;
+ active = true;
+ currentFeedrate = START_FEED_RATE;
}
void Move::Exit()
@@ -53,5 +55,29 @@ void Move::Qmove()
{
if(!gCodes->ReadMove(nextMove))
return;
+ platform->Message(HOST_MESSAGE, "Move - got a move:");
+ for(char i = 0; i <= DRIVES; i++)
+ {
+ ftoa(scratchString, nextMove[i], 3);
+ platform->Message(HOST_MESSAGE, scratchString);
+ platform->Message(HOST_MESSAGE, ", ");
+ }
+ platform->Message(HOST_MESSAGE, "
\n");
+ // Make it so
+
+ for(char i = 0; i <= AXES; i++)
+ currentPosition[i] = nextMove[i];
+}
+
+void Move::GetCurrentState(float m[])
+{
+ for(char i = 0; i < DRIVES; i++)
+ {
+ if(i < AXES)
+ m[i] = currentPosition[i];
+ else
+ m[i] = 0.0;
+ }
+ m[DRIVES] = currentFeedrate;
}
diff --git a/Platform.h b/Platform.h
index 6a32370..700e5fd 100644
--- a/Platform.h
+++ b/Platform.h
@@ -74,6 +74,8 @@ Licence: GPL
#define JERKS {15.0, 15.0, 0.4, 15.0} // (mm/sec)
#define DRIVE_RELATIVE_MODES {false, false, false, true} // false for default absolute movement, true for relative to last position
+#define GCODE_LETTERS {'X', 'Y', 'Z', 'E', 'F' }
+
// AXES
@@ -305,101 +307,5 @@ inline unsigned long Platform::Time()
return micros();
}
-//***************************************************************************************
-
-// Network connection
-
-inline int Platform::ClientStatus()
-{
- return clientStatus;
-}
-
-inline void Platform::SendToClient(unsigned char b)
-{
- if(client)
- {
- client.write(b);
- //Serial.write(b);
- } else
- Message(HOST_MESSAGE, "Attempt to send byte to disconnected client.");
-}
-
-inline unsigned char Platform::ClientRead()
-{
- if(client)
- return client.read();
-
- Message(HOST_MESSAGE, "Attempt to read from disconnected client.");
- return '\n'; // good idea??
-}
-
-inline void Platform::ClientMonitor()
-{
- clientStatus = 0;
-
- if(!client)
- {
- client = server->available();
- if(!client)
- return;
- //else
- //Serial.println("new client");
- }
-
- clientStatus |= CLIENT;
-
- if(!client.connected())
- return;
-
- clientStatus |= CONNECTED;
-
- if (!client.available())
- return;
-
- clientStatus |= AVAILABLE;
-}
-
-inline void Platform::DisconnectClient()
-{
- if (client)
- {
- client.stop();
- //Serial.println("client disconnected");
- } else
- Message(HOST_MESSAGE, "Attempt to disconnect non-existent client.");
-}
-
-//*****************************************************************************************************************
-
-// Interrupts
-
-inline void Platform::SetInterrupt(long t)
-{
-
-}
-
-inline void Platform::Interrupt()
-{
- reprap->Interrupt(); // Put nothing else in this function
-}
-
-//*****************************************************************************************************************
-
-// Drive the RepRap machine
-
-inline void Platform::SetDirection(byte drive, bool direction)
-{
- digitalWrite(directionPins[drive], direction);
-}
-
-inline void Platform::Step(byte drive)
-{
- digitalWrite(stepPins[drive], !digitalRead(stepPins[drive]));
-}
-
-inline int Platform::GetRawTemperature(byte heater)
-{
- return analogRead(tempSensePins[heater]);
-}
#endif
diff --git a/Platform.ino b/Platform.ino
index 4759c05..0959b42 100644
--- a/Platform.ino
+++ b/Platform.ino
@@ -42,6 +42,107 @@ Platform::Platform(RepRap* r)
active = false;
}
+//*****************************************************************************************************************
+
+// Interrupts
+
+inline void Platform::SetInterrupt(long t)
+{
+
+}
+
+inline void Platform::Interrupt()
+{
+ reprap->Interrupt(); // Put nothing else in this function
+}
+
+//***************************************************************************************
+
+// Network connection
+
+inline int Platform::ClientStatus()
+{
+ return clientStatus;
+}
+
+inline void Platform::SendToClient(unsigned char b)
+{
+ if(client)
+ {
+ client.write(b);
+ //Serial.write(b);
+ } else
+ Message(HOST_MESSAGE, "Attempt to send byte to disconnected client.");
+}
+
+inline unsigned char Platform::ClientRead()
+{
+ if(client)
+ return client.read();
+
+ Message(HOST_MESSAGE, "Attempt to read from disconnected client.");
+ return '\n'; // good idea??
+}
+
+inline void Platform::ClientMonitor()
+{
+ clientStatus = 0;
+
+ if(!client)
+ {
+ client = server->available();
+ if(!client)
+ return;
+ //else
+ //Serial.println("new client");
+ }
+
+ clientStatus |= CLIENT;
+
+ if(!client.connected())
+ return;
+
+ clientStatus |= CONNECTED;
+
+ if (!client.available())
+ return;
+
+ clientStatus |= AVAILABLE;
+}
+
+inline void Platform::DisconnectClient()
+{
+ if (client)
+ {
+ client.stop();
+ //Serial.println("client disconnected");
+ } else
+ Message(HOST_MESSAGE, "Attempt to disconnect non-existent client.");
+}
+
+
+
+//*****************************************************************************************************************
+
+// Drive the RepRap machine
+
+inline void Platform::SetDirection(byte drive, bool direction)
+{
+ digitalWrite(directionPins[drive], direction);
+}
+
+inline void Platform::Step(byte drive)
+{
+ digitalWrite(stepPins[drive], !digitalRead(stepPins[drive]));
+}
+
+inline int Platform::GetRawTemperature(byte heater)
+{
+ return analogRead(tempSensePins[heater]);
+}
+
+//*******************************************************************************************************************
+
void Platform::Init()
{
byte i;
diff --git a/RepRapFirmware.h b/RepRapFirmware.h
index 072437b..5f291ee 100644
--- a/RepRapFirmware.h
+++ b/RepRapFirmware.h
@@ -28,11 +28,8 @@ Licence: GPL
#define DATE "2012-11-18"
#define LAST_AUTHOR "reprappro.com"
-class Platform;
-class Move;
-class Heat;
-class GCodes;
-class Webserver;
+#include "Configuration.h"
+#include "Platform.h"
class RepRap
{
@@ -42,9 +39,12 @@ class RepRap
void Init();
void Spin();
void Exit();
-
void Interrupt();
-
+ Platform* GetPlatform();
+ Move* GetMove();
+ Heat* GetHeat();
+ GCodes* GetGCodes();
+ Webserver* GetWebserver();
private:
@@ -56,18 +56,15 @@ class RepRap
Webserver* webserver;
};
-#include "Configuration.h"
-#include "Platform.h"
#include "Webserver.h"
#include "GCodes.h"
#include "Move.h"
#include "Heat.h"
-
+char* ftoa(char *a, const float& f, int prec);
extern RepRap reprap;
-
#endif
diff --git a/RepRapFirmware.ino b/RepRapFirmware.ino
index 0a2abae..668afa3 100644
--- a/RepRapFirmware.ino
+++ b/RepRapFirmware.ino
@@ -64,6 +64,12 @@ RepRap::RepRap()
heat = new Heat(platform, gCodes);
}
+inline Platform* RepRap::GetPlatform() { return platform; }
+inline Move* RepRap::GetMove() { return move; }
+inline Heat* RepRap::GetHeat() { return heat; }
+inline GCodes* RepRap::GetGCodes() { return gCodes; }
+inline Webserver* RepRap::GetWebserver() { return webserver; }
+
void RepRap::Init()
{
platform->Init();
@@ -98,12 +104,36 @@ void RepRap::Spin()
}
-
void RepRap::Interrupt()
{
}
+//*************************************************************************************************
+
+// Utilities and storage not part of any class
+
+static long precision[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
+
+char* ftoa(char *a, const float& f, int prec)
+{
+ char *ret = a;
+ long whole = (long)f;
+ sprintf(a,"%d",whole);
+ while (*a != '\0') a++;
+ *a++ = '.';
+ long decimal = abs((long)((f - (float)whole) * precision[prec]));
+ sprintf(a,"%d",decimal);
+ return ret;
+}
+
+
+
+
+
+
+
+