~hp/chimaera_man

efcd31785f5abcb00e74f650c419e9e4e8c052b4 — Hanspeter Portner 1 year, 2 months ago 5baa27c wiki
Decrease header depths by one
M about/index.md => about/index.md +7 -7
@@ 2,9 2,9 @@
toc: false
---

## About
# About

### how to cite?
## how to cite?

All hardware documentation and design is released under the [CERN OHL v.1.2](http://ohwr.org/projects/cernohl/wiki). There are no patentable mechanical components or special production techniques involved in our design and we live in the _insightful_ part of the world that regards software patents as unreasonable. The design however is protected against patent trolls with a [defensive publication](https://en.wikipedia.org/wiki/Defensive_publication) which renders any patent filing by a third party invalid due to [prior art](https://en.wikipedia.org/wiki/Prior_art).



@@ 18,7 18,7 @@ All hardware documentation and design is released under the [CERN OHL v.1.2](htt
>	([bib](nime2014_hportner.bib) | 
>	[pdf](http://www.nime.org/proceedings/2014/nime2014_397.pdf))

### what is it?
## what is it?

The _Chimaera_ is a poly-magneto-phonic-theremin (we had to come up with this new subcategory in the domain of electronic instruments, as the _Chimaera_ did not fit anywhere else). Other terms that would describe it well could be: a general-purpose-continuous-music-controller, a multi-touch-less-ribbon-controller or a possible offspring of a mating experiment of a keyboard and violin.



@@ 34,11 34,11 @@ _Chimaera S128: 8 sensor units (128 sensors) embedded in a beech case._
![Chimaera S128](pix/shop/DSC_0230.JPG)
![Chimaera S128](pix/shop/DSC_0231.JPG)

### where does the inspiration come from?
## where does the inspiration come from?

We dreamed about a fully hackable music controller that would be as expressive as the violin, the [theremin](http://en.wikipedia.org/wiki/Theremin), the [trautonium](http://en.wikipedia.org/wiki/Trautonium) and the [continuum fingerboard](http://www.hakenaudio.com/Continuum/), as versatile in its usage as the [Monome](http://monome.org), as open as the [Arduino](http://arduino.cc) and all that at an affordable price. As there was no such thing, we had to come up with something by ourself.

### what were its design goals?
## what were its design goals?

The main design goals for the device were to have a music controller that gives the player optimal control on musical expression. Now what is music in the first place? Our favorite definition is: _music is structured sound_. And the most prominent three parameters that distinguish sounds from each other in turn are pitch, time and volume. To have full control over music, therefore a player needs to have full control over pitch and volume of generated sounds and their temporal progression. And full control in this setting specifically means that pitch and volume can be controlled over continuous ranges with a high temporal resolution.



@@ 54,7 54,7 @@ The points therefore that had to be fulfilled were:
* driver-less communication and integration into any setup or operating system
* possibility for network performances via UDP and TCP inherently included

### how does it work?
## how does it work?

The chimaera consists of three parts: the sensory part, the computing part and the communication part.



@@ 70,7 70,7 @@ _Dump of sensor array consisting of 144 hall effect sensors. Two magnetic fields

For more in-depth informations look at the [hardware](hardware/#) and [firmware](firmware/#) documentations.

### how does it sound?
## how does it sound?

It does not make any sound by itself, it is just a controller. It is up to you to decide how the controller data is converted to sound, _you are in full control_.


M build/index.md => build/index.md +6 -6
@@ 2,9 2,9 @@
toc: false
---

## Build
# Build

### Reflow-solder the SU-16 Unit
## Reflow-solder the SU-16 Unit

The building of a sensor unit is straight-forward and should be doable even for a skilled beginner in SMD soldering. We deliberately choose the big chips (SOIC) for the multi-legged chips and a 0603 footprint for the smallest passive components.



@@ 24,7 24,7 @@ The building of a sensor unit is straight-forward and should be doable even for 
![SU-16 unit pcb only](pix/pcb/pcb_su-16_rev8.png)
![SU-16 unit assembled](pix/pcb/pcb_su-16_rev8_assembled.png)

### Reflow-solder the DSP-F3 Unit
## Reflow-solder the DSP-F3 Unit

The building of a DSP unit is a bit more tricky (because of the two 48-pin, 0.5mm pitch LQFP packages). If this will be your first project with 0.5mm pitch components, you may want to do some preliminary exercises first. We deliberately choose the 0603 footprint for the remaining components.



@@ 46,7 46,7 @@ The building of a DSP unit is a bit more tricky (because of the two 48-pin, 0.5m
![DSP-F3 unit pcb only](pix/pcb/pcb_dsp-f3_rev4.png)
![DSP-F3 unit assembled](pix/pcb/pcb_dsp-f3_rev4_assembled.png)

### Prepare the case
## Prepare the case

Get yourself a case or create your own at the next [FabLab](http://www.fabfoundation.org/fab-labs/).



@@ 63,7 63,7 @@ The wrapping sheet has been designed as a kerf-bent enclosure. Depending on the 
![embed the PCBs into the case](pix/case/DSC_0216.JPG)
![embed the PCBs into the case](pix/case/DSC_0217.JPG)

### Wiring up the units
## Wiring up the units

The _Chimaera_ is modular in design and can be equipped with varying amounts of sensor units. As the DSP unit has three analog-to-digital converters running in parallel, the analog inputs from the sensor units are distributed evenly for best performance. The analog-to-digital channels are adjacent on the socket header: 4 channels (pins 1-4) for ADC1 followed by 4 channels (pins 5-8) for ADC2 and 2 channels (pins 9-A) for ADC3.



@@ 87,7 87,7 @@ For the configurations for 1 sensor unit (S16) up to 10 sensor units (S160), the
	9    1234 5678 .9
	A    1234 5678 A9

### Hardware calibration
## Hardware calibration

Apart from the four lines _S0-S3_ which switch channels on the multiplexer, the sensor units are purely analog circuitry and can be and/or need to be tweaked at different points for optimal performance. Please read up the corresponding section in the [hardware](hardware/#) documentation in order to understand what the exact function of each of the three trim potentiometers is.


M faq/index.md => faq/index.md +1 -1
@@ 2,7 2,7 @@
toc: false
---

## Frequently Asked Questions
# Frequently Asked Questions

__Where does the name come from?__


M firmware/index.md => firmware/index.md +11 -11
@@ 2,11 2,11 @@
toc: false
---

## Firmware
# Firmware

So we have a lot of sensors and a micro controller. How do we get to our event signals? That is what this page is all about. One component of our event signal for a given magnetic source is its distance from the sensor. We will start right there and firstly look at the relationship of magnetic field and distance.

### Distance - magnetic field - relationship
## Distance - magnetic field - relationship

The strength of the magnetic field of a permanent magnet decreases with increasing distance from the sensor. This decrease is non-linear and the equations involved are non-trivial, it depends on the material and form of the permanent magnet. As a general rule, a cubic relationship is assumed. Nowadays, magnetic fields can be approximated with finite-element calculations, this however is overkill and not at all possible in realtime on a microcontroller. To approximate the distance of a given magnet from the sensor based on the sensed magnetic field flux at the latter in realtime it is therefore best to do some non-linear curve fitting for the given pair of sensor and magnet before-hand. In realtime, the fitted distance-function is simply applied to the sensed magnetic field flux.



@@ 27,7 27,7 @@ The relationship can vary considerably between different types of permanent magn
<math  xmlns="http://www.w3.org/1998/Math/MathML"  display="block"><mtable  columnalign="right center left"><mtr><mtd><mi>B</mi></mtd><mtd>  <mo>=</mo></mtd><mtd>  <mfenced separators="" open="("  close=")"><mrow><mtable  align="axis" style=""  equalrows="false" columnlines="none none none none none none none none none" equalcolumns="false"><mtr><mtd   columnalign="center"><mn>0</mn></mtd><mtd   columnalign="center"> <mn>0</mn> </mtd><mtd   columnalign="center"><mn>0</mn></mtd></mtr><mtr><mtd   columnalign="center"><mroot><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>1</mn></mrow></msub></mrow><mrow><mn>3</mn></mrow></mroot></mtd><mtd   columnalign="center"><msqrt><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>1</mn></mrow></msub></mrow></msqrt></mtd><mtd   columnalign="center"><msub><mrow><mi>b</mi></mrow><mrow><mn>1</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><mroot><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>2</mn></mrow></msub></mrow><mrow><mn>3</mn></mrow></mroot></mtd><mtd   columnalign="center"><msqrt><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>2</mn></mrow></msub></mrow></msqrt></mtd><mtd   columnalign="center"><msub><mrow><mi>b</mi></mrow><mrow><mn>2</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><mroot><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>3</mn></mrow></msub></mrow><mrow><mn>3</mn></mrow></mroot></mtd><mtd   columnalign="center"><msqrt><mrow><msub><mrow><mi>b</mi></mrow><mrow><mn>3</mn></mrow></msub></mrow></msqrt></mtd><mtd   columnalign="center"><msub><mrow><mi>b</mi></mrow><mrow><mn>3</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"> <mn>1</mn></mtd><mtd   columnalign="center"> <mn>1</mn> </mtd><mtd   columnalign="center"><mn>1</mn></mtd></mtr><!--*\c@MaxMatrixCols c--></mtable>                                                                                       </mrow></mfenced>                  </mtd><mtd><mtext>&#x0028;1&#x0029;</mtext><mtext      ></mtext><mtext></mtext></mtd></mtr><mtr><mtd><mi>y</mi></mtd><mtd>  <mo>=</mo></mtd><mtd>  <mfenced separators="" open="("  close=")"><mrow><mtable  align="axis" style=""  equalrows="false" columnlines="none none none none none none none none none" equalcolumns="false"><mtr><mtd   columnalign="center"><mn>0</mn></mtd></mtr><mtr><mtd   columnalign="center"><msub><mrow><mi>y</mi></mrow><mrow><mn>1</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><msub><mrow><mi>y</mi></mrow><mrow><mn>2</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><msub><mrow><mi>y</mi></mrow><mrow><mn>3</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><mn>1</mn></mtd></mtr><!--*\c@MaxMatrixCols c--></mtable>                                                                                                </mrow></mfenced>                  </mtd><mtd><mtext>&#x0028;2&#x0029;</mtext><mtext      ></mtext><mtext></mtext></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd>  <mo>=</mo></mtd><mtd>  <mfenced separators="" open="("  close=")"><mrow><mtable  align="axis" style=""  equalrows="false" columnlines="none none none none none none none none none" equalcolumns="false"><mtr><mtd   columnalign="center"><msub><mrow><mi>c</mi></mrow><mrow><mn>0</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><msub><mrow><mi>c</mi></mrow><mrow><mn>1</mn></mrow></msub></mtd></mtr><mtr><mtd   columnalign="center"><msub><mrow><mi>c</mi></mrow><mrow><mn>2</mn></mrow></msub></mtd></mtr><!--*\c@MaxMatrixCols c--></mtable>                                                                                                                       </mrow></mfenced><mo>=</mo><msup><mrow><mrow><mo>&#x0028;</mo><mrow><msup><mrow><mi>B</mi></mrow><mrow><mi>T</mi></mrow></msup><mo>&#x22C5;</mo><mi>B</mi></mrow><mo>&#x0029;</mo></mrow></mrow><mrow><mo>&#x2212;</mo><mn>1</mn></mrow></msup><mo>&#x22C5;</mo><msup><mrow><mi>B</mi></mrow><mrow><mi>T</mi></mrow></msup><mo>&#x22C5;</mo><mi>y</mi></mtd><mtd><mtext>&#x0028;3&#x0029;</mtext><mtext      ></mtext><mtext></mtext></mtd></mtr></mtable></math>


### Sensor calibration
## Sensor calibration
Get familiar first with the [hardware ](hardware/#) of the _Chimaera_ sensor unit, it will help a lot to understand all the following.

Although we now know the relationship between magnetic flux and vicinity we cannot yet approximate the distance of a magnet from its sensor. From the sensor unit we get a voltage which is linearly related to the magnetic flux the currently active sensor is in. However, the sensors do not all have the exactly same sensitivity and quiescent output, their values scatter over a given range. We have to take care of this firstly.


@@ 119,22 119,22 @@ From the normalized magnetic flux <math  xmlns="http://www.w3.org/1998/Math/Math
. As those vicinities are comparable over the whole sensor array, we are now ready to interpolate the position <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><mi>x</mi></math>
 of the magnetic source along the sensor array axis.

### Blob event handling
## Blob event handling
With a blob we refer to a recognized magnetic field source (e.g. permanent magnet) that is to be tracked over space and time. Blob event handling can be divided into several stages: decipher polarity, narrowing down the area of interest on the sensor array, actual blob detection, interpolation of blob position, group association and blob tracking.

#### Magnetic flux polarity
### Magnetic flux polarity
First thing that is to be done is to discriminate between the polarities of the potentially present magnetic field sources. For each sensor value, we therefore subtract the previously calibrated quiescent value, so we get the difference of the present raw sensor value from its quiescent value. The sign of this difference gives us the polarity of the magnetic source we are encountering here, e.g. south and north polarity. The absolute value of the difference gives us the strength of the magnetic field (which is to be normalized with previously calibrated factors in a later step). 

#### Area of interest
### Area of interest
After each scan of the whole sensor array, areas of interest are marked on the array. These are regions, where the sensor value exceeds the threshold magnetic flux <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><msub><mrow><mi>B</mi></mrow><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></math>
. The rest of the sensors are not of interest for the further steps. We do not apply the distance-magnetic-field relationship over all sensors at this step, as it would be computationally too costly. During calibration, for each sensor we precalculated its raw value <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><msub><mrow><mi>V</mi></mrow><mrow><mi>o</mi><mo>,</mo><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></math>
 corresponding to threshold magnetic flux <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><msub><mrow><mi>B</mi></mrow><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></math>
. This then can be efficiently checked against for each sensor at each update step to find out whether the threshold has been exceeded or not.

#### Blob detection
### Blob detection
In the next step, we search for peaks in the areas of interest. A peak will correspond to an individual magnetic field source and is simply defined as a sensor with an absolute value which is greater than the values of a given number of adjacent sensors in the same area of interest. We save all found peaks along the sensor array for the blob's positional interpolation in the next step.

#### Blob interpolation
### Blob interpolation
As always more than one sensor is excited by an individual magnetic source, we can decipher its real position by interpolation around the peak sensor. We therefore fit curves <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><msub><mrow><mi>y</mi></mrow><mrow><mi>n</mi></mrow></msub><mrow><mo>&#x0028;</mo><mrow><mi>x</mi></mrow><mo>&#x0029;</mo></mrow></math>
 over a varying number of sensor values around the peak and find the maximum <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><mrow><mo>&#x0028;</mo><mrow><mi>X</mi><mo>,</mo><mi>Y</mi></mrow><mo>&#x0029;</mo></mrow></math>
 by finding the cross point of the curve's derivative. Only at this step we convert the sensor values into normalized vicinities based on calibration data. For efficiency reasons, we use a precalculated lookup table for the distance-magnetic-field relationship, because the cube root and square root functions would be too costly.


@@ 168,13 168,13 @@ _Vicinities of four adjacent sensors and a cubic fit with Catmull-Rom splines (o

_Vicinities of four adjacent sensors and a fit with a Lagrange polynomial (order 3) between all four values._

#### Group association
### Group association
For convenience, we have introduced a concept of groups. Each blob has not only a given position on the sensor array, but is also affiliated to a group. A group is defined by a range (<math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><msub><mrow><mi>x</mi></mrow><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub><mo>.</mo><mo>.</mo><msub><mrow><mi>x</mi></mrow><mrow><mi>m</mi><mi>a</mi><mi>x</mi></mrow></msub></math>
) on the sensor array and magnetic field flux polarity (south, north or both). Only blobs with a position in the range of - and a polarity corresponding to a given group will be associated with the latter.

Groups can overlap, e.g. there can be two groups for the same range with differing polarities. A blob can only be part of one group at a time though and will be affiliated to the first matching one.

#### Blob tracking
### Blob tracking
Up to now, everything we have done was based on the current state of the sensor array. However, to track blobs over time, there needs to be a means to associate identified blobs in the current iteration to blobs found in previous iterations to decipher whether new blobs have appeared or old ones have disappeared.

To link current blobs to previous blobs they are matched by position on the sensor array. Each new blob gets a unique ID, which will persist over time as long as the blob can be linked to itself in a previous iteration step, until the blob disappears. In the special case when a blob can be linked but has exited its previous group, it will be regarded as a new one, too.


@@ 182,5 182,5 @@ To link current blobs to previous blobs they are matched by position on the sens
Out of the blob tracking, we get a stream of event signals: When a new blob has appeared, an __on__ event is triggered. When a blob could be linked to a previous iteration step, a __set__ event is triggered to update the blobs position. When a blob has disappeared, an __off__ event is triggered. All event signals will be triggered with complete set of current parameters: position <math  xmlns="http://www.w3.org/1998/Math/MathML"  display="inline"><mrow><mo>&#x0028;</mo><mrow><mi>X</mi><mo>,</mo><mi>Y</mi></mrow><mo>&#x0029;</mo></mrow></math>
, polarity (south or north) and group association.

### Summary
## Summary
So, what the firmware does in the end is: converting a raw array of sampled sensor values into a stream of blob event signals. The event signals now can be translated into a given transport protocol and sent over the network to drive other software or hardware. This is elaborated upon in a dedicated section, the [usage](usage/#).

M flash/index.md => flash/index.md +6 -6
@@ 2,15 2,15 @@
toc: false
---

## Flash
# Flash

You have two possibilities to get to the firmware for your newly bought/built device: You can resort to prebuilt stable releases or you can compile your own images. The first approach is the more convenient one as it does not involve any fiddling with source code and cross compiling tool chains. The latter approach is more demanding and meant for people that like to be at the bleeding-edge or developers.

### Stable releases
## Stable releases

We provide pre-built images for [stable firmware releases](https://dl.open-music-kontrollers.ch/chimaera_firmware/stable/chimaera_firmware-latest-stable.zip). The images are built for all 10 possible hardware configurations (from 16 up to 160 sensor devices). Download the one matching your device, skip the build instructions and directly jump to the flashing instructions.

### Building from source
## Building from source

Get the most recent pre-built [gcc-arm-embedded](https://launchpad.net/gcc-arm-embedded/) cross compiling tool chain for your operating system (Linux, Windows, OS X), extract it somewhere in your path and add its _bin_ subdirectory to your PATH, so all the executables are found by your shell. On 64-bit systems you may need a minimal multi-lib environment (lib32-glibc), as the prebuilt binaries are 32-bit only.



@@ 44,7 44,7 @@ You can also build a shareable release by packing the binary into a DfuSe contai

This will give you e.g. *build/chimaera_S144-0.2.0-4.dfu*.

### Flashing
## Flashing

The _Chimaera_ has an embedded DfuSe (USB device firmware update STMicroelectronics extension) bootloader to download custom or new firmware to the device. We use [dfu-util](http://dfu-util.sourceforge.net/) to do so, you will need a recent version of it. Dfu-util is supported on all major platforms.



@@ 66,7 66,7 @@ When working with a prebuilt stable release or a self-built DfuSe container, the

After successful flashing, the device automatically resets into its running mode.

#### Linux / BSD
### Linux / BSD

To check whether the device is in flash mode, search the output of _lsusb_ for the following line:



@@ 79,7 79,7 @@ For the download to work, you need to have read and write privileges to the devi
	----------------------------------------
	ATTRS{idProduct}=="df11", ATTRS{idVendor}=="0483", MODE="664", GROUP="uucp", SYMLINK+="chimaeraDfuSe"

#### Windows
### Windows

The [ZADIG tool](http://zadig.akeo.ie/) has been shown to be valuable to install all neded USB drivers on Windows for flashing to work.


M hardware/index.md => hardware/index.md +8 -8
@@ 2,13 2,13 @@
toc: false
---

## Hardware
# Hardware

The hardware of the _Chimaera_ so far consists of two types of printed circuit boards and an optional enclosure.

### Circuitry
## Circuitry

#### Sensor Unit (_SU-16_)
### Sensor Unit (_SU-16_)

![su-16 top](pix/eda/chimaera_sensor_unit_Rev8-3v3_top.png)
![su-16 bottom](pix/eda/chimaera_sensor_unit_Rev8-3v3_bottom.png)


@@ 28,7 28,7 @@ Each sensor unit has its own 3.3V low-drop-out voltage regulator to drive the wh

You still want to know more? Then get directly to the KiCAD design files at our [hardware repository](https://git.open-music-kontrollers.ch/~hp/chimaera_sensor_unit).

#### Digital Signal Processing Unit (_DSP-F3_)
### Digital Signal Processing Unit (_DSP-F3_)

![dsp-f3 top](pix/eda/chimaera_dsp_unit_Rev4-3v3_top.png)
![dsp-f3 bottom](pix/eda/chimaera_dsp_unit_Rev4-3v3_bottom.png)


@@ 41,9 41,9 @@ Finally there are a RJ45 MagJack and a mini USB socket. USB is solely used to fl

You still want to know more? Then get directly to the KiCAD design files at our [hardware repository](https://git.open-music-kontrollers.ch/~hp/chimaera_dsp_unit).

### Accessories
## Accessories

#### Magnetic Plektrum (_MPlek_)
### Magnetic Plektrum (_MPlek_)

We have designed a simple ring to easily stick the permanent magnets to your fingers. We call it a magnetic plektrum (MPlek). Is is not worn like a normal ring as it is only stuffed over your _phalanx media_ and it is assembled with an accompanying neodymium magnet of specific size in order to be functional.



@@ 52,7 52,7 @@ We have designed a simple ring to easily stick the permanent magnets to your fin

_MPlek with place for a rectangular Neodymium magnet of dimensions 20x4x3mm (LxWxH)._

#### Magnetic Stamp (_MStamp_)
### Magnetic Stamp (_MStamp_)

We have also designed an alternative holder for the needed magnet in the form of a small stamp. It is intended for use cases where the player would prefer a more loose attachment to the magnet.



@@ 63,7 63,7 @@ _Mstamp with place for a rectangular Neodymium magnet of dimensions 20x4x3mm (Lx

You still want to know more? Then get directly to the CAD design files at our [hardware repository](https://git.open-music-kontrollers.ch/~hp/chimaera_mplek)

#### Lasercut Case (_L-Case_)
### Lasercut Case (_L-Case_)

![case simple](pix/cad/chimaera_S144_2.5mm_prev_simple.svg)


M index.md => index.md +7 -7
@@ 2,9 2,9 @@
toc: false
---

## About
# About

### how to cite?
## how to cite?

All hardware documentation and design is released under the [CERN OHL v.1.2](http://ohwr.org/projects/cernohl/wiki). There are no patentable mechanical components or special production techniques involved in our design and we live in the _insightful_ part of the world that regards software patents as unreasonable. The design however is protected against patent trolls with a [defensive publication](https://en.wikipedia.org/wiki/Defensive_publication) which renders any patent filing by a third party invalid due to [prior art](https://en.wikipedia.org/wiki/Prior_art).



@@ 18,7 18,7 @@ All hardware documentation and design is released under the [CERN OHL v.1.2](htt
>	([bib](nime2014_hportner.bib) | 
>	[pdf](http://www.nime.org/proceedings/2014/nime2014_397.pdf))

### what is it?
## what is it?

The _Chimaera_ is a poly-magneto-phonic-theremin (we had to come up with this new subcategory in the domain of electronic instruments, as the _Chimaera_ did not fit anywhere else). Other terms that would describe it well could be: a general-purpose-continuous-music-controller, a multi-touch-less-ribbon-controller or a possible offspring of a mating experiment of a keyboard and violin.



@@ 34,11 34,11 @@ _Chimaera S128: 8 sensor units (128 sensors) embedded in a beech case._
![Chimaera S128](pix/shop/DSC_0230.JPG)
![Chimaera S128](pix/shop/DSC_0231.JPG)

### where does the inspiration come from?
## where does the inspiration come from?

We dreamed about a fully hackable music controller that would be as expressive as the violin, the [theremin](http://en.wikipedia.org/wiki/Theremin), the [trautonium](http://en.wikipedia.org/wiki/Trautonium) and the [continuum fingerboard](http://www.hakenaudio.com/Continuum/), as versatile in its usage as the [Monome](http://monome.org), as open as the [Arduino](http://arduino.cc) and all that at an affordable price. As there was no such thing, we had to come up with something by ourself.

### what were its design goals?
## what were its design goals?

The main design goals for the device were to have a music controller that gives the player optimal control on musical expression. Now what is music in the first place? Our favorite definition is: _music is structured sound_. And the most prominent three parameters that distinguish sounds from each other in turn are pitch, time and volume. To have full control over music, therefore a player needs to have full control over pitch and volume of generated sounds and their temporal progression. And full control in this setting specifically means that pitch and volume can be controlled over continuous ranges with a high temporal resolution.



@@ 54,7 54,7 @@ The points therefore that had to be fulfilled were:
* driver-less communication and integration into any setup or operating system
* possibility for network performances via UDP and TCP inherently included

### how does it work?
## how does it work?

The chimaera consists of three parts: the sensory part, the computing part and the communication part.



@@ 70,7 70,7 @@ _Dump of sensor array consisting of 144 hall effect sensors. Two magnetic fields

For more in-depth informations look at the [hardware](hardware/#) and [firmware](firmware/#) documentations.

### how does it sound?
## how does it sound?

It does not make any sound by itself, it is just a controller. It is up to you to decide how the controller data is converted to sound, _you are in full control_.


M introspect/index.md => introspect/index.md +1 -1
@@ 2,7 2,7 @@
toc: false
---

## Introspect
# Introspect

<span style="color:gray">Updated - 15 Dec 2015 (Version 0.7.0)</span>


M issues/index.md => issues/index.md +2 -2
@@ 2,8 2,8 @@
toc: false
---

## Issues
# Issues

### Latency
## Latency

If the connection from the _Chimaera_ to your host shows too high latencies (>2ms), please first check (and blame) your network infrastructure (inefficient routing, slow hubs, switches or network adapters) and operating system (Windows mainly) before blaming the device to not be performant enough.

M media/index.md => media/index.md +3 -3
@@ 2,9 2,9 @@
toc: false
---

## Media
# Media

### Audio samples
## Audio samples

<table>
	<tr><td class="media">Analogue Lament


@@ 107,7 107,7 @@ toc: false
	</td></tr>
</table>

### Video samples
## Video samples

<div style="text-align:center">
	<div class="aspect_ratio" style="padding-bottom:35%">

M setup/index.md => setup/index.md +17 -17
@@ 2,11 2,11 @@
toc: false
---

## Setup
# Setup

_This part is general in the sense that it teaches you on what it needs to integrate the _Chimaera_ into your setup, but does not tell you how and therefore is platform independent._

### Networks and Firewalls
## Networks and Firewalls

In order that the _Chimaera_ can talk to your host and your host can talk to the _Chimaera_, the IP of the _Chimaera_ has to be whitelisted in the firewall settings of your host and the _Chimaera_ has to know where to send its messages to.



@@ 14,13 14,13 @@ Whitelisting the IP of the _Chimaera_ can be done in different ways. On one hand

The IP of the _Chimaera_ and the IP of the host the _Chimaera_ sends its messages to, can be changed by means of the configuration system.

### Time synchronization
## Time synchronization

The _Chimaera_ can send its touch messages timestamped, so you exactly know when a specific message has been created/transmitted by the _Chimaera_ (this is important when sending the messages over complex networks where messages may get lost or misordered and to generally prevent jitter by postponing the dispatching of the messages at the host). But timestamped messages only make sense when the source and destination of the communication path refer to the same time in the first place. If you want to make use of timestamped messages (you don't have to, of course), the _Chimaera_ therefore needs to synchronize its time with the one of time master.

The _Chimaera_ offers two means of time synchronization to a time master, via the _network time protocol_ for coarse resolution synchronization at low sensor update rates and via _precision time protocol_ for fine resolution synchronization at high sensor update rates.

#### Network time protocol
### Network time protocol

The problem of synchronizing two devices over network has long since been solved by the [network time protocol (NTP)](http://www.ntp.org/). The _Chimaera_ can make use of it, too. However, there is no need to run a fully fledged NTP client on the _Chimaera_, the simplified network time protocol (SNTP) is enough for our application. The SNTP client on the _Chimaera_ can be enabled or disabled by means of the configuration system. In order for it to work properly, you need to tell the _Chimaera_ the IP address of a host that runs a NTP daemon. The _Chimaera_ then will send SNTP requests to the server at a configurable rate (e.g. 4 seconds by default), wait for the answer and synchronize its clock to the server.



@@ 28,7 28,7 @@ The server which runs the NTP daemon may be the same host the _Chimaera_ sends i

NTP has been designed for synchronizing devices across the internet down to a few milliseconds at best. The _Chimaera_ sends SNTP requests at high rates and can synchronize to a nearby time master down to a 10th millisecond at best. Synchronization via SNTP therefore is only recommended for low sensor update rates of the _Chimaera_, e.g. up to 1-1.5 kHz.

#### Precision time protocol
### Precision time protocol

For higher sensor update rates, e.g. 1.5-3 kHz, there is a need for a more accurate means of synchronization down to a few dozen microseconds at least. The _Chimaera_ can be synchronized via the [precision time protocol (PTPv2)](http://en.wikipedia.org/wiki/Precision_Time_Protocol), aka IEEE 1588-2008, to a master timebase on a local area network.



@@ 36,11 36,11 @@ PTP is relatively new (2002) compared to NTP and was developed to synchronize e.

__That's all to get the _Chimaera_ communicate with your setup - driverlessly, so to speak.__

## Linux/BSD
# Linux/BSD

_This part is specifically about the setup on Linux and BSD. In a great part this can be adapted to other Unix flavors, too (e.g. OS X)._

### Network setup
## Network setup

The _Chimaera_ has its own IP address and needs to be incorporated into your local network. So you have to make sure that the _Chimaera_ is not blocked by a firewall and that the various ports used for communication are open (at least for the _Chimaera_). The default IP of the _Chimaera_ is 192.168.1.177. In order to receive data from the _Chimaera_, you have to enable communication from and to that specific address, or an address space where the _Chimaera_'s IP falls into, e.g. you can define a LAN with addresses 192.168.1.0 - 192.168.1.255 and whit-list it in your firewall configuration.



@@ 64,16 64,16 @@ Ping on .local domain (resolve via Avahi/mDNS)

You can configure the devices MAC address, IP, gateway address and subnet mask to your liking via the configuration systems method [/comm/mac](introspect/#/comm/mac), [/comm/ip](introspect/#/comm/ip) and [/comm/gateway](introspect/#/comm/gateway) .

### Time synchronization
## Time synchronization

#### PTP setup
### PTP setup

On Linux, you definitely want to use PTP for synchronization. If you happen to have a system that supports hardware timestamping (becoming the norm for new network interfaces), you want to go with [linuxptp](http://linuxptp.sourceforge.net/). If you only look for a software PTP implementation, you can do with _linuxptp_, too or use [ptpd](http://ptpd.sourceforge.net/), which also supports other POSIX systems.


PTP communication takes place over multicast, to enable the _Chimaera_ as PTP slave and configure it, you can use the configuration system via [/ptp/enabled](introspect/#/ptp/enabled), [/ptp/multiplier](introspect/#/ptp/multiplier), [/ptp/offset_stiffness](introspect/#/ptp/offset_stiffness) and [/ptp/delay_stiffness](introspect/#/ptp/delay_stiffness) .

#### NTP setup
### NTP setup

The host, the _Chimaera_ sends its SNTP request to, can be configured via [/sntp/enabled](introspect/#/sntp/enabled), [/sntp/address](introspect/#/sntp/address) and [/sntp/tau](introspect/#/sntp/tau).



@@ 87,30 87,30 @@ To get a NTP daemon up and running on Linux is simple, just install the correspo
	.
	.

## OS/X
# OS/X

As OS/X is a BSD/Unix derivate, most things said about the latter two should be applicable analogously.

As we never have, do not currently and never ever will call an Apple product our own, we cannot give detailed explanations on steps needed to configure firewall, NTP server, PTP time master, Bonjour services and process thread scheduling. Please refer to the manuals.

## Windows
# Windows

A standard setup of Windows will most probably be worse at networking than Linux/BSD/OS X affecting latency of the _Chimaera_ to host connection. Windows always tries (and sometimes fails) to be smart, e.g. it may throttle its networking through-put while running audio/video applications which is really bad if audio is sent over and/or controlled via the network as in the case of the _Chimaera_, obviously. Windows' soft real-time capabilities are not accessible to the user which makes tuning of process thread priorities a non-option, either.

### Boosting networking
## Boosting networking

So, the one thing that can be done from a user perspective to get the best out of the system is to change registry entries to boost network performance and disable network throttling in audio setups. Tools exist that do that for you. They were created for real-time networked games to solve the identical issues as in our case, e.g. to have low-latency networking with concurrent low-latency audio and video. Hence, it may be best to look up the needed tricks on gaming sites.

### Firewall
## Firewall

Adding the right rules to the firewall settings should be straight forward. You may want to use a fixed IP or the MAC address of the _Chimaera_ or define a trusted IP range, the device will be part of. Consult the manual of your firewall software.

### Time synchronization
## Time synchronization

#### PTP setup
### PTP setup

You will have to look far to find any hardware support for PTP on windows and windows lacks the needed real-time capabilities for a robust software implementations in the first place. Most probably you will have to fall back to NTP or do without timestamping altogether when using the _Chimaera_ on windows, which is no problem per-se.

### NTP server
## NTP server

There is an open-source NTP server available for windows at [timesync tool](http://www.timesynctool.com/).

M sources/index.md => sources/index.md +4 -4
@@ 2,20 2,20 @@
toc: false
---

## Sources
# Sources

### Device firmware sources
## Device firmware sources

* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_firmware>

### Device hardware sources
## Device hardware sources

* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_dsp_unit>
* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_sensor_unit>
* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_case>
* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_mplek>

### Client software sources
## Client software sources

* <https://git.open-music-kontrollers.ch/~hp/chim.lv2>
* <https://git.open-music-kontrollers.ch/~hp/chimaera/chimaera_pd>

M usage/index.md => usage/index.md +30 -30
@@ 2,7 2,7 @@
toc: false
---

## Usage
# Usage

If you have read the [firmware](firmware/#) documentation, you now know, that the device converts the raw sensor data to a stream of __on__, __off__ and __set__ event signals. Before the event signals reach your host computer running your audio framework, there is one more step involved: the serialization of the event data into a given transport protocol.



@@ 26,11 26,11 @@ You can do much more crazy things, of course, e.g. controlling a single synth wi

Below you can find an overview of the standard output engines, their formatting and usage scenarios. If none should fit your application, there still is the possibility to write your own, of course.

### Dump
## Dump

The dump output engine writes out the raw sensor data as a binary blob. The engine is insusceptible to lost and out-of-order packets. There is a single bundled OSC message of the form:

#### /dump
### /dump

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 56,7 56,7 @@ This output engine is used during both hardware and software sensor calibration,

*Chimaera graphical sensor dump implemented in SuperCollider showing 4 present magnetic sources. Get the code at our [SuperCollider repository](https://git.open-music-kontrollers.ch/~hp/chimaera_sc)*

### TUIO 1.0
## TUIO 1.0

Learn more about the [TUIO 1.0 protocol specification](http://www.tuio.org/?tuio10). We use the __2Dobj__ profile of the TUIO 1.0 spec as default. It is the profile which best fits the information coming from the _Chimaera_. The angular velocity and acceleration are meaningless for the device. But as those values are part of the __2DObj__ profile and need to be sent, the _Chimaera_ just sets them to zero.



@@ 68,7 68,7 @@ This output engine does not directly serialize _on_ and _off_ events. The host i

This output engine is insusceptible to lost and out-of-order packets and thus save to use over UDP.

#### /tuio/2Dobj or /tuio/\_sixya
### /tuio/2Dobj or /tuio/\_sixya

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 94,7 94,7 @@ This output engine is insusceptible to lost and out-of-order packets and thus sa
</tr>
</table>

#### /tuio/2Dobj or /tuio/\_sixya
### /tuio/2Dobj or /tuio/\_sixya

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 155,7 155,7 @@ This output engine is insusceptible to lost and out-of-order packets and thus sa
</tr>
</table>

#### /tuio/2Dobj or /tuio/\_sixya
### /tuio/2Dobj or /tuio/\_sixya

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 177,7 177,7 @@ _Note: Not all implementations may have been designed (and implemented according

The engine is activated via: [/engines/tuio1/enabled](introspect/#/engines/tuio1/enabled)

### TUIO 2.0
## TUIO 2.0

Learn more about the [TUIO 2.0 protocol specification](http://www.tuio.org/?tuio20). This is the successor to TUIO 1.0. It is pretty similar to the 1.0 spec, but more modularized with a much cleaner name space. The spec is new and not yet widely used. We prefer it compared to the 1.0 spec, as it is more efficient for simple applications like ours (lower bandwidth and less to parse). We use __tok__ component messages to transport blob events.



@@ 187,7 187,7 @@ This output engine does not directly serialize _on_ and _off_ events. The host i

This output engine is insusceptible to lost and out-of-order packets and thus save to use over UDP.

#### /tuio2/frm
### /tuio2/frm

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 213,7 213,7 @@ This output engine is insusceptible to lost and out-of-order packets and thus sa
</tr>
</table>

#### /tuio2/tok
### /tuio2/tok

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 277,7 277,7 @@ This output engine is insusceptible to lost and out-of-order packets and thus sa
</tr>
</table>

#### /tuio2/alv
### /tuio2/alv

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 302,7 302,7 @@ Ready to use SuperCollider classes and sketches using the _TUIO 2.0_ engine can 

The engine is activated via: [/engines/tuio2/eanbled](introspect/#/engines/tuio2/enabled). Output of derivative signals can be toggled via: [/engines/tuio2/derivatives](introspect/#/engines/tuio2/derivatives).

### SuperCollider
## SuperCollider

We use SuperCollider as one of our main software synthesizers, we therefore implemented this output engine to be able to directly send event data to the SuperCollider synthesis servers _scsynth_ and _supernova_. To fully understand this engine, you may need to get familiar with the SuperCollider server messaging system first. There is an overview of the latter at [http://doc.sccode.org](http://doc.sccode.org/Reference/Server-Command-Reference.html).



@@ 312,7 312,7 @@ For optimal control, groups on the device can be configured in different profile

As the creation of a synth on the server needs a synth name, synth ID, group add action, group ID, out channel and whether the sensor array range should control a synth instance or a synth group, all these have to be provided to the device before-hand via [/engines/scsynth/attributes](introspect/#/engines/scsynth/attributes/0).

#### /s\_new
### /s\_new

_is triggered at a __ON__ event and only sent with synth allocation enabled_



@@ 370,7 370,7 @@ _is triggered at a __ON__ event and only sent with synth allocation enabled_
</tr>
</table>

#### /n\_setn
### /n\_setn

_is triggered at an __ON__ event and only sent with synth gating enabled_



@@ 416,7 416,7 @@ _is triggered at an __ON__ event and only sent with synth gating enabled_
</tr>
</table>

#### /n\_setn
### /n\_setn

_is triggered at a __SET__ event and always sent_



@@ 462,7 462,7 @@ _is triggered at a __SET__ event and always sent_
</tr>
</table>

#### /n\_set
### /n\_set

_is triggered at an __OFF__ event and only sent with synth gating enabled_



@@ 491,7 491,7 @@ Ready to use SuperCollider classes and sketches using the _scsynth_ engine can b

The engine is activated via: [/engines/scsynth/enables](introspect/#/engines/scsynth/enabled). Output of derivative signals can be toggled via: [/engines/scsynth/derivatives](introspect/#/engines/scsynth/derivatives).

### Dummy
## Dummy

The _Dummy_ output engine is a direct 1to1 translation of the blob event stream to Open Sound Control messages. For an __On__ event, there is an __/on__ message, for an __Off__ event an __/off__ message and for a __Set__ event a __/set__ message. Apart from the latter ones, the engine also outputs an __/idle__ message at a fixed interval when no events are present which may help the host to recover from lost __Off__ events.



@@ 499,13 499,13 @@ _Note: This is a good starting point for writing your own output engine because 

This output engine is susceptible to lost packets and should only be used on small and stable networks with UDP, works fine with TCP, though.

#### /idle
### /idle

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>
</table>

#### /on
### /on

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 548,7 548,7 @@ This output engine is susceptible to lost packets and should only be used on sma
</tr>
</table>

#### /off
### /off

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 559,7 559,7 @@ This output engine is susceptible to lost packets and should only be used on sma
</tr>
</table>

#### /set
### /set

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 594,7 594,7 @@ This output engine is susceptible to lost packets and should only be used on sma

The engine can be run in a redundant data mode where both group ID and type ID are sent for _/set_ and _/off_ messages via [/engines/dummy/redundancy](introspect/#/engines/dummy/redundancy). This has the advantage that the receiver does not have to do any bookkeeping at all, e.g. does not have to remember any blob-group-type ID associations as they are inherently included in each single message. Enabling redundancy however slightly increases used bandwidth.

#### /off
### /off

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 615,7 615,7 @@ The engine can be run in a redundant data mode where both group ID and type ID a
</tr>
</table>

#### /set
### /set

<table>
<tr><th>Type</th><th>Description</th><th>Min</th><th>Max</th></tr>


@@ 664,7 664,7 @@ Ready to use Pure Data sketches using the _Dummy_ engine can be found at our [Pu

The engine is activated via: [/engines/dummy/enabled](introspect/#/engines/dummy/enabled). Output of derivative signals can be toggled via: [/engines/dummy/derivatives](introspect/#/engines/dummy/derivatives).

### OSC-MIDI
## OSC-MIDI

There are numerous ways to translate the event data into MIDI commands, here we just provide the most common ones. If you need an alternate conversion theme, it makes sense to use one of the other output engines and only convert to MIDI on the host. Or you may adapt this output engine to your needs.



@@ 690,7 690,7 @@ The path of the message defaults to __/midi__ and can be changed via [/engines/o

This output engine is susceptible to lost packets (that is the nature of MIDI) and should only be used on small and stable networks with UDP, works fine with TCP, though.

#### /midi
### /midi

<table>
<tr><th>Type</th><th>Description</th></tr>


@@ 716,7 716,7 @@ Ready to use Renoise sketches using the _OSC-MIDI_ engine can be found at our [R

The engine is activated via: [/engines/oscmidi/enabled](introspect/#/engines/oscmidi/enabled).

### Custom
## Custom

The Custom output engine was designed as a compromise when you need a special output format but do not want to (or cannot) implement it into the firmware directly.



@@ 776,7 776,7 @@ Ready to use Renoise sketches using the _OSC-MIDI_ engine can be found at our [R

The engine is activated via: [/engines/custom/enabled](introspect/#/engines/custom/enabled).

#### Example
### Example

The following configuration e.g. can be used to send _/gate_ messages for _on_ and _off_ callbacks and _/cv_ messages for _set_ callbacks. The blob id _$b_ is mapped to the range [0,7]. Position _$x_ is inverted from [0,1] to [1,0]. If vicinity _$z_ is less than 0.5, the second expression returns -1 or 1 otherwise.



@@ 785,7 785,7 @@ The following configuration e.g. can be used to send _/gate_ messages for _on_ a
	$ oscsend ... /engines/custom/append isss $[RANDOM] 'off' '/gate' 'i($b 8%) i(0)'
	$ oscsend ... /engines/custom/append isss $[RANDOM] 'set' '/cv' 'i($b 8%) f(1 $x-) i(1~ 1 $z 0.5&lt;?)'

### Groups
## Groups

To ease handling of multi-touch events, we have introduced the concepts of blob groups. A blob is only detected if it is part of a given group. A group association is only triggered when a blobs position falls within the range the group was defined for and when the magnetic polarity of the blob matches the groups one, too. A given group can respond to a single or both magnetic polarities.



@@ 799,7 799,7 @@ _Chimaera graphical group configurator implemented in SuperCollider showing 8 di

Group settings can be changed through [/sensors/group/attributes](introspect/#/sensors/group/attributes/0), loaded through [/sensors/group/load](introspect/#/sensors/group/load) and saved across reboots through [/sensors/group/save](introspect/#/sensors/group/save).

### Software calibration
## Software calibration

Start calibration routine by getting the device into calibration mode.



@@ 833,7 833,7 @@ Calibration now is done. You may want to test your new calibration and then save

[/calibration/save](introspect/#/calibration/save) ii $[RANDOM] 0

### Reset
## Reset

The _Chimaera_ can boot up in three modes: in soft, in hard or in flash mode. In soft mode, the _Chimaera_ loads its previously stored configuration from EEPROM, whereas in hard mode, the device boots up with factory presets. A soft reset may be necessary for some configuration settings to take effect. A hard reset may be useful in cases where you screwed up the configuration and want to start from scratch. In flash mode, the device can be flashed with an up-to-date or custom firmware.
If the _Chimaera_ is (re)powered, it boots up and loads its saved configuration. A normal startup therefore is equivalent to soft mode.