Robotic Arm With Vacuum Suction Cup for Pick and Place

In this tutorial, we will build a robotic arm with a vacuum suction cup that can enable you to pick up items in one location and place them in another.

Our goal is to build an early prototype of a product that can make it easier and faster for factories and warehouses to do their work.

Real-World Applications

Robotic arm systems have a number of real-world applications. Here are just a few examples: 

Not only do robotic arms help solve labor shortages, but they also help increase productivity when they work alongside humans. In this video from The Wall Street Journal, you can see how robotic arms working side-by-side with humans can enhance productivity.

covariant-ai-robot-small
Source: YouTube – A robot made by Covariant

We will build an early prototype of the products you see above. Let’s get started!

Prerequisites

You Will Need

This section is the complete list of components you will need for this project: 

Robot Arm Kit (Assembled) – Go to ebay and type “Air Pump Robotic Arm Kit” or go to Aliexpress and type “Robotic arm vacuum suction pump”

  • 2 x KS-3620 180° Servo (Suitable Voltage: 4.8 – 6.6V; No-load Current: 80-100mA)
  • 1 x KS-3620 270° Servo  (Suitable Voltage: 4.8 – 6.6V; No-load Current: 80-100mA)
  • 1 x Micro Air (Vacuum) Pump (Suitable Voltage: 3.7V – 6V; Rated current: <0.4A)
  • 1 x Solenoid Valve – Electrically controlled valve that opens up and lets air through when it receives the proper voltage – (Suitable Voltage 3V – 6V; Rated current: 0.14A)
  • 1 x Silicone Tubing Hose (2mm inner diameter)

Robot Suction Cup Vacuum Pump Kit For 25T (i.e. 25 Teeth Servo Spline) Servos (check ebay or Aliexpress)

  • 1 x Set of Silicone Suction Cup (Dual)
  • 2 x PWM Electronic Switches
  • 1 x Vacuum Pump
  • 1 x 800mm Silicone Hose
  • 1 x Tee-Joint Electronic Valve (also known as Solenoid Valve)

Extra Components You’ll Need

Getting Started

Test the Servo Motors

The first thing we need to do is to test the three servo motors. 

Here is the wiring diagram in pdf format. 

We need to power the servo motors with an external power supply because they draw a lot of current…so much current that it would damage your Arduino Mega if you were to connect the power leads directly.

Here are two different programs you can use to test. The first program enables you to control the position of the servos directly using the potentiometers. The second program sweeps each motor back and forth.

2020-07-11-081518

When you launch these programs on the robot, I recommend you turn on the external power first. Then plug the 9V battery into the Arduino.

/*
Program: Control 3 Servos Using Arduino and Potentiometers
File: control_3_servos_with_potentiometer_varspeedservolib.ino
Description: Turn the knob of the potentiometers 
             to control the angle of the 3 servos.
             This program enables you to control the speed of the servos
             as well.
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 10, 2020
*/
 
#include <VarSpeedServo.h> 

// Define the number of servos
#define SERVOS 3

// Create the servo objects.
VarSpeedServo myservo[SERVOS]; 

// Speed of the servo motors
// Speed=1: Slowest
// Speed=255: Fastest.
const int desired_speed = 255;

// Attach servos to digital pins on the Arduino
int servo_pins[SERVOS] = {3,5,6};

// Analog pins used to connect the potentiometers
int potpins[SERVOS] = {A0,A1,A2}; 

// Variables to read the value from the analog pin
int potpin_val[SERVOS]; 

void setup() {
  
  for(int i = 0; i < SERVOS; i++) {
    
    // Attach the servos to the servo object 
    // attach(pin, min, max  ) - Attaches to a pin 
    // setting min and max values in microseconds
    // default min is 544, max is 2400 
    myservo[i].attach(servo_pins[i], 544, 2400);  
  }
}
 
void loop() {  

  // Update servo position
  for(int i = 0; i < SERVOS; i++) {
    potpin_val[i] = analogRead(potpins[i]);
    potpin_val[i] = map(potpin_val[i], 0, 1023, 0, 180);
    myservo[i].write(potpin_val[i], desired_speed, true);
  }
}    
/*
Program: Control 3 Servos Using Arduino and Sensor Shield v5.0
File: move_3_servo_motors_to_angle.ino
Description: Move servo motors to a specific angle
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 10, 2020
*/
 
#include <VarSpeedServo.h> 

// Define the number of servos
#define SERVOS 3

// Create the servo objects.
VarSpeedServo myservo[SERVOS]; 

// Speed of the servo motors
// Speed=1: Slowest
// Speed=255: Fastest.
const int desired_speed = 25;

// Attach servos to digital pins on the Arduino
int servo_pins[SERVOS] = {3,5,6};

void setup() {
  
  for(int i = 0; i < SERVOS; i++) {
    
    // Attach the servos to the servo object 
    myservo[i].attach(servo_pins[i]);  
  }
}
 
void loop() {  

  // Move each servo back and forth
  for(int i = 0; i < SERVOS; i++) {
    myservo[i].write(60, desired_speed, true); 
    myservo[i].write(120, desired_speed, true);   
    myservo[i].write(60, desired_speed, true); 
    delay(250);
  }
  delay(250); 
}     

Connect the Components

Now that you’ve tested the motors, it is time to connect everything else.

Get all the components that you need to build this project, and lay them out on a table. Now is a good time to double check that you have everything you need.

2020-07-15-181642

Wire up all the components. You can use either this diagram or this diagram depending on your preference. 

I suggest downloading the wiring diagram and then zooming in so you can see everything. 

Don’t be intimidated by all the connections. Just go one part and one wire at a time. Take it slowly so that you wire everything up correctly.

For the two solenoid wires and the momentary push button switch, it doesn’t matter which one is Ground and which one is VCC (i.e. positive voltage).

Launch Manual Suction Control

We will control our robot manually using the three potentiometers. Load the control_3_servos_with_potentiometer_varspeedservolib.ino program (you made earlier) to your Arduino.

Now plug in everything so that your program is running. The power supply I’m using is 6V for the voltage with a 3A current limit.

2020-07-15-195316
2020-07-15-195334
2020-07-15-195358
2020-07-15-195406
2020-07-15-195426
2020-07-15-195439
2020-07-15-195459
2020-07-15-195450

You may notice in the beginning that the servos jump a bit when you first launch the program. That’s totally normal.

In a real-world setting, you would want to consider programming the robot so that you can press a button and return the servos to the home position before you shut it down. Then, when you restart the program, the robotic arm will initialize in the home position. This way, you won’t have an arm flying around when you launch the arm. 

Using the potentiometers to control the angles of the servos, move the suction cup to a specific object you want to pick up.

When the suction cup reaches the object, push and hold down quickly on the object in order to pick it up.

Then move the servos to your desired drop location.

When ready, release the suction by pushing the momentary push button switch.

Launch Automatic Suction Control

We will now use a force sensitive resistor to control when to deactivate suction. A force sensitive resistor detects physical pressure, squeezing, and weight.

We will use this resistor to automatically detect when the suction cup has made contact with an object. This component will therefore help us automate the process of picking and placing an object.

Test the Force Sensitive Resistor

Let’s begin by writing a small program to test the force sensitive resistor.

Here is the wiring diagram in pdf format.

2020-07-17-155722
2020-07-17-163542

Here is the code. I saved the file as test_force_sensitive_resistor.ino:

/* FSR simple testing sketch. 
 
Connect one end of FSR to power, the other end to Analog 5.
Then connect one end of a 10K resistor from Analog 5 to ground 
 
For more information see www.ladyada.net/learn/sensors/fsr.html */
 
int fsrPin = A5;     // the FSR and 10K pulldown are connected to A5
int fsrReading;     // the analog reading from the FSR resistor divider
 
void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
}
 
void loop(void) {
  fsrReading = analogRead(fsrPin);  
 
  Serial.print("Analog reading = ");
  Serial.print(fsrReading);     // the raw analog reading
 
  // We'll have a few threshholds, qualitatively determined
  if (fsrReading < 10) {
    Serial.println(" - No pressure");
  } else if (fsrReading < 200) {
    Serial.println(" - Light touch");
  } else if (fsrReading < 500) {
    Serial.println(" - Light squeeze");
  } else if (fsrReading < 800) {
    Serial.println(" - Medium squeeze");
  } else {
    Serial.println(" - Big squeeze");
  }
  delay(200);
} 

For a full description of the force sensitive resistor, check out this post on Adafruit.com

Load the code to your Arduino.

With your USB still plugged in, run the code, and open the Serial Monitor in the Arduino IDE. You will need to click the green magnifying glass in the upper-right of the IDE.

Press the round part of the force sensitive resistor with your finger, and observe the output on the Serial Monitor.

2020-07-17-155359JPG

I highly recommend soldering the Force Sensitive Resistor to male-to-male solder wires. 

If you’ve never soldered before, there are a ton of good YouTube videos on how to do it. You can also check this link where I did some soldering for a robotic car.

Install the Force Sensitive Resistor on the Robot

Cover the head (round part) of the force sensitive resistor in order to protect it. I used some cling wrap and tape to protect it.

2020-07-20-210325

Secure the cling wrap over the force sensitive resistor using some scotch tape.

2020-07-20-210330

Now grab one of the big washers (with 1/2 in. inner diameter and 2 in. outer diameter).

Cut some small pieces of Scotch permanent mounting tape, and place it around the hole.

2020-07-25-160545
2020-07-25-173422

Slide the washer over the tube until it sits on top of the nut above the suction cup.

Now grab the other big washer (with 1/2 in. inner diameter and 2 in. outer diameter).

Tape it to the end-effector of the robotic arm using Scotch permanent mounting tape.

Grab the force sensitive resistor and tape it to the big washer that is attached to the robotic arm (i.e. the upper washer). The two wires should flow out through the back of the robotic arm.

The front of the force sensitive resistor should face upward right against the tape.

2020-07-25-173447

Take the tube and thread it through the hole in the robotic arm.

Place a washer and then a nut down over the tube so that both sit on top of the end effector.

Using your fingers, secure the nut on top of the washer. Do not secure it tightly…just enough so that it isn’t loose (We’ll come back to this screw in the next section)

2020-07-25-173453

Pictures are worth 1000 words, so here is how the setup should look when you’re done.

2020-07-25-173507
2020-07-25-173516
2020-07-25-173557

Calibrate the Robotic Arm With Force Sensitive Resistor

Now, we need to adjust the nut that sits on top of the end effector to the appropriate tightness.

Connect the force sensitive resistor according to the wiring diagram here in pdf format.

Load test_force_sensitive_resistor.ino to your Arduino.

With your USB still plugged in, run the code, and open the Serial Monitor in the Arduino IDE. You will need to click the green magnifying glass in the upper-right of the IDE.

You should see the reading “no pressure” on your Serial Monitor.

Tighten the nut until you see a reading of “Light touch,” “Light squeeze,” or “Medium squeeze.” 

Now, loosen the nut until you see the first reading of “No pressure”. 

To test to see if everything is working properly, with your hand (no need to turn on the motors), guide the robotic arm towards an object. 

Press the suction cup down on an object and then pull it off the object. 

  1. Each time you press the suction cup down on an object you should see either “Light touch,” “Light squeeze,” “Medium squeeze,” or “Big squeeze.”
  2. When the suction cup isn’t touching anything, you should see “No pressure.”

Once you’ve got 1 and 2 above, your robotic arm with force sensitive resistor is calibrated properly.

Have patience. It takes a while to secure the nut to just the right tightness. You want it not too tight but not too loose.

Test the Solenoid Valve With PWM Electronic Switch 

Let’s test our solenoid valve to see if it is working properly. You will need to wire everything up like you see in this diagram.

2020-07-31-155515

If you are using a DC variable power supply, like I am, set it for 0.5A for the current limit and 6V for the voltage.

Where did I get 0.5A from? I know the current ratings for the vacuum pump and the solenoid, so I’m considering a 0.3A max for the vacuum pump and 0.2A max for the solenoid so that I don’t destroy them by allowing too much current to flow through them.

Now, write the following code and upload it to your Arduino. This code makes the vacuum suction cup turn ON for five seconds and then turn OFF for five seconds

/*
Program: Test Solenoid Valve With PWM Electronic Switch
File: test_solenoid_valve.ino
Description: This program tests a solenoid valve 
  with electronic switch to see if it is working
  properly.
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 29, 2020
*/

#include <VarSpeedServo.h> 

// Create a solenoid valve control object
VarSpeedServo my_solenoid_valve;

// Attach solenoid to digital pin on the arduino
int solenoid_pin = 9;

void setup() {
  // Attach the solenoid to the solenoid valve control object
  my_solenoid_valve.attach(solenoid_pin);

  // We assume the vacuum pump is turned ON
  // When the vacuum pump is ON, and the solenoid valve OFF:
  // --Suction is ON
  // When the vacuum pump is ON, and the solenoid valve ON:
  // --Suction is OFF
  // Start with solenoid valve OFF (0 is OFF, 180 is ON)
  my_solenoid_valve.write(0);
}

// The vacuum suction cup turns ON for five seconds and then 
// turns OFF for five seconds. 
void loop() {
  my_solenoid_valve.write(0); // Turn the solenoid valve OFF (Suction is ON)
  delay(5000); // Wait five seconds
  my_solenoid_valve.write(180); // Turn the solenoid valve OFF (Suction is OFF)
  delay(5000); // Wait five seconds
  
}

Test the Vacuum Pump With PWM Electronic Switch 

Let’s test our vacuum pump to see if it is working properly. You will need to wire everything up like you see in this diagram.

2020-07-31-161848

If you are using a DC variable power supply, like I am, set it for 0.5A for the current limit and 6V for the voltage

Now, write the following code and upload it to your Arduino. This code makes the vacuum suction cup turn ON for five seconds and then turn OFF for five seconds. 

/*
Program: Test Vacuum Pump With PWM Electronic Switch
File: test_vacuum_pump.ino
Description: This program tests a vacuum pump 
  with electronic switch to see if it is working
  properly.
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 29, 2020
*/

#include <VarSpeedServo.h> 

// Create a vacuum pump control object
VarSpeedServo my_vacuum_pump;

// Attach vacuump pump to digital pin on the arduino
int vacuum_pump_pin = 10;

void setup() {
  // Attach the vacuum pump to the vacuum pump control object
  my_vacuum_pump.attach(vacuum_pump_pin);

  // Start with vacuum pump ON (0 is OFF, 180 is ON)
  my_vacuum_pump.write(180);
}

// The vacuum suction cup turns ON for five seconds and then 
// turns OFF for five seconds. 
void loop() {
  my_vacuum_pump.write(180); // Turn the vacuum pump ON (Suction is ON)
  delay(5000); // Wait five seconds
  my_vacuum_pump.write(0); // Turn the vacuum pump OFF (Suction is OFF)
  delay(5000); // Wait five seconds
  
}

Test the Vacuum Pump and Solenoid Valve With PWM Electronic Switches

Let’s test our vacuum pump and solenoid valve together to see if they work properly as a unit. You will need to wire everything up like you see in this diagram.

2020-07-31-163513
2020-07-31-163526
2020-07-31-163532

If you are using a DC variable power supply, like I am, set it for 0.5A for the current limit and 6V for the voltage

Now, write the following code and upload it to your Arduino. This code makes the vacuum suction cup turn ON for five seconds and then turn OFF for five seconds. 

/*
Program: Test Vacuum Pump and Solenoid Valve With PWM Electronic Switches
File: test_vacuum_pump_and_solenoid.ino
Description: This program tests the vacuum pump and solenoid valve 
  together to see if they work properly as a unit. 
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 29, 2020
*/

#include <VarSpeedServo.h> 

// Create a solenoid valve control object
VarSpeedServo my_solenoid_valve;

// Create a vacuum pump control object
VarSpeedServo my_vacuum_pump;

// Attach solenoid to digital pin on the arduino
int solenoid_pin = 9;

// Attach vacuump pump to digital pin on the arduino
int vacuum_pump_pin = 10;

void setup() {
  // Attach the solenoid to the solenoid valve control object
  my_solenoid_valve.attach(solenoid_pin);

  // Attach the vacuum pump to the vacuum pump control object
  my_vacuum_pump.attach(vacuum_pump_pin);

  // We assume the vacuum pump is turned ON
  // When the vacuum pump is ON, and the solenoid valve OFF:
  // --Suction is ON
  // When the vacuum pump is OFF, and the solenoid valve ON:
  // --Suction is OFF
  // Start with vacuum pump ON (0 is OFF, 180 is ON)
  my_vacuum_pump.write(180);
  // Start with solenoid valve OFF (0 is OFF, 180 is ON)
  my_solenoid_valve.write(0);
}

// The vacuum suction cup turns ON for five seconds and then 
// turns OFF for five seconds. 
void loop() {

  // Suction is ON
  my_solenoid_valve.write(0); 
  my_vacuum_pump.write(180); 
  
  delay(5000); // Wait five seconds

  // Suction is OFF
  my_solenoid_valve.write(180);
  my_vacuum_pump.write(0); 
  
  delay(5000); // Wait five seconds  
}

Test Force Sensitive Resistor With Vacuum Pump and Solenoid Valve

Let’s add our force sensitive resistor to our setup.

You will need to wire everything up like you see in this diagram.

If you are using a DC variable power supply, like I am, set it for 0.5A for the current limit and 6V for the voltage

Now, write the following code and upload it to your Arduino. This code runs in two stages:

  • Stage 0 (Pick up object)
    • Starts with the suction turned OFF (i.e. vacuum is OFF and solenoid is ON)
    • Gives you time to move the robotic arm in position so that the vacuum suction cup is touching the object you want to pick up.
    • Checks to see if the vacuum suction cup is touching the object you want to pick up.
    • If the vacuum suction cup is touching the object you want to pick up, suction is turned ON (i.e. vacuum is switched ON and solenoid is switched OFF).
  • Stage 1 (Place object)
    • Gives you time to move the robotic arm in position to place the object in your desired location.
    • Suction is turned OFF, and the object is released.
/*
Program: Test Force Sensitive Resistor With Vacuum Pump and Solenoid Valve
File: test_vacuum_solenoid_force_sensor.ino
Description: This program tests the vacuum pump, solenoid valve, and 
  force sensitive resistor to see if they work properly as a unit. 

  Connect one end of FSR to power, the other end to Analog 5.
  Then connect one end of a 10K resistor from Analog 5 to ground.
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 29, 2020
*/

#include <VarSpeedServo.h> 

// Create a solenoid valve control object
VarSpeedServo my_solenoid_valve;

// Create a vacuum pump control object
VarSpeedServo my_vacuum_pump;

// Attach solenoid to digital pin on the arduino
int solenoid_pin = 9;

// Attach vacuum pump to digital pin on the arduino
int vacuum_pump_pin = 10;

int fsrPin = A5;     // the FSR and 10K pulldown are connected to A5
int fsrReading = 0;     // the analog reading from the FSR resistor divider
int stage = 0; // Keep track of the stage we are in

void setup() {
  
  // Attach the solenoid to the solenoid valve control object
  my_solenoid_valve.attach(solenoid_pin);

  // Attach the vacuum pump to the vacuum pump control object
  my_vacuum_pump.attach(vacuum_pump_pin);

  // When the vacuum pump is ON, and the solenoid valve OFF:
  // --Suction is ON
  // When the vacuum pump is OFF, and the solenoid valve ON:
  // --Suction is OFF
  // Start with Suction OFF
  my_solenoid_valve.write(180); // 0 is OFF, 180 is ON
  my_vacuum_pump.write(0); // 0 is OFF, 180 is ON
}

void loop() {

  /* Stage 0 - Pick up an object */
  while(stage == 0) {

    // Check to see if contact has been made with an object
    fsrReading = analogRead(fsrPin);
    fsrReading += analogRead(fsrPin);
    fsrReading += analogRead(fsrPin);
    fsrReading = fsrReading / 3;
    if (fsrReading > 300) {
      // Suction is ON
      my_solenoid_valve.write(0); 
      my_vacuum_pump.write(180); 
      stage = 1;
    }
  }

  // Move the robotic arm into position to place the object.
  // Delay is in milliseconds. Change this value as you see fit.
  delay(3000); 

  /* Stage 1 - Place an object */
  // Suction is OFF
  my_solenoid_valve.write(180); 
  my_vacuum_pump.write(0); 
  stage = 0;
}

Putting It All Together for Pick and Place

Now, to finish off all this, let’s add the servo motors so that we can control the robotic arm with the potentiometers.

You will need to wire everything up like you see in this diagram.

2020-08-01-190609

If you are using a DC variable power supply, like I am, set it for 3.5A for the current limit and 6V for the voltage

Now, write the following code and upload it to your Arduino. Control the robotic arm using the three potentiometers. The code is similar to the code from the last section with just a few new lines of code.

/*
Program: Robot With Vacuum Pump and Automatic Suction Control
File: automatic_suction_control.ino
Description: This program uses a vacuum pump, solenoid valve, and 
  force sensitive resistor to create automatic suction control. 

  Connect one end of FSR to power, the other end to Analog 5.
  Then connect one end of a 10K resistor from Analog 5 to ground.
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 30, 2020
*/

#include <VarSpeedServo.h> 

/********************** SERVOS ***********************/
// Define the number of servos
#define SERVOS 3

// Create the servo objects.
VarSpeedServo myservo[SERVOS]; 

// Speed of the servo motors
// Speed=1: Slowest
// Speed=255: Fastest.
const int desired_speed = 255;

// Attach servos to digital pins on the Arduino
int servo_pins[SERVOS] = {3,5,6};

// Analog pins used to connect the potentiometers
int potpins[SERVOS] = {A0,A1,A2}; 

// Variables to read the value from the analog pin
int potpin_val[SERVOS]; 

/****************** SOLENOID VALVE *******************/

// Create a solenoid valve control object
VarSpeedServo my_solenoid_valve;

// Attach solenoid to digital pin on the arduino
int solenoid_pin = 9;

/******************* VACUUM PUMP *********************/

// Create a vacuum pump control object
VarSpeedServo my_vacuum_pump;

// Attach vacuum pump to digital pin on the arduino
int vacuum_pump_pin = 10;

/*************** FORCE SENSITIVE RESISTOR *************/

int fsrPin = A5;     // the FSR and 10K pulldown are connected to A5
int fsrReading = 0;     // the analog reading from the FSR resistor divider
int stage = 0; // Keep track of the stage we are in

void setup() {

  // Set up servos
  for(int i = 0; i < SERVOS; i++) {
    
    // Attach the servos to the servo object 
    // attach(pin, min, max  ) - Attaches to a pin 
    // setting min and max values in microseconds
    // default min is 544, max is 2400 
    myservo[i].attach(servo_pins[i], 544, 2400);  
  }
  
  // Attach the solenoid to the solenoid valve control object
  my_solenoid_valve.attach(solenoid_pin);

  // Attach the vacuum pump to the vacuum pump control object
  my_vacuum_pump.attach(vacuum_pump_pin);

  // When the vacuum pump is ON, and the solenoid valve OFF:
  // --Suction is ON
  // When the vacuum pump is OFF, and the solenoid valve ON:
  // --Suction is OFF
  // Start with Suction OFF
  my_solenoid_valve.write(180); // 0 is OFF, 180 is ON
  my_vacuum_pump.write(0); // 0 is OFF, 180 is ON

}

void loop() {

  /* Stage 0 - Pick up an object */
  while(stage == 0) {

    // Move the robotic arm into position to pick up the object
    // Modify the number of time steps as you see fit.
    for(int j = 0; j < 50; j++) {

      // Update servo position
      for(int i = 0; i < SERVOS; i++) {
        potpin_val[i] = analogRead(potpins[i]);
        potpin_val[i] = map(potpin_val[i], 0, 1023, 0, 180);
        myservo[i].write(potpin_val[i], desired_speed, true);
      }
    }

    // Check to see if contact has been made with an object
    fsrReading = analogRead(fsrPin);
    fsrReading += analogRead(fsrPin);
    fsrReading += analogRead(fsrPin);
    fsrReading = fsrReading / 3;
    if (fsrReading > 300) {
      // Suction is ON
      my_solenoid_valve.write(0); 
      my_vacuum_pump.write(180); 
      stage = 1;
    }
  }

  // Move the robotic arm into position to place the object
  // Modify the number of time steps as you see fit.
  for(int j = 0; j < 3000; j++) {
    
    // Update servo position
    for(int i = 0; i < SERVOS; i++) {
      potpin_val[i] = analogRead(potpins[i]);
      potpin_val[i] = map(potpin_val[i], 0, 1023, 0, 180);
      myservo[i].write(potpin_val[i], desired_speed, true);
    }
  }

  /* Stage 1 - Place an object */
  // Suction is OFF
  my_solenoid_valve.write(180); 
  my_vacuum_pump.write(0); 
  stage = 0;
}

How to Build a DIY Aluminium 6-DOF Robotic Arm From Scratch

In this tutorial, we will build a robotic arm with six degrees of freedom from scratch. A degree of freedom is the number of variables needed to fully describe the position and orientation of a system (e.g. x, y, z, and rotation about each of those axes in the case of our robotic arm).

Our goal is to build an early prototype of a product to make it easier and faster for factories, warehouses, and food processing plants to pick up objects and place them into boxes (i.e. pick and place).

I modeled the robot in a CAD (Computer-aided design) program called Creo Parametric. Here are the STL files.

robotic_arm_6dof_creo_parametric_6_0_cad_2

Real-World Applications

Robotic arm systems have a number of real-world applications. Here are just a few examples: 

  • Warehouses and Logistics
  • Grocery Stores
  • Hospitals and Medical Centers
  • Military
  • Food Processing Plants
  • And more…

Let’s get started!

Prerequisites

  • No prior knowledge necessary. We’ll build everything from the ground up.

You Will Need

This section is the complete list of components you will need for this project.

Directions

Let’s assemble the robotic arm. Follow the steps carefully, and take your time to make sure everything is set up properly. It took me almost a week to assemble the arm. Go slowly.

The instructions for assembling the arm come inside the package, but let’s walk through the process anyways.

Unpack the Robotic Arm Kit

Open the robotic arm kit. Lay out all the components on a table. You should have the following pieces of hardware:

2020-05-15-130141
  • 1 x Aluminum Clamp Claw
  • 1 x L-type Servo Bracket
  • 3 x U-type Robot Waist Bracket
  • 4 x Long U-type Servo Bracket
  • 4 x Miniature Ball Radial Bearing
  • 5 x Multi-functional Servo Bracket
  • 6 x MG996R Servo
  • 6 Sets x Aluminum Servo Horns
  • 4 Sets x Round Head M3*10 Screws and M3 Nuts (The 10 means 10mm in length, including the head)
  • 20 Sets x Round Head M3*8 Screws and M3 Nuts 
  • 24 Sets x Fixed Head M4*10 Screws and M4 Nuts (I never used these)
  • 30 Sets x Round Head M3*6 Screws and M3 Nuts
  • *Note: The kit that I have didn’t have labels on the screws, making it tricky to figure out what screws to use at what stage. Just use screws and nuts that can fit into the hole when the time comes. Don’t sweat over the exact type of screw I mention in this tutorial. The end goal is to make sure every part is secure.

Assemble the Base

Grab 6 x M3*8 screws and nuts (these are the screws that are 8mm long from the top of the head to the base of the screw)..

Using a screwdriver (helpful to use needle-nose pliers to hold the nut in place as you screw in the screws and nuts), connect two of the U-type robot waist brackets together using the M3*8 screws and nuts.

2020-05-15-184837
2020-05-16-112416

Grab the third U-type robot bracket, and attach it to one side of the base using six M3*8 screws and nuts.

2020-05-16-135056

Install the First Servo Motor

Grab one M3*10 screw, nut, and a bearing.

Grab one Multi-functional servo bracket.

2020-05-17-133726

Place a screw through the hole. It might have a bit of trouble fitting through the hole, so make sure you apply enough force to snap it through there.

2020-05-17-134051

Insert the bearing over the screw, with the wide end of the bearing touching the Multi-functional servo bracket.

Insert the nut over the screw in order to hold the bearing in place. 

Tighten the screw with a 7/32 inch wrench.

2020-05-17-135137

Now we need to attach the Multi-functional servo bracket to that U-type bracket that was mounted on top of the robot base. Use four M3*6 screws and nuts to do this job.

2020-05-17-142815

Take one of your servo motors outside of its bag.

Mount it over the two arms of the Multi-functional servo bracket. Make sure the motor is mounted just as you see it here. We will call this servo motor the steering servo.

2020-05-18-082351

Get four M3*8 screws and nuts (the fattest screws and nuts in the kit). Use these to secure the steering servo into place. 

I recommend holding the nut in place with one of your fingers or the needle-nose pliers and using a Phillips screwdriver to tighten the screw inside the nut. 

2020-05-18-083951

Here is how your setup should look at this stage.

2020-05-18-085055

Grab one of the plastic rocker arms. It should be inside the bag that had your servo motor.

Insert the rocker arm on top of the steering servo. The grooves of the steering servo should fit nicely with the grooves of the rocker arm.

The rocker arm should be placed perpendicular across the steering servo axis (i.e. that golden, grooved metal circle on top of the steering servo).

2020-05-18-090425

Now take your finger and move the rocker arm to the left and to the right.

Take note of where the rocker stops turning when you twist the rocker arm to the left side with your fingers.

Now take note of where the rocker arm stops turning on the right side.

Reposition the rocker arm so that it is perpendicular across the steering servo when the underlying steering servo axis is exactly at the halfway point between the left and right stopping points that you just marked.

2020-05-18-091312

After you have adjusted the angle of the steering servo axis using the rocker arm, grab the servo horn.

Carefully remove the rocker arm by pulling it straight up off the steering servo axis. You want to be careful not to move the steering servo axis.

Fit the servo horn on top of the steering servo axis so that it looks like this. One of the holes of the servo horn should point straight forward.

2020-05-18-092712

Twist the servo horn from right to left. The rotation range should be 0-225°.

Once you are sure that the servo horn is positioned properly over the steering servo axis, secure it into place by placing a screw in the center.

2020-05-18-092717

Grab one of the long U-type brackets.

Slip the hole of the U-type bracket over the bearing underneath the servo motor.

2020-05-18-100142

Slip the other end of the U-type bracket over the top of the servo motor. The big hole of the U-type bracket should be over the screw.

2020-05-18-100338

Grab a small screw.

Place the screw in one of the small holes of the long U-type bracket. Don’t tighten too hard at this stage.

2020-05-18-100359

Move the U-type bracket from left to right. Make sure it can touch each side of that third U-type robot waist bracket.

Now, remove the screw you just put in.

2020-05-18-102150

Install the Second Servo Motor

Grab a bearing, a long screw, and a nut.

Grab a Multi-functional servo bracket.

2020-05-19-112304

Secure the bearing on the Multi-functional servo bracket using the screw and the nut.

2020-05-19-113447

Grab four M3*6 screws.

Use the screws to secure the Multi-functional servo bracket on top of the long U-type servo bracket.

2020-05-19-114506

Grab another servo. This servo will be called the arm servo since it is responsible for raising and lowering the robotic arm.

2020-05-19-114731

Place it into the Multi-functional servo bracket.

Secure the servo into place with four fat screws (M3*8) and nuts. I recommend using needle-nose pliers to hold the nut steady while you use a Phillips screwdriver to tighten the screw.

2020-05-19-115625

Grab one of the plastic rocker arms. It should be inside the bag that had your servo motor.

Insert the rocker arm on top of the steering servo. The grooves of the steering servo should fit nicely with the grooves of the rocker arm. 

The rocker arm should be placed perpendicular across the steering servo axis (i.e. that golden, grooved metal circle on top of the steering servo).

Now take your finger and move the rocker arm to the left and to the right. 

Take note of where the rocker stops turning when you twist the rocker arm to the left side with your fingers.

Now take note of where the rocker arm stops turning on the right side.

Reposition the rocker arm so that it is perpendicular across the steering servo when the underlying steering servo axis is exactly at the halfway point between the left and right stopping points that you just marked.

After you have adjusted the angle of the steering servo axis using the rocker arm, grab the servo horn.

2020-05-19-120733

Carefully remove the rocker arm by pulling it straight up off the steering servo axis. You want to be careful not to move the steering servo axis.

Fit the servo horn on top of the steering servo axis so that it looks like this. One of the holes of the servo horn should point straight forward.

Twist the servo horn from right to left. The rotation range should be 0-225°.

Once you are sure that the servo horn is positioned properly over the steering servo axis, secure it into place by placing a screw in the center.

2020-05-19-121511

Grab one of the long U-type brackets.

Slip the hole of the U-type bracket over the bearing on one side of the Multi-functional bracket.

Slip the other end of the U-type bracket over the top of the servo motor. The big hole of the U-type bracket should be over the screw.

2020-05-19-121620

Grab four M3*6 screws.

Place the four screws over the small holes of the long U-type bracket.

Move the U-type bracket from left to right. Make sure it has a full range of motion. It should hit the first U-type bracket when you twist it to the right. That is fine.

2020-05-19-122446

Now, we are going to attach a long U-type servo bracket to the U-type bracket you just secured.

Grab a long U-type servo bracket and four M3*6 screws and nuts.

Your robotic arm should have a full range of motion, backward and forwards.

2020-05-20-145630

Install the Elbow

Now, we need to install the elbow.

Grab the L-type servo bracket, a Mult-functional servo bracket, a bearing, an M3*10 screw, and a nut.

2020-05-20-150252

Attach the bearing to the Multi-functional servo bracket using the M3*10 screw and nut.

2020-05-20-150749

Grab two M3*6 screws and nuts. If you’ve run out of M3*6 screws, just use screws and nuts in the kit that are able to fit through the holes. Sometimes the kits don’t have all the screws you need, and it doesn’t help that the kit that I received came with unlabeled screws.

Attach the L-type servo bracket to the Mult-functional servo bracket as shown in the image below. Use the two screws and nuts.

2020-05-20-152217

Grab the last long U-type bracket.

2020-05-21-114542

Use two M3*6 screws and nuts to secure the U-type bracket to the L-type bracket.

2020-05-21-115308

Grab a servo motor.

Place the servo motor into the Mult-functional servo bracket.

Secure the servo motor into the Multi-functional servo bracket with four M3*8 screws and nuts. Again, don’t worry if you don’t have enough M3*8 screws and nuts. The goal is to use screws and nuts to secure the servo motor into the holder.

2020-05-21-120040

Grab one of the plastic rocker arms. It should be inside the bag that had your servo motor.

Insert the rocker arm on top of the steering servo. The grooves of the steering servo should fit nicely with the grooves of the rocker arm. 

2020-05-21-120132

Now take note of where the rocker arm stops turning on the right side.

Reposition the rocker arm so that it is perpendicular across the steering servo when the underlying steering servo axis is exactly at the halfway point between the left and right stopping points that you just marked.

After you have adjusted the angle of the steering servo axis using the rocker arm, grab the servo horn.

Carefully remove the rocker arm by pulling it straight up off the steering servo axis. You want to be careful not to move the steering servo axis.

Fit the servo horn on top of the steering servo axis so that it looks like this. 

Twist the servo horn from right to left. The rotation range should be 0-225°.

Once you are sure that the servo horn is positioned properly over the steering servo axis, secure it into place by placing a screw in the center.

2020-05-21-120458

Place the Multi-functional servo bracket (with attached servo motor) inside the top U-bracket.

Secure it into place with four screws.

2020-05-21-120853

Install the Wrist

Grab two Multi-functional brackets.

Get a bearing, a screw, and a nut. Attach them to one of the Multi-functional brackets.

2020-05-21-153906

Grab two M3*6 screws and nuts. Use these screws and nuts to connect the Multi-functional brackets together.

2020-05-21-155644

Grab a servo motor, and place it into one of the Multi-functional brackets.

2020-05-21-160651

Grab four M3*8 screws and secure the servo motor into place.

2020-05-21-161152

Grab the arm rudder and place it over the servo axis.

As we have done with other servo motors, the arm rudder should be straight up and down at the halfway point of the motion of the servo (when you twist to the left and right).

Once you are happy with the angle, take the arm rudder off, and replace it with a servo horn.

Stick a screw in the middle of the servo horn to tighten it.

2020-05-21-161528

Place the Mult-functional bracket in the U-type bracket.

Use the servo horn screws to secure the servo horn into place.

Install the Hand Servo

Grab another servo motor.

Place the servo motor into the Multi-functional bracket up top.

Secure the servo motor into the Multi-functional bracket using four screws and nuts.

Add the arm rudder on top of the servo axis, and do the same routing we have done before to find the halfway point. You want the arm rudder to be up and down across the servo motor at the halfway point.

2020-05-21-171153

Attach the Claw

Grab a screw and place it in the center of the hand servo horn.

Grab two screws and secure the claw to the hand servo horn.

Grab the last servo and four M3*6 screws.

Attach the last servo to the claw using the screws. If you run out of screws, feel free to pull some screws from the base of the robot.

2020-05-21-172349

Grab the arm rudder and place it on top of the servo axis.

Find the halfway point of the servo axis. When you find the halfway point place the arm rudder on top of the axis so that it points straight up and down.

Carefully take the arm rudder off.

Push the servo horn over the servo axis.

Use a small screw to secure the servo horn on the servo axis. The screw that you should use is the one with something that looks like a disk or a washer around the neck near the head. Don’t tighten it too tight.

Arrange the claw in the open position.

Grab two small black screws. 

Secure the loose piece of the claw to the servo horn using the two black screws.

Check that you’re able to open and close the claw. The claw should close completely.

That’s it. If you’ve gotten this far, you have assembled the body of your robotic arm.

Move the Robotic Arm

Your robotic arm has six motors (six degrees of freedom). To move your robotic arm, you can buy a six-channel digital servo tester (you can find them on eBay or AliExpress) and move them like I explain on this post.

All you need to do is connect your digital servo tester to a power source (i.e. 6V…which can be a 4xAA battery pack), and also connect your servos to the tester. You’ll be up and running in just a few minutes.

2-Way Communication Between Raspberry Pi and Arduino

In this tutorial, I’ll show you how to set up two-way communication between your Raspberry Pi and your Arduino. I’ve done something similar in the past, but let’s take a look at a simpler example.

Here is our end goal:

  • We will send a block of integers from the Raspberry Pi to the Arduino. 
  • We will then have the Arduino repeat those integers back to the Raspberry Pi. 
  • The Raspberry Pi will then print the integers it received from the Arduino.

A real-world application of two-way communication between Raspberry Pi and Arduino is when you have a robotic arm that needs to pick up an object from a conveyor belt in a warehouse (or factory) and place that object inside a bin. This task is commonly known as pick and place

A camera is mounted above the robotic arm. You want to have the Raspberry Pi detect and recognize objects via the camera (using computer vision software like OpenCV), do some calculations, and then send servo angle values to the Arduino. The Arduino will then move the servo motors accordingly so the robotic arm can pick up the object.

Prerequisites

  • You have the Arduino IDE (Integrated Development Environment) installed either on your personal computer or on your Raspberry Pi. I’m using Arduino Uno.
  • You have Raspberry Pi set up. (Raspberry Pi 3B, 3B+, 4, etc…doesn’t matter which one)

Directions

Send a String From Arduino to Raspberry Pi

Let’s get started by sending a string of text (“Hello World”) from your Arduino to your Raspberry Pi.

Write the following program and upload it to your Arduino. Save it as send_string_to_raspberrypi.ino

/*
Program: Send Strings to Raspberry Pi
File: send_string_to_raspberrypi.ino
Description: Send strings from Arduino to a Raspberry Pi
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 5, 2020
*/

void setup(){
  
  // Set the baud rate  
  Serial.begin(9600);
  
}

void loop(){
  
  // Print "Hello World" every second
  // We do println to add a new line character '\n' at the end
  // of the string.
  Serial.println("Hello! My name is Arduino.");
  delay(1000);
}

Before you connect the Arduino to your Raspberry Pi, you need to set up the Raspberry Pi so that it can receive data from the Arduino. We first need to figure out the port that connects the Arduino and the Raspberry Pi.

Turn on your Raspberry Pi, and open a new terminal window.

Update the list of packages on your system:

sudo apt-get update

Upgrade any outdated packages (optional):

sudo apt-get upgrade

Install the PySerial package.

python3 -m pip install pyserial
1-install-pyserialJPG

If you get an error, you need to install pip first. After you run the command below, then try installing PySerial again.

sudo apt install python3-pip

Open a new terminal window, and type the following command to get a list of all the ports that begin with the prefix tty.

ls /dev/tty*

Here is what you should see:

2-ls-dev-ttyJPG

Now, plug the USB (Universal Serial Bus) cable into your Arduino and connect that to the USB port of your Raspberry Pi.

Reboot your computer.

sudo reboot

Once you’ve rebooted the computer, type the command again in the terminal window on your Raspberry Pi:

ls /dev/tty*

You see the new port? You should see a new port with a name like /dev/ttyACM0. That is your Arduino.

3-ls-dev-tty-afterJPG

Another way to see all the USB devices connected to your Raspberry Pi is to use this command:

lsusb

Set the baud rate of that port (i.e. the speed of data communication over that port/channel). Let’s use 9600. 9600 isn’t set in stone. For other projects you could use 38400, 57600, 115200, etc.

stty -F /dev/ttyACM0 9600

Let’s check the baud rate to see if it is set properly.

stty -F /dev/ttyACM0
4-check-the-baud-rateJPG

Now, create a new folder that will store the code we are going to write.

cd Documents
mkdir pi_arduino_communication

Move inside that folder.

cd pi_arduino_communication

Install gedit, my favorite text editor.

sudo apt-get install gedit

Create a new Python program.

gedit receive_string_from_arduino.py

Write the following code and save it.

#!/usr/bin/env python3

###############################################################################
# Program: Receive Strings From an Arduino
# File: receive_string_from_arduino.py
# Description: This program runs on a Raspberry Pi. It receives a string from 
#  Arduino and prints that string to the screen.
# Author: Addison Sears-Collins
# Website: https://automaticaddison.com
# Date: July 5, 2020
###############################################################################

import serial # Module needed for serial communication

# Set the port name and the baud rate. This baud rate should match the
# baud rate set on the Arduino.
# Timeout parameter makes sure that program doesn't get stuck if data isn't
# being received. After 1 second, the function will return with whatever data
# it has. The readline() function will only wait 1 second for a complete line 
# of input.
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Get rid of garbage/incomplete data
ser.flush()

# Infinite loop
while (1):

  # If there is data available
  if(ser.in_waiting > 0):
  
    # Read everything until the new line character
    # Convert the data from a byte into a string of type 'utf-8'
    # You could also use 'ascii'
    # rstrip() function removes trailing characters like
    # the new line character '\n'
    line = ser.readline().decode('utf-8').rstrip()
	
    # Print the data received from the Arduino
    print(line)

Make it executable.

chmod +x receive_string_from_arduino.py

Now run the program.

./receive_string_from_arduino.py

You should see this print out to your screen.

5-receive-string-from-arduinoJPG

When you’re ready, press CTRL+C to stop the Python script.

Send a String From Raspberry Pi to Arduino

In this section, we will:

  1. Create a Python program that sends a string from the Raspberry Pi to the Arduino
  2. The Arduino will respond back to the Raspberry Pi with the string it has received.
  3. The Raspberry Pi will print out the string it received from the Arduino.

Let’s start by creating the program for the Arduino.

Create the following sketch, and upload it to your Arduino. Save it as receive_string_from_raspberrypi.ino.

/*
Program: Receive Strings From Raspberry Pi
File: receive_string_from_raspberrypi.ino
Description: Receive strings from a Raspberry Pi
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 5, 2020
*/

void setup(){
  
  // Set the baud rate  
  Serial.begin(9600);
  
}

void loop(){

  if(Serial.available() > 0) {
    String data = Serial.readStringUntil('\n');
    Serial.print("Hi Raspberry Pi! You sent me: ");
    Serial.println(data);
  }
}

Now go over to your Raspberry Pi, and open a new Python file.

Open a new terminal window, and type the following commands:

cd Documents/pi_arduino_communication
gedit send_strings_to_arduino.py

Write the following code and save it.

#!/usr/bin/env python3

###############################################################################
# Program: Send Strings to an Arduino From a Raspberry Pi
# File: send_strings_to_arduino.py
# Description: This program runs on a Raspberry Pi. It sends strings
#   to Arduino. It also receives the  string it sent
#   and prints it to the screen. This provides bi-directional (2-way) communication
#   between Arduino and Raspberry Pi.
# Author: Addison Sears-Collins
# Website: https://automaticaddison.com
# Date: July 5, 2020
###############################################################################

import serial # Module needed for serial communication
import time # Module needed to add delays in the code

# Set the port name and the baud rate. This baud rate should match the
# baud rate set on the Arduino.
# Timeout parameter makes sure that program doesn't get stuck if data isn't
# being received. After 1 second, the function will return with whatever data
# it has. The readline() function will only wait 1 second for a complete line 
# of input.
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Get rid of garbage/incomplete data
ser.flush()

# Infinite loop
while (1):

  send_string = ("My name is Raspberry Pi\n")
  
  # Send the string. Make sure you encode it before you send it to the Arduino.
  ser.write(send_string.encode('utf-8'))
  
  # Do nothing for 500 milliseconds (0.5 seconds)
  time.sleep(0.5)

  # Receive data from the Arduino
  receive_string = ser.readline().decode('utf-8').rstrip()

  # Print the data received from Arduino to the terminal
  print(receive_string)

Make it executable.

chmod +x send_strings_to_arduino.py

Plug your Arduino into your Raspberry Pi using the USB cable.

Now run the Python program.

./send_strings_to_arduino.py

You should see this print out to your screen.

6-send-strings-to-arduinoJPG

Press CTRL+C when you’re done.

Send Integers From Arduino to Raspberry Pi

Let’s create programs to send integers from Arduino to Raspberry Pi.

Upload the following code to your Arduino. Save the file as send_ints_to_raspberrypi.ino.

/*
Program: Send Integers to Raspberry Pi
File: send_ints_to_raspberrypi.ino
Description: Send integers from Arduino to a Raspberry Pi
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 5, 2020
*/

// Initialize the variables with some randomly-chosen integers
// that could represent servo motor angles, for example.
int servo_0_angle = 90;
int servo_1_angle = 7;
int servo_2_angle = 63;
int servo_3_angle = 85;
int servo_4_angle = 162;
int servo_5_angle = 45;

void setup(){
  
  // Set the baud rate  
  Serial.begin(9600);
  
}

void loop(){
  
  // Print integers every 500 milliseconds
  // We do println to add a new line character '\n' at the end
  // of the comma-separated stream of integers
  Serial.print(servo_0_angle); Serial.print(",");
  Serial.print(servo_1_angle); Serial.print(",");
  Serial.print(servo_2_angle); Serial.print(",");
  Serial.print(servo_3_angle); Serial.print(",");
  Serial.print(servo_4_angle); Serial.print(",");
  Serial.println(servo_5_angle); 
  delay(500);
}

Now go over to your Raspberry Pi. 

Open a new terminal and go to your folder.

cd Documents/pi_arduino_communication

Create a new Python program.

gedit receive_ints_from_arduino.py

Write the following code and save it.

#!/usr/bin/env python3

###############################################################################
# Program: Receive Integers From an Arduino
# File: receive_ints_from_arduino.py
# Description: This program runs on a Raspberry Pi. It receives comma-separated 
#  integers from Arduino and prints them to the screen.
# Author: Addison Sears-Collins
# Website: https://automaticaddison.com
# Date: July 5, 2020
###############################################################################

import serial # Module needed for serial communication

# Set the port name and the baud rate. This baud rate should match the
# baud rate set on the Arduino.
# Timeout parameter makes sure that program doesn't get stuck if data isn't
# being received. After 1 second, the function will return with whatever data
# it has. The readline() function will only wait 1 second for a complete line 
# of input.
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Initialize 6 integers
servo_0_angle = 90
servo_1_angle = 90
servo_2_angle = 90
servo_3_angle = 90
servo_4_angle = 90
servo_5_angle = 90

# Infinite loop
while (1):

  # Read everything until the new line character
  # Convert the data from a byte into a string of type 'utf-8'
  # You could also use 'ascii'
  line = ser.readline().decode('utf-8')

  # Take out the commas. Parse the string into a list.
  parsed = line.split(',')
	
  # rstrip() function removes trailing characters like
  # the new line character '\n' and '/r'. Also removes
  # white space.
  parsed = [x.rstrip() for x in parsed]
	
  # We know we need to receive 6 integers. This code helps with any loss
  # of data that might happen as data is transferred between Arduino
  # and the Raspberry Pi.
  if(len(parsed) > 5):
    print(parsed)
	  
    # We add the '0' character to the end of each item in the 
    # parsed list. This makes sure that there are no empty
    # strings in the list. Adding 0 makes sure that we have
    # at least 6 string values we can convert into integers.
    # Dividing by 10 removes the trailing 0 but it makes the integer a float.
    # We then have to convert the float to an integer.
    servo_0_angle = int(int(parsed[0]+'0')/10)
    servo_1_angle = int(int(parsed[1]+'0')/10)
    servo_2_angle = int(int(parsed[2]+'0')/10)
    servo_3_angle = int(int(parsed[3]+'0')/10)
    servo_4_angle = int(int(parsed[4]+'0')/10)
    servo_5_angle = int(int(parsed[5]+'0')/10)
  print("Servo 0 Angle: " + str(servo_0_angle))
  print("Servo 1 Angle: " + str(servo_1_angle))
  print("Servo 2 Angle: " + str(servo_2_angle))
  print("Servo 3 Angle: " + str(servo_3_angle))
  print("Servo 4 Angle: " + str(servo_4_angle))
  print("Servo 5 Angle: " + str(servo_5_angle))
	
  # This line proves that we have successfully converted the strings
  # to integers.
  print("Sum of Servos 0 and 1: " + str(servo_0_angle + servo_1_angle))

Make it executable.

chmod +x receive_ints_from_arduino.py

Plug your Arduino into your Raspberry Pi using the USB cable.

Now run the Python program.

./receive_ints_from_arduino.py

You should see this print out to your screen.

7-receive-ints-from-arduinoJPG

Send Integers From Raspberry Pi to Arduino

Let’s put it all together. We will:

  1. Create a Python program that sends integers from the Raspberry Pi to the Arduino.
  2. The Arduino will respond back to the Raspberry Pi with the integers it has received.
  3. The Raspberry Pi will print out the integers it received from the Arduino.

Let’s start by creating the program for the Arduino.

Create the following sketch, and upload it to your Arduino. Save it as receive_ints_from_raspberrypi.ino.

/*
Program: Receive Integers From Raspberry Pi
File: receive_ints_from_raspberrypi.ino
Description: Receive integers from a Raspberry Pi
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 5, 2020
*/

// Initialize the integer variables
int servo_0_angle = 90;
int servo_1_angle = 90;
int servo_2_angle = 90;
int servo_3_angle = 90;
int servo_4_angle = 90;
int servo_5_angle = 90;

int sum = 0;

void setup(){
  
  // Set the baud rate  
  Serial.begin(9600);
  
}

void loop(){

  if(Serial.available() > 0) {
    servo_0_angle = Serial.parseInt();
    servo_1_angle = Serial.parseInt();
    servo_2_angle = Serial.parseInt();
    servo_3_angle = Serial.parseInt();
    servo_4_angle = Serial.parseInt();
    servo_5_angle = Serial.parseInt(); 

    // Compute a sum to prove we have integers
    sum = servo_0_angle + servo_1_angle;

    // We do println to add a new line character '\n' at the end
    // of the comma-separated stream of integers
    Serial.print(servo_0_angle); Serial.print(",");
    Serial.print(servo_1_angle); Serial.print(",");
    Serial.print(servo_2_angle); Serial.print(",");
    Serial.print(servo_3_angle); Serial.print(",");
    Serial.print(servo_4_angle); Serial.print(",");
    Serial.print(servo_5_angle); Serial.print(",");
    Serial.println(sum); 
  }
}

Now go over to your Raspberry Pi, and open a new Python file.

gedit send_ints_to_arduino.py

Write the following code and save it.

#!/usr/bin/env python3

###############################################################################
# Program: Send Integers to an Arduino From a Raspberry Pi
# File: send_ints_to_arduino.py
# Description: This program runs on a Raspberry Pi. It sends integers
#   to Arduino in comma-separated format. It also receives the integers it sent
#   and prints them to the screen. This provides bi-directional (2-way) communication
#   between Arduino and Raspberry Pi.
# Author: Addison Sears-Collins
# Website: https://automaticaddison.com
# Date: July 5, 2020
###############################################################################

import serial # Module needed for serial communication
import time # Module needed to add delays in the code

# Set the port name and the baud rate. This baud rate should match the
# baud rate set on the Arduino.
# Timeout parameter makes sure that program doesn't get stuck if data isn't
# being received. After 1 second, the function will return with whatever data
# it has. The readline() function will only wait 1 second for a complete line 
# of input.
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Intialize the integer values we'll send to Arduino
servo_0_angle = 90
servo_1_angle = 7
servo_2_angle = 63
servo_3_angle = 85
servo_4_angle = 162
servo_5_angle = 45

# Get rid of garbage/incomplete data
ser.flush()

# Infinite loop
while (1):

  # Convert the integers to a comma-separated string
  angle_value_list = [str(servo_0_angle),str(servo_1_angle),str(
    servo_2_angle),str(servo_3_angle),str(servo_4_angle),str(servo_5_angle)]	
  send_string = ','.join(angle_value_list)
  send_string += "\n"

  # Send the string. Make sure you encode it before you send it to the Arduino.
  ser.write(send_string.encode('utf-8'))

  # Receive data from the Arduino
  receive_string = ser.readline().decode('utf-8', 'replace').rstrip()

  # Print the data received from Arduino to the terminal
  print(receive_string)

Make it executable.

chmod +x send_ints_to_arduino.py

Plug your Arduino into your Raspberry Pi using the USB cable.

Now run the Python program.

./send_ints_to_arduino.py

You should see this print out to your screen.

8-send_ints_to_arduinoJPG

Note that instead of receive_ints_from_raspberrypi.ino, you can use this code (receive_ints_from_raspberrypi_strings.ino). It is a bit more complicated (and takes up almost double the amount of memory), but the output is exactly the same. This is to show you that there are many ways to skin the cat:

/*
Program: Receive Integers From Raspberry Pi
File: receive_ints_from_raspberrypi_strings.ino
Description: Receive integers from a Raspberry Pi
Author: Addison Sears-Collins
Website: https://automaticaddison.com
Date: July 5, 2020
*/

// Initialize the integer variables
int servo_0_angle = 90;
int servo_1_angle = 90;
int servo_2_angle = 90;
int servo_3_angle = 90;
int servo_4_angle = 90;
int servo_5_angle = 90;

// Initialize the String variables
String servo_0_angle_str = "";
String servo_1_angle_str = "";
String servo_2_angle_str = "";
String servo_3_angle_str = "";
String servo_4_angle_str = "";
String servo_5_angle_str = "";

int sum = 0;

// Get ready to accept comma-separated values
int comma_position;

void setup(){
  
  // Set the baud rate  
  Serial.begin(9600);
  
}

void loop(){

  if(Serial.available() > 0) {

    // Read string until the new line character
    String data = Serial.readStringUntil('\n');

    // There are 6 integers we will be receiving from the
    // Raspberry Pi

    // Integer 0
    comma_position = data.indexOf(',');   
    servo_0_angle_str = data.substring(0,comma_position);
    servo_0_angle = servo_0_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Integer 1
    comma_position = data.indexOf(',');   
    servo_1_angle_str = data.substring(0,comma_position);
    servo_1_angle = servo_1_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Integer 2
    comma_position = data.indexOf(',');   
    servo_2_angle_str = data.substring(0,comma_position);
    servo_2_angle = servo_2_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Integer 3
    comma_position = data.indexOf(',');   
    servo_3_angle_str = data.substring(0,comma_position);
    servo_3_angle = servo_3_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Integer 4
    comma_position = data.indexOf(',');   
    servo_4_angle_str = data.substring(0,comma_position);
    servo_4_angle = servo_4_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Integer 5
    comma_position = data.indexOf(',');   
    servo_5_angle_str = data.substring(0,comma_position);
    servo_5_angle = servo_5_angle_str.toInt();
    data = data.substring(comma_position+1, data.length());

    // Compute a sum to prove we have integers
    sum = servo_0_angle + servo_1_angle;

    // We do println to add a new line character '\n' at the end
    // of the comma-separated stream of integers
    // The stuff below is ready by the Raspberry Pi
    Serial.print(servo_0_angle); Serial.print(",");
    Serial.print(servo_1_angle); Serial.print(",");
    Serial.print(servo_2_angle); Serial.print(",");
    Serial.print(servo_3_angle); Serial.print(",");
    Serial.print(servo_4_angle); Serial.print(",");
    Serial.print(servo_5_angle); Serial.print(",");
    Serial.println(sum); 
  }
}

That’s it for this tutorial. Keep building!