How do I split an incoming 6 value string into separate variables?

edited May 2017 in Arduino

Hey there, This is my first Processing project. So far it's going well, but I'm stuck with the string splitting bit.

OK, so ive programmed the arduino, and its connected to sensors giving correct values in the serial window (arduinoIDE)

but when Processing grabs the string and splits it, all I'm getting is zeros. Just zeros. nothing but zeros.

the graphic window appears to work correctly given the crappy data its getting.

The program is a live feed connected to an EFI engine for keeping an eye on extra sensors whilst on the Dynamometer. Anyway, if I could get some help that would be great!

`import grafica.*;
import processing.serial.*;
import processing.serial.Serial;

GPointsArray myArray = new GPointsArray(0);
Serial myPort;                                                   // The serial port
//float inByte = 0;                                              // defines starting value for the serial input(doesnt seem to be needed)
int count;
int[] sensors;                                                   // declare 'sensors' as an array (just incase I need it)
// int value;
int xPos = 20;                                                   // horizontal position of the graph
int yPos = 300;                                                  // current vertical position of the graph
int sensorNum;
int lastxPos = xPos;                                             // previous horizontal position of the graph
int lastyPos0= 0;                                                // last vertical position of the 1st graph and.......
int lastyPos1= 0;     
int lastyPos2= 0;   
int lastyPos3= 0;   
int lastyPos4= 0;    
int lastyPos5= 0;                                                // ........last vertical position of the 6th graph
String startvals = "'0','0','0','0','0','0'";
int vals[]; 

void setup () {
  size(1024, 300);                                               // set the window size
  println(Serial.list ());                                       // List all the available serial ports
  myPort = new Serial(this, Serial.list()[1], 9600);             //open  second COMport on PC
  myPort.bufferUntil(000);                                       // don't generate a serialEvent() unless you get a 000 (which im not convinced will work)
  background(0);                                                 // set inital background:
//  vals = new int[6];
//  println(vals);
//  String[] vals = (splitTokens(startvals));
                 }
void draw () {
  // draw the line:
  println(vals[0]);                                              // (debug)  visually check the first sensor value
  stroke(300,205, 0);
  line (lastxPos, lastyPos0, xPos,250- vals[0]);                 // draw for sensor one and...
  stroke(30,205, 0);
  line (lastxPos, lastyPos1, xPos,250- vals[1]);
  stroke(300,205, 60);
  line (lastxPos, lastyPos2, xPos,250- vals[2]);
  stroke(300,05, 200);
  line (lastxPos, lastyPos3, xPos,250- vals[3]);
  stroke(300,205, 30);
  line (lastxPos, lastyPos4, xPos,250- vals[4]);
  stroke(300,205, 300);
  line (lastxPos, lastyPos5, xPos,250- vals[5]);                 // .......draw for sensor 6

  lastxPos = xPos;                                               // 
  lastyPos0 = vals[0];   
  lastyPos1 = vals[1];
  lastyPos2 = vals[2];
  lastyPos3 = vals[3];
  lastyPos4 = vals[4];
  lastyPos5 = vals[5];

  if (xPos >= width) {                                           // at the edge of the screen, go back to the beginning:
    xPos = 0;                                                    // reset to start of window 
    lastxPos = 0;                                                // reset to start of window
    background(50);          
  } else {     
    xPos =xPos + 20;                                             // increment the horizontal position:
          }
}


void serialEvent(Serial s) {                                    //*******************************************************
 vals = int(splitTokens(s.readString()));                //***  Divide incoming string to seperate variables   ***
// startvals = splitTokens(",");                             //*** These two lines are previous attempts that      ***
// vals[] = splitTokens(s, ", ");                             //*** didn't seem to work.                            ***
                                                                          //***   ***   ***  ***   ***   ***   ***   ***   ***  ***
  lastyPos0 = (vals[0]);                                        //***    This cant be right, surely                   ***
  lastyPos1 = (vals[1]);                                        //***                                                 ***
  lastyPos2 = (vals[2]);                                        //***  THIS is where I am lost! I am certain this is  ***
  lastyPos3 = (vals[3]);                                        //***  NOT how to do this but I cant find another way ***
  lastyPos4 = (vals[4]);                                        //***  online to do it.                               ***
  lastyPos5 = (vals[5]);                                        //*******************************************************

  redraw = true;
}`

Answers

  • Can you post your ino code?

    Kf

  • edited May 2017

    Sure!

        const uint8_t turboSpdPin = 5; //TurboSpeed Input Digital Pin
        const uint8_t map1Pin = A0; // Map Sensor 1 Input Analog pin
        const uint8_t map2Pin = A1; // Map Sensor 2 Input Analog pin
        const uint32_t oneSecond = 1000000; //Meassured time
        uint32_t timer = 0;
        uint32_t sts = 0;
        const uint32_t c = 1; // wait for 3000 pulses
        uint32_t ets = 0;
        int turboSpdPinState = LOW;
        int turboSpd = 0;
        int prevturboSpdPinState = LOW;
        int map1inputValue = 0;  //set sensor value to 0 
        int map2inputValue = 0;  //set sensor value to 0
        int aux1Value = 0; // set start value to 0
        int aux2Value = 0; // set start value to 0
        int Digitalaux1Value = 0;
        const int Aux1 = A2; //Define Aux Input Pin number as Analog 2
        const int Aux2 = A3; //Define Aux Input Pin number as Analog 3
        const int extPwr = 5;
        const int turbineActivity = 6;
        const int map1connected = 7;
        const int map2connected = 8;
        const int pwrOn = 9;
    
    
    
        void setup()
        {
         Serial.begin(9600);
         pinMode(turboSpdPin, INPUT); //Declared Digital Pin 5 as Input
         digitalWrite(turboSpdPin,LOW); 
         pinMode(10,INPUT);
        }
         void loop() {
    
          map1inputValue = analogRead(map1Pin);   //read map sensor input
          map2inputValue = analogRead(map2Pin);   //     " "
          aux1Value = analogRead(Aux1);
          aux2Value = analogRead(Aux2);
          Digitalaux1Value = digitalRead (10);
          pulseIn(turboSpdPin,HIGH);
          sts = micros(); // start time stamp
           for (uint32_t i=c; i>0; i--)
            pulseIn(turboSpdPin,LOW);
    
         ets = micros(); // end time stamp
         //Serial.print("$");
         Serial.print((c*1e6/(ets-sts))); // output Hz
         Serial.print(",");
         Serial.print(map1inputValue);
         Serial.print(",");
         Serial.print(map2inputValue);
         Serial.print(",");
         Serial.print(aux1Value);
         Serial.print(",");
         Serial.print(aux2Value);
         Serial.print(",");
         Serial.println(Digitalaux1Value);
    
    
    
        }
    
  • the data stream is for example: 100,45,43,67,102,10

  • In your processing code, change this myPort.bufferUntil(000); to myPort.bufferUntil('\n'); and see if this does the trick.

    Also check the link provided by GoToLoop as that code is very simple and shows one way to interact with Arduino units.

    Kf

  • edited May 2017

    I had a look at GoToLoop's link and it seems to be where some of my code originally came from.

    Changing that line to what you suggested, give an 'Invalid character constant' error Edit: I used forward slash, stupid, stupid, stupid.

    I now have a NullPointerException on the second line of the DRAW function

  • Yes, because you commented out line 30 in your setup. You need to initialize your array: vals=new int[6];

    Kf

  • ok, fixed line 30.

    still just zeros

  • Notice when you use redraw in serial event, you need to use noLoop() in setup. This is how it works. redraw/noLoop works together. NoLoop() in setup forces draw() to be drawn only once and thenthe program keeps running but the draw instructions (which updates the display) are not executed. When you get data in your serial event, you have to make sure you have valid data. Then, after you process the valid data, you execute redraw(); which executes the draw() function only once.

    So every time you get your data in the serialEvent() function, it will trigger the drawing instructions in draw. More information in https://processing.org/reference/redraw_.html and https://processing.org/reference/noLoop_.html

    You need to make sure you have good data in serial event. For example, check below.

    If you have more problems, please post your latest code.

    Kf

    void serialEvent(Serial s) {                                    //*******************************************************
     vals = int(splitTokens(s.readString()));                //***  Divide incoming string to seperate variables   ***
    // startvals = splitTokens(",");                             //*** These two lines are previous attempts that      ***
    // vals[] = splitTokens(s, ", ");                             //*** didn't seem to work.                            ***
    
    
    //ONLY process data if you got 6 elements:  
    If(vals.length ==6){
                                                                              //***   ***   ***  ***   ***   ***   ***   ***   ***  ***
      lastyPos0 = (vals[0]);                                        //***    This cant be right, surely                   ***
      lastyPos1 = (vals[1]);                                        //***                                                 ***
      lastyPos2 = (vals[2]);                                        //***  THIS is where I am lost! I am certain this is  ***
      lastyPos3 = (vals[3]);                                        //***  NOT how to do this but I cant find another way ***
      lastyPos4 = (vals[4]);                                        //***  online to do it.                               ***
      lastyPos5 = (vals[5]);   
    
      redraw = true;            
                                        //*******************************************************
    
    }
    
    
    }
    
Sign In or Register to comment.