==============================
Giocherellare con un Mind Flex
==============================
:CreationDate: 2015-10-23 13:11:34
:Id: HW/mindflex
:tags: - hardware
- software
Qualche tempo fa comprai un `Mind Flex`_, con l'idea di interfacciarlo
a qualche motore, e controllare qualcosa **con la mente**!
Ovviamente è rimasto su uno scaffale per anni.
Successivamente mi sono procurato un `MicroView`_, perché è bellino.
Ovviamente, pure quello è rimasto su uno scaffale per anni.
Oggi ho finalmente messo assieme le due cose.
.. _`Mind Flex`: http://store.neurosky.com/products/mindflex
.. _`MicroView`: http://learn.microview.io/Intro/general-overview-of-microview.html
Il software
===========
Prima di tutto, ho dovuto mettere su l'IDE Arduino e il
compilatore. Farlo su una Gentoo è meno ovvio di quanto dovrebbe, ma
grazie a `un post molto chiaro su sito Apollo NG`_ sono riuscito a
installare il tutto::
emerge arduino crossdev dev-java/rxtx
USE="multilib -cxx" crossdev -s1 --without-headers \
--target avr \
--gcc 4.5.4 --binutils 2.21.1-r1 --libc 1.7.0
USE="multilib cxx" crossdev -s4 \
--target avr \
--gcc 4.5.4 --binutils 2.21.1-r1 --libc 1.7.0
ln -nsf /usr/x86_64-pc-linux-gnu/avr/lib/ldscripts \
/usr/avr/lib/ldscripts
ln -nsf /usr/x86_64-pc-linux-gnu/avr/lib/ldscripts \
/usr/x86_64-pc-linux-gnu/avr/binutils-bin/2.20.1/ldscripts
cd /usr/avr/lib
ln -nsf avr5/crtm328p.o .
ln -nsf avr6/crtm2561.o .
ln -nsf avr6/crtm2560.o .
.. _`un post molto chiaro su sito Apollo NG`: https://apollo.open-resource.org/mission:log:2015:01:20:gentoo-crossdev-compile-avr-gcc-for-arduino-and-cura
Librerie Arduino
----------------
Mi sono servite due librerie: quella per `leggere i dati del EEG
Neurosky`_ e quella per `controllare l'hardware del Microview`_.
Le ho clonate della directory del mio "sketchbook"::
mkdir -p ~/sketchbook/libraries
cd ~/sketchbook/libraries
git clone git@github.com:geekammo/MicroView-Arduino-Library.git \
MicroView
git clone git@github.com:kitschpatrol/Brain
Notare che la libreria del MicroView deve stare in una cartella
chiamata ``MicroView``, e non ``MicroView-Arduino-Library``: l'IDE
Arduino ha delle restrizioni sui nomi delle librerie.
.. _`leggere i dati del EEG Neurosky`: https://github.com/kitschpatrol/Brain
.. _`controllare l'hardware del Microview`: https://github.com/geekammo/MicroView-Arduino-Library/
L'hardware
==========
Ho seguito le istruzioni che ho trovato su `Frontier Nerds`_: ho
saldato un file al piedino "T" della scheda Neurosky, un filo a massa,
e (aggiunta mia) un filo al "+" della batteria. In questo modo posso
alimentare il MicroView con le batterie del Mind Flex: quando avevo
provato a alimentarli separatamente, la scheda Neurosky non riusciva a
prendere il segnale, probabilmente a causa del rumore sulla linea di
alimentazione.
Ho poi connesso (tramite una piccola breadboard, per il momento) il
MicroView ai fili: massa al piedino 8, alimentazione al piedino 16,
segnale al piedino 9 (ingresso seriale).
.. _`Frontier Nerds`: http://www.frontiernerds.com/brain-hack
Il programma
============
Questo è il programmino, molto semplice, che ho scritto::
#include <MicroView.h>
#include <Brain.h>
// il MindFlex è connesso alla seriale
Brain brain(Serial);
void setup() {
// il MindFlex parla a 9600 bps
Serial.begin(9600);
// prepara il display del MicroView
uView.begin();
uView.clear(ALL);
// usa il font più piccolo, 5x7
uView.setFontType(0);
}
const int hist_width=3;
const int hist_pad=1;
void loop() {
if (brain.update()) { // abbiamo dati da mostrare?
uView.clear(PAGE);
// mostra la qualità del segnale, 0=buono, 200=nessun segnale
uView.setCursor(0,0); uView.print(brain.readSignalQuality());
// mostra i due segnali di "alto livello"
uView.setCursor(0,9); uView.print(brain.readAttention());
uView.setCursor(18,9); uView.print(brain.readMeditation());
// ci sono poi 8 bande di frequenza
const uint32_t* power = brain.readPowerArray();
// trova il massimo, per scalarle
uint32_t max_value=0;
for (int x=0;x<8;++x) {
if (power[x] > max_value) {
max_value = power[x];
}
}
// disegna un semplice istogramma
for (int x=0;x<8;++x) {
int x0 = (hist_width + hist_pad) * x;
// abbiamo 30 pixel in verticale
int height = power[x] * 30 / max_value;
for (int o=0;o<hist_width;++o) {
uView.lineV(x0+o,47-height,height);
}
}
// copia il buffer sul display
uView.display();
}
}
E questo è tutto.