Do It Your Vibe

autocostruzione di oggetti vibranti grazie ad Arduino

ingredienti hardware (quelli che ho usato io, ma va bene qualcosa di equivalente):

  1. arduino
  2. motore vibrante (io ho usato un 310-101 della Precision Microdrives)
  3. resistenza da 33Ω
  4. diodo lineare (1N4001)
  5. transistor PNP (TO92, BC557A)

La parte hardware è molto semplice: vogliamo controllare la vibrazione del nostro motore vibrante con Arduino, ovvero con un suo pin output PWM. Siccome i pin di input/output non reggono il carico di un motore elettrico, bisogna usare un’altra fonte: nel nostro caso basta il pin dei 5v di Arduino, ma in casi di motori più grossi sarebbe il caso di usare batterie/alimentatori esterni (bisogna controllare nella scheda tecnica del motore quanto è il consumo di corrente in mA e confrontarlo con quanto arduino può fornire – cercate sul sito di Arduino). Il diodo serve ad evitare che il motore, girando per inerzia, produca una corrente che risalga in senso opposto fino al nostro alimentatore, facendolo arrabbiare non poco. La resistenza è per lo più simbolica ad evitare che si cortocircuiti quando il motore, girando a regime, fa poca resistenza (o qualcosa del genere).

Il transistor è il vero clou della questione: i piedini esterni si infilano nel circuito (indipendente) del motore, ed il piedino centrale controllerà, come un interruttore graduato, la corrente che passerà attraverso il transistor (e quindi quanto girerà il nostro motore).

Tutto ciò spiegato come lo spiegherei al bar. Più precisamente:

Fatto ciò, dobbiamo programmare il nostro amico Arduino. Abbiamo un output – il Pin 11 in PWM – che controllerà quanto e come vibrerà il nostro motore vibrante. Dobbiamo dunque collegarci un input, che può provenire da:

  • un pulsante
  • un potenziometro
  • un sensore di pressione/temperatura/luce
  • un computer

nel nostro caso, abbiamo deciso di collegare un pc in seriale, in modo da poterci sbizzarrire come più ci piace. Quindi, il nostro arduino ascolterà sulla porta seriale per un byte, e userà questo come valore per l’output del pin 11 – niente di più banale, a dire il vero.

const int vibePin = 11;
int vibeVal;
void setup() {
    Serial.begin(9600);
    Serial.println("BEGIN");
    analogWrite(vibePin, 255);
}
 
void loop() {
    if (Serial.available()){
         vibeVal = Serial.read();
         vibeVal = map(vibeVal, 0, 255, 50, 255);
         vibeVal = constrain(vibeVal, 0, 255);
         if (vibeVal < 55)
             vibeVal = 0;
         analogWrite(vibePin, 255 - vibeVal);
     }
}

Questo codice in realtà fa un po’ di più: dati scientifici dimostrano, che il motore vibrante in mio possesso, si spegne totalmente se il valore del pin viene settato sotto una certa soglia, e non parte se il valore non supera un’altra soglia, leggermente più alta della prima (si fa più fatica ad accenderlo che a tenerlo acceso, un po’ come le auto). Il valore di queste due soglie dipende dal motore e dalla resistenza, per cui fate delle prove. Per tagliare la testa al toro, dopo qualche tentativo, ho deciso che al di sotto della soglia di “startup”, quella per farlo partire da fermo, non mi interessava arrivarci, né da fermo né da acceso. La vibrazione era troppo poco percepibile per preoccuparsi di tenere il motore acceso a quel livello. Il valore di output (originariamente dicevamo è un byte, quindi tra 0 e 255) viene rimappato (tra 50 e 255) e tutto ciò che è sotto la soglia viene buttato a zero.

L’effetto finale è buono. Il motore non si spegne quando non deve.

A questo punto bisogna scrivere qualcosa sul proprio pc che si colleghi alla seriale e controlli il vibratore. Se ci pensate 5 minuti, sicuro vi vengono in mente almeno 3-4 buone idee. Io ho realizzato questa, con Processing, copiando-e-incollando i vari esempi che ho trovato nel pacchetto:

import processing.serial.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
 
Minim minim;
//AudioPlayer in;
AudioInput in;
BeatDetect beat;
BeatListener bl;
Serial sPort;
 
float[] beats;
int vibe;
 
void setup()
{
  String portName = Serial.list()[0];
  sPort = new Serial(this, portName, 9600);
 
  size(512, 200);
  smooth();
 
  minim = new Minim(this);
  minim.debugOn();
 
  in = minim.getLineIn(Minim.STEREO, 512);
  // in = minim.loadFile("musica.mp3",2048);
  // in.play();
 
  beat = new BeatDetect(in.bufferSize(), in.sampleRate());
  beat.setSensitivity(300);
  bl = new BeatListener(beat, in);  
 
  beats = new float[3];
}
 
int sumarr(float[] a){
  float sum = 0;
  for (int i = 0; i < a.length; i++)
    sum += a[i];
  return int(sum);
}
 
void decrease(float[] a) {
  for (int i = 0; i < a.length; i++)
    a[i] = constrain(a[i]*0.95,0,255/3);
}
 
void draw()
{
  background(0);
  stroke(255);
  if ( beat.isKick() ) beats[0] = 255/3;
  if ( beat.isSnare() ) beats[1] = 255/3;
  if ( beat.isHat() ) beats[2] = 255/3;
 
  sPort.write(constrain(sumarr(beats),0,255));
  decrease(beats);
  for(int i = 0; i < in.bufferSize() - 1; i++){
     line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
     line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
   }
}
 
void stop()
{
  sPort.write(0);
  in.close();
  minim.stop();
  super.stop();
}

Il file BeatDetect l’ho copiato pari pari dagli esempi, lo trovate in FrequencyEnergy.pde (Examples->Library->Minim), anche se ho dovuto modificarlo in questa maniera (va messo come nuovo tab in Processing, per chi non lo sapesse, e deve chiamarsi BeatListener):

class BeatListener implements AudioListener
{
  private BeatDetect beat;
  private AudioSource source;
 
  BeatListener(BeatDetect beat, AudioSource source)
  {
    this.source = source;
    this.source.addListener(this);
    this.beat = beat;
  }
 
  void samples(float[] samps)
  {
    beat.detect(source.mix);
  }
 
  void samples(float[] sampsL, float[] sampsR)
  {
    beat.detect(source.mix);
  }
}

Questo simpatico pezzo di codice prende l’audio del vostro microfono, ve lo disegna come onda di frequenze per il vostro piacere, ma soprattutto analizza ritmo e battiti e li converte, un po’ grossolanamente, in un byte che viene sputato lungo la seriale fino al vostro ardu-vibro. Scommentando e commentando le giuste righe (non ce ne sono altre), si può usare un file audio invece del microfono. Penso che si possa anche prendere direttamente l’uscita finale del vostro pc ed usare direttamente quella come sorgente audio, anche se non c’è tra il codice commentato.

2 pensieri su “Do It Your Vibe

  1. intanto non so perché mi scambi per reginazabo 🙂 non che mi spiaccia!

    il motore l’ho preso da SparkFun qui http://www.sparkfun.com/products/8449 però penso che si riescano a trovare cose simili in italia. guarda sul sito di arduino l’elenco dei rivenditori, non solo quelli italiani: io ho trovato ottimi prezzi di spedizione anche da quelli tedeschi e inglesi. O comunque dei buoni negozi di elettronica per hobbisti, sicuro che nel produttivo nord-est qualcosa trovi! 😀

    appena ho tempo aggiungo delle foto: il motore è provvisto di un comodo adesivo, ed io l’ho inserito dentro una scatolina di plastica, fa proprio la sua porca figura…

  2. Ciao reginazabo,
    mi chiamo Marco e sto facendo una tesi di Interaction Design. Innanzitutto grazie del tutorial: adesso so che il prototipo che vorrei fare può funzionare! Seconda cosa, volevo chiederti dove hai comprato il motore: direttamente da precision microdrives o da un rivenditore in Italia? Vorrei fare delle prove con dei motori diversi, anche perché non li ho mai usati (al massimo un caro vecchio servo). Quindi volevo sapere se hai notizia di rivenditori italiani, così mi evito lo smazzo delle spese di spedizione. Son a Padova, magari conosci pure un rivenditore in zona, sarebbe fantastico!
    Grazie ancora del tutorial! Ciao,
    Marco

I commenti sono chiusi.