How to remote control a Servo Motor (SG90) using Raspberry PI Zero W with Python and Arduino

Last Updated on

This article shows you how to remotely control a SG90 servo motor from Raspberry PI and Arduino Uno.

At the end of his procedure, we’ll connect with a remote SSH session to Raspberry PI and we’ll move Servo Motor by pressing “a”, “s” and “d” keys from our computer.

Elegoo SG90 Servo Motor

Servo is a type of geared motor that can only rotate 180 degrees. It is controlled by sending electrical pulses which tell the servo what position it should move to. The Servo has three wires, of which one is the ground wire (brown) and should be connected to GND, one is the power wire (red) and should be connected to a 5v port, and one is the signal wire (orange) and should be connected to a PWM port.

Servo motor are also Power hungry. While Arduino are capable to manage their power requirements, Raspberry PI is less permissive. Following guide works fine with a Raspberry PI Zero W powered from a proper power supply, but I suggest to use also a Power supply directly connected to Arduino Board.

For this article, I’m going to use a Raspberry PI Zero W with soldered header. But this article apply also to other Raspberry PI boards.

What We Need

As usual, I suggest adding from now to your favourite ecommerce shopping chart all needed hardware, so that at the end you will be able to evaluate overall costs and decide if continuing with the project or removing them from shopping chart. So, hardware will be only:

Raspberry PI Zero WH board
Raspberry PI Zero WH board

You can also use newer Raspberry PI boards instead of Raspberry PI Zero W. This guide will use an Elegoo UNO as Arduino board. You may find useful evaluating a sensors kit (like Elegoo Starter Kit). This is a cost saving solution if you want to test many sensors for different purposes and also includes an Elegoo Uno board.

Step-by-Step Procedure

Wiring Diagram

Please refer to following picture for wiring:

Raspberry PI Arduino Elegoo SG90 Servo Motor wiring

Install OS (Raspbian Buster Lite)

Follow instructions available at Install Raspbian Buster Lite in your Raspberry PI and connect via remote ssh.

Make sure your OS is up to date with following commands:

sudo apt update
sudo apt upgrade

Install required Python packages and libraries

We need to start from arduino-cli (refer to Connecting Raspberry PI Zero W to Arduino). Following instruction will go ahead description, that can be found in referred page. From Raspberry PI terminal:

mkdir -p local/bin
echo 'export PATH="$HOME/local/bin:$PATH"' >> .bashrc
source .profile
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/home/pi/local/bin sh
arduino-cli config init
arduino-cli core update-index

Connect now your Arduino board to Raspberry PI USB port. From Raspberry PI terminal:

arduino-cli board list

Following step may change if you received an output different from “Arduino Uno arduino:avr:uno arduino:avr” (which is Elegoo Uno board). In this case, please refer how to proceed with detailed descriptions in Connecting Raspberry PI Zero W to Arduino. In case you are using Elegoo Uno board, from Raspberry PI terminal:

arduino-cli core install arduino:avr
echo 'alias acompile="arduino-cli compile --fqbn arduino:avr:uno" ' >> ~/.bashrc
echo 'alias aupload="arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:avr:uno"' >> ~/.bashrc
source .profile

Create Servo Libary

This part refers to Installing external libraries with arduino-cli article. We’ll create a folder for Arduino libraries and we’ll get Servo library from my download page. You can anymore dowload i from your favourite source and un zip taking attention to Installing external libraries with arduino-cli recommendations on libraries tree. From Raspberry PI terminal:

mkdir -p Arduino/libraries
cd Arduino/libraries
wget https://peppe8o.com/download/arduino_lib/Servo.zip
unzip Servo.zip
cd -

Install Pyserial

To use Raspberry PI USB as a serial port, we’ll need miniterm (refer to Reading a serial USB port from Raspbian Buster Lite with Python). From Raspberry PI terminal:

sudo apt install python3-pip
pip3 install pyserial

Create, Compile and Upload Servo Motor Sketch

Here comes the new. From Rapsberry PI terminal, create an empty sketch with arduino-cli:

arduino-cli sketch new servo_sketch

This will create a new folder (“servo_sketch”) containing only a file “servo_sketch.ino” with a void basic sketch. Edit it:

nano servo_sketch/servo_sketch.ino

empty this file and copy following code. Descriptions are near each row.

#include <Servo.h>

Servo myservo; // create servo object to control a servo
char receivedPos;

void setup() {
 Serial.begin(9600);
 myservo.attach(9); // attaches the servo on pin 9 to the servo object
 myservo.write(90); // on power on, move servo to central position
 Serial.println("Welcome!"); // banner on connection with instructions
 Serial.println("Use following keys to control SG90 Servo Motor");
 Serial.println("a: moves to absolute position 180 dregrees");
 Serial.println("s: moves to absolute position 90 dregrees");
 Serial.println("d: moves to absolute position 0 dregrees");
 Serial.println("other keys: no moves");
}

void loop() {
 while(Serial.available()) {
  String commands = Serial.readString(); // read the incoming data as string
  Serial.println("I read string: "+ commands); // feedback of data received
  receivedPos = commands.charAt(0); // convert to char to enable Switch Statement use
  switch (receivedPos) {
   case 'a': myservo.write(180); break;
   case 's': myservo.write(90); break;
   case 'd': myservo.write(0); break;
   default: break;
  }
 }
}

You can also download from this from following my download area link: servo_sketch.ino. Compile and upload to your Arduino from Raspberry PI terminal:

acompile servo_sketch/ && aupload servo_sketch/

Use the sketch

This sketch listens to serial port incoming keys and uses “a”, “s” and “d” to move servo motor. From Raspberry PI type:

python3 -m serial.tools.miniterm

this should return:

pi@raspberrypi:~ $ python3 -m serial.tools.miniterm
--- Available ports:
--- 1: /dev/ttyACM0 'ttyACM0'
--- 2: /dev/ttyAMA0 'ttyAMA0'
--- Enter port index or full name:

Type 1 to select ttyACM0 (for Elegoo Uno, or the one corresponding to your Arduino board port) and press ENTER. Servo motor will go by default to a center position (90 degrees), then a usage banner will be show and terminal goes in listening mode:

pi@raspberrypi:~ $ python3 -m serial.tools.miniterm
--- Available ports:
--- 1: /dev/ttyACM0 'ttyACM0'
--- 2: /dev/ttyAMA0 'ttyAMA0'
--- Enter port index or full name: 1
--- Miniterm on /dev/ttyACM0 9600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Welcome!
Use following keys to control SG90 Servo Motor
a: moves to absolute position 180 dregrees
s: moves to absolute position 90 dregrees
d: moves to absolute position 0 dregrees
other keys: no moves

Now press “a” or “s” or “d” keys at your choice to move servo to full left (“a” key”). center (“s” key”) or full right (“d” key). Other keys will not give effects. While pressing a key, terminal will give you a feedback with read button. Be aware to wait for a very little while from eache key pression (9600 baud serial port is something different from an ADSL…:) ).

Use Ctrl+] to exit.

Enjoy!