5 Commits

Author SHA1 Message Date
Sam Perry 1f7043f2ed Finished bonus section 2016-10-02 09:48:02 +01:00
Sam Perry 727885e6be Finished vibrato section 2016-10-01 22:03:53 +01:00
Sam Perry ecd35bfffa Finished keyboard section 2016-10-01 21:29:24 +01:00
Sam Perry 4471b9c224 Minor changes to writeup 2016-10-01 13:59:30 +01:00
Sam Perry a8e8bea6e4 Initial commit
Created blank .tex document
Added images to resources folder.
2016-10-01 11:53:59 +01:00
7 changed files with 157 additions and 141 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 985 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

-112
View File
@@ -1,112 +0,0 @@
"""
ldr.py
Display analog data from Arduino using Python (matplotlib)
Author: Mahesh Venkitachalam
Website: electronut.in
"""
import sys, serial, argparse
import numpy as np
from time import sleep
from collections import deque
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# plot class
class AnalogPlot:
# constr
def __init__(self, strPort, maxLen):
# open serial port
self.ser = serial.Serial(strPort, 9600)
self.ax = deque([0.0]*maxLen)
self.ay = deque([0.0]*maxLen)
self.maxLen = maxLen
# add to buffer
def addToBuf(self, buf, val):
if len(buf) < self.maxLen:
buf.append(val)
else:
buf.pop()
buf.appendleft(val)
# add data
def add(self, data):
assert(len(data) == 2)
self.addToBuf(self.ax, data[0])
self.addToBuf(self.ay, data[1])
# update plot
def update(self, frameNum, a0, a1):
try:
line = self.ser.readline()
data = [float(val) for val in line.split()]
# print data
if(len(data) == 2 and not pause):
self.add(data)
a0.set_data(range(self.maxLen), self.ax)
a1.set_data(range(self.maxLen), 0)
except KeyboardInterrupt:
print('exiting')
if not pause:
return a0,
# clean up
def close(self):
# close serial
self.ser.flush()
self.ser.close()
pause = False
def onClick(event):
global pause
pause = not pause
# main() function
def main():
# create parser
parser = argparse.ArgumentParser(description="LDR serial")
# add expected arguments
parser.add_argument('--port', dest='port', required=True)
# parse args
args = parser.parse_args()
#strPort = '/dev/tty.usbserial-A7006Yqh'
strPort = args.port
print('reading from serial port %s...' % strPort)
# plot parameters
analogPlot = AnalogPlot(strPort, 300)
print('plotting data...')
# set up animation
fig = plt.figure()
ax = plt.axes(xlim=(0, 300), ylim=(0, 1023))
a0, = ax.plot([], [])
a1, = ax.plot([], [])
fig.canvas.mpl_connect('button_press_event', onClick)
anim = animation.FuncAnimation(fig, analogPlot.update,
fargs=(a0, a1),
frames=None,
interval=50)
# show plot
plt.show()
# clean up
analogPlot.close()
print('exiting.')
# call main
if __name__ == '__main__':
main()
-29
View File
@@ -1,29 +0,0 @@
// analog-plot
//
// Read analog values from A0 and A1 and print them to serial port.
//
// electronut.in
#include "Arduino.h"
void setup()
{
// initialize serial comms
Serial.begin(9600);
}
void loop()
{
// read A0
int val1 = analogRead(0);
// read A1
int val2 = analogRead(1);
// print to serial
Serial.print(val1);
Serial.print(" ");
Serial.print(val2);
Serial.print("\n");
// wait
delay(50);
}
+157
View File
@@ -0,0 +1,157 @@
\documentclass[titlepage]{scrartcl}
\usepackage{enumitem}
\usepackage[british]{babel}
\usepackage[style=apa, backend=biber]{biblatex}
\DeclareLanguageMapping{british}{british-apa}
\usepackage{url}
\usepackage{float}
\usepackage[labelformat=empty]{caption}
\restylefloat{table}
\usepackage{perpage}
\MakePerPage{footnote}
\usepackage{abstract}
\usepackage{graphicx}
% Create hyperlinks in bibliography
\usepackage{hyperref}
\usepackage{amsmath}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{blindtext}
\setkomafont{disposition}{\normalfont\bfseries}
\graphicspath{
{./resources/},
}
\addbibresource{~/Documents/library.bib}
\newsavebox{\abstractbox}
\renewenvironment{abstract}
{\begin{lrbox}{0}\begin{minipage}{\textwidth}
\begin{center}\normalfont\sectfont\abstractname\end{center}\quotation}
{\endquotation\end{minipage}\end{lrbox}%
\global\setbox\abstractbox=\box0 }
\usepackage{etoolbox}
\makeatletter
\expandafter\patchcmd\csname\string\maketitle\endcsname
{\vskip\z@\@plus3fill}
{\vskip\z@\@plus2fill\box\abstractbox\vskip\z@\@plus1fill}
{}{}
\makeatother
\DeclareCiteCommand{\citeyearpar}
{}
{\mkbibparens{\bibhyperref{\printdate}}}
{\multicitedelim}
{}
\begin{document}
\title{ECS742\\Interactive Digital Media Techniques\\Mini-Assignment 1: Arduino}
\subtitle{\LARGE{Technical Report}}
\author{Sam Perry\\Student Number: 160842984}
\date{}
\maketitle
\section{Connecting and reading the FSR}
Initially, a circuit was created to demonstrate the reading of values from
the FSR (Force Sensitive Resistor). A 5V supply was used to pass a current
through the resistor, which was measured via analog input 0. A 10kohm
pull-down resistor was connected to ground between the FSR and the input.
This was necessary to avoid a direct connection between the 5V supply and
ground at points when the FSR provides little to no resistance. This also
creates a consistently low value to input when resistance from the FSR
is high, avoiding unpredictable floating readings caused by a disconnected
input.\\
\begin{figure}[H]
\makebox[\textwidth]{\includegraphics[width=0.35\textwidth]{Step1}}
\end{figure}
Code was written to print values to the serial port. A Python script was
used to record these values as shown:
\begin{figure}[H]
\caption{Value measured over time. A sharp increase in pressure followed by a gradual release is displayed.}
\makebox[\textwidth]{\includegraphics[width=0.75\textwidth]{FSR_Linearity}}
\end{figure}
From these readings it can be seen that there is a non-linear relationship
between applied pressure and measurement. As the voltage measured is
proportional to the inverse of the FSR resistance \parencite{ada2016},
voltage increases at what appears to be an exponentially decreasing rate as
resistance increase at the same rate.
\section{Using the FSR values to create a tone}
Building on the circuit developed in step 1, a speaker was attached. The
speaker was connected to digital output 8 and to ground. Code was written
to read input from the FSR, scale values to fall between pre-determined
high and low values, and output a tone of the frequency specified for 20ms.
The result is an instrument that outputs rapid short tones that increase in
pitch based on pressure applied.
\begin{figure}[H]
\makebox[\textwidth]{\includegraphics[width=0.35\textwidth]{Step2}}
\end{figure}
The speaker is capable of producing tones as low as around 100hz. Below
this, the tone begins to lose it's tonal quality and the rhythmic
characteristics become more prominent. The speaker can also produce tones
as high as around 10Khz, however perceived loudness deteriorates beyond
5-6Khz.\\
The instruments is capable of producing interesting melodies and has a
tactile response. However the lack of control over amplitude and the
inaccuracy of the resistor result in difficulties when trying to perform a
sequence of specific notes. This could be improved reducing the range of
playable frequencies. This would allow for greater pitch accuracy at a cost
of a lower range of possible tones.
\section{Using buttons to make a simple keyboard}
Buttons were then added to the instrument. This allows a user to play 8
tones in a chromatic scale. Each button was attached to the circuit in a
similar fashion to that of the FSK. Pull down resistors were used and each
button was assigned a digital input, allowing the arduino to determine the
state of the button as being on (HIGH) or off (LOW). Although this method
worked corectly, an alternative method using a "resistor ladder" is
detailed in the arduino projects book~\parencite[p.79]{arduino2015}. This
would allow for the same performance, whilst using only one analog input as
opposed to the 8 digital inputs as used in this implementation. The
arduino was then programmed to iterate across buttons until an active
button was found. An array of note frequencies would then be accessed by
index to determine the button's note frequency. This could then be played
through the built in tone function using the speaker.\\
\begin{figure}[H]
\makebox[\textwidth]{\includegraphics[width=0.35\textwidth]{Step3}}
\end{figure}
The instrument is now able to play precise tones with far greater accuracy
than was possible using the FSR. However, this comes at the cost of the
tactile and expressive control offered by the FSR. The limit of available
notes and lack of touch sensitivity make for an unintuitive playing
experience.
\section{Adding vibrato using the FSR}
Vibrato was added to the keyboard instrument by scaling the values from the
FSR based on the output pitch. By calculating the output pitch +/- 5\%, the
pitch could be modulated by scaling FSR values to within these upper and
lower boundaries. This allows the user to vary the pitch with the
expressivity of the FSR whilst maintaining a degree of accuracy from the
button based input. A issue arises in the FSR resting at it's lowest value,
forcing a player to modulate upwards from -5\% rather than beginning at the
pitch specified by the button. This may cause issues for a performer with
regards to staying in tune, as a performer would have to consistently apply
pressure to stay at the centre frequency of any given note. An
alternative would be to start at the desired frequency and bend up or down
only, although this may alter the pitch too far from the initial pitch.
Another alternative might be to have two FSRs, one for each direction.
However, this would not allow for the same level of smoothness around the
centre frequency due to the need to switch.
\section{Bonus - Melody Playback}
Melody playback was implemented by iterating over an array of note indexes
on each button press. Button state was stored in a variable to allow melody
position to be incremented over repeated presses of the button. Melody
position was reset to 0 at the end of each loop to allow for continuous
looping of the melody.
\printbibliography
\end{document}