Guitar-Playing Robot

Project Goal: To create an autonomous guitar-playing robot that can play any song autonomously

Personal Goal: To merge my skillset across different disciplines (electrical, mechanical, and software) through a project of interest while growing in these areas as well

Technologies used: 

Project Breakdown: The project is broken into two systems. 1) the neck subsystem, which is in charge of pressing down on the strings, and 2) the soundhole subsystem which will strum the strings when appropriate. Note that currently only the first system has been implemented and the second is in the design phase. Hence, when talking about the project I will be referring to the neck subsystem.

Song Played: Riptide by Vance Joy

How it Works

The project works as follows:

First, I will make the remark that the chordbox notation is used to represent a chord as it is the simplest and optimal description form to be used in code. This is because chordbox notation is comprised of six characters made up of numbers and letters. The characters are ordered in terms of the strings (i.e the fourth character corresponds to the fourth string). The letters, "X" or "O" , depict strings that are not pressed where 0 means it is also not strummed ("X" is). The numbers indicate the fret position at which the string is pressed. Consequently, given the chordbox for a C chord, "X32010" it means we are placing the servo arms pressed against the strings for the second string on the third fret, the third string on the second fret and the fifth string on the first fret. Then when strumming we strum all but the fourth and sixth strings.

This process involves three files:

"Chords.txt" - list in the form: (chord):(chordbox notation). For example, A minor will read Am:X02210. 

"(song name)_chords.txt" - Chords used in a specific song in order

"Translated_(song name)_chords.txt" - The output of the python code which gives motor positions. For example, "AP66" instructs the DC motor A to move to a position 66mm below the top of the neck and have the servo press down on the string (indicated by the "P").

 The python script works as follows:

The script opens the song_chords file and creates a list with all the chords that are used in the song. Then it cross-references each chord using the chords file to have them in chrodbox notation. In addition, there is a dictionary that associates each fret with its corresponding distance in millimeters. Now, the script creates a new text file that will hold the translated chords. As the code reads through the song_chords file, it appends six new lines to the translated file which indicates the current chord. Each new line in the text file is representative of what is happening at each string (as per the example given in the second file description).


Due to Arduino Mega constraints, the compatible microSD card's must be very small compared to what is currently available on the market, however, the 512MB card used is more than enough to hold multiple text files each with the translated chords for many songs so that if desired, the guitar could play songs back-to-back. This also means that if we want to add a song all we have to do is run the python script for the new song and upload it to the microSD card.


In order to make sure that the buttons are pressed, the servo carts have a cylinder extrusion on the side facing the top of the neck that will come in contact and push the buttons indicating they are at the top of the neck and the song can begin to play.


There are six DC geared motors each with a magnetic encoder which allows me to keep track of how many rotations it has done. Since these DC motors control the positioning of the servo carts via the belt, I convert the linear distance that each cart must travel to the number of rotations needed from its DC motor. Since the carts move a lot while performing a song, a deviation between the current position and the desired one appears over time (friction on the track, inertia of DC motors shaft, etc..). To fix this problem I used a Proportional, Integral, and Derivative (PID) controller which minimizes the error. Hence, the code ensures that the servos are all within a certain range of their desired position before indicating them to press down on the strings accordingly. 

SPECIFICS

Rotational and Translational Converters:  DC motor rotations will control the position of the servo carts along the neck of the guitar (translational distance) which will dictate the chord that will be played at any given moment. The Arduino code file contains converter functions that determine the number of rotations required by a DC motor so that the servo cart travels a desired translational distance to play a particular chord. This conversion facilitates the use of encoders as feedback for the PID controller.

Use of PID controller:  In order to minimize the error in the positioning of the servo carts (determined by the DC motors) the PID controller finds the optimal speed at which the motors should move so that the servo carts achieve their desired position. As the servo carts approach this position, the PID controller output speed will decrease toward zero. It is important to note that the DC motors run less reliably at very small speeds. As a result, a design decision was made to set a minimum speed value for which when the PID output speed is smaller than this value, the servo cart speed will be set to zero as the cart must already be within a certain range of its desired position. 

Encoders: The micro metal DC gear motors have magnetic encoders on their rear shaft which allows for their rotations to be tracked by the code using interrupts. The encoders are used by the PID controller to know the deviation of the motor's current and desired number of rotations, hence, working as a feedback system to improve the accuracy in setting up a chord. Note that the desired number of rotations is found in the output of the translational-to-rotations function (given the desired translational distance).

Motor Driver: The motor driver used in the project is the DVR8833 as it can handle two DC motors per board and can be driven in both directions enabled by dual H-bridges. Furthermore, the necessary 6V to run the DC motors is well within the range of the motor driver, and the maximum output current is more than enough for what the motors require.

Power: A 12V AC to DC power converter with up to 5A is used with a DC-DC adjustable step-down buck converter to power all six DC motors. 

Components List