I’m trying to write Processing code that uses ControlP5 to create an GUI that have sliders that send values to Arduino code to control many servos. If I have four sliders called Hand, Wrist, Elbow, and Shoulder in Processing code and four servos called servo01, servo02, servo03, and servo04 in Arduino code, moving the hand slider should cause servo01 to move, wrist slider should cause servo02 to move, etc. The problem is that serial.write can’t send data to correct servo.
import processing.serial.*;
import controlP5.*;
Serial myPort;
ControlP5 cp5;
ControlGroup messageBox;
String data = "0";
String string01;
void setup()
{
size(1200,800);
myPort = new Serial(this, "COM9", 9600);
myPort.bufferUntil('\n');
cp5 = new ControlP5(this);
createMessageBox();
}
void draw()
{
background(0);
}
void createMessageBox()
{
PFont myFont = createFont("Arial",16,true);
Slider slider01 = cp5.addSlider("slider01val");
slider01.setLabel("Left Hand");
slider01.setSize(360,30);
slider01.setPosition(50,50);
slider01.setRange(0,180);
slider01.setColorForeground(color(0,113,220));
slider01.setColorBackground(color(255,255,255));
slider01.setValue(0);
slider01.setFont(myFont);
Slider slider02 = cp5.addSlider("slider02val");
slider02.setLabel("Right Hand");
slider02.setSize(360,30);
slider02.setPosition(600,50);
slider02.setRange(0,180);
slider02.setColorForeground(color(0,113,220));
slider02.setColorBackground(color(255,255,255));
slider02.setValue(0);
slider02.setFont(myFont);
}
void controlEvent(ControlEvent theEvent)
{
if(theEvent.getController().getName().equals("slider01val"))
{
int val01 = int(theEvent.getController().getValue());
println("slider01 value is ",val01);
println(3);
//myPort.write(val);
}
if(theEvent.getController().getName().equals("slider02val"))
{
int val02 = int(theEvent.getController().getValue());
println("slider02 value is ",val02);
//myPort.write(sliderval02);
}
}
`#include <Servo.h>
Servo myServo01;
Servo myServo02;
char myServo01Channel=0, myServo02Channel=1;
char serialChar=0;
int val01 = 0;
int val02 = 0;
void setup()
{
myServo01.attach(3);
myServo02.attach(4);
myServo01.write(0);
myServo02.write(0);
Serial.begin(9600);
}
void loop(){
while(Serial.available() <=0); //Wait for a character on the serial port.
serialChar = Serial.read(); //Copy the character from the serial port to the variable
if(serialChar == myServo01Channel){ //Check to see if the character is the servo ID for the tilt servo
while(Serial.available() <=0); //Wait for the second command byte from the serial port.
myServo01.write(Serial.read()); //Set the tilt servo position to the value of the second command byte received on the serial port
}
else if(serialChar == myServo02Channel){ //Check to see if the initial serial character was the servo ID for the pan servo.
while(Serial.available() <= 0); //Wait for the second command byte from the serial port.
myServo02.write(Serial.read()); //Set the pan servo position to the value of the second command byte received from the serial port.
}
//If the character is not the pan or tilt servo ID, it is ignored.
}````
How can I fix the problems?
One technique that I have used is to send a character along with the value, eg ‘a’ + value might be for hand, ‘b’+value might be for wrist, etc. On the Arduino end check to see which character was sent and then use ‘switch’ to send the value to the correct control. You could probably also use an array if you wanted to send all the values at one time; I’m assuming that you want to send them individually as each slider is manipulated.
The following source code is one possible solution and demonstrates a single servo, which is all that I have to test with. If you use this technique you will have to scale it up to four servos.
Processing Code:
import processing.serial.*;
import controlP5.*;
Serial port;
ControlP5 cp5;
int handValue = 20; // init
int val;
void setup() {
size(600,300);
background(0);
printArray(Serial.list());
port = new Serial(this, Serial.list()[2], 9600);
cp5 = new ControlP5(this);
cp5.addSlider("handValue")
.setPosition(100, 50)
.setSize(200,20)
.setRange(0, 180)
.setId(1);
}
void draw() {
if(port.available() > 0) {
val = port.read();
println("received from Arduino: ", val);
}
}
void controlEvent(ControlEvent theEvent) {
switch(theEvent.getController().getId()) {
case(1): // hand
handValue = (int)(theEvent.getController().getValue());
String handStr = str('h') + str(handValue);
port.write(handStr);
println("transmit hand string = ", handStr);
break;
case(2): // wrist
break;
case(3): // elbow
break;
case(4): // shoulder
break;
}
}
Arduino Code:
#include <Servo.h>
Servo servo1;
int recdValue;
int handVal;
void setup() {
Serial.begin(9600);
servo1.attach(9); // Connected to digital 9 (yellow), 5v (red), gnd (black)
}
void loop() {
if ( Serial.available()) {
int inByte = Serial.read();
switch (inByte) {
case 'h': // hand
recdValue = Serial.parseInt();
handVal = recdValue;
servo1.write(handVal);
break;
case 'w': // wrist
break;
case 'e': // elbow
break;
case 's': // shoulder
break;
}
Serial.write(recdValue); // Send back to Processing for verification
}
}