How to read values over serial

Hi Everyone!
I’ve got a Processing code sending values over serial from 0 to 255 with a letter i wanna use to indicate wich servo has to write() the received value after being mapped to 0-180;
Exampe:
int LposY= getY.LposY().
myPort.write(‘W’+LposY).

At this point Processing sends something like: W128, W231 or for LposX S134, S92
But i really don’t know how to assing every letter to a servo and use the value after in the specified servo.
Any help?

Original Code:

//imports
import processing.serial.*; // for communication via Serial
import procontroll.*; // hacks into the Xbox One Controller feed
import java.io.*; // internal dependency for procontroll


Serial myPort; // for communication with Arduino


ControllIO controll; // abstraction of the Controller object
ControllDevice device; // abstraction of the entire Xbox One Controller
ControllStick Lstick; // the left stick on the Xbox One Controller
ControllStick Rstick; // the right stick on the Xbox One Controller
ControllCoolieHat DPad; // the Dpad
ControllSlider XBOXTrig; // the controller's triggers

float leftTriggerMultiplier, leftTriggerTolerance, leftTriggerTotalValue;
float rightTriggerMultiplier, rightTriggerTolerance, rightTriggerTotalValue;

ControllButton A;
ControllButton B;
ControllButton Y; 
ControllButton X;
ControllButton L1;
ControllButton L2;
ControllButton L3;
ControllButton R1;
ControllButton R2;
ControllButton R3;
ControllButton Select;
ControllButton Start;
ControllButton Up;
ControllButton Down;
ControllButton Left;
ControllButton Right;

void setup() {
  size(255, 255);
  size(255, 255);
  size(255, 255);
  // initiation
  controll = ControllIO.getInstance(this); // used to instantiate the controll object
  device = controll.getDevice("Controller (XBOX One For Windows)"); // ask the controll object for the Xbox One Controller
  
  // can check which serial ports are being used and by what
  println(Serial.list()); 
  
  // print all available sticks, sliders and buttons of the Xbox One Device
  device.printSticks();
  device.printSliders();
  device.printButtons();

  // set average tolerance, to reduce jerks
  device.setTolerance(0.05f);
  
  // initiating the sliders which make up the analog sticks
  ControllSlider LXslider = device.getSlider("x");
  ControllSlider LYslider = device.getSlider("y");
  ControllSlider RXslider = device.getSlider("x");
  ControllSlider RYslider = device.getSlider("y");

  // initating the sticks with the four sliders previously created
  Lstick = new ControllStick(device.getSlider(1), device.getSlider(0));
  Rstick = new ControllStick(device.getSlider(3), device.getSlider(2));

  // Identifying the triggers
  XBOXTrig = device.getSlider(4);
  leftTriggerTolerance = rightTriggerTolerance = XBOXTrig.getTolerance();
  leftTriggerMultiplier = rightTriggerMultiplier = XBOXTrig.getMultiplier();
  
  // initiating the button objects
  Y = device.getButton(3);
  B = device.getButton(1);
  A = device.getButton(0);
  X = device.getButton(2);
  R1 = device.getButton(5);
  R3 = device.getButton(9);
  L1 = device.getButton(4);
  L3 = device.getButton(8);
  DPad = device.getCoolieHat(10);
  DPad.setMultiplier(-1);
  Select = device.getButton(6);
  Start = device.getButton(7);
 
  // initiate the Serial object to connect to the Arduino
  String portName = Serial.list()[0];// Change depending on which Serial Port your Arduino is connected to
  myPort = new Serial(this, portName, 9600);
  
  // Aesthetics
  fill(0); // makes the rectangle black
  rectMode(CENTER); // to ensure that the center of the rectangle represents the position of the stick
}

void draw() {
  background(255); // refresh
  
  // Analyse the input coming from the stick output
  // since the value is beween -1 and 1 scale it up to 128 and ensure it is an integer
  // by a cast. Since negative values are not accepted by servos, and there are 
  // serial communication issues, add 128 to the scaled value to get a 1 byte integer.
  int LposX = 128+int(Lstick.getX()*128);
  int LposY = 128+int(Lstick.getY()*128);
  int RposX = 128+int(Rstick.getX()*128);
  int RposY = 128+int(Rstick.getY()*128);
  int posZ = 128+int(XBOXTrig.getValue()*128);
  
  
  
  // ensure that the rectangle does not leave the bounds of the canvas
  // as well as making sure that the servos don't go out of bounds
  LposX = constrain(LposX, 1, 254);
  LposY = constrain(LposY, 1, 254);
  RposX = constrain(RposX, 1, 254);
  RposY = constrain(RposY, 1, 254);
  posZ = constrain(posZ, 1, 254);
  
 // send the signal if the stick indicates a turn to the left or right
  boolean turn = false; // to ensure that the stop signal is not sent if the car is supposed to turn
  try {
    // Turn Right
    if (LposX >= 150){
      myPort.write("Q"+LposX);
      println("LposX");
      turn = true;
    }
    // Turn Left
    if (LposX <= 127){
      myPort.write("Q"+LposX);
      println("LposX");
      turn = true;
    }
    // Move Forward
    if (LposY <= 150){
      myPort.write("W"+LposY);
      println("LposY");
      turn = true;
    }
    // Move Backward
    if (LposY >= 127){
      myPort.write("W"+LposY);
      println("LposY");
      turn = true;
    }
    // Camera Pan Left
    if (RposX >= 150){
      myPort.write("E"+RposX);
      println("RposX");
      turn = true;
    }
    // Camera Pan Right
    if (RposX <= 127){
      myPort.write("E"+RposX);
      println("RposX");
      turn = true;
    }// Move Forward
    if (posZ <= 150){
      myPort.write("T"+posZ);
      println("posZ");
      turn = true;
    }
    // Move Backward
    if (posZ >= 127){
      myPort.write("T"+posZ);
      println("posZ");
      turn = true;
    }
  } 
  catch(Exception ex) {
    println("Exception has been reached");
  }
  
  // check for the A button to be pressed
  // Move Backward (Brake)
  if (A.pressed()) {
    fill(0, 255, 0); // if pressed change the color of the rectangle to green
    myPort.write("A");
    println("Backward");
  }
  // check for the B button to be pressed
  // Reset Camera Position
  if (B.pressed()){
    fill(255,0,0); // if pressed change the color of the rectangle to red
    myPort.write("S");
    println("Reset Camera");
  }
  // check for the X button to be pressed
  // Reset Steering
  if (X.pressed()){
    fill(0,0,255); // if pressed change the color of the rectangle to blue
    myPort.write("D");
    println("Reset Steering");
  }
  // check for the Y button to be pressed
  // Reset Throttle
  if (Y.pressed()){
    fill(255,255,0); // if pressed change the color of the rectangle to yellow
    myPort.write("F");
    println("Reset throttle");
  }
  // Camera Pan Left
    if (L1.pressed()){
      myPort.write("G");
      println("Pan Left");
      turn = true;
    }
    // Camera Pan Right
    if (R1.pressed()){
      myPort.write("H");
      println("Pan Right");
      turn = true;
    }
    // check for the start button to be pressed
    // Reset Camera Position
    if (Start.pressed()){
    fill(255,0,0); // if pressed change the color of the rectangle to red
    myPort.write("J");
    println("Reset Camera");
  }
  // check for the select button to be pressed
  // Reset Camera Position
  else if (Select.pressed()){
    fill(255,0,0); // if pressed change the color of the rectangle to red
    myPort.write("K");
    println("Reset All");
  }
  // If no signal needs to be sent send the stop signal
  else if(!turn){
    fill(0); // otherwise let the rectangle be black
    myPort.write("L");
  }
  // position the rectangles using the information on the position of the stick on the Xbox One Controller
  rect(LposX, LposY, 20, 20);
  rect(RposX, RposY, 20, 20);
}

Queries about reading input from Serial, splitting it into parts and acting on the value of the parts must be one of the most common questions raised here.

As a start, on the Arduino wait until there is serial data available (Serial.available() then read a byte (Serial.read()) and print it so that you can see what you are getting. The clever stuff about splitting up the input, determining which servo is specified and moving that servo can come later.

Meanwhile, if you browse back a few pages in this section you will find similar questions to yours being asked and answered.

Simple letter + value code is exactly what Nick Gammon addresses with example in this tutorial blog:
http://gammon.com.au/serial

If i manually write (because cannot open serial monitor while running Processing) W128 arduino writes:

i received: 87 i received: 49 i received: 50 i received: 56

http://www.asciitable.com/

Ok, now the link GoForSmoke posted did the trick so thank you but another problem comes out:
in gammon’s code value is a representation for the string incoming but how can i constrain and map if value is not an int?

// Example state machine reading serial input
// Author: Nick Gammon
// Date: 17 December 2011

// the possible states of the state-machine
typedef enum {  NONE, GOT_Q, GOT_R, GOT_W, GOT_E } states;

// current state-machine state
states state = NONE;
// current partial number
unsigned int currentValue;
#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;

void setup ()
{
  Serial.begin (9600);
 
 servo1.attach(3);
 servo2.attach(4);
 servo3.attach(5);

 int value;
 
 value = constrain(value, 0, 255);
 value = map(value, 0, 255, 0, 180);
 
  state = NONE;
}  // end of setup

void processSPD (const unsigned int value)
{
  // do something with RPM 
  Serial.print ("SPD = ");
  Serial.println (value);
  servo1.write(value);
} // end of processRPM

void processTRG (const unsigned int value)
{
  // do something with RPM 
  Serial.print ("TRG = ");
  Serial.println (value);
  servo1.write(value);
}

void processSTR (const unsigned int value)
{
  // do something with speed 
  Serial.print ("STR = ");
  Serial.println (value);
  servo2.write(value);
} // end of processSpeed

void processCAM (const unsigned int value)
{
  // do something with gear 
  Serial.print ("CAM = ");
  Serial.println (value);
  servo3.write(value);  
} // end of processGear

void handlePreviousState ()
{
  switch (state)
  {
  case GOT_Q:
    processSPD (currentValue);
    break;
    case GOT_R:
    processTRG (currentValue);
    break;
  case GOT_W:
    processSTR (currentValue);
    break;
  case GOT_E:
    processCAM (currentValue);
    break;
    // end of switch
  }  

  currentValue = 0; 
}  // end of handlePreviousState

void processIncomingByte (const byte c)
{
  if (isdigit (c))
  {
    currentValue *= 10;
    currentValue += c - '0';
  }  // end of digit
  else 
  {

    // The end of the number signals a state change
    handlePreviousState ();

    // set the new state, if we recognize it
    switch (c)
    {
    case 'Q':
      state = GOT_Q;
      break;
    case 'R':
      state = GOT_R;
      break;
    case 'W':
      state = GOT_W;
      break;
    case 'E':
      state = GOT_E;
      break;
    default:
      state = NONE;
      break;
    }  // end of switch on incoming byte
  } // end of not digit  
  
} // end of processIncomingByte

void loop ()
{
  if (Serial.available ())
    processIncomingByte (Serial.read ());
    

  // do other stuff in loop as required
  
}  // end of loop

Evidently, given that you are expecting the packet: "W128", AWOL is too subtle:

i received: 87 // ASCII value for 'W' is 87 i received: 49 // ASCII value for '1' is 49 i received: 50 // ASCII value for '2' is 50 i received: 56 // ASCII value for 8 is 56

econjack: Evidently, given that you are expecting the packet: "W128", AWOL is too subtle:

It's probably my only failing. 8)

Can atoi be useful in this?

Can atoi be useful in this?

Maybe, but printing char(acters) as char(acters) rather than as "int"s may yield simpler results.

Can atoi be useful in this?

Depends on what you want to do. If the format of the serial data is always a letter (e.g., 'W') followed by up to 3 digits, and you need those digits as a numeric value, then yes, it can be very helpful. Suppose your message came in over the serial link as message[]. which we will assume is a character array. Then the following code fragment might help:

char whichServo = message[0];         // The 'W' in a packet like "W128"
int servoValue = atoi(&message[1]);   // The digits start with element 1, not 0

The whole page of Nick's blog covers the whole subject. The second part is state machine showing exactly what you want and it does not need atoi().

When digits are received, as they arrive an unsigned int is 'moved up' 1 digit then the new digit is added. This is because text numbers arrive high-value to low-value order. 123 is 1x100 + 2x10 + 3. So you read the 2 then x10 and add the 1, then x10 and add the 3 all as they come.

void processIncomingByte (const byte c)
{
  if (isdigit (c))
  {
    currentValue *= 10;
    currentValue += c - '0';
  }  // end of digit
  else 
  {

    // The end of the number signals a state change
    handlePreviousState ();

    // set the new state, if we recognize it
    switch (c)
    {
    case 'R':
      state = GOT_R;
      break;
    case 'S':
      state = GOT_S;
      break;
    case 'G':
      state = GOT_G;
      break;
    default:
      state = NONE;
      break;
    }  // end of switch on incoming byte
  } // end of not digit  
  
}

If all you do is grab the code, you won't learn half of the tutorial there. if you learn it all, this kind of thing will not be a problem again.

So the 3 digits are fine but as i upload values from 0 to 255 servos can't reach because they can make max 180 degrees so i need in the code some thing like:

pos = map(pos, 0, 255, 0, 180);

(i prefer degrees than ms for now but if using ms it's better tell me).

I prefer us over degrees for better precision.

If you map something to degrees and then degrees to servo value not degrees then you set up for 2 round offs.

jitter solved myself taking the baud from 9600 to 115200. servos now are ok. what about changing input between two sliders like the z axis an Left stick's y for a servo by just pressing a button?

You get serial by checking Serial.available().

How would you get a button? That may be trickier than just checking a pin, depending on the button but still the principle is the same.

The important part is to not let doing one thing hold everything else up, which is called blocking code.

Sorry, i didn't tell you but i am working on an fpv so i am using the procontroll library on processing with my xbox one controller... I already have a code made by this guy...yash savani wich was made for only one servo but already supported buttons. Also would be good to have the throttle servo (servo1) writing the farther value from 90° between the Y of the L stick and the Z axis (triggers). What i wanna do is having the control of my rc car like a fpv and at the same time watching the received video on my monitor like playing a game. Better button or magical higher/lower value to control an fpv?