Go Down

Topic: ideas for parsing hpgl code? (Read 1 time) previous topic - next topic

roypardi

Hi, I need to write a parser for hpgl code received over Serial. I've looked around for examples and the ones I've found are over my head and either can't compile them or can't fix the errors. Sometimes (most times?) trying to reuse code that one doesn't understand is not very useful for either getting the project done or learning.

So - I am thinking of just writing my own. HPGL is a simple semi-colon delimited command format: PD3206,1566;

Anyone have any tips on how to break out the alpha cmd (PD) and the x, y ints?

--Roy

Here is what I've been trying (without success so far):
Code: [Select]
#include <avr/pgmspace.h>

void setup()
{
 Serial.begin(9600);
}

void loop()
{
 char* scratchpad;
 scratchpad = "PD3450.0,2202.0";
 char s[10];
 float f;

 int n = sscanf_P(scratchpad,PSTR("%f %s"),&f,&s);

 Serial.println("--------------");
 Serial.print("n ");
 Serial.println(n);
 Serial.print("f ");
 Serial.println(f);
 Serial.print("s ");
 Serial.println(s);

 delay(2000);
}



Coding Badly

Quote
I need to write a parser for hpgl code received over Serial

To what end?

PaulS

The strtok function allows you to extract tokens from strings. To extract the PD token, use
Code: [Select]
char *token = strtok(scratchpad, "-0123456789");

Then, modify the scratchpad string to remove the token.

To get the X and Y values, use
Code: [Select]
char *xStg = strtok(scratchpad, ",");
char *yStg = strtok(NULL, ";");

The second call uses NULL as the string to process, so the same string (as specified in the last call that didn't pass a NULL) continues to be parsed.

The first call stops processing when a minus sign or a digit is found, but that delimiter is pointed to, so we need to remove the token and start over with the now-modified string. Otherwise, the next token would begin with the character following the delimiter, which is not what we want.

zoomkat

In the latest versions of the arduino IDE there is a string handling function that can form strings from inputs, then parce them in various ways.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

roypardi

Quote
In the latest versions of the arduino IDE there is a string handling function that can form strings from inputs, then parce them in various ways.


Thanks - that's helpful (I realize it is not as fast as other methods but I can make progress, etc.)

Once I pull out the x + y as Strings, is there an easy way to convert them to integers?

Code: [Select]
void setup()
{
 Serial.begin(9600);
}

void loop()
{
 String scratchpad = "PD3450.0,-2202.0";
 String cmd = scratchpad.substring(0, 2);

 Serial.println("--------------");
 Serial.println(cmd);

 int len = scratchpad.length();
 int i = scratchpad.indexOf(",");

 String x = scratchpad.substring(2, i);
 String y = scratchpad.substring(i + 1, len);

 Serial.print("x: ");
 Serial.println(x);
 Serial.print("y: ");
 Serial.println(y);

 delay(2000);
}

zoomkat

I use atoi like below.

Code: [Select]

servo1 = readString.substring(7, 11);
     servo2 = readString.substring(12, 16);
     
     Serial.println(servo1);
     Serial.println(servo2);
     
     int n1;
     int n2;
     
     n1 = atoi(servo1); //convert string to number
     n2 = atoi(servo2);
     myservo1.writeMicroseconds(n1);
     myservo2.writeMicroseconds(n2);
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

roypardi

Thanks for atoi. I had to convert the String datatype to a char array in order to get atoi to work. Probably not the most efficient way to accomplish the task of parsing this sort of incoming data ("PD3450.0,-2202.0;") but it's code I can understand and build on.



Code: [Select]
void setup()
{
 Serial.begin(9600);
}

void loop()
{
 int sTime = millis();
 String scratchpad = "PD3450.0,-2202.0";
 String cmd = scratchpad.substring(0, 2);

 int len = scratchpad.length();
 int i = scratchpad.indexOf(",");

 String x = scratchpad.substring(2, i);
 String y = scratchpad.substring(i + 1, len);

 char X_array[20];
 char Y_array[20];

 x.toCharArray(X_array, 20);
 y.toCharArray(Y_array, 20);

 float X1 = atoi(X_array);
 float Y1 = atoi(Y_array);

 int eTime = sTime - millis();
 Serial.println("--------------");
 Serial.print("elapsed:");
 Serial.println(eTime);
 Serial.print("cmd:");
 Serial.println(cmd);
 Serial.print("x: ");
 Serial.println(X1);
 Serial.print("y: ");
 Serial.println(Y1);

 delay(2000);
}

Berry_nijs

pretty curious what you will come up with,
I´m struggling with the same problem at the moment,

The thing i probably will do is interpret the hpgl on my computer (Probably c# or so) and send custom stripped clean commands to the arduino over serial.

Quit some time ago I  build a crappy robot arm controller which didnt work too well, but this principle of sending data worked fine..
doing all the difficult calculating on my laptop and have the arduino only reaspond to simple commands,

This is the scripot i used back than
Code: [Select]

#include <Servo.h>
#include <stdlib.h>     // needed for atoi

char buffer[4];
int received;

Servo joop;  
Servo pietje;  

int joopangle;
int pietjeangle;

void setup()
{

Serial.begin(9600);

joop.attach(9);
pietje.attach(10);
Serial.println("ready");
}

void loop()
{
 
 if (Serial.available())
   {
         
       buffer[received++] = Serial.read();
       buffer[received] = '\0';
       
       if (received == (sizeof(buffer)))
       {
           int firstletter = buffer[0];
           char finalval[3] = {buffer[1], buffer[2], buffer[3]};
           int servoangle = atol(finalval);
           if(firstletter == 'J')
             {
               joopangle = servoangle;
               
             }
             
            if(firstletter == 'P')
            {
              pietjeangle = servoangle;
              pietje.write(pietjeangle);
             joop.write(joopangle);  
            }
            received = 0;
            delay(50);
     }  
 }
}

Once again I´m very curious for your result; keep posting..

roypardi

Hi -

I've wrestled a lot with motori: http://sensi.org/~svo/motori/

He has a fairly complete, basic parser but I found the code very Arduino "unfriendly" - lots of compiler issues - and my knowledge of C/C++/the Arduino build process was not sufficient to tech it out. He is also using timers and interrupts and it was hard to uncouple that (again, my insufficient understanding of his code).

I've finally got it working - using his method of scanning the input but basically rewriting the whole thing to work with Arduino (along with coding in a way I can understand and debug). Learned a lot!

Meanwhile I've also been thinking through my whole toolchain and wondering if .hpgl is the best end result, compared to gcode. I think I have settled on using pstoedit as my main conversion utility and its .hpgl export isn't as good as its gcode export. So my whole excursion into hpgl may have been for the learning/scars only ...  :)

The RepRap gcode parser is Arduino freindly and easier to get up and running.

-r

garyinspringhill

Would you be willing to share your aduino to hpgl code? It seems just what I need to build on for a project I have in mind.

Thanks

Go Up