How to…

This page shows you how to measure different signals such as temperature, pressure, biosignals and how to process them in Python, R, Octave/MATLAB, and gnuplot. If you want to write your own software from scratch there is also a command reference how Attys communicates with your PC or mobile.

Getting started

  1. Switch on the Attys. You should see a blue LED flashing inside.
  2. Pair the Attys with your bluetooh device. If the device asks for a PIN enter 1234. If the device shows a random number then just confirm.
  3. Download the application software you’d like to use and start using your Attys. For initial testing we recommend AttysScope.
  4. During data transmission the blue LED is continuously on.
  5. Charge your Attys with any USB charger. Once its charged the red LED will switch off and the green LED switches on instead.

Recording from different sensors

Attys can measure any sensor signal and also can measure resistance. Because of its wide input range from a few milivolts to volts it can easily measure directly small signals such as biosignals but also larger signals form standard sensors.

Biosignals


Here we show you how to record ECG, EMG and point you to our sister web page which teaches you in depth how to record and analyse bio signals.

To record the data we recommend AttysScope which is our general purpose oscilloscope program so that you learn how to record the signals. Once you know the inner workings of the biosignals you can then switch to AttysECG and AttysEEG which are pre-configured to make your life easier.

BTW: You can order the cables and electrodes in our shop!

General tips how to record biosignals

High gain

Biosignals have very small amplitudes in the region of 1mV or less. If you use AttysScope set the gain to 500 or more to see the biosignals. ECG and EMG are about 1mV whereas EEG is about 50uV. AttysECG and AttysEEG are already configured for the right gain.

Highpass filter / DC removal

Electrodes generate DC potentials because they are wet inside and/or are in contact with skin which releases sweat. Switch on the highpass filter for any biosignal. For ECG and EEG a cutoff of 0.1Hz is advisable. For EMG a 10Hz cutoff is better which removes most cable movements. AttysEEG and AttysECG have DC filters enabled by default.

Mains filter

In theory a differential amplifier removes all mains form the biosignal but in practise that is not the case. In general it is advisable to switch on the mains filter. However, it also adds some ringing around sharp edges. Because the Attys is wireless powerline interferences is less of a problem. Make sure that you choose the correct mains frequency of your country.

Keep cables short and run them under the clothing

Any freely dangling cable will add changing DC shifts to the recording. Avoid lose cables, run them under clothing and keep them as short as possible. That improves the recording quality drastically. For that reason the Attys should be worn, for example on a belt and close to the electrodes. If you record an ECG during jogging or running it’s even advisable to wear tight clothing and run the cables underneath so that there is no movement at all. This also reduces mains interference.

One ECG lead: Einthoven II

  • right shoulder/arm: “-“
  • left hip/leg: “+”
  • right hip/leg: “GND”

This is the most popular configuration which usually has the strongest signal.

Settings for AttysScope

  • Gain: x500 or more
  • Highpass(HP)/DC filter: on at 0.1Hz
  • Mains bandstop (BS): on

The same settings apply for the other ECG configurations.

Two/three ECG leads: Einthoven I,II,III

The Attys can also be configured to record in the classical Einthoven fashion where one of the electrodes is shared between two channels. Select the special Einthoven/ECG mode in AttysScope/attys-scope or in the JAVA/C++ API for both channels. In this configuration the two “+” inputs of the Attys are internally connected so that we need to connect only one electrode to “+”. The 2nd Channel measures then between the “+” electrode and “GND” so that the GND electrode has two roles: it provides the “-” electrode of channel two and acts as the overall reference.

Measuring Einthoven II,III


Channel 1 records Einthoven II and Channel 2 of the Attys Einthoven III:

  • right shoulder: “-” connected to Channel 1
  • left shoulder: “GND”
  • left leg: “+” connected to Channel 1.

Calculating Einthoven I

Wonder how to get Einthoven I? Just calculate the first Einthoven lead with I=II-III. There are similar formulas for the other leads such as aVL, aVR and aVF.

Two independent biosignal channels (ECG, EMG, EEG, EOG, …)

If you want to record two independent channels then use the differential inputs of channel 1 as before and in addition channel 2 is measured between the ch2 terminal and GND.

  • Channel 1: “+” against “-“
  • Channel 2: “+” against “GND” which is internally connected to “-” of Channel 2

For example for Holter style recordings one might want to place the channel 2 electrodes on the chest while channel 1 records Einthoven II.

In case you wonder why this works with “GND” connected to “-” for the 2nd channel, here is the full explanation: GND is just a technicality to bring all inputs within the working range of the amplifiers. GND won’t feature in the measurement result as it’s subtracted out. Internally the Attys Instrumentation amplifier does the following (for both channels): Chx = (‘+’ – GND) – (‘-‘ – GND) = ‘+’ – ‘-‘ – ‘GND’ + ‘GND’ = ‘+’ – ‘-‘ which means it first measures the signals from both the ‘+’ and ‘-‘ plugs against GND and then subtracts them. You see that GND cancels out. So one can set GND to any voltage and even just connect it to ‘-‘ which is done in the Attys to save a plug!

EMG

Electrode placement

One channel: Muscle activity can be measured by placing the +/- electrodes right over the muscles and the reference electrode (GND) close by.

Two channels: For channels one place the “+” and “-” over the one muscle and “+” and GND of channel 2 over the other muscle.

Recording settings

  • Use AttysScope to record the EMG
  • Set the highpass (DC) filter to 10Hz
  • Enable 50/60Hz mains filter removal
  • Monitor the muscle strength with the peak to peak values (text or window on the right)

Postprocessing

This Python script calculates the amplitude of the EMG signal and then smooths it with an averaging filter with 1s duration:

import numpy as np
import pylab as pl
data = np.loadtxt('emg.tsv');
y = data[:,10];
y2 = abs(y);
w = 250;
y3 = np.convolve(y2,np.ones(w)/w,mode='same');
# plot the EMG
plt.subplot(211)
plt.plot(y)
plt.ylabel('EMG/V')
plt.subplot(212)
# plot the amplitude
pl.plot(y3);
pl.show();

Column 10 of the datafile contains the filtered signal of analogue channel 1. Column 11 contains the channel 2. If you want to process EMG from two muscles, for example extensor and flexor, just extract the 2nd channel with y4=data[:,11] and then do the same processing for it as done for channel 1.

Here is a plot where we recorded from the biceps (channel one) and triceps (channel two) and applied the above script twice to the two separate channels.

EEG

This is a pretty complex topic — because you need to learn how to distinguish between brain activity and artefacts: for example which waves in the video above originated from muscle activity and which from Kirsty’s brain? To get started check out our biosignal pages and take it from there!

Settings for AttysScope:

  • Gain: x1000 or more
  • Highpass(HP)/DC filter: on at 0.1Hz
  • Mains bandstop (BS): on

Electrodes

For EEG you need to place at least one electrode over a section of the head where there is most probably hair. As you see in the video we use a headband to keep the electrode in place. There are special electrodes which are called cup electrodes which hold a small amount of electrode gel and then are kept in place with an EEG-cap or a headband. If you haven’t got any of these electrodes at hand than you can also use standard ECG electrodes and just use a scissor to remove the adhesive part of the electrode so that it wont stick to any hair. This has also the advantage that you won’t need to add any electrode gel to it as the ECG electrodes come with pre-applied electrode gel.

Evoked potentials (VEP/AEP)

EEG is buried in a high amount of EMG noise. However, if we stimulate the brain repetitively and then measure the EEG over and over again then we can average out the muscle noise which eventually will make the EEG stand out. This is shown above in the clip for a visual stimulus and is called visually evoked potential (VEP). AttysEEG can also generate auditory stimuli which are then repeated many times. This is called Auditory Evoked Potential (AEP).


Visually Evoked Potentials (VEP)


Traditionally, the electrodes are placed with “+” at the back of the head, the “-” on the forehead and the GND on the mastoid. However the “-” at the forehead generates strong eye blink artefacts. As alternative one can place the “-” behind the other ear to reduce eyeblink artefacts. They will eventually average out but it just makes the experiment shorter. Electrode positions are:

  • “Attys Channel 1: +”: at Oz at the back of the head over the visual cortex
  • “Attys Channel 1: -“: at Fz on the forehead
  • “Attys GND” at A1 or A2 at the mastoid or behind the ears where good contact is guaranteed and it’s comfortable. Exact position is not important.

The experimental procedure is:

  1. Attach electrodes as described
  2. Sit in a comfortable position so that muscle activity is minimal, look at the screen and relax!
  3. Switch on the VEP stimulus / recording
  4. Wait for 200 sweeps or more until the VEP appears
  5. Switch off the VEP stimulus / recording
  6. Move about normally again.

ISCEV standard for clinical visual evoked potentials


Acoustically Evoked Potentials (AEP)


Here we measure the response of the auditory cortex which is behind the ears. Consequently, the active electrode is behind the ear and the negative one on the forehead. The GND is behind the other ear.

  • “Attys Channel 1: +”: behind the ear over the auditory cortex
  • “Attys Channel 1: -“: at Fz on the forehead
  • “Attys GND” at A1 or A2 at the mastoid or behind the ears where good contact is guaranteed and it’s comfortable. Exact position is not important.

The experimental procedure is:

  1. Attach electrodes as described
  2. Sit in a comfortable position so that muscle activity is minimal and wear a headphone for the stimulus
  3. Do a quick test run to adjust the headphone loudness. It should be clearly audible
  4. Switch on the AEP stimulus / recording
  5. Wait for 1000 sweeps or more until the VEP appears
  6. Switch off the VEP stimulus / recording
  7. More about normally again

Because the AEP is smaller than the VEP one needs to wait a bit longer. Watch a movie with subtitles or let the radio run the background. The AEP won’t be affected. It’s also advisable to lie down in a comfortable position to avoid muscle activity and closing the eyes helps to avoid eyeblink artefacts.

Learn in depth about biosignals

If you want to learn in depth how to record different biosignals such as ECG, EEG and EMG then check out the biosignal howto pages where we explain with YouTube videos how to record ECG, EMG, EEG and other modalities. All experiments on this web page can be done with the Attys.

Learn how to measure temperature, acceleration, light intensity and many other physical quantities

Watch Aidan how he measures the acceleration of a meccano car, the temperature of an iron with a thermocouple and provides the answer for the 2nd most important question in the universe: if the light in a fridge really goes off when the fridge door is closed.

Acceleration and orientation

The Attys contains a 3 axis high precision accelerometer which you can use to determine velocity and position by integrating its signal. The built in compass can be used to determine the orientation of the Attys and provides an absolute frame of reference.

Temperature

Thermocouple

Thermocouples can be used to measure temperatures as high as 2000 degrees Celsius.

Thermocouples generate a small voltage which is proportional to the measured temperature. In our store you can buy a K type thermocouple which gives us 39uV/C. This voltage is called Seebeck voltage and is generated when two different kind of wires are welded together. The trouble is that these two wires end up inside of a plug containing probably two copper clamps which will give us an additional voltage. People call this place “cold junction” where this unwanted voltage is generated. The cold junction reduces the voltage measured which we can be written down as a simple formula:

V_out = a (T_h – T_c)

where a is the so called Seebeck coefficient which is 39uV/C for our K type sensors and T_h and T_c are our hot and and cold junction temperatures. In other words, T_h is the actual temperature we would like to measure whereas T_c is the temperature of our socket at the pre-amplifier. We see that we subtract the temperature of the cold junction from the temperature from the hot junction. With a bit of school math we arrive at our formula which converts the voltage to temperature:

T_h = V_out / a + T_c

attsy-scope for Windows/Linux and in generaly the C++/JAVA/Python API can measure from Attys internal temperature sensor so that it’s easy to calculate the temperature from the thermocouple. There are example programs in Python for both the Python API and attys-scope.

You can also measure temperature with the help of an NTC resistor. This is a resistor which decreases its resistance when heated up. The Attys can also measure resistance so that also an NTC can be connected to it — without any additional components.

LM35

The temperature sensor LM35 is a classic under the temperature sensors. It is housed in a standard plastic transistor package and just needs about 5V supply voltage, for example three 1.5V battery cells. The LM35 outputs 10mV/C so that the Attys can easily cover temperatures from zero degrees up to 100C.

To turn it into a temperature probe just solder a ribbon cable on the sensor and then put some epoxy over the pins. If the cable is quite long the LM35 tends to oscillate wildly which can be prevented by adding a 2.2K load resistor from its output to GND.

Light intensity

The LDR reduces its resistance when light shines on it. With the Attys in resistance measuring mode one can measure light intensity straight away.

Mechanical strain

This is a piezo sounder which you can find in your noisy greeting cards. There it’s used as a speaker but it can also be used as a sensor. Just connect it to the unipolar input of the Attys and in parallel a 1M resistor. This is the same sensor which has been used in the demo video.

Mechanical pressure

This is a force resistive sensor (FSR) which decreases its resistance when you apply pressure to it. The Attys can measure resistance by sending a small current through the external component so that no external components are required.

Processing your data

The data format of the Attys software packages

All Attys software packages save the data in human readable form as a text file. Every line in the textfile is a sample taken at a certain moment in time. Every column is a channel. The channels are separated by a tabstop. Such a datafile is called “tab separated values” or TSV. If you want to archive it later you can just zip it and will then yield even smaller sizes than comparable binary formats.

In the following sections we show you how the data can be imported into different software packages for post-processing.

Python

TSV files are python compatible so that you can load them into two dimensional numpy arrays.

Plotting

import numpy as np
import pylab as pl
data = np.loadtxt('demo_ecg.tsv');
pl.plot(data[0:1000,0],data[0:1000,2]);
pl.xlabel('time/sec');
pl.ylabel('II/V');
pl.show();

Both numpy and pylab are feature rich libraries which allow you to do signal processing and analysis of your data.

Check out github for examples.

Filtering of data

Python’s scipy library has powerful functions to process the data. Here is an example which first performs highpass filtering on the input signal and then bandstop filtering at 50Hz to remove mains interference.

# sampling rate
fs = 250
# highpass Butterworth filter
cutoff = 0.25
# create a 4th order highpass
b, a = signal.butter(2, cutoff/fs*2.0, 'highpass')
# filter the signal adc1
adc1filt = signal.lfilter(b, a, adc1)
# create a 2nd order order stopband filter at 50Hz
# to remove the 50Hz mains
f1 = 45
f2 = 55
b, a = signal.butter(2, [f1/fs*2.0, f2/fs*2.0 ], 'bandstop')
# filter the 1st ADC channel
adc1filt = signal.lfilter(b, a, adc1filt)

Record data directly with Python

For the pure Python enthusiasts there are Python scripts on github which demonstrate how to directly read data from the Attys, filter and display it. You can also write Python add ons for attys-scope for Windows. The are numerous examples on github.

OCTAVE / MATLAB(tm)

OCTAVE allows you to filter, plot and post-process the data you’ve recorded with the Attys.

Loading tab separated data in a matrix

With the command

load mysignal.tsv

you load the TSV file into the matrix ‘mysignal’. The different channels are now in the different columns of the matrix. Every row contains the samples from one moment in time.

Extracting one channel

Let’s extract the analogue channel which is in column 8:

y=mysignal(:,8);

This command stores channel one in the vector ‘y’.

Plotting the channel

Use use the ‘plot’ command to create a graph of the signal:

plot(y)

The plot command can also plot time against data so if you extract the time t=mysignal(:,1); as well then you can plot your data against the timestamps:

plot(t,y);

Filtering of the signal

With just three commands one can filter the signal. For example, a lowpass filter at cutoff frequency 10Hz can be set up with these commands:

pkg load signal %(OCTAVE only)
[b,a]=butter(4,10/250*2); % filter coefficients
y2=filter(b,a,y); % filter the signal

This sets up a 4th order Butterworth lowpass filter with a cutoff frequency of 10Hz where the sampling rate of the Attys has been at 250Hz. Type ‘help butter’ how to set up other filters.

R stats

Loading data into R

data <- read.table("mydata.tsv")

The data shows up as a two dimensional array where every row is a sample.

Plotting data

We extract the columns needed and then plot them.

t = data[,1]
y = data[,2]
plot(t,y,"l")

GNUPLOT

GNUPLOT is a plot program which uses simple text commands to plot data. It's available for a myriad of different platforms, for example for Windows, MAC, Linux, Android and MACOS.

Plotting

The plot command is central in gnuplot:

plot "mysignal.tsv" using 1:8 with lines

The 'using' keyword selects the columns (here 1 against 8) and 'with lines' tells gnuplot to join the datapoints with lines.

Saving the plot as a graphics file

gnuplot can save in many different formats. As an example let's say we'd like to export the plot as a PNG image for a web page:

set term png
set output "channel1.png"
replot

which replots the last plot but into the PNG image 'channel1.png'.

How to talk to the Attys directly?

The Attys communicates with the host via the bluetooth serial port emulation called "rfcomm" which means that it transmits the measured values as text and receives text commands.

  • Data from Attsy to host: either CSV or BASE64
  • Data from the host to the Attys: text commands

These are the text commands you send to the Attys to change its settings. All commands need to be transmitted without any space and are in general in the form single letter, equal sign and a number. If the command has been understood the Attys reports "OK" back. Only the x=1 command (starts sending data) won't send "OK". Note that you first need to stop the data transmission with the command x=0 to issue any other command.

  • Stop data transmission: x=0
  • Start data transmission: x=1
  • Sampling rate:
    • 125Hz (base64/CSV): r=0
    • 250Hz (base64): r=1
    • 500Hz (base64): r=2 (experimental)
    • 1kHz (base64): r=3 (experimental)
  • Data format:
    Data is transmitted as unsigned integers. For the ADC converters the conversion is:
    inVolt = (raw_data - 0x800000) / 0x800000 * 2.42 / ADC_GAIN;
    where the ADC_GAIN is set by the a= and b= commands (default is a gain of 6). For the accelerometer and magnetometer the conversion is:
    inphysicalunits = (raw_data - 0x8000) / 0x8000 * fullScaleRange
    where the full scale range for the magnetometer is 4800.0E-6F and the full scale range for the accelerometer is set by the t= command (see below). The default is 16G. The timestamp is 8 bit and wraps around. If samples cannot be transmitted the timestamp might have gaps so that missing samples can be detected. adc_gpio carries in bits zero and one the internal gpio pins. Bit 7 of adc_gpio is set to one if power is connected for charging.
    • CSV data output (default): d=0
      sprintf(tmp,"01,%02x,%04x,%04x,%04x,%04x,%04x,%04x,%04x,%04x,%04x,%l06x,%l06x,%02x",
      timestamp,
      accel_x,accel_y,accel_z,
      mag_x,mag_y,mag_z,
      adc_ch1,adc_ch2,adc_gpio);
    • Base64/binary (recommended for 250Hz): d=1
      struct __attribute__((__packed__)) bin_data_t {
      uint32_t adc_ch1 : 24;
      uint32_t adc_ch2 : 24;

      uint8_t adc_gpio;
      uint8_t timestamp;

      uint16_t accel_x;
      uint16_t accel_y;
      uint16_t accel_z;

      uint16_t mag_x;
      uint16_t mag_y;
      uint16_t mag_z;

      The short version with just the ADCs transmitted is (f=0,d=1):

      struct __attribute__((__packed__)) bin_data_t {
      uint32_t adc_ch1 : 24;
      uint32_t adc_ch2 : 24;

      uint8_t adc_gpio;
      uint8_t timestamp;
  • Send status back to a terminal (for example putty): i=0
  • Master reset: m=0
  • Accelerometer full scale range:
    • 2G: t=0
    • 4G: t=1
    • 8G: t=2
    • 16G: t=3
  • Partial/full data set:
    • Full data set with all channels: f=1
    • ADC data only: f=0
      Note that this has no effect on CSV data.
  • Gain/Multiplxer: this command uses the upper 4 bits (called here ggg) of a byte for the gain and the lower 4 bits to set the multiplexer (called here mmm):
    0ggg0mmm
    The bits ggg set the gain for the ADC at
    0: x6, 1: x1, 2: x2, 3: x3, 4: x4, 5: x8, 6: x12

    Settings for the multiplexer are
    mmm=0 for normal operation, mmm=1 for connection to GND, mmm=4 for the internal temperature sensor and mmm=6 for an internal connection between both analogue "+" inputs for ECG/Einthoven recordings on both channels.

    • Set mux/gain of ADC channel 1: a=0ggg0mmm as a decimal number, for example a=16 sets the gain to 1 because 16=00010000 and a=0 sets the gain to 6.
    • Set mux/gain of ADC channel 2: b=0ggg0mmm as a decimal number.
  • Constant Current: you can switch on a constant current on a channel to measure the resistance against GND. This is useful to determine the electrode resistance or to measure resistance in general. There are two commands: the i-command sets the current and the c-command sets the channel.

    • Switch on current on:
      • Channel 1 "+" socket against GND: "c=1"
      • Channel 1 "-" socket against GND: "c=2"
      • Channel 2 "+" socket against GND: "c=4"
    • Set current in uA:
      • 6nA: "i=0"
      • 22nA: "i=1"
      • 6uA: "i=2"
      • 22uA: "i=3"

    Note that the Attys has protection resistors at its input sockets so that even when you short-circuit the sockets to GND you'll measure a voltage. The series resistance is 55K which you need to subtract from any absolute resistance readings.

Disclaimer: Use the information shown on this page and the other related pages at your own risk. See the disclaimer in the CC Attribution-Noncommercial-Share Alike 3.0 Unported license. Safety first: when recording biosignals always use an electrically isolated Attys for all signal- and power-connections when conducting experiments with subjects. If you measure biosignals from other people you might need to apply for ethical approval. Make sure that the subject is electrically isolated from the mains at all times! Never record biosignals while the Attys is being charged.

Except where otherwise noted, content on this page is licensed under the following license: CC Attribution-Noncommercial-Share Alike 4.0 International.