Controlling a Servo with Arduino

Servo motors are digitally controlled actuators, which allow the precise setting of angles via pulse-width encoding. Servos used in RC models are low-cost and easy to program, which makes them attractive for prototyping in sound art and other DIY projects. The following example is a copy of the original example at Arduino.


Breadboard Wiring

Connecting the servo motor to the Arduino requires no additional parts, except for jumper cables. It is directly powered from the Arduino's 5V pin (larger servos may require an additional power source) and receives data from the Pulse-With-Modulation pin ~9:

Arduino breadboard wiring for servo motor.

Arduino breadboard wiring for servo motor.


Arduino Code

The following code lets the sweep 180 degrees forward and backward, managed by two for loops (count up / count down) inside the main loop. Most consumer servos manage this range from 0 to 180 degrees and wrap exceeding values accordingly.

#include <Servo.h>

Servo myservo;
int pos = 0;

void setup() {
  myservo.attach(9);
}

void loop() {

  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);
    delay(15);
  }

  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}

Exercise

Diffusion

Following the tradition of Pierre Schaeffer, Diffusion refers to the live spatialization of tape music, respectively fixed media content. Typically, the music is played back in a low channel order (e.g. Stereo) and sent to a large number of loudspeakers using an 'inverted' mixing desk.

/images/spatial/natasha_villa.jpg

Natasha Barrett diffusing on a 3D system at a TU Studio concert (Villa Elisabeth, 2018).


The Acousmonium

The GRM (Groupe de Recherche Musicale) Acousmonium is an elaborate loudspeaker setup, designed for the diffusion of acousmatic music. It is made for touring and was first presented in Germany at the 1983 “Inventionen” festival by François Bayle. The system returned to Berlin for the 2008 edition of the SMC, where it was paired with the large WFS system at TU Berlin's H104:

/images/spatial/acousmonium_H104.JPG

The Acousmonium at TU Berlin (H104) during SMC 2008.


The BEAST

The Birmingham Electroacoustic Sound Theater (BEAST) is a modern version of the Acousmonium approach. It features 100+ loudspeakers in multiple groups with specific characteristics and purposes:

/images/spatial/beast_setup.JPG

Different loudspeakers of the BEAST system.

/images/spatial/beast_sketch.png

BEAST setup at CBSO Centre, Birmingham, May 2009 (Wilson, 2010).

The BEAST was presented in Berlin at the 2010 Inventionen Festival, when Jonty Harrisson was guest professor at TU Berlin. Read more in the online archive of the festival.

/images/spatial/BEAST_kirche.jpg

BEAST at Inventionen Festival 2008 (Elisabethkirche, Berlin).


References

2010

Receiving OSC in SuperCollider

OSCFunc

By default, a running instance of sclang listens to incoming OSC messsages on the port 57120. For listening to a specific OSC message, an OSC function can be defined with a specific path. SC will then evaluate the defined function when OSC messages are received at the default port with the matching path:

~osc_receive = OSCFunc(

{ arg msg, time, addr, recvPort;

post('Revceived message to path: ');
msg[0].postln;

post('With value: ');
msg[1].postln;

}, '/test/message');

Exercise


OSCdef

OSCdef is more flexible and allows to change definitions on the fly, without deleting nodes (the OSCdef identifier does not have to match the OSC path - but it does in this example):

OSCdef(\poster,

        {|msg, time, addr, recvPort|

        post('With value: ');
        msg[1].postln;

},'/poster', n);

Exercises


Opening Specific UDP Ports

For many applications it can be helpul to open a specific port for a puropse. Sometimes the server booting process can be interrupted by messages being sent to ''57120'' before booting is competed. An additional port can be opened like this:

thisProcess.openUDPPort(6666);

A list of all open ports can be queried from the language:

thisProcess.openPorts

Using OSC in Pure Data

Vanilla Only

Sending OSC

The default version of PD is referred to as Vanilla. OSC can be used in Puredata without further packages, by means of the ojects netsend, oscformat and oscparse. The patch osc-send-vailla.pd sends a message to port 6666 on the localhost (127.0.0.1). The message has the following structure and contains one float argument:

/oscillator/frequency/ [float]

/images/basics/pd-osc-send-vanilla.png

Receiving OSC

The corresponding receiver patch osc-receive-vanilla.pd listens on port 6666. Using the route object, the message is unwrapped until the single float argument can be processed by the number box:

/images/basics/pd-osc-receive-vanilla.png

Using Externals

Dependencies

Sending OSC

The following example is based on additional externals. For using them, install the external mrpeach with the Deken tool inside Puredata: https://puredata.info/docs/Deken The send patch uses the hostname localhost instead of an IP address. The path /oscillator/frequency of the OSC message has been defined arbitrarily - it has to match between client and receiver. Before sending OSC messages, the connect message needs to be clicked.

/images/basics/pd-osc-send.png

Receiving OSC

Before receiving OSC messages, the udpreceive object needs to know which port to listen on. Messages are then unpacked and routed according to their path, using the routeOSC object.

/images/basics/pd-osc-receive.png


References

1997

  • Miller S. Puckette. Pure Data. In Proceedings of the International Computer Music Conference (ICMC). Thessaloniki, \\ Greece, 1997.
    [details] [BibTeX▼]

1988

  • Miller S. Puckette. The patcher. In Proceedings of the International Computer Music Conference (ICMC). Computer Music Association, 1988.
    [details] [BibTeX▼]

Digital Filters

Digital filters are delay-based processing units. In short: they affect a signal by overlapping it with delayed versions of the same signal. There are two basic categories of digital filters:

FIR filters

Finite Impulse Response (FIR) filters can be considered simple convolution processors. They are implemented without recursion, respectively feedback. IIR filters are robust and easy to design, yet they are more CPU expensive.

IIR Filters

Infinite Impulse Response (IIR) filters are recursive computational structures. They are used for many time-critical operations, since they are less CPU hungry. In contrast to FIR filters, they can become unstable and may affect the signal in unwanted ways.


Both categories will be introduced in the following sections. In a detailed comparison, they show a couple of differences, both having advantages and disadvantages.

Using the Git Repository

Git is a distributed version control system. Changes to (text) files are grouped in chunks called commits. You can create new branches of a repository for specific features or tasks and merge those branches after you finished your changes.

Cloning a Git Repository

git clone https://github.com/anwaldt/SPRAWL.git

This creates a directory with the name SPRAWL and clones the git repository locally.

With git log you can see all recent commits.

Create Branches, Adding Changes and Committing

Let's create a new branch for our changes:

git checkout -b new_changes

Now we are on a new created branch called new_changes. If you omit the -b you checkout a branch that is on the remote repository.

The easiest way to committing changes is to commit every changes of files.

git add file.txt
git add file2.txt
git commit -m "Fixes wording of file.txt and file3.t wsgh s"

Sometimes it happens that you commited your changes too early but didn't pushed your changes to the remote server. If you only want to change the commit message you can use git commit --amend. The same command works for adding more changes to the last commit. Don't forget to use git add filename.

Pushing Changes to the Remote Server

With git you can have more than one remote repository. After you cloned the sprawl repository you will have a remote repository with the name origin.

student@h2912420:~/SPRAWL$ git remote -v
origin  https://github.com/anwaldt/SPRAWL.git (fetch)
origin  https://github.com/anwaldt/SPRAWL.git (push)

But you don't have any push access to this repository. To get your changes into the mainline SPRAWL repository you have to fork the project on github. At the right top corner at the sprawl's repo you must click on fork. Then you can add your own repo to your local SPRAWL clone:

$ git remote add ntonnaett https://github.com/ntonnaett/SPRAWL.git
$ git remote -v
ntonnaett       https://github.com/ntonnaett/SPRAWL.git (fetch)
ntonnaett       https://github.com/ntonnaett/SPRAWL.git (push)
origin  git@github.com:anwaldt/SPRAWL.git (fetch)
origin  git@github.com:anwaldt/SPRAWL.git (push)
git push ntonnaett

Exchange ntonnaett with your personal remote name. After you committed all your changes you can open a pull request on the mainline sprawl repository.

Using the Git Repository

Git is a distributed version control system. Changes to (text) files are grouped in chunks called commits. You can create new branches of a repository for specific features or tasks and merge those branches after you finished your changes.

Cloning a Git Repository

git clone https://github.com/anwaldt/SPRAWL.git

This creates a directory with the name SPRAWL and clones the git repository locally.

With git log you can see all recent commits.

Create Branches, Adding Changes and Committing

Let's create a new branch for our changes:

git checkout -b new_changes

Now we are on a new created branch called new_changes. If you omit the -b you checkout a branch that is on the remote repository.

The easiest way to committing changes is to commit every changes of files.

git add file.txt
git add file2.txt
git commit -m "Fixes wording of file.txt and file3.t wsgh s"

Sometimes it happens that you commited your changes too early but didn't pushed your changes to the remote server. If you only want to change the commit message you can use git commit --amend. The same command works for adding more changes to the last commit. Don't forget to use git add filename.

Pushing Changes to the Remote Server

With git you can have more than one remote repository. After you cloned the sprawl repository you will have a remote repository with the name origin.

student@h2912420:~/SPRAWL$ git remote -v
origin  https://github.com/anwaldt/SPRAWL.git (fetch)
origin  https://github.com/anwaldt/SPRAWL.git (push)

But you don't have any push access to this repository. To get your changes into the mainline SPRAWL repository you have to fork the project on github. At the right top corner at the sprawl's repo you must click on fork. Then you can add your own repo to your local SPRAWL clone:

$ git remote add ntonnaett https://github.com/ntonnaett/SPRAWL.git
$ git remote -v
ntonnaett       https://github.com/ntonnaett/SPRAWL.git (fetch)
ntonnaett       https://github.com/ntonnaett/SPRAWL.git (push)
origin  git@github.com:anwaldt/SPRAWL.git (fetch)
origin  git@github.com:anwaldt/SPRAWL.git (push)
git push ntonnaett

Exchange ntonnaett with your personal remote name. After you committed all your changes you can open a pull request on the mainline sprawl repository.

Sending OSC from SuperCollider

For sending OSC from SuperCollider, a NetAddr object needs to be generated. It needs an IP address and a port:

~out_address  = NetAddr("127.0.0.1", 6666);

Sending Values Once

This first example sends an OSC message once when the following line is evaluated. The previously created NetAddr object can be used to send OSC messages with its sendMsg method:

~out_address.sendMsg('/test/message', 1);

Sending Values Continuously

Based on the previous example, a routine can be created which continuously reads values from control rate buses to send their instantaneous value via OSC. The osc_routine runs an infinite loop with a short wait interval to limit the send rate and the CPU load:

  ~cBus = Bus.control(s,1);

  ~osc_routine = Routine({

        inf.do({

      // read value from bus
                  var value      = ~cBus.getSynchronous(~nVbap);

      // send value
                  ~out_address.sendMsg('/oscillator/frequency', value);

                  // wait
                  0.05.wait;

          });
});

Once created, the routine can be started and stopped with the methods play() and stop(). While running, bus values can be changed to test the functionality:

~osc_routine.play();

~cBus.set(300);

~cBus.set(700);

~osc_routine.stop();

Exercise