Disappearing data ...

Hi

I am writing a program that amongst other things needs to speak to an Alicat mass flow controller.

I have a packet structure that I'm passing from a Free Pascal program.

At the point where I have a problem I am passing a character array with "234567" - 6 digits.

The first digit is a unit number and identifies controller B correctly.

So now I have a string with "B" in it and I want to concatenate the 34567 ... I really can't see why the values in glCommandBody are not being copied across in the for loop.

I tried strcat and strncpy, but no joy.

And maybe I'm not doing the carriage return properly either ... (a newline is not required)

Thanks in advance.

void setAlicat ()
{
char emptyStr [20];
char tStr[20] ;
int unitNumber ;
int ido ;

unitNumber = glCommandBody[0] - '0' ; //char glCommandBody [50] - global

strcpy (emptyStr,"") ;

//Select Alicat

switch (unitNumber)
{
case 1: strcpy (emptyStr, "A") ; break ; //works
case 2: strcpy (emptyStr, "B") ; break ;
case 3: strcpy (emptyStr, "C") ; break ;
} //end of switch

//Now extract flow setting to send

// Serial.println (glCommandBody) ; //contains "234567"

// Serial.println (strlen(glCommandBody)) ; //returns 6

for (ido=1; ido == strlen (glCommandBody) - 1; ido++)
emptyStr[ido] = glCommandBody[ido] ;

// Serial.println (emptyStr) ; //Returns "B" !

emptyStr [strlen (glCommandBody)] = '\0' ;

Serial.println (emptyStr) ; //Still "B"

// emptyStr [strlen(emptyStr)-1] = '\r' ; //Put a carriage return on

// Serial.println (emptyStr) ; //You guessed it: "B"

Serial2.print ( tStr ) ; //Alicat can't make head or tail of it
Serial.println ( tStr) ;

Your for-loop should check for <= instead of ==.
You never put anything in tstr.

You will need to make sure that your emptyStr is terminated with a ‘\0’ (yes, you do); do not try to print emptyStr before that.

char glCommandBody[] = "234567";

void setup() {

  Serial.begin(57600);

  char emptyStr [20];
  char tStr[20] ;
  int  unitNumber ;
  int  ido ;

  unitNumber = glCommandBody[0] - '0' ; //char glCommandBody [50] - global

  strcpy (emptyStr, "") ;

  //Select Alicat

  switch (unitNumber)
  {
    case 1: strcpy (emptyStr, "A") ; break ;  //works
    case 2: strcpy (emptyStr, "B") ; break ;
    case 3: strcpy (emptyStr, "C") ; break ;
  } //end of switch

  //Now extract flow setting to send

  Serial.print("glCommandBody: ["); Serial.print (glCommandBody); Serial.println("]");  //contains "234567"
  Serial.print("strlen glCommandBody: "); Serial.println (strlen(glCommandBody)) ;      //returns 6

  for (ido = 1; ido <= strlen (glCommandBody) - 1; ido++)
  {
    emptyStr[ido] = glCommandBody[ido];
  }

  Serial.print("emptyStr: ["); Serial.print (emptyStr); Serial.println("]");            //Returns "B"  !
  emptyStr [strlen (glCommandBody)] = '\0' ;
  Serial.print("emptyStr: ["); Serial.print (emptyStr); Serial.println("]");            //Still "B"

  //  emptyStr [strlen(emptyStr)-1] = '\r' ;  //Put a carriage return on

  //   Serial.println (emptyStr) ;  //You guessed it: "B"


  //Serial2.print ( tStr ) ; //Alicat can't make head or tail of it
  Serial.println ( tStr) ;
  // put your setup code here, to run once:

}

void loop()
{
}

Output

glCommandBody: [234567]
strlen glCommandBody: 6
emptyStr: [B34567]
emptyStr: [B34567]

Hi

tStr was in use before I edited the program 96,347 times!! It's redundancy doesn't really affect the program at the critical point?

Why >= ? I'm incrementing by single integers so it should be equal to the test at some point?
At the point where I am copying the data across, I am using a char to char transfer, so I wouldn't have thought that it was testing the null terminator?

I wasn't sure about my assignment of '\0' a few lines lower down. Is that the correct way to do it?

Thanks

Hil

Aah - you’re right! It was the test <= that did it.

I had printed after adding the ‘\0’ so I’m slightly free of sin …

I’m too much a Pascal programmer!

Many thanks.

Hil

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

If the test fails, the for-loop ends.

Regarding the adding of the '\0', I think you have it right; I usually do a call to memset to clear the array before populating it. That way I don't have to worry.

Robin2:
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Where do you see String with capital S?

sterretje:
Where do you see String with capital S?

In my nightmares and flashbacks.
You weren't there, man.

sterretje:
Where do you see String with capital S?

You are quite correct - there are none. Senior Moment :slight_smile:

...R

Thanks all for the advice! Even the String advice!

Heavens, I wish that I COULD use String. I die for myStr = "B" + etc.

The main module (to monitor a stable isotope laser) is written in Lazarus but the Arduino is a brilliant interface module.

Hil

SpyderHil:
Heavens, I wish that I COULD use String. I die for myStr = "B" + etc.

Yeah, great for cranial depilation.