|
|
Lake District, UK
Offline
Jr. Member
Karma: 0
Posts: 62
Electronics needs smoke to work, if it escapes its broken
|
 |
« Reply #16 on: January 27, 2013, 12:45:48 pm » |
Hi Zoomkat, i saw the information you pointed out, unfortunately i couldnt find an example which would simply strip characters from a string between linits. could you provide me with a direct link to the example cheers Jason
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 50
Posts: 6535
Arduino rocks
|
 |
« Reply #17 on: January 27, 2013, 01:10:56 pm » |
Hi Zoomkat, i saw the information you pointed out, unfortunately i couldnt find an example which would simply strip characters from a string between linits. could you provide me with a direct link to the example cheers Jason
The below shows how to find the position of a delimiting character in a string, then using an offset, find the location of the next delimiting character in the string. Once you know the positions of the two characters, you can use those locations to capture the substring between the two like in the bottom example. http://arduino.cc/en/Tutorial/StringIndexOfhttp://arduino.cc/en/Tutorial/StringSubstring
|
|
|
|
|
Logged
|
|
|
|
|
Lake District, UK
Offline
Jr. Member
Karma: 0
Posts: 62
Electronics needs smoke to work, if it escapes its broken
|
 |
« Reply #18 on: January 27, 2013, 01:41:33 pm » |
Yes i understand what you are saying but unfortunately i dont have delimiting characters the format is 255O255|the part of the code which is handling the parsing does not see the end character "|" which has already been stripped. i need to be able to use the character position instead. the examples dont offer any suggestion on how to do this.
as mentioned above i could in VB.
I am currently going back over the code and seeing if i can adopt Pauls suggestion.
thanks for the help J.
|
|
|
|
|
Logged
|
|
|
|
|
Temple, Texas
Offline
Sr. Member
Karma: 14
Posts: 354
|
 |
« Reply #19 on: January 27, 2013, 02:00:14 pm » |
with cmd="255O255|";
preconditions strlen(cmd)==8 && cmd[3]=='O' && cmd[7]=='|' )
int slave=atoi( cmd); // gives you the address int value=atoi( cmd+4); // gives you the value
Doesn't that "get you there from here"?
Also are you sure about the 3 digit thing? i.e. you will be getting "023O004|" not "23O4|"
John
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2884
I only know some basic electricity....
|
 |
« Reply #20 on: January 27, 2013, 02:27:14 pm » |
Yes i understand what you are saying but unfortunately i dont have delimiting characters the format is 255O255|the part of the code which is handling the parsing does not see the end character "|" which has already been stripped. i need to be able to use the character position instead. the examples dont offer any suggestion on how to do this.
Using a 4 char array string you can put the first 3 serial chars in array[0], [1], [2], and make [3] = 0. Then you have a C string suitable for atoi(). i need to be able to use the character position instead. the examples dont offer any suggestion on how to do this.
Make a variable to hold the final number. **1** Multiple final number variable by 10. **2** Read the 1st serial char, check that it is >= '0' and <= '9' and if so, subtract '0' and add to the final number variable. Repeat **1** and **2** two more times. If no errors then you have read 3 digits and your converted value is in the final number variable. Otherwise rely on black box function until you learn how simple the basis for the above is. C++ container classes on an UNO is like Formula 1 cars on a half acre dirt track. Possible but ....
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Temple, Texas
Offline
Sr. Member
Karma: 14
Posts: 354
|
 |
« Reply #21 on: January 27, 2013, 02:34:54 pm » |
Using a 4 char array string you can put the first 3 serial chars in array[0], [1], [2], and make [3] = 0. Then you have a C string suitable for atoi().
array and array+4 are already suitable for atoi: int xxx = atoi(array); int yyy = atoi(array+4); John
|
|
|
|
« Last Edit: January 27, 2013, 02:40:08 pm by johncc »
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2884
I only know some basic electricity....
|
 |
« Reply #22 on: January 27, 2013, 02:53:10 pm » |
Not without terminating zeros. Go ahead and try.
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Temple, Texas
Offline
Sr. Member
Karma: 14
Posts: 354
|
 |
« Reply #23 on: January 27, 2013, 03:23:59 pm » |
Not without terminating zeros. Go ahead and try.
Sure // Return true if a valid cmd "xxxOyyy|" , false if not // output parameters xx and yy bool parse_O_command( const char * str, int & xx, int & yy) { // "Input string should arrive in the format of 255O255|" if ( strnlen(str,8)== 8 && str[3]=='O' && str[7]=='|'){ xx=atoi(str); // the first 3 characters are the Slave device address yy=atoi(str+4); // str[4] and after are digital value return true; } return false; }
Test Suite void setup(){
int adr, val; bool valid;
valid = parseOcommand("123O456|", adr, val); Serial << "1: " << adr << "," << val << " : " << (valid?"valid":"not a valid") << " O command" << endl;
char buf8[8] = {'2','4','6','O','1','8','8','|'}; valid = parseOcommand(buf8, adr, val); Serial << "2: " << adr << "," << val << " : " << (valid?"valid":"not a valid") << " O command" << endl;
char buf7[7] = {'2','4','6','O','1','7','7'}; valid = parseOcommand(buf7, adr, val); Serial << "3: " << adr << "," << val << " : " << (valid?"valid":"not a valid") << " O command" << endl;
Serial << "Done" << endl; }
Output 1: 123,456 : valid O command 2: 246,188 : valid O command 3: 246,188 : NOT valid O command Done
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #24 on: January 27, 2013, 03:30:30 pm » |
Not without terminating zeros. Go ahead and try. The initial string is, presumably, NULL terminated. The atoi() function stops processing when it encounters a NULL or when it encounters some non-integer character. So, NULL terminating is not technically required, since it is the original array that is being passed to atoi(), twice. If the parts of the original array were copied to other arrays, then, the copies would need to be NULL terminated.
|
|
|
|
|
Logged
|
|
|
|
|
Temple, Texas
Offline
Sr. Member
Karma: 14
Posts: 354
|
 |
« Reply #25 on: January 27, 2013, 03:39:11 pm » |
Not without terminating zeros. Go ahead and try. The initial string is, presumably, NULL terminated. The atoi() function stops processing when it encounters a NULL or when it encounters some non-integer character. So, NULL terminating is not technically required, since it is the original array that is being passed to atoi(), twice. If the parts of the original array were copied to other arrays, then, the copies would need to be NULL terminated. Thank you. And even that last warning would not be important if the format is "xxxOyyy|", as per original post. But I think he said later that maybe there is no | terminator.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #26 on: January 27, 2013, 04:24:11 pm » |
@OP are you writing both ends? In that case just send a struct, rather than mucking around with delimiters, atoi, substrings, etc. I wrote a simple library on this page (for RS485 too): http://www.gammon.com.au/forum/?id=11428That lets you send a block of memory (ie. a struct) complete with start and end terminators (so you don't come in halfway through a piece of data), and a sumcheck. An example struct could be: typedef struct { byte command; long arg; } tCommand;
That lets you send a command to your device with a long (32-bit) argument being some sort of argument to that command.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 50
Posts: 6535
Arduino rocks
|
 |
« Reply #27 on: January 27, 2013, 04:55:12 pm » |
Yes i understand what you are saying but unfortunately i dont have delimiting characters the format is 255O255|the part of the code which is handling the parsing does not see the end character "|" which has already been stripped. i need to be able to use the character position instead. the examples dont offer any suggestion on how to do this.
Not sure what the problem is, but the bottom code shows how to get the desired characters from a string. Will your string always have an O between the two desired numbers? If so you should be able to atoi the initial string to get the first 255 number, and get the rest of the string past the center O and atoi it also. I do this to parse GET strings. 255O255 String stringOne = "Content-Type: text/html"; // you can also look for a substring in the middle of a string: if (stringOne.substring(14,18) == "text") { } String stringOne = "Content-Type: text/html"; // substring(index) looks for the substring from the index position to the end: if (stringOne.substring(19) == "htm") { }
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2884
I only know some basic electricity....
|
 |
« Reply #28 on: January 27, 2013, 07:09:23 pm » |
O 0
guess what the difference is
NULL is zero, not |
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Lake District, UK
Offline
Jr. Member
Karma: 0
Posts: 62
Electronics needs smoke to work, if it escapes its broken
|
 |
« Reply #29 on: January 31, 2013, 06:47:00 am » |
Thanks for the replies, i have taken onboard all of your ideas and given them all a try.
As Nick has noticed, i still working on a RS485/modbus communication project
the command was going to be the device ID xxx - a function "o" being Output (Digital) and yyy being the value/byte sent to the slave device to drive the digital values which are Bit weighted.
This was going to be the structure and would be similar format for all commands from a host PC to the RS485 master device. the numbering format was to be 3 characters no matter what and the function would always be a character.
From Pauls earlier post the comma delimited suggestion appears to be the most simplistic and straight forward method.
It should now allow me to to create address IDs of any size - say 4000 The function command could be similar, i will probablly keep to values in 1 byte ie, 0 to 255 as Nick Gammons RS485 comms example uses Bytes in the message transfer.
Its a steep learning curve, thank you all for your assistance, much appreciated
|
|
|
|
|
Logged
|
|
|
|
|
|