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