Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm working on interfacing some older positioning equipment with an arduino, but having done the majority of my work with higher level language I'm having trouble adjusting to the limitations of AVR-GCC.

I basically have two questions: Is this a good way to parse out the strings? What can I do to optimize this code for an embedded platform?

// this is in the global scope of my program. normally accepted as bad code, 
// but it seems to make sense in the context of an embedded platform.
// "global" cache
int data[10];

void getPosition(){
    // position message is always less than 25 bytes with null termination characters
    byte bufferIndex = 0;
    char buffer[25];

    // read the position command from the serial port
    // should look like:
    //      D20BIX+00733Y+00080S99\r\n
    //  
    // and we need the X+00000 and Y+00000 parts
    //
    if (Serial.available() > 0){
        while (Serial.available() > 0 && bufferIndex < 25){
            buffer[bufferIndex] = Serial.read();

            if (buffer[bufferIndex++] == '\n'){
                buffer[bufferIndex] = '\0';
                break;
            }
        }

        Serial.flush();

        // check to see if we have good orientation on the buffer by
        // checking for lines starting with model identifier 'D'
        String input = String(buffer);

        if (buffer[0] == 'D' && bufferIndex <=24){  
            int x_result = data[1];
            int y_result = data[4];
            String check;
            char token_buffer[8] = {'0', '0', '0', '0', '0', '0', '0', '0' };

            // scan for x, target token is X+00000
            String x_token = input.substring(5, 11);
            check = x_token.substring(2, 6);
            check.toCharArray(token_buffer, 8);

            x_result = atoi(token_buffer);
            if (x_token[1] == '-'){
                x_result *= -1;
            }

            // scan for y, target token is Y+00000
            String y_token = input.substring(12, 18);
            check = y_token.substring(2, 6);
            check.toCharArray(token_buffer, 8);

            y_result = atoi(token_buffer);
            if (y_token[1] == '-'){
                y_result *= -1;
            }

            // finalize results
            data[1] = x_result;
            data[4] = y_result;
        }
    }
}
share|improve this question

1 Answer

up vote 1 down vote accepted

IMHO string parsing is not a good idea for embedded applications. If you really care for speed, it would be better to use some binary format w/o dynamic length numbers etc.

I suggest you cannot change protocol due to legacy code/hardware. Then you could try turning your parser into finite automate. You just make a table (first index for current state, second index for a class of read char, value is new state and function to call) and then (state, f) = transition[state][class_of[*s++]]; f(); Files, generated with YACC for some simple grammars, could be helpful.

If you need just some minor modifications to your code, here you are. First you read data into your buffer. All you have to do then is just some calculations with Horner scheme:

x_result = ((buffer[5]-'0')*10+buffer[6]-'0')*10+... ;
if (buffer[4] == '-') x_result =- x_result;

String constructor, substring method and other string operations are quite costly.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.