I'm totally new to Arduino and processing so I could really use some advice about what I'm trying to do. I have been trying to use Processing and Arduino IDE to control 2 motors simultaneously from a GUI drawn by processing. So when I click a button in the Processing window I write a 2 byte string to the Serial port and use the first byte to decide which motor to adjust and the second byte for the position of the motor. When I try this the Processing program seems to write the correct 2 byte string. Also, if I run the IDE program on its own and type a 2 byte string into the serial monitor the motors move to the correct position. However, when I run both at the same time the motor ends up not moving correctly even though no errors show up. I'm not sure why this happens and any help would be great. If there's a better way to do this please let me know. I want to add more motors when I get this working.
The Arduino code is here:
#include <Servo.h>
Servo claw_servo; // create servo object to control a servo
Servo wrist_servo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 180; // variable to store the servo position
const int BUFFER_SIZE = 2; // variable for expected serial data packet size
char incomingByte[BUFFER_SIZE]; // for incoming serial data
String choice; // string for selecting motor to move
void setup() {
claw_servo.attach(8); //setting up motor 1
wrist_servo.attach(9); // setting up motor 2
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
Serial.readBytes(incomingByte, BUFFER_SIZE);// read in 2 bytes into the incomingByte variable
choice = incomingByte[0]; //first byte decides motor
//pos = choice;
if (choice == 'a'){
pos = incomingByte[1];
claw_servo.write(pos);//second byte writes motor position to servo
}
else if (choice == 'b'){
pos = incomingByte[1];
wrist_servo.write(pos);//second byte writes motor position to servo
}
//delay(20)
}
}
The Processing code is:
import controlP5.;
import processing.serial.;
Serial port; // The serial port we will be using
ControlP5 cp5; //creat ControlP5 object
PFont font;
boolean press; //left boolean for claw
boolean press2; //right boolean for claw
boolean press3; //left boolean for wrist
boolean press4; //right boolean for wrist
int servo_pos = 150;
void setup(){ //same as arduino program
String portName = (Serial.list()[2]); // List COM-ports
println(portName);
// You will want to change the [1] to select the correct device
// Remember the list starts at [0] for the first option.
port = new Serial(this, portName, 9600);
//port.bufferUntil('\n');
size(500,800); //window size, (width,height)
//add button to empty window
cp5 = new ControlP5(this);
font = createFont("arial", 50);
Button b1 = cp5.addButton("<-") //"<-" is name of button
.setPosition(30, 50) //x and y coordinates
.setSize(100, 80) //(width,height)
.setFont(font)
;
Button b2 = cp5.addButton("->") //"<-" is name of button
.setPosition(170, 50) //x and y coordinates
.setSize(100, 80) //(width,height)
.setFont(font)
;
Button b3 = cp5.addButton("<-'") //"<-" is name of button
.setPosition(30, 150) //x and y coordinates
.setSize(100, 80) //(width,height)
.setFont(font)
;
Button b4 = cp5.addButton("->'") //"<-" is name of button
.setPosition(170, 150) //x and y coordinates
.setSize(100, 80) //(width,height)
.setFont(font)
;
b1.addCallback(new CallbackListener() { //adds functionality to button
public void controlEvent(CallbackEvent theEvent) {
switch(theEvent.getAction()) {
case(ControlP5.ACTION_PRESS): press = true; println(press); break;
case(ControlP5.ACTION_RELEASE): press = false; println(press) ; break;
}
}
}
);
b2.addCallback(new CallbackListener() { //adds functionality to button
public void controlEvent(CallbackEvent theEvent) {
switch(theEvent.getAction()) {
case(ControlP5.ACTION_PRESS): press2 = true ; break;
case(ControlP5.ACTION_RELEASE): press2 = false ; break;
}
}
}
);
b3.addCallback(new CallbackListener() { //adds functionality to button
public void controlEvent(CallbackEvent theEvent) {
switch(theEvent.getAction()) {
case(ControlP5.ACTION_PRESS): press2 = true ; break;
case(ControlP5.ACTION_RELEASE): press2 = false ; break;
}
}
}
);
b4.addCallback(new CallbackListener() { //adds functionality to button
public void controlEvent(CallbackEvent theEvent) {
switch(theEvent.getAction()) {
case(ControlP5.ACTION_PRESS): press2 = true ; break;
case(ControlP5.ACTION_RELEASE): press2 = false ; break;
}
}
}
);
}
void draw(){ //same as loop in arduino
background(150, 0, 150); // background color of window (r, ,g, b) or (0 to 255)
//giving a title to window
text("Motor Control", 100, 10);
if (servo_pos < 89 && press || servo_pos < 181 && press)
{
servo_pos += 1;
if (servo_pos > 180)
{
servo_pos = 180;
}
char x = char(servo_pos);
String x2 = str(x);
String y = "a";
String between = y+x2;
println(servo_pos);
port.write(between);
delay(200);
}
if (servo_pos > 89 && press2 || servo_pos > 181 && press2)
{
servo_pos -= 1;
if (servo_pos < 90)
{
servo_pos = 90;
}
char x = char(servo_pos);
String x2 = str(x);
String y = "a";
String between = y+x2;
println(servo_pos);
port.write(between);
delay(200);
}
if (servo_pos < 89 && press3 || servo_pos < 181 && press3)
{
servo_pos += 1;
if (servo_pos > 180)
{
servo_pos = 180;
}
char x = char(servo_pos);
String x2 = str(x);
String y = "b";
String between = y+x2;
println(servo_pos);
port.write(between);
delay(200);
}
if (servo_pos > 89 && press4 || servo_pos > 181 && press4)
{
servo_pos -= 1;
if (servo_pos < 90)
{
servo_pos = 90;
}
char x = char(servo_pos);
String x2 = str(x);
String y = "b";
String between = y+x2;
println(between);
port.write(between);
delay(200);
}
println(servo_pos);
}