Arduino and Processing Not communicating?

Hi I have some processing code that basically moves a slider and sends the info to the ardunio so it outputs that to a servo. The arudino code test's the processing code BEFORE sending it out to the servo to ensure that its free from errors.

I know I don't really need to do this and there are libraries for this like firmatta, but I don't want to use those.

The issue is when I upload my arduino code to the board, then close the arduino IDE and start up the processing IDE and run that code, when I move the slider on the processing window, it does not move my servo? I am using a velros sg90 servo and I connect it to pin 3 on my arduino UNO.

Arduino code:

int servo1Pin = 3;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(servo1Pin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:


}

void serialEvent()
{
  //This function is called whenever a serial message (from Processing) is received.
  if (Serial.available() > 0)
  {
    String message = Serial.readString();
    String command = getValue(message, '_', 0);
    int value = getValue(message, '_', 1).toInt();
    if (command.equals("Servo1"))
    {
      setServo(servo1Pin, value);
    }
    else if (command.equals("anotherCommand"))
    {
      //do something
    }
    else
    {
      //It's not any programmed message! Must be a mistake
      Serial.println("ERROR: invalid message");
    }

  }
}

String getValue(String data, char separator, int index)
{
  //Split a String with a separator character and retrieve the substring at location index
  // getValue("test:message", ':', 0) would retrieve "test", getValue("test:message", ':', 1) would retrieve "message"
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void setServo(int pin, int value)
{
  //write a value to a pin

  if (value > 0 && value < 256)
  {
    analogWrite(pin, value);

    //Assuming it takes 25 ms for the servo to reach its destination (this might not be necessary for every application)
    delay(25);
    Serial.println("SUCCESS: servo moved");
  }
  else
  {
    Serial.println("ERROR: invalid servo position");
  }
}

Processing Code:

import processing.serial.*;          //imports serail library
import controlP5.*;                  //Part of processing library

    Slider Servo1;
    Serial serial;
    ControlP5 cp5;
    void setup() 
    {
      size(950, 900);

     println(Serial.list());
      String port = Serial.list()[0];          
      serial = new Serial(this, port, 9600);    //sets COMM Port Baud Rate
      cp5 = new ControlP5(this);                                //dynamic variable of control class


     Servo1 = cp5.addSlider(".").setRange(0,180).setValue(90).setPosition(110,134).setSize(270,25).setNumberOfTickMarks(270).setLabelVisible(true)
     .setColorForeground(color(102,102,102)).setColorBackground(color(255,153,0)).setColorActive(color(102,102,102));
    }

 void draw() 
{
 //will fill alter

  background(color(51,102,153));                        //background of GUI color in RGB format
  println("Servo1" + int(Servo1.getValue()));
}

Servos do not work with analogWrite. You could use the Servo library and Servo.write. Robin2's serial input basics is a better way to do serial. Non blocking and uses charcter arrays instead of Strings.

Assuming it takes 25 ms for the servo to reach its destination

Most hobby servos take about 200ms to go 60 degrees. Check the data sheet for your servo.

I cannot use the Servoobject.write() function becasue write only takes 1 int value, when I need two values, 1 for pin and one for the value being sent?

Is there some work around to this? You can edit my code if you like.

I cannot use the Servoobject.write() function becasue write only takes 1 int value, when I need two values, 1 for pin and one for the value being sent?

Nonsense. Don't send the pin number. Send the servo number. Move the nth Servo object (you DO have an array, right?) the required amount.

So I could do something like servoObject.write(pin) ?

And what do you mean by the requirement amount, I am just sending the slider value from processing which are integers to the arduino?

Also do you think my processing code is ok as in I just need to work on the arduino code, for the servo to receive the data from processing?

So I could do something like servoObject.write(pin) ?

No. RTFM. The servo object KNOWS what pin it is connected to. What it needs to know is the angle you want it to go to.

Also do you think my processing code is ok

If the slider position is 27, the Processing code is sending "Servo127Servo127Servo127". No, I don't think that that is good.

for the servo to receive the data from processing?

Do you REALLY think that the servo can receive data from Processing?

Paul I changed the write function to servoObject.write(value), however your second point about if the slider is at 23 it would send servo123, but if you notice I have a function called getValue that takes 3 parameters and breaks up the string coming from processing after the '_', but again this still wont move the servo??

You are right btw processing did send this and the servo still wont move, so maybe that getValue function needs to be re-done? What do you think I should do?

I edited my void draw in processing too but it still wont work??:

void draw() 
{
 //will fill alter

  background(color(51,102,153));                        //background of GUI color in RGB format
  serial.write("Servo1_" + str(Servo1.getValue()));
  
}

but if you notice I have a function called getValue that takes 3 parameters and breaks up the string coming from processing after the '_', but again this still wont move the servo??

The servo won't move because servos are STILL not moved using analogWrite(). Get over it. Write the proper code to move the servo. Here'sa hint. There's a Servo library. Use it.

Or, hit the bricks.

Can you correct my code? Cause I am taking your advice about the analog write, but I still don't see where I am using analog write?

kloud:
Can you correct my code? Cause I am taking your advice about the analog write, but I still don't see where I am using analog write?

void setServo(int pin, int value)
{
//write a value to a pin

if (value > 0 && value < 256)
{
analogWrite(pin, value);

Paul I already changed that function from analogwrite to servoObject.write(value), where value is the angle of the servo. I also changed the 25ms to 500ms and its still won't work?

My procesing code is sending/writing strings to arduino pins if the slider moves, and there is a function that splits the string up due to the separator '_' so processing would send Servo1_27 and that getValue function gets the 27 and cast it to an integer to put into the setServo function.

I am grateful though that I got this far.
I have no idea what to do next even, though I took your advice, I am still stuck?

I am still stuck?

Are you?

If you are, post your current code, and explain your observations.

With Firmata out of the picture, you can focus on the Arduino side, by sending data to the Arduino from the Serial Monitor app. That lets you see the responses. You can do the same from Processing, but it's a little more work.

I observe that both arduino and processing code compile without warning, and in processing when I move the slider on the processing window, and lets say I move the slider to 27, processing would send Servo1_27. Here is code

Processing code:

import processing.serial.*;          //imports serail library
import controlP5.*;                  //Part of processing library

    Slider Servo1;
    Serial serial;
    ControlP5 cp5;
    void setup()
    {
      size(950, 900);

     println(Serial.list());
      String port = Serial.list()[0];         
      serial = new Serial(this, port, 9600);    //sets COMM Port Baud Rate
      cp5 = new ControlP5(this);                                //dynamic variable of control class


     Servo1 = cp5.addSlider(".").setRange(0,180).setValue(90).setPosition(110,134).setSize(270,25).setNumberOfTickMarks(270).setLabelVisible(true)
     .setColorForeground(color(102,102,102)).setColorBackground(color(255,153,0)).setColorActive(color(102,102,102));
    }

 void draw()
{
 //will fill alter

  background(color(51,102,153));                        //background of GUI color in RGB format
  serial.write("Servo1_" + str(Servo1.getValue()));
 
}

Arduino Code:

#include <Servo.h>

Servo myservo;
int servo1Pin = 3;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 
 //pinMode(servo1Pin, OUTPUT);

myservo.attach(servo1Pin );
}

void loop() {
 // put your main code here, to run repeatedly:


}

void serialEvent()
{
 //This function is called whenever a serial message (from Processing) is received.
 if (Serial.available() > 0)
 {
   String message = Serial.readString();
   String command = getValue(message, '_', 0);
   int value = getValue(message, '_', 1).toInt();
   if (command.equals("Servo1"))
   {
     setServo(servo1Pin, value);
   }
   else if (command.equals("anotherCommand"))
   {
     //do something
   }
   else
   {
     //It's not any programmed message! Must be a mistake
     Serial.println("ERROR: invalid message");
   }

 }
}

String getValue(String data, char separator, int index)
{
 //Split a String with a separator character and retrieve the substring at location index
 // getValue("test:message", ':', 0) would retrieve "test", getValue("test:message", ':', 1) would retrieve "message"
 int found = 0;
 int strIndex[] = { 0, -1 };
 int maxIndex = data.length() - 1;

 for (int i = 0; i <= maxIndex && found <= index; i++) {
   if (data.charAt(i) == separator || i == maxIndex) {
     found++;
     strIndex[0] = strIndex[1] + 1;
     strIndex[1] = (i == maxIndex) ? i + 1 : i;
   }
 }
 return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void setServo(int pin, int value)
{
 //write a value to a pin

 if (value > 0 && value < 256)
 {
   myservo.write(value);

   //Assuming it takes 25 ms for the servo to reach its destination (this might not be necessary for every application)
   delay(500);
   Serial.println("SUCCESS: servo moved");
 }
 else
 {
   Serial.println("ERROR: invalid servo position");
 }
}

Don't know if you could test my code out, if thats possible to see what I mean?

Don't know if you could test my code out, if thats possible to see what I mean?

You test it. Close Processing. Open the serial monitor. In the input field, type Servo1_27. Observe what the Arduino does. Does the RX light blink?

Add Serial.print() statements in the serialEvent() function. Does it ever get called?

What is the value of message? What is the value of command? What is the value of value?

What is the point of passing a pin number to setServo() when you never use it?

PaulS:
You test it. Close Processing. Open the serial monitor. In the input field, type Servo1_27. Observe what the Arduino does. Does the RX light blink?

Yes it does

PaulS:
Add Serial.print() statements in the serialEvent() function. Does it ever get called?

Yes see the answers to your next questions

PaulS:
What is the value of message? What is the value of command? What is the value of value?

Ok when I put Servo1_27 in serial monitor, first the function setServo is called and that returns, Success Servo moved.

I then did a serial println for value which prints 27.
Next was serial println for command an that outputted Servo1
Finally I did it again for message which outputted Servo1_27

Please see my link for proof
http://imgur.com/a/M8KRi

PaulS:
What is the point of passing a pin number to setServo() when you never use it?

I made changes to the setServo() an took it off like you just said since I have no use for it.

Now even after all this, when I upload arduino code to UNO, an close IDE, then start processing IDE an run that code, servo DOES NOT move??? I even put println statements in processing to see what I am sending an its sending what its suppose to. The Servo1_ and the value the slider is at.

I am out of ideas? fyi the servo is not faulty since it moves when I put in Servo1_27 in serial moniter. Maybe take a look at my processing code cause I dont know what else to do.

I got it to work. In my processing code, I initially put serial.write("Servo1_" + str(ServoValue)) in draw(). This basically was overflowing the serial connection because the function draw() runs at 60fps, so what I did was I created an public void controlEvent(ControlEvent theEvent) function that basically wrote to the serial port once an event, such as a slider being moved or a button being pressed occurred.

And it works.

But this leaves the question, Paul if I had multiple sliders connected to multiple servos, is this method really an efficient way of doing things, without using firmatta? If there is a better way can you post it with some code?

You can make more than one servo objects ya know.

I know but how would I make sure the data sent to the arduino gets sent to the correct pin, without making like 4 or 5 different functions, one for each servo object? You can make an example with my code if you want.

You can make an example with my code if you want.

Well, if you posted your code, we could...

Servo LotsOfServos[4];
int servoPins[] = { 4, 5, 6, 7 };

void setup()
{
   for(byte b=0; b<4; b++)
   {
      LotsOfServos[b].attach(servoPins[b]);
   }
}

void loop()
{
   int num = -1;
   int pos = -1;

   if(Serial.available() > 0)
   {
      GetSerialData(num, pos);
   }

   if(num >= 0)
   {
      LotsOfServos[num].write(pos);
   }
}

void GetSerialData(int &num, int &pos)
{
   // read the serial data like <num, pos>
   // and assign values to num and pos
}

See this: Serial Input Basics - updated - Introductory Tutorials - Arduino Forum

Make sure you, or Processing, sends data the way you need to read it.

PaulS:
Well, if you posted your code, we could...

My arduino code is the same since the last time I posted it, its just the processing code that changed, which isn't what I am talking about here. It's my arduino code.

PaulS:
Make sure you, or Processing, sends data the way you need to read it.

Yep thanks to you about asking me all those questions a few posts back I debug the arduino and processing code to confirm this.

Also thank you for that piece of code, I will try it out and get back to you.