serial buffer to array to variables.... desparate!

Hello arduino community,

I know this is a topic many times spoken, but i still couldn't make it work and find the right answer in the topics i searched for... so here it is:

I own an arduino mega1280 and use 0022 to make and upload my code.
I've already made quite a few projects including custom midi shields and love the way things work. Problem is, i'm not good at C, i'm a more fluent programmer of vb.

So i use vb.net to program my interface. Anyway, i'm making a printer like a plotter that uses stepper motors, i made my own custom class for them and they work like a charm, so i use serial communication to send instructions to the arduino from vb.net
it's simple, an instruction is like
XMOTP0024 meaning move motor X to the right for 24 steps. all instructions will be fixed length of 9 characters, and i want to split it into header=XMOT sign=P steps=24.
i've tried many ways of doing it, using memcpy, strcpy, one-by one characters copy... but one of these lines always seems to mess up my buffer or resulting variables can anyone help?

here's the piece of code that deals with it:

int ledPin = 13;
char buffer[9];
char header[4];
char number[4];
int received;

void setup() {
//setup motor pins
pinMode(ledPin, OUTPUT);
//serial communication
Serial.begin(9600); // start serial communication
received=0;
}

void loop() {

//take instruction from serial port, fill buffer
if (Serial.available()){
buffer[received++] = Serial.read();
if (received >= (sizeof(buffer))){
received=0;

//extract variables from buffer
memcpy(number, &buffer[5],4);
memcpy(header, &buffer[0],4);
int steps = atoi(number);
char sign = buffer[4];

//DEBUG print over serial
Serial.println(header);
Serial.println(sign);
Serial.println(steps);
}
}
}

using the serial monitor i'm giving XMOTP0025 but i get back
xmot0025
p
25

i just can't get the "header" to work in any way...! does any experienced programmer have something to suggest?

thank you in advance!

Each of your arrays needs to be 1 element larger. Then, you need to add the NULL after copying data, BEFORE you call any function that expects a string - atoi() or print().

        memcpy(number, &buffer[5],4);
        number[4] = '\0';
        memcpy(header, &buffer[0],4);
        header[4] = '\0';

thank you for this, it's now messing the steps value...

XMOTP0024
header: XMOT
sign: P
steps: 0

any ideas? XD

code now is
memcpy(number, &buffer[5],4);
number[4] = '\0';
memcpy(header, &buffer[0],4);
header[4] = '\0';
int steps = atoi(number);
char sign = buffer[4];

any ideas?

You might try printing number to see that it actually contains.

hmm... it's blank...
i just used

char number[4]={'0'};

on top for its initialisation and it's now working...!! any other way i can fix it or is it ok if i leave it like that?

doing the same for header
char number[4]={'0'};
messes it, it becomes XMOT0024
...

This worked for me...

int ledPin = 13;
char buffer[10];
char header[5];
char number[6];
int received;

void setup()
{
  //setup motor pins
  pinMode(ledPin, OUTPUT);
  //serial communication
  Serial.begin(9600); // start serial communication
  received=0;
}

void loop()
{
  //take instruction from serial port, fill buffer
    if (Serial.available())
    {
      buffer[received++] = Serial.read();
      if (received >= 9)
      {
        buffer[received] = '\0';
        received=0;
       
        //extract variables from buffer
        memcpy(number, &buffer[5],4);
        number[4] = '\0';
        memcpy(header, &buffer[0],4);
        header[4] = '\0';
        
        int steps = atoi(number);
        char sign = buffer[4];
       
        //DEBUG print over serial
        Serial.println(header);
        Serial.println(number);
        Serial.println(sign);
        Serial.println(steps);
    }
  }
}

XMOT
0025
P
25

Strange thing is, if char header[5]; the number is ok, working, if char header[4]; it's messing the number, but what does header have to do with number? :blush:

Strange thing is, if char header[5]; the number is ok, working, if char header[4]; it's messing the number, but what does header have to do with number?

If header is sized to hold 4 elements, and you write in the 5th position, you step on some other memory location. Depending on the order that the compiler puts things in memory, and how/when those items are accessed, this could have catastrophic consequences or never be noticed.

I guess you know which category your situation falls in.

since arrays in arduino too are zero-based, should 4 be enough to hold
header[0]=X
header[1]=M
header[2]=O
header[3]=T
header[4]='\0'
?

Also another question about the serial communication and byte send-receive,
is it possible that arduino will miss a byte or a whole line? after a few lines of sending commands to it with a 250ms delay between them, a XMOTP0002 becomes
XXMOTP000
2YMOTN000
1XMOTN000
2....
and it loses the alignment... is there a way i can make sure the bytes are safely transferred and read?

thank you so much for your help already!!

since arrays in arduino too are zero-based, should 4 be enough to hold
header[0]=X
header[1]=M
header[2]=O
header[3]=T
header[4]='\0'
?

The value in the [] in the declaration is the number of elements, not the upper index. So, no.

ooook! thank you very much for this precious piece of info!
this is what happens when you mix vb.net with c XD
it's all solved now :slight_smile: