Skeleton of the GCode interpreter written.

This commit is contained in:
reprappro 2013-04-16 23:49:15 +01:00
parent 00ca902341
commit b23e6943a8
9 changed files with 331 additions and 121 deletions

View file

@ -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

View file

@ -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

View file

@ -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, "<br>\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, "<br>\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, "<br>\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, "<br>\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.<br>\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.<br>\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.<br>\n");
return 0;
}
int result = (int)strtol(&gcodeBuffer[readPointer + 1], NULL, 0);
readPointer = -1;
return result;
}

5
Move.h
View file

@ -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];
};

View file

@ -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, "<br>\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;
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;
}