Final Project – Robot Arm Version II by Joe

Introduction: Create an interactive system of your choice using Processing and Arduino. Focus on careful and timely sensing of the relevant actions of the audience that you’re designing for and on the prompt, clear and effective response. Any interactive project is going to involve listening, thinking and communicating. Whether it involves one cycle or many, the interaction should be engaging for your audience.

Group MembersNone

Project: Robot Arm Mark II 

  • Purpose: To utilize all of the tools we have learned this semester and create one great final project combining Arduino and Processing.
  • Materials:
    • GOPR4974Robot Arm: 6 Different Types of Metal Brackets (TaoBao), Metal Claw, JX Servo Motors (10KG, 20 KG, and 30 KG), Arduino Romeo BLE, 6V 2 Amp Power Adapter, Nuts and Bolts, M/M Wires, Laser, Laser Cut Wood Base, Turn Table, Hot Glue, Electrical Tape, Wire Covering, GOPR4970Zip Ties, and Metal Support Beams.
    • Dual JoyStick Controller: 2 DFRobot Joysticks (3 Axis), 3 Way Cables, Adobe Illustrator to Design Box, Nuts, and Bolts, and Laser Cut Wood.
    • Other: Processing, Arduino IDE, and Taobao.

 

 

 

 

  • Physical Process:
    • Robot Arm: The robot arm took the longest time to make. I started by ordering metal brackets and heavy duty servo motors on TaoBao. I looked GOPR5014online as a reference to find a way to build it, but the models online were around 1000 to 2000 kuai. I was able to find similar parts for 3 to 5 kuai a piece. The only costly part of the project was buying servo motors for 60 to 100 kuai depending on the strength (10 to 30 KG). After the first few days, I had my initial prototype ready and used my old Processing interface to control it. However, one of the biggest challenges I had was finding adequate power for the motors without supplying too much. The motors were drastically underpowered with 6 Heavy Duty servo motors GOPR5040running on 5V and 2 Amps. I tried to fix this problem by using voltage regulators to control the voltage to 8V and 6V, but it did not work. I am assuming the reason it did not work was because of the 12V Power Adapter only having 1 Amp. Eventually, I bought a 6V 2Amp Power Adapter, and this solved the problem (nominal voltage is 6V). The next big challenge I had to overcome was the base. With such a big robot arm I had to find a way to keep my very tiny base from tipping. I decided to use clamps to hold the base down which did it jobs well, but bent the base in the middle (thin material), and still wobbled a bit. I made two prototype designs using Adobe Illustrator and the Laser Cutter, creating and measuring out my own GOPR5058base designs. Eventually, I arrived at a 3 Layer base to hold my Arduino, base motor, wires. and turning pan. The last issue I ran into was that my 30 KG motor that had been fried. I am not sure if the voltage broke it or too much weight, but the motor started malfunctioning and jumping from place to place, or just not working at all. A very stressful time, since this motor was the main motor supporting the whole arm, but I replaced it with a smaller 20 KG motor. For now, the 20 KG motor seems strong enough. The robot arm took a lot of trial and error and looks quite a bit different in comparison to my original sketches of the arm. I probably took the arm apart 15 times before getting my desired result. The arm was much more work than I had anticipated, but overall I am very happy with my results.
    • Dual JoyStick Controller: The Dual JoyStick Controller was initially created for my UED class, but I wanted to showcase the design in class. Since part of the GOPR5081 copyrequirement was using Processing, this will not be my main focus, but only a comparison. The reason I decided to create a physical controller instead of a virtual one is because the design is much more intuitive to use in the physical world to control a physical device. The Robot Arm is a device I want to be used for education in Robotics or education in General for advanced beginners, and having a virtual controller is fairly limited in the feeling and simplicity of a physical controller. The Dual Joystick Controller has now gone through three prototyping phases. The first phase included making molds to see which would fit the 13211189_10206466960617260_1068812936_oindividual joystick the best. I laser cut about 5 before getting the perfect fit. Then I used MakerCase.com to make a box for the joysticks and added on the cut outs for the joystick and some logos. The case worked well but  was not intuitive enough for the user to just pick up the device and use it. I decided to add symbols, logos, and directions on the back to clarify how to use the device while keeping the design simple and clean. By the end, I had tested about 10 users before perfecting my design to make it as intuitive as possible.
  • Arduino IDE Process: 
    • Robot Arm (Processing): The coding process for the Robot Arm in Arduino was somewhat strenuous. In regards to the Processing part, I had to use the serial port in order to connect from Arduino to Processing. I started by loading the servo library and naming my 6 servos consecutively from servoa to servof. Then I attached each servo pin to digital pins 3 to 8 and added a void setup for the degree I wanted each servo motor to start at. From there I added DigitalWrite for port 10 in order to turn on my laser. Then added an if statement to read the currentMotor using an integer to measure which motor is currently being used (val from 1 to 6). Afterward, I added another if statement for currentMotor to be equal to 1 through 6, and if it equals that current motor then it is equal to servoa to servof (example: servo a is currentMotor == 1).
    • Processing Controller: The controller was based on my previous design for the Mid-Term, meaning that the majority of the code was taken from there. I used the ControlP5 library for the controls. I wanted to focus on Screen Shot 2016-05-10 at 9.45.38 AMthe User Experience, so I created a new layout, changed the color, and a few other things. Changing the layout required me to move the bars according to pascals, mentally it was not difficult, but took a lot of time to get the look right. In regards to the layout, I wanted the bars to match the motion of the motors to make it more intuitive, and kept the same labeling system like the anatomy of an arm. Then I changed the color from blue to red to remind myself this was the most updated version, and ultimately changed it to white to allow for a cleaner look. I then put pre-set angles in for the motors to allow for more accuracy. The biggest problem (besides the poorly designed user interface) was the fact that the motors all started at 0, so when you would click somewhere the robot arm would instantly jump to that location at a very fast speed and sometimes malfunction. By setting it at the given angle, the user will know where each angle starts.
    • Robot Arm and Dual JoyStick Controller: The process for both was done simultaneously since both are controlled by processing. I started by loading in the servo library and creating servos using the command: Servo servoa, servob… servof. I then added integers named JoyStick_X, JoyStick_Y, JoyStick_XX, JoyStick_YY, JoyStick_Z, and JoyStick_ZZ that would connect to each of the analog/digital pins for the given value. I also added ints for the current servo values (measure in degrees) labeled as robot_X, robot_Y, robot_XX, robot_YY, robot_Z, robot_ZZ these will read and convert the values of the joysticks later on. The end variables for the JoyStick_ and robot_  (X, XX, Y, YY, Z, ZZ) all correspond with one another. Int previous, current, and count were added to help change the value of robot_Z which was dynamic with JoyStick_Z and would switch from 0 to 1 back to 0, but I wanted it to stay 0 if clicked, then change to 1 if clicked. Next comes void setup, where I connected the JoyStick Z as an input, and then made it an output every time clicked to pin 10. This will in response turn the laser on and off everytime it is clicked. Then I attached servoa through servof to digital pins 3 to 8. I used servo.write to set the given value of each servo motor degree to start at during the setup process. Next comes void loop, I defined integers x, y, z, xx, yy, zz and connected them to the corresponding JoyStick_ (example: x = analogRead)JoyStick_X). Then I connected the previously made current integer to digitalRead(JoyStick_Z) since the Z value of the JoyStick is connected to the Arduino’s digital pin. I then serial printed all of the x, xx, y, yy, z, zz values that will later be used to measure the servo angle. For every int ( x, xx, y, yy), except z and zz, I created the following if statement. Since the range for the JoySticks ranges from 0 to 1023, I made an if statement that if the x < 500 that the robot_X value will decrease by 1, and that if it is greater than 510 it will increase by 1. The reason for making it less than 500 and greater than 510 is so that I could give a ±5 due to the fluctuation of the JoySticks. In order to stop the JoyStick from going past the motors limit I also added if the robot_X is under 179 degrees and over 1 degrees (setting the limit). I also wanted to make the speed of the motors vary on how far or close the JoyStick is pushed, so I created robot_var (int) in order to make them equal to increments of 1 or 3 depending on how far the joystick is pushed in the given direction. All of the following if statements were done to give the user a more natural sense of how to use the controller. Most people feel if they push something further then it should move faster (like a gaming remote), or the direction of the JoySticks should match the direction of movement of the arm. I added a constraint statement for one of my motors, so that it would not move past a certain point because it can not lift any weight and malfunctions when it moves to far forward. Since the Z joysticks are a bit different, I had to write a different statement. They are digital meaning they only know on and off, so the pressed down position of the joystick is 0 and the up position is 1. This raised a problem because I could not keep a clamp closed or laser on unless the button was being held the whole time. Therefore with the help of Aven (who helped me with the above if statements), I was able to create a new if statement that makes the robot_Z stay switch from 0 to 1 every time it is clicked. Since everything I have done so far has all been to serial.println everything, I know have to write serial.println the robot_X, robot_Y, robot_XX, robot_YY, robot_Z, and the robot_ZZ. Most of the edits to numbers in the if statements, constraints, etc… were done after this was printlined to make for a more accurate set of data. I then set digitalWrite to pin 10 and had robot_ZZ control the input/output. For the claw, I mapped z = map(digitalRead(robot_Z), 0, 1, 110, 180) so that 0 means closed and 1 means open. 110 and 180 are both the degrees for the servo motor, 0 and 1 are the on and off spots for robot_Z (translated from JoyStick_Z). Afterwards, I wrote servoa.write(z), servob.write(robot_Y),  servoc.write(robot_X), etc… so that each servo would directly correlate to the print lined value of the robot_ integers (that are being adjusted by the JoyStick Integers/Values). Overall, much of the code I wrote took trial and error, and much of the input values for motors and the joysticks took a bit of usage before the calibration was perfected.
  • Processing Process:
    • Processing Controller: Since the majority of my time was spent on the physical aspect of the robot I was limited in my time to make a perfected Screen Shot 2016-04-28 at 5.17.15 PMprocessing controller. Before making the Dual JoyStick Controller, I updated my old processing sketch from the Mid Term with a new design and simplistic color scheme. I also moved the controls around to make it more intuitive, but after user testing found that it was still complicated and hard to use for a beginner. After a bit more tweaking, the design was better but still not perfect. Although the virtual control of processing is amazing in that I can add features to the arm like motion-following or detecting objects to pick up, along with an endless assortment of other options, I felt that it was too complicated of a control for a new user.
  • Improvements: I was a bit disappointed with the design aspect of my robot arm. There was not much time to think of a uniquely innovative design that would allow for maximum torque and efficiency from my motors. Eventually, (perhaps over summer) I will create a Robot Arm that utilizes cables and gears to control the different parts of the arms instead of directly controlling them and putting a lot of stress and weight on the servos. I would also like to make a phone application that I can control through Bluetooth or Wifi that can send tasks to the Robot Arm to complete. I do not want to have a physical controller for the Robot Arm, but instead, make it fully automated and autonomous for any assigned task.
  • Arduino Code with JoySticks: 
#include <Servo.h>

// create servo object to control a servo
Servo servoa, servob, servoc, servod, servoe, servof;

//JoyStick variables set values
//Note: JoyStick_X/Y/Z are for the first JoyStick Controller
//Note: JoyStick_XX/YY/ZZ are for the first JoyStick Controller
int JoyStick_X = 0; //x - will be connected to Analog (Blue) Pin 0
int JoyStick_Y = 1; //y - will be connected to Analog (Blue) Pin 1

int JoyStick_XX = 2; //xx - will be connected to Analog (Blue) Pin 2
int JoyStick_YY = 3; //yy - will be connected to Analog (Blue) Pin 3

int JoyStick_Z = 11; //Push Down Button - will be connected to Digital (Green) Pin 11
int JoyStick_ZZ = 12; //Push Down Button - will be connected to Digital (Green) Pin 12

//robot set values for println (eventually translated into digitalRead)
int robot_X = 35; //x 0 to 180 - Connected to JoyStick_X
int robot_Y = 180; //y 0 to 180 - Connected to JoyStick_Y

int robot_XX = 135; //x 0 to 180 - Connected to JoyStick_XX
int robot_YY = 90; //y 0 to 180 - Connected to JoyStick_YY

int robot_Z = 0; //key - Connected to JoyStick_Z
int robot_ZZ = 0; //key- Connected to JoyStick_ZZ

//Variables for robot_Z and robot_ZZ to change digital states
int previous = 1;
int current;
int count = 0;

int previousZZ = 1;
int currentZZ;
int countZZ = 0;



void setup()
{
 //Serial read allows connection to programs like Processing
 Serial.begin(9600); // 9600 bps

 //JoyStick_Z is an input
 pinMode(JoyStick_Z, INPUT);

 //Connects to Pin 10 as OutPut (laser)
 pinMode(10, OUTPUT);

 //Connects servos to digital pins (green)
 servoa.attach(3);
 servob.attach(4);
 servoc.attach(5);
 servod.attach(6);
 servoe.attach(7);
 servof.attach(8);

 delay(80);

 servoa.write(175);
 servob.write(180);
 servoc.write(35);
 servod.write(35);
 servoe.write(135);
 servof.write(90);
 digitalWrite(10, HIGH);

 delay(50);

 for (int i = 100; i <= 175; i++) {
 servoa.write(i);
 delay(15);
 }
 for (int i = 100; i <= 175; i++) {
 servoa.write(i);
 delay(15);
 }

 for (int i = LOW; i <= HIGH; i++) {
 digitalWrite(10, i);
 delay(500);
 }
 for (int i = LOW; i <= HIGH; i++) {
 digitalWrite(10, i);
 delay(500);
 }


 servoa.write(175);
 servob.write(180);
 servoc.write(35);
 servod.write(35);
 servoe.write(135);
 servof.write(90);
 digitalWrite(10, HIGH);
 delay(50);


}




void loop()
{
 //variables for reading joystick values
 int x, y, z, xx, yy, zz;

 //connecting variables to analogRead each joystick (X,XX,Y,YY)
 x = analogRead(JoyStick_X);
 y = analogRead(JoyStick_Y);
 xx = analogRead(JoyStick_XX);
 yy = analogRead(JoyStick_YY);

 //connecting variables to digitalRead each joystick (Z,ZZ)
 current = digitalRead(JoyStick_Z);
 currentZZ = digitalRead(JoyStick_ZZ);

 //println the current values of each JoyStick
 Serial.print("X:");
 Serial.print(x , DEC);
 Serial.print(", Y:");
 Serial.print(y , DEC);
 Serial.print(", Z:");
 Serial.print(z , DEC);

 Serial.print("XX:");
 Serial.print(xx , DEC);
 Serial.print(", YY:");
 Serial.print(yy , DEC);
 Serial.print(", ZZ:");
 Serial.print(zz , DEC);


 //JoyStick_X left and right motion controlling servo
 //Set range between 500 and 510 because stationary value is 505±3
 if (x < 500) { // moving my joystick left
 if (robot_X >= 1) { // so, move my robot x left
 robot_X = robot_X += 1; //decrease by incriments of 1
 }
 } else if (x > 510) { // moving my joystick right
 if (robot_X <= 179) { // so, move my robot x left
 robot_X = robot_X -= 1; //increase by incriments of 1
 }
 }


 //JoyStick_Y left and right motion controlling servo
 //Set range between 505 and 515 because stationary value is 509±3
 if (y < 470) { // moving my joystick down
 if (robot_Y >= 1) { // so, move my robot x down...
 robot_Y = robot_Y -= 3;
 }
 } else if (y > 481) { // moving my joystick up
 if (robot_Y <= 179) { // so, move my robot y down...
 robot_Y = robot_Y += 3;
 }
 }

 //JoyStick_XX left and right motion controlling servo
 //Set range between 500 and 510 because stationary value is 505±3
 if (xx < 437) { // moving my joystick left
 if (robot_XX >= 1) { // so, move my robot x left
 robot_XX = robot_XX += 3; //decrease by incriments of 1
 }
 } else if (xx > 447) { // moving my joystick right
 if (robot_XX <= 179) { // so, move my robot x left
 robot_XX = robot_XX -= 3; //increase by incriments of 1
 }
 }

 //JoyStick_YY left and right motion controlling servo
 //Set range between 505 and 515 because stationary value is 509±3
 if (yy < 418) { // moving my joystick down
 if (robot_YY >= 1) { // so, move my robot x down...
 robot_YY = robot_YY -= 3;
 }
 } else if (yy > 428) { // moving my joystick up
 if (robot_YY <= 179) { // so, move my robot y down...
 robot_YY = robot_YY += 3;
 }
 }


 //JoyStick_Z Push Up and Down motion controlling servo or laser
 if (current == 1 && current != previous) {
 count++;
 robot_Z = count % 2;
 }

 previous = current;

 //JoyStick_ZZ Push Up and Down motion controlling servo or laser
 if (currentZZ == 1 && currentZZ != previousZZ) {
 countZZ++;
 robot_ZZ = countZZ % 2;
 }

 previousZZ = currentZZ;



 //println robot values to later be used as servo values
 Serial.print("robot X:");
 Serial.print(robot_X , DEC);
 Serial.print(", robot Y:");
 Serial.print(robot_Y , DEC);
 Serial.print(", robot Z:");
 Serial.println(robot_Z , DEC);

 Serial.print("robot XX:");
 Serial.print(robot_XX , DEC);
 Serial.print(", robot YY:");
 Serial.print(robot_YY , DEC);
 Serial.print(", robot ZZ:");
 Serial.println(robot_ZZ , DEC);

 //connection back into pins
 digitalWrite(10, robot_ZZ); //Laser

 //sets the servo position according to the scaled value of Robot println
 z = map(digitalRead(robot_Z), 0, 1, 110, 180);
 servoa.write(z); //Gripper
 servob.write(robot_Y); //Wrist
 servoc.write(robot_X); //Forearm
 servod.write(robot_X); //Elbow
 servoe.write(robot_XX); //Shoulder
 servof.write(robot_YY); //Base

 delay(1); // waits for the servos to get there
}
  • Arduino Code with Processing Controls: 
#include <Servo.h>
Servo servoa, servob, servoc, servod, servoe, servof; // create servo object to control a servo
int currentMotor = 0;

int val = 0; // variable to read the value from the analog pin

void setup() {
 Serial.begin(9600);

 pinMode(10, OUTPUT); // attaches the laser on pin to

 servoa.attach(3); // attaches the servo on pin to the servo object
 servob.attach(4); // attaches the servo on pin to the servo object
 servoc.attach(5); // attaches the servo on pin to the servo object
 servod.attach(6); // attaches the servo on pin to the servo object
 servoe.attach(7); // attaches the servo on pin to the servo object
 servof.attach(8); // attaches the servo on pin to the servo object


 delay(80);

 servoa.write(175);
 servob.write(180);
 servoc.write(40);
 servod.write(35);
 servoe.write(95);
 servof.write(90);
 digitalWrite(10, HIGH);

 delay(50);

 for (int i = 100; i <= 175; i++) {
 servoa.write(i);
 delay(15);
 }
 for (int i = 100; i <= 175; i++) {
 servoa.write(i);
 delay(15);
 }

 for (int i = LOW; i <= HIGH; i++) {
 digitalWrite(10, i);
 delay(500);
 }
 for (int i = LOW; i <= HIGH; i++) {
 digitalWrite(10, i);
 delay(500);
 }


 servoa.write(175);
 servob.write(180);
 servoc.write(40);
 servod.write(35);
 servoe.write(95);
 servof.write(90);
 digitalWrite(10, HIGH);
 delay(50);

}




void loop() {
 digitalWrite(10, HIGH);

 if (Serial.available()) {
 val = Serial.read();

 if (val == 1) {
 currentMotor = 1;
 }
 else if (val == 2) {
 currentMotor = 2;
 }
 else if (val == 3) {
 currentMotor = 3;
 }
 else if (val == 4) {
 currentMotor = 4;
 }
 else if (val == 5) {
 currentMotor = 5;
 }
 else if (val == 6) {
 currentMotor = 6;
 }
 }


 if (currentMotor == 1) {
 servoa.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
 else if (currentMotor == 2) {
 servob.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
 else if (currentMotor == 3) {
 servoc.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
 else if (currentMotor == 4) {
 servod.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
 else if (currentMotor == 5) {
 servoe.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
 else if (currentMotor == 6) {
 servof.write(val); // sets the servo position according to the scaled value
 delay(1);
 }
}
  • Processing Code with Arduino (Video Cam Commented Out): 
import processing.serial.*;
import controlP5.*;
import processing.video.*;

Serial port;
ControlP5 cp5;
Capture cam;

int myColor = color(255);


void setup() {
 size(865, 685);

 //String[] cameras = Capture.list();
 //if (cameras.length == 0) {
 // println("There are no cameras available for capture.");
 // exit();
 //} else {
 // println("Available cameras:");
 // for (int i = 0; i < cameras.length; i++) {
 // println(cameras[i]);
 // }
 //} 

 ////cam = new Capture(this, cameras[21]);
 //cam = new Capture(this, cameras[7]); //Testing w/out external cam
 //cam.start();

 cp5 = new ControlP5(this);

 //ButtonBar b = cp5.addButtonBar("bar")
 // .setPosition(260, 460)
 // .setSize(330, 50)
 // .setColorActive(color(180))
 // .setColorForeground(color(255,100))
 // .setColorBackground(color(180))
 // .addItems(split("a b c d", " "))
 // ;
 //println(b.getItem("a"));
 //b.changeItem("a", "text", "Clamp");
 //b.changeItem("b", "text", "Laser");
 //b.changeItem("c", "text", "Track");
 //b.changeItem("d", "text", "Dance");
 //b.onMove(new CallbackListener() {
 // public void controlEvent(CallbackEvent ev) {
 // ButtonBar bar = (ButtonBar)ev.getController();
 // println("Button Clicked ", bar.hover());
 // }
 //}
 //);

 cp5.addSlider("Clamp")
 .setPosition(10, 570)
 .setWidth(825)
 .setHeight(40)
 .setRange(100, 180)
 .setValue(180)
 .setNumberOfTickMarks(25)
 .setSliderMode(Slider.FLEXIBLE)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 cp5.addSlider("Wrist")
 .setPosition(15, 10)
 .setSize(55, 530)
 .setRange(0, 180)
 .setValue(180)
 .setNumberOfTickMarks(60)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 cp5.addSlider("ForeArm")
 .setPosition(100, 10)
 .setSize(55, 530)
 .setRange(5, 175)
 .setValue(40)
 .setNumberOfTickMarks(60)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 cp5.addSlider("Elbow")
 .setPosition(695, 10)
 .setSize(55, 530)
 .setRange(5, 175)
 .setValue(35)
 .setNumberOfTickMarks(60)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 cp5.addSlider("Shoulder")
 .setPosition(780, 10)
 .setSize(55, 530)
 .setRange(5, 100)
 .setValue(95)
 .setNumberOfTickMarks(30)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 cp5.addSlider("Base")
 .setPosition(10, 630)
 .setWidth(825)
 .setHeight(40)
 .setRange(5, 175)
 .setValue(90)
 .setNumberOfTickMarks(60)
 .setSliderMode(Slider.FLEXIBLE)
 .setColorActive(color(255, 100))
 .setColorForeground(color(255))
 .setColorBackground(color(180))
 ;

 println("Available serial ports:");
 println(Serial.list());

 port = new Serial(this, Serial.list()[3], 9600);
}

void draw() {
 background(35);
 textSize(32);
 text("Robot Arm Mark II", 270, 40); 
 textSize(16);
 text("by Joseph Young", 350, 65); 
 fill(255);

 //if (cam.available() == true) {
 // cam.read();
 //}
 //image(cam, 180, 130);
}
//
void Clamp(int val) {
 println("Clamp "+val);
 port.write(1);
 port.write(val);
}

void Wrist(int val) {
 println("Wrist "+val);
 port.write(2);
 port.write(val);
}

void ForeArm(int val) {
 println("ForeArm "+val);
 port.write(3);
 port.write(val);
}

void Elbow(int val) {
 println("Elbow "+val);
 port.write(4);
 port.write(val);
}

void Shoulder(int val) {
 println("Shoulder "+val);
 port.write(5);
 port.write(val);
}

void Base(int val) {
 println("Base "+val);
 port.write(6);
 port.write(val);
}

void bar(int n) {
 println("bar clicked, item-value:", n);
}

 

Leave a Reply