I'm trying to controll 2 servos with my iPhone/iPad with TouchOSC. One servo works perfect but two... thats the problem.
Here is my setup:
iPhone > TouchOSC (2 faders) > Processing > Arduino (with io shield) > servoA and servoB
Arduino Code:
#include <Servo.h>
Servo myservo;
Servo myservo2;// create servo object to control a servo
int val = 0;
//int message = 0;
int redLED = 0;
void setup() {
Serial.begin(9600); //set serial to 9600 baud rate
myservo.attach(8);
myservo2.attach(9);
}
void loop(){
if (Serial.available() > 0) { // Check if there is a new message
val = Serial.read(); // Put the serial input into the message
//val = message;
myservo.write(val); // sets the servo position according to the scaled value
delay(15);
myservo2.write(val); // sets the servo position according to the scaled value
delay(15);
}
}
Processing Code:
import oscP5.*; // Load OSC P5 library
import netP5.*; // Load net P5 library
import processing.serial.*; // Load serial library
Serial arduinoPort; // Set arduinoPort as serial connection
OscP5 oscP5; // Set oscP5 as OSC connection
// arduino //
int redLED = 0;
int redLEDB = 0;
int [] led = new int [2];
int currentPos = 0;
int desiredPos = 0;
int currentPosB = 0;
int desiredPosB = 0;
void setup() {
size(200,200);
noStroke();
oscP5 = new OscP5(this,8000); // Start oscP5, listening for incoming messages at port 8000
arduinoPort = new Serial(this, Serial.list()[0], 9600); // Set arduino to 9600 baud
}
void oscEvent(OscMessage theOscMessage) {
String addr = theOscMessage.addrPattern();
if(addr.indexOf("/1/servo") != -1) {
desiredPos = int(theOscMessage.get(0).floatValue());
}
if(addr.indexOf("/2/servo2") != -1) {
desiredPosB = int(theOscMessage.get(0).floatValue());
}
}
void draw() {
background(50);
if(currentPos != desiredPos) {
String pos = str(desiredPos);
println("Servo_A " + pos);
arduinoPort.write(desiredPos);
currentPos = desiredPos;
}
if(currentPosB != desiredPosB) {
String pos = str(desiredPosB);
println("Servo_B " + pos);
arduinoPort.write(desiredPosB);
currentPosB = desiredPosB;
}
redLED = int(map(desiredPos, 0, 180, 0, 255));
fill(redLED,0,0);
ellipse(50,50,50,50);
redLEDB = int(map(desiredPosB, 0, 180, 0, 255));
fill(redLEDB,0,0);
ellipse(120,50,50,50);
}
Both servos are moving if I change the sliders on the iPhone.
Both servos are moving if I change the sliders on the iPhone.
Why does that surprise you?
val = Serial.read(); // Put the serial input into the message
//val = message;
myservo.write(val); // sets the servo position according to the scaled value
delay(15);
myservo2.write(val); // sets the servo position according to the scaled value
delay(15);
You are telling both servos to go to the same position.
Looks to me like you want to read a value, send one servo to that position, read another value and send the other servo to that position.
Thanks, I get the point to define an extra value but don't know how to write it down in the script (sorry i'm a newbie)
Make the highlighted changes:
if (Serial.available() > 1)
{ // Check if there are 2 new messages
val = Serial.read(); // Put the serial input into the message
myservo.write(val); // sets the servo position according to the scaled value
delay(15);
val = Serial.read(); // Put the serial input into the message
myservo2.write(val); // sets the servo position according to the scaled value
delay(15);
}
Thanks I changed the code, still both servo's move on both sliders in TouchOSC. Is there a way to 'link' the right incoming message to the right output? I guess something goes wrong in the processing code...
I guess something goes wrong in the processing code...
Only you can see the debug output from Processing. So, if you have to guess that there is something wrong, then we have no way to argue with you.
You need to send an identifier for each value, so that the Arduino knows which servo to move.
Looking at the Processing code, I don't see the need. There is an OSC event when you move a slider. In the event handler, either desiredPos or desiredPosB (desiredPos should be desiredPosA) is given a new value. Nothing is sent to the Arduino, though.
In the draw() method, desiredPos and desiredPosB are compared to the old positions, and only the changed values are sent. So, yes, you are right. There may only be one value sent per iteration of loop.
There needs to be two values sent - which servo should move and where it should move to.
Both draws are writing to the same arduinoPort (arduinoPort.write(desiredPosB); ) is that what you mean? How do I create a unique id for each port (still learning...)
Then, change the Arduino code:
if (Serial.available() > 1)
{ // Check if there are 2 new messages
char srv = Serial.read(); // Read which servo
val = Serial.read(); // Read the position
if(srv == 'A')
myservo.write(val); // sets the servo position according to the scaled value
else if (srv == 'B')
myservo2.write(val); // sets the servo position according to the scaled value
delay(15);
}