Hi,
I like to control two servos via processing and arduino. There should be different ways to control the servos:
- with sliders
- with textboxes, where I can set the angle and speed or something like that.
Well.. my code works but I don't know if i'm doing it right.
My processing code is something like that:
import controlP5.*;
import processing.serial.*;
ControlP5 cp5;
Serial serial;
Textfield freq1_x, wiederholung1_x, winkel1_x, freq1_y, wiederholung1_y, winkel1_y;
Button X, Y;
Slider slider_x, slider_y;
int delay;
String winkel_y, freq_y, wieder_y;
void setup() {
// Draw the GUI window
size(670,680);
cp5 = new ControlP5(this);
smooth();
int serialPortNumber = 1;
// =======================================================
println(Serial.list());
String port = Serial.list()[serialPortNumber];
serial = new Serial(this, port, 9600);
// =======================================================
// CONTROLLER SETUP
// =======================================================
// SLIDER
slider_x = cp5.addSlider("servo_x")
.setNumberOfTickMarks(15)
.snapToTickMarks(false)
.setPosition(30,630)
.setSize(550,30)
.setRange(800,2200)
.setValue(1500)
;
slider_y = cp5.addSlider("servo_y")
.setNumberOfTickMarks(15)
.snapToTickMarks(false)
.setPosition(600,20)
.setSize(30,550)
.setRange(800,2200)
.setValue(1500)
;
//BUTTONS
nur_x = cp5.addButton("X")
.setPosition(350,20)
.setSize(150,40)
.setValue(0)
;
nur_y = cp5.addButton("Y")
.setPosition(350,90)
.setSize(150,40)
.setValue(0)
;
// TEXTBOXEN
winkel1_x = cp5.addTextfield("winkel_x")
.setPosition(220,20)
.setSize(100,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0")
;
wiederholung1_x = cp5.addTextfield("wiederholungen_x")
.setPosition(100,20)
.setSize(100,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0");
;
freq1_x = cp5.addTextfield("frequenz_x")
.setPosition(20,20)
.setSize(50,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0");
;
winkel1_y = cp5.addTextfield("winkel_y")
.setPosition(220,90)
.setSize(100,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0")
;
wiederholung1_y = cp5.addTextfield("wiederholungen_y")
.setPosition(100,90)
.setSize(100,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0");
;
freq1_y = cp5.addTextfield("frequenz_y")
.setPosition(20,90)
.setSize(50,40)
.setFont(createFont("arial",20))
.setFocus(true)
.setColor(color(255,0,0))
.setText("0");
;
}
void draw() {
background(0,0,0);
}
void controlEvent(ControlEvent theEvent) {
if(millis() > delay){
delay = millis()+100;
if(theEvent.isController() == true){
print("control event from : "+theEvent.getController().getName());
}
if (theEvent.name() == "Y"){
String freq_y = cp5.get(Textfield.class,"frequenz_y").getText();
String wieder_y = cp5.get(Textfield.class,"wiederholungen_y").getText();
String winkel_y = cp5.get(Textfield.class,"winkel_y").getText();
print("4"+freq_y+wieder_y+winkel_y+"*");
serial.write("4"+freq_y+wieder_y+winkel_y+"*");
}
if (theEvent.name() == "X"){
String freq_x = cp5.get(Textfield.class,"frequenz_x").getText();
String wieder_x = cp5.get(Textfield.class,"wiederholungen_x").getText();
String winkel_x = cp5.get(Textfield.class,"winkel_x").getText();
print("3"+freq_x+wieder_x+winkel_x+"*");
serial.write("3"+freq_x+wieder_x+winkel_x+"*");
}
if(theEvent.name() == "servo_x"){
int servo_x_value = round(cp5.get(Slider.class,"servo_x").getValue());
serial.write("1"+servo_x_value+"*");
print("1"+servo_x_value+"*");
}
if(theEvent.name() == "servo_y"){
int servo_y_value = round(cp5.get(Slider.class,"servo_y").getValue());
serial.write("2"+servo_y_value+"*");
print("2"+servo_y_value+"*");
}
if (nur_x.isPressed() == true){
int servo_x_value = round(cp5.get(Slider.class,"servo_x").getValue());
serial.write("1"+servo_x_value+"*");
print("1"+servo_x_value+"*");
}
}
}
Every mode gets a different "id" at the beginning from serial.write().
My arduino code:
void setup() {
// Open serial connection, 9600 baud
Serial.begin(9600);
servo_x.attach(9);
servo_y.attach(11);
servo_x.writeMicroseconds(reset_x);
servo_y.writeMicroseconds(reset_y);
}
void loop()
{
if(stringComplete)
{
input = inputString.substring(0,1).toInt();
switch(input)
{
case 1: // X SLIDER
temp = inputString.substring(1,5);
temp2 = temp.toInt();
stringComplete = false;
inputString = "";
servo_x.write(temp2);
break;
case 2: // Y SLIDER
temp = inputString.substring(1,5);
temp2 = temp.toInt();
stringComplete = false;
inputString = "";
servo_y.writeMicroseconds(temp2);
break;
case 3: // X
hz = inputString.substring(1,3);
wieder = inputString.substring(3,6);
winkel = inputString.substring(6,10);
stringComplete = false;
inputString = "";
frequenz_x(hz,wieder,winkel);
break;
case 4: // Y
hz = inputString.substring(1,3);
wieder = inputString.substring(3,6);
winkel = inputString.substring(6,10);
stringComplete = false;
inputString = "";
frequenz(hz,wieder,winkel);
break;
}
}
}
Like i'm said: The code works and the servos do what they should. But there are some errors:
- In processing I get a NullPointerException. There is something wrong with the textboxes, but i just don't know what.
- When I start the processing sketch it seems it sends something over serial to the arduino because my servos doing some crazy stuff in the beginning.
- My servos are kind of "noisy". Like they get a command via serial and don't know what to do.
How would you implement this stuff?
best regards!