Pages: [1]   Go Down
Author Topic: ideas for parsing hpgl code?  (Read 1288 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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);
}

Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13073
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I need to write a parser for hpgl code received over Serial
To what end?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 652
Posts: 50868
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Then, modify the scratchpad string to remove the token.

To get the X and Y values, use
Code:
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.
Logged

0
Offline Offline
Tesla Member
***
Karma: 147
Posts: 9741
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
Logged

0
Offline Offline
Tesla Member
***
Karma: 147
Posts: 9741
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I use atoi like below.

Code:
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);
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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..
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ...  smiley

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

-r
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: