How can I split up serial data into multiple variables

edited April 2017 in Arduino

Im sending data from arduino to processing. I have six variables to send. Currently Im doing it through serial and Ive got processing to receive the data, currently it arrvies in processing as 6 lines of data. How can I set it up so I can have 6 variables in processing.

Answers

  • @GoToLoop im struggling to follow how the code is working regarding to how it is taking the received data and separating it into multiple variables in processing.

  • You should post your most current attempt, both for Arduino's C & Processing's Java.

  • edited April 2017

    @GoToLoop The arduino is just printing the 6 variables Serial.println(D1); Serial.println(D2); Serial.println(D3); Serial.println(D4); Serial.println(D5); Serial.println(D6); So those variables are six numbers ranging from 0 to 400

    Then in proccesing, im using some code from a tutorial about reading the serial and thats about as far as i got. ` import processing.serial.*; Serial myPort; float value;

    void setup() { myPort = new Serial(this, Serial.list()[0], 9600); }

    void draw() { }

    void serialEvent(Serial p){ String message = myPort.readStringUntil(13); if(message!=null){ value = float(message); println(value); } } `

  • edited April 2017

    Your current code doesn't match any of the tips given at the link I've posted above. :-<
    Also read about how to post code in this forum: :-B
    https://forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text

  • @gotoloop well using your code im still at the same problem where all i have is processing spaming out loads of numbers. How do i turn those numbers into six variables in processing.

  • Have you already changed your Arduino's code in order to follow the model proposed in that link I've posted?

    You 1st need to create a transmission model in order to implement a receiving model. L-)

  • @GoToLoop okay im using your code now for both arduino and processing. Now all I get is a single line of six separate numbers. How can i convert this to six integers.

  • If you've got an array w/ 6 elements, just declare 6 variables to receive each value from it.
    Or better yet, just use the array directly. No need for 6 separate variables. =P~

  • @GoToLoop thats the bit i dont understand how to do.

  • That's why you should attempt to do it and post it here so we can have an idea what's going wrong.

  • @GoToLoop I attempted to arrary it and also made a quick draw so i could tell if it was working, and all I get is 0s when im not sending 0s.

    import processing.serial.Serial;
    int[] serialInArray = new int[6];
    int YPositive;
    int YNegative;
    int XPositive;
    int XNegative;
    int ZPositive;
    int ZNegative;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    void setup() {
    
      size(500,500);
    
      noLoop();
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
    }
    
    void draw() {
      println(myString);
      textSize(32);
      text(YPositive,50,50);
      text(YNegative,50,100);  
      text(XPositive,50,150);
      text(XNegative,50,200);  
      text(ZPositive,50,250);
      text(ZNegative,50,300);  
    
    }
    
    void serialEvent(final Serial s) {
      myString = s.readString().trim();
      redraw = true;
    YPositive = serialInArray[0];
    YNegative = serialInArray[1];
    XPositive = serialInArray[2];
    XNegative = serialInArray[3];
    ZPositive = serialInArray[4];
    ZNegative = serialInArray[5];
    }
    
  • You don't need to define the size of the array in line 2. The size is defined by the return value of readString() function in serialEvent.

    This is a modified version of your serial event below.

    Kf

    void serialEvent(final Serial s) {
      myString = s.readString().trim();
      redraw = true;
    
      serialInArray=split(myString," ");  //ASSUMING your data is space separated
    
      if(serialInArray.length==6){  //VERY IMPORTANT in your case
      YPositive = serialInArray[0];
      YNegative = serialInArray[1];
      XPositive = serialInArray[2];
      XNegative = serialInArray[3];
      ZPositive = serialInArray[4];
      ZNegative = serialInArray[5];
    
      }
      else{
        println("WARNING: Incorrect number of tokens received: "+serialInArray.length);
      }
    }
    
  • @kfrajer with your code i get the error "cannot convert from String[] to int" if i keep defining the integer. if i remove the integer it says "serialInArray cannot be resolved to a variable". So where would i define serialInArray and what would I define it as.

    Also nice idea with the incorrect number message.

  • Change line 5: serialInArray=int(split(myString," ")); Notice I am assuming you are sending all your 6 values from your arduino and they are separted by spaces. This is a guess from my side. It is better if you post your arduino code as well.

    Check this related to your question: https://processing.org/reference/intconvert_.html

    Keep your serialInArray global so it can be accessed by draw and serialEvent.

    Kf

  • edited April 2017

    @kfrajer this is the arduino code Serial.print(duino1.D1); Serial.write('\t'); Serial.print(duino1.D2); Serial.write('\t'); Serial.print(duino1.D3); Serial.write('\t'); Serial.print(duino1.D4); Serial.write('\t'); Serial.print(duino1.D5); Serial.write('\t'); Serial.println(duino1.D6);

    this is the processing code at the moment its still getting a error to do with the serial array. "the primitive type int of serialInArray does not have a field length"

    import processing.serial.Serial;
    int serialInArray;
    int YPositive;
    int YNegative;
    int XPositive;
    int XNegative;
    int ZPositive;
    int ZNegative;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    void setup() {
    
      size(500,500);
    
      noLoop();
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
    }
    
    void draw() {
      println(myString);
      textSize(32);
      text(YPositive,50,50);
      text(YNegative,50,100);  
      text(XPositive,50,150);
      text(XNegative,50,200);  
      text(ZPositive,50,250);
      text(ZNegative,50,300);  
    
    }
    
    void serialEvent(final Serial s) {
      myString = s.readString().trim();
      redraw = true;
    
      serialInArray=int(myString," ");  //ASSUMING your data is space separated
    
      if(serialInArray.length==6){  //VERY IMPORTANT in your case
      YPositive = serialInArray[0];
      YNegative = serialInArray[1];
      XPositive = serialInArray[2];
      XNegative = serialInArray[3];
      ZPositive = serialInArray[4];
      ZNegative = serialInArray[5];
    
      }
      else{
        println("WARNING: Incorrect number of tokens received: "+serialInArray.length);
      }
    }
    
  • Serial.print(duino1.D1);
    Serial.write('\t');
    Serial.print(duino1.D2);
    Serial.write('\t');
    Serial.print(duino1.D3);
    Serial.write('\t');
    Serial.print(duino1.D4);
    Serial.write('\t');
    Serial.print(duino1.D5);
    Serial.write('\t');
    Serial.println(duino1.D6);
    
  • You need an array! int[] serialInArray;

    And line 39 should be serialInArray=int(myString,TAB);

    Kf

  • edited April 2017

    @EndlessOyster, your serialEvent() doesn't match the 1 from "Efficient Serial Multi-Value Reading (v1.1)":
    https://forum.Processing.org/two/discussion/16618/processing-with-arduino-void-serialevent#Item_1

    This is the 1 you should use as the template for your own: B-)

    import processing.serial.Serial;
    
    int[] vals = new int[6];
    
    void serialEvent(final Serial s) {
      vals = int(splitTokens(s.readString()));
      redraw = true;
    }
    

    Obviously, if you insist to assign each indexed value from the tokenized array into separate variables, that needs to be done as 1 by 1 assignments: (:|

    import processing.serial.Serial;
    
    int YPositive, YNegative, XPositive, XNegative, ZPositive, ZNegative;
    
    void serialEvent(final Serial s) {
      final int[] vals = int(splitTokens(s.readString()));
    
      YPositive = vals[0];
      YNegative = vals[1];
      XPositive = vals[2];
      XNegative = vals[3];
      ZPositive = vals[4];
      ZNegative = vals[5];
    
      redraw = true;
    }
    

    I don't have any of the hardware, so you've gotta test it for yourself whether it's working now.
    If it isn't yet, post again your most current attempt. Good luck! :-bd

  • @GoToLoop with your code it goes wrong. when i run it, it starts fine gets the first couple numbers correct, then in the serial on processing it says "Error, disabling serialEvents() For COM4" "Null"

  • @EndlessOyster

    Try the code below. Make sure you get continuous readings before you start parsing your data. If the code below works, then use split to convert your data from tab separated values to an array: https://processing.org/reference/split_.html

    Kf

    import processing.serial.Serial;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    void setup() { 
      size(500,500); 
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
      noLoop();
    }
    
    void draw() {
      if(myString!=null)
        println(myString);
    
    }
    
    void serialEvent(final Serial s) {
    
      myString = s.readString().trim();
      redraw = true;  
    }
    
  • edited April 2017

    ... with your code it goes wrong.

    @EndlessOyster, haven't you paid attention to my lastest previous request?

    If it isn't yet, post again your most current attempt. Good luck! :-bd

    The code I've given you was clearly an incomplete sample.
    For example, there were no setup() nor draw() there.
    In order to pinpoint what's going wrong, you need to post your most current complete attempt! [-(

  • import processing.serial.Serial;
    int[] vals = new int[6];
    int YPositive, YNegative, XPositive, XNegative, ZPositive, ZNegative;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    void setup() {
    
      size(500,500);
    
      noLoop();
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
    }
    
    void draw() {
      println(myString);
      textSize(32);
      text(YPositive,50,50);
      text(YNegative,50,100);  
      text(XPositive,50,150);
      text(XNegative,50,200);  
      text(ZPositive,50,250);
      text(ZNegative,50,300);  
    
    }
    
    void serialEvent(final Serial s) {
      final int[] vals = int(splitTokens(s.readString()));
    
      YPositive = vals[0];
      YNegative = vals[1];
      XPositive = vals[2];
      XNegative = vals[3];
      ZPositive = vals[4];
      ZNegative = vals[5];
    
      redraw = true;
    }
    
  • Does this code works or do you still have an error? it seems fine to me. My preference is to check the vals in line 31 to see if it contains 6 entries, otherwise you will have an error trying to access, for example, a null array.

    Kf

  • Still getting a error message

    "Error, disabling serialevent() for com3 Null"

    I know on the arduino side its sending the the data, because i check the serial there and its sending it fine.

  • Try this:

    Kf

    void serialEvent(final Serial s) {
      String str=s.readString();
    
      if(str==null) 
        return;
    
      final int[] vals = int(splitTokens(str));
    
      YPositive = vals[0];
      YNegative = vals[1];
      XPositive = vals[2];
      XNegative = vals[3];
      ZPositive = vals[4];
      ZNegative = vals[5];
    
      redraw = true;
    }
    
  • edited April 2017

    Some notes: :-B

    1. You can delete line #2. B/c vals[] is only being used inside serialEvent().
    2. Delete lines #6 & #19. B/c myString is neither initialized nor used, and it is simply null.
    • Theoretically, my serialEvent() should simply work.
    • But if somehow there's some error transmission, and 1 or more variables fail to get received, vals[] won't have its length = 6.
    • Then, it's indeed a good precaution idea to check out whether we've actually got 6 received values:

    void serialEvent(final Serial s) {
      final int[] vals = int(splitTokens(s.readString()));
      if (vals.length < 6)  return; // drop the whole thing if it's less than 6 values
    
      YPositive = vals[0];
      YNegative = vals[1];
      XPositive = vals[2];
      XNegative = vals[3];
      ZPositive = vals[4];
      ZNegative = vals[5];
    
      redraw = true;
    }
    
  • @GoToLoop. its working now but the problem now is that depending when you start the processing. it will show the data as 0s then overlay the actually number on top of the 0.

  • edited April 2017

    Oh, you've forgotten to invoke background() or clear() as draw()'s 1st statement: L-)

    1. https://processing.org/reference/background_.html
    2. https://processing.org/reference/clear_.html

    void draw() {
      clear();
    
      text(YPositive, 50, 50);
      // and so on...
    }
    

    Another detail: Move your textSize() to setup(). No need to repeat it over & over within draw()! =P~

  • Brilliant that solved it. Thanks for the help guys, that should be me good!

Sign In or Register to comment.