splitting incoming string

Discussion in 'Programmer's Corner' started by Dabu WhiteHacker, Sep 21, 2018.

  1. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    I am using HC-12 to send and receive potentiometer values from one arduino to another.
    i am sending potentiometer values in a form of string.
    this is what i am getting at the other end.
    T329E518A504D657
    and i want to seperat them as follow
    T = 329
    E = 518
    A = 504
    D = 657
    how is that possible?
     
  2. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    CODE

    Code (C):
    1. ========================================================================================
    2.  
    3. Transmitter code:
    4. #include <SoftwareSerial.h>
    5. SoftwareSerial HC12(12, 11);
    6.  
    7. const int throttle = 0;
    8. const int elevator = 1;
    9. const int aerlone = 2;
    10. const int adjust = 3;
    11.  
    12. int throttle_value=0;
    13. int aerlone_value=0;
    14. int elevator_value=0;
    15. int adjust_value=0;
    16.  
    17. String throttle_string;
    18. String elevator_string;
    19. String aerlone_string;
    20. String adjust_string;
    21.  
    22. String packet;
    23.  
    24. void setup() {
    25.   pinMode(throttle,INPUT);
    26.   pinMode(elevator,INPUT);
    27.   pinMode(aerlone,INPUT);
    28.   pinMode(adjust,INPUT);
    29.   HC12.begin(9600);
    30.   Serial.begin(9600);
    31. }
    32. void loop() {
    33.   throttle_value=analogRead(throttle);
    34.   elevator_value=analogRead(elevator);
    35.   aerlone_value=analogRead(aerlone);
    36.   adjust_value=analogRead(adjust);
    37.   throttle_string = String(throttle_value);
    38.   elevator_string = String(elevator_value);
    39.   aerlone_string = String(aerlone_value);
    40.   adjust_string = String(adjust_value);
    41.   packet = "T"+throttle_string+"E"+elevator_string+"A"+aerlone_string+"D"+adjust_string;
    42.   HC12.print(packet);
    43.    delay(500);
    44. }
    45.  
    46. ========================================================================================
    47.  
    48. Receiver code:
    49. #include <SoftwareSerial.h>
    50. SoftwareSerial HC12(10, 9);
    51.  
    52. void setup() {
    53.   Serial.begin(9600);
    54.   HC12.begin(9600);
    55. }
    56.  
    57. void loop() {
    58.    while (HC12.available()) {            
    59.     Serial.write(HC12.read());  
    60.   }
    61. }
    Moderators note : used code tags
     
    Last edited by a moderator: Sep 21, 2018
  3. WBahn

    Moderator

    Mar 31, 2012
    22,990
    6,884
    Are the strings always rigidly in that format? Specifically, are the four numbers always 3 digit representations even if the values are less than 100?
     
  4. dl324

    AAC Fanatic!

    Mar 30, 2015
    7,101
    1,635
    One possibility:
    Code (Text):
    1. main (void) {
    2.   char *string="T329E518A504D657";
    3.   int t, e, a, d;
    4.   sscanf(string, "T%dE%dA%dD%d", &t, &e, &a, &d);
    5.   printf("T = %d\nE = %d\nA = %d\nD = %d\n", t, e, a, d);
    6. }
     
  5. danadak

    Well-Known Member

    Mar 10, 2018
    1,586
    327
    You can always put a delimiter character in between elements,
    that takes care of variable sized elements being sent.

    T329E518A504D657

    In your case an upper case letter can be considered delimiter,
    eg. test each char as you scan string, if upper case letter then
    thats end of last var/start of new var.

    or do this

    T329/E518/A504/D657

    and use "/" as delimiter.

    Regards, Dana.
     
  6. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    no numbers can be from one digit to 4 digits
     
  7. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
     
  8. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    ok i wil use / as delimiter but how is that possible to scan that delimiter and save next characters as new?
     
  9. ericgibbs

    Moderator

    Jan 29, 2010
    5,735
    1,070
    hi Dabu,
    I would suggest you use a comma ',' as the delimiter between text fields in a message string, terminate the string with <crlf> [at the HC12 TX end]
    If you decided to log the data as text, it would be a text.csv file type, which could imported into a Excel type spreadsheet and plotted.

    ie: T329,E518,A504,D657<crlf>

    You could extract the fields by stepping thru the string, build a defined field sub string until the ',' is found and then build the second sub string and so on, upto the <crlf>.
    The sub fields could be any length.

    The leading 'T' character could be used as a RX Sync char.
    [this method works well with GPS reception strings, which can vary in length, using '$' as the Sync char]

    E

    Update:
    An alternative method would be to 'pad' out the individual fields in at the HC12 TX end, with leading zero's '0'.
    [this is the method I use for HC12 data TX/RX]

    So all the fields are 4 digits long, extracting the fixed length fields in the RX sketch is simplified.
     
    Last edited: Sep 22, 2018
  10. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,392
    1,485
    Don't use the arduino string type. It causes lots of problems like this.
    Instead use a standard 'C' character array.
     
    nsaspook likes this.
  11. jpanhalt

    Expert

    Jan 18, 2008
    6,321
    1,192
    Considering the error shown in post #7, why not send the potentiometer values as values? None of the 3-digit strings represent values that are more than 2 bytes. Then, you would save the trouble of converting the string "329" and so forth back into binary values for further processing.
     
  12. danadak

    Well-Known Member

    Mar 10, 2018
    1,586
    327
    Last edited: Sep 22, 2018
  13. dl324

    AAC Fanatic!

    Mar 30, 2015
    7,101
    1,635
    You're using the wrong variable type. sscanf() requires a character variable; you're using a string variable that appears to be an Arduino construct that is more flexible, but uses more memory than a NULL terminated array of type char.

    IMO, sscanf() is a better option than parsing the string yourself or inserting more delimiters. The %d field will accept variable length strings of digits. You just need to insure that your string will never be malformed.
     
  14. danadak

    Well-Known Member

    Mar 10, 2018
    1,586
    327
    I was referring to standard C library, not Arduino. HiTech and Cypress
    in most recent work.

    scanf. I found using above compilers that burden in code space from scanf
    was too high, had to write my own scanner. Not as general of course,
    which is why scanf is bloated compared to simple user scan code.

    Regards, Dana.
     
  15. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    could you describe this method more briefly ?
     
  16. danadak

    Well-Known Member

    Mar 10, 2018
    1,586
    327
  17. ebp

    Well-Known Member

    Feb 8, 2018
    1,842
    642
    Is there some reason you wouldn't simply parse the characters as they arrive one by one rather than putting them into a string and then parsing the string.

    This looks to me like other things I have seen where both ends are overburdened by making the data into some sort of human-readable strings instead of making it compact and easily parsed. Nothing in the system except the human at the far end cares if humans can read characters while they are traveling through the air or some wires. I'd make a fixed packet of 8 bytes of raw ADC data with a checksum of two more bytes. It is compact, easy to parse and has a reliability feature. Sometimes it does make sense to burden the transmitting end with formatting of one form or another if the receiving end is very busy all the time.
     
    MrSoftware, Dabu WhiteHacker and xox like this.
  18. Dabu WhiteHacker

    Thread Starter Member

    Sep 5, 2017
    43
    0
    now i cam sending each byte separately and reading it one by one
    https://hastebin.com/pegohacano.cs
     
Loading...